@brainbase-labs/cli 0.49.0 → 0.51.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/README.md +11 -6
- package/dist/index.js +320 -191
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -116,18 +116,23 @@ this confirms admission or delivery, not task success.
|
|
|
116
116
|
|
|
117
117
|
## Renaming and labelling tasks
|
|
118
118
|
|
|
119
|
-
|
|
119
|
+
Label a task when you create it, find tasks by label, and change a task's
|
|
120
|
+
title, its labels or its model, including while it runs:
|
|
120
121
|
|
|
121
122
|
```sh
|
|
122
|
-
brainbase task
|
|
123
|
+
brainbase task create --message "Nightly smoke run" --metadata env=staging
|
|
124
|
+
brainbase task list --metadata env=staging
|
|
125
|
+
brainbase task update <task-id> --title "Nightly smoke run" --metadata env=prod
|
|
123
126
|
brainbase task update <task-id> --unset-metadata env --json
|
|
124
127
|
brainbase task update <task-id> --model claude-sonnet-5-5
|
|
128
|
+
brainbase task update <task-id> --clear-model
|
|
125
129
|
```
|
|
126
130
|
|
|
127
|
-
`--metadata` and `--unset-metadata` keep every label you do not name
|
|
128
|
-
|
|
129
|
-
`--model` switches the model the
|
|
130
|
-
running keeps its model.
|
|
131
|
+
`--metadata` and `--unset-metadata` keep every label you do not name, and
|
|
132
|
+
edits from several clients at once all survive. `--clear-metadata` removes them
|
|
133
|
+
all, and `--clear-title` removes the title. `--model` switches the model the
|
|
134
|
+
task's next turn runs on; a turn already running keeps its model.
|
|
135
|
+
`--clear-model` returns the task to its agent's default model. See
|
|
131
136
|
[the command reference](docs/reference/commands.mdx) for every flag.
|
|
132
137
|
|
|
133
138
|
## Benchmark management
|
package/dist/index.js
CHANGED
|
@@ -36091,7 +36091,7 @@ function padStart(s, n) {
|
|
|
36091
36091
|
// package.json
|
|
36092
36092
|
var package_default = {
|
|
36093
36093
|
name: "@brainbase-labs/cli",
|
|
36094
|
-
version: "0.
|
|
36094
|
+
version: "0.51.0",
|
|
36095
36095
|
description: "Pack, share, and install agent templates across harnesses (Claude Code, Codex, ...).",
|
|
36096
36096
|
type: "module",
|
|
36097
36097
|
bin: {
|
|
@@ -68334,6 +68334,9 @@ var import_picocolors30 = __toESM(require_picocolors(), 1);
|
|
|
68334
68334
|
function sanitizeLabel(s3) {
|
|
68335
68335
|
return s3.replace(/\u001b\][\s\S]*?(?:\u0007|\u001b\\|$)/g, "").replace(/\u001b\[[\u0030-\u003f]*[\u0020-\u002f]*[\u0040-\u007e]?/g, "").replace(/\u001b[\s\S]?/g, "").replace(/[\u0000-\u001f\u007f-\u009f\u2028\u2029]/g, "");
|
|
68336
68336
|
}
|
|
68337
|
+
function sanitizeLines(s3) {
|
|
68338
|
+
return s3.split(/\r\n|[\n\r\u2028\u2029]/).map(sanitizeLabel);
|
|
68339
|
+
}
|
|
68337
68340
|
|
|
68338
68341
|
// src/cli/agent-status.ts
|
|
68339
68342
|
function capabilityDrifted(field) {
|
|
@@ -86110,8 +86113,173 @@ async function waitForAccount(agentId, slug, before2, options) {
|
|
|
86110
86113
|
var import_picocolors68 = __toESM(require_picocolors(), 1);
|
|
86111
86114
|
|
|
86112
86115
|
// src/cli/task-create.ts
|
|
86113
|
-
var
|
|
86116
|
+
var import_picocolors64 = __toESM(require_picocolors(), 1);
|
|
86114
86117
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
86118
|
+
|
|
86119
|
+
// src/cli/task-update.ts
|
|
86120
|
+
var import_picocolors63 = __toESM(require_picocolors(), 1);
|
|
86121
|
+
var TASK_UPDATE_USAGE = "brainbase task update <task-id> [--title <text> | --clear-title] [--metadata key=value]... [--unset-metadata <key>]... [--clear-metadata] [--model <id> | --clear-model] [--json]";
|
|
86122
|
+
var TITLE_MAX = 200;
|
|
86123
|
+
var MODEL_UNSUPPORTED = "This control plane does not support changing a task's model yet.";
|
|
86124
|
+
var CLEAR_MODEL_UNSUPPORTED = "This control plane does not support resetting a task's model yet.";
|
|
86125
|
+
async function runTaskUpdate(taskId, options) {
|
|
86126
|
+
const title = validTitle(options);
|
|
86127
|
+
const labels = validLabelEdit(options);
|
|
86128
|
+
const model = validModel(options);
|
|
86129
|
+
if (title === undefined && !labels && !options.clearMetadata && model === undefined && !options.clearModel) {
|
|
86130
|
+
throw new Error(`Nothing to update: pass --title, --clear-title, --metadata, --unset-metadata, --clear-metadata, --model or --clear-model.
|
|
86131
|
+
` + `Usage: ${TASK_UPDATE_USAGE}`);
|
|
86132
|
+
}
|
|
86133
|
+
const input = {};
|
|
86134
|
+
if (title !== undefined)
|
|
86135
|
+
input.title = title;
|
|
86136
|
+
if (options.clearMetadata) {
|
|
86137
|
+
input.metadata = Object.fromEntries(labels?.set ?? []);
|
|
86138
|
+
} else if (labels) {
|
|
86139
|
+
input.metadata_patch = {
|
|
86140
|
+
set: Object.fromEntries(labels.set),
|
|
86141
|
+
unset: [...labels.unset]
|
|
86142
|
+
};
|
|
86143
|
+
}
|
|
86144
|
+
if (model !== undefined)
|
|
86145
|
+
input.model = model;
|
|
86146
|
+
if (options.clearModel)
|
|
86147
|
+
input.clear_model = true;
|
|
86148
|
+
let task;
|
|
86149
|
+
try {
|
|
86150
|
+
task = await masApi.updateTask(taskId, input);
|
|
86151
|
+
} catch (error2) {
|
|
86152
|
+
if (!(error2 instanceof ApiError))
|
|
86153
|
+
throw error2;
|
|
86154
|
+
if (error2.status === 422 && rejectsBodyField(error2.body, "clear_model")) {
|
|
86155
|
+
throw new ApiError(CLEAR_MODEL_UNSUPPORTED, error2.status, error2.body);
|
|
86156
|
+
}
|
|
86157
|
+
if (error2.status === 422 && rejectsBodyField(error2.body, "model")) {
|
|
86158
|
+
throw new ApiError(MODEL_UNSUPPORTED, error2.status, error2.body);
|
|
86159
|
+
}
|
|
86160
|
+
if (labels && input.metadata_patch && mergeUnsupported(error2)) {
|
|
86161
|
+
task = await updateByReplacingLabels(taskId, input, labels);
|
|
86162
|
+
} else {
|
|
86163
|
+
throw error2;
|
|
86164
|
+
}
|
|
86165
|
+
}
|
|
86166
|
+
if (options.json) {
|
|
86167
|
+
console.log(JSON.stringify(task, null, 2));
|
|
86168
|
+
return;
|
|
86169
|
+
}
|
|
86170
|
+
banner("task update — rename or relabel a task");
|
|
86171
|
+
console.log(format(task));
|
|
86172
|
+
}
|
|
86173
|
+
function mergeUnsupported(error2) {
|
|
86174
|
+
return error2.status === 501 || error2.status === 422 && rejectsBodyField(error2.body, "metadata_patch");
|
|
86175
|
+
}
|
|
86176
|
+
async function updateByReplacingLabels(taskId, input, labels) {
|
|
86177
|
+
const { metadata_patch: _merge, ...rest2 } = input;
|
|
86178
|
+
const current = await masApi.getTask(taskId);
|
|
86179
|
+
return masApi.updateTask(taskId, {
|
|
86180
|
+
...rest2,
|
|
86181
|
+
metadata: applyLabelEdit(current.metadata ?? {}, labels)
|
|
86182
|
+
});
|
|
86183
|
+
}
|
|
86184
|
+
function validTitle(options) {
|
|
86185
|
+
if (options.clearTitle) {
|
|
86186
|
+
if (options.title !== undefined) {
|
|
86187
|
+
throw new Error("--title and --clear-title cannot be combined.");
|
|
86188
|
+
}
|
|
86189
|
+
return "";
|
|
86190
|
+
}
|
|
86191
|
+
if (options.title === undefined)
|
|
86192
|
+
return;
|
|
86193
|
+
const title = options.title.trim();
|
|
86194
|
+
if (!title) {
|
|
86195
|
+
throw new Error("--title must not be blank; use --clear-title to remove the title.");
|
|
86196
|
+
}
|
|
86197
|
+
if ([...title].length > TITLE_MAX) {
|
|
86198
|
+
throw new Error(`--title must be at most ${TITLE_MAX} characters.`);
|
|
86199
|
+
}
|
|
86200
|
+
return title;
|
|
86201
|
+
}
|
|
86202
|
+
function validModel(options) {
|
|
86203
|
+
if (options.model !== undefined && options.clearModel) {
|
|
86204
|
+
throw new Error("--model and --clear-model cannot be combined.");
|
|
86205
|
+
}
|
|
86206
|
+
if (options.model === undefined)
|
|
86207
|
+
return;
|
|
86208
|
+
const model = options.model.trim();
|
|
86209
|
+
if (!model)
|
|
86210
|
+
throw new Error("--model must not be blank.");
|
|
86211
|
+
if (!MODEL_ID_RE.test(model)) {
|
|
86212
|
+
throw new Error(`--model "${sanitizeLabel(model)}" is not a valid model id: use letters, digits and . _ - : / only, at most 128 characters.`);
|
|
86213
|
+
}
|
|
86214
|
+
return model;
|
|
86215
|
+
}
|
|
86216
|
+
function parseLabelArgs(raw, flag = "--metadata") {
|
|
86217
|
+
const labels = new Map;
|
|
86218
|
+
for (const arg of raw ?? []) {
|
|
86219
|
+
const equals = arg.indexOf("=");
|
|
86220
|
+
if (equals < 0) {
|
|
86221
|
+
throw new Error(`${flag} expects key=value, got "${arg}".`);
|
|
86222
|
+
}
|
|
86223
|
+
const key2 = arg.slice(0, equals).trim();
|
|
86224
|
+
if (!key2) {
|
|
86225
|
+
throw new Error(`${flag} needs a non-empty key, got "${arg}".`);
|
|
86226
|
+
}
|
|
86227
|
+
if (labels.has(key2)) {
|
|
86228
|
+
throw new Error(`${flag} sets "${key2}" more than once.`);
|
|
86229
|
+
}
|
|
86230
|
+
labels.set(key2, arg.slice(equals + 1));
|
|
86231
|
+
}
|
|
86232
|
+
return labels;
|
|
86233
|
+
}
|
|
86234
|
+
function validLabelEdit(options) {
|
|
86235
|
+
const set3 = parseLabelArgs(options.metadata);
|
|
86236
|
+
const unset2 = new Set;
|
|
86237
|
+
for (const raw of options.unsetMetadata ?? []) {
|
|
86238
|
+
const key2 = raw.trim();
|
|
86239
|
+
if (!key2)
|
|
86240
|
+
throw new Error("--unset-metadata needs a non-empty key.");
|
|
86241
|
+
if (set3.has(key2)) {
|
|
86242
|
+
throw new Error(`"${key2}" is both set with --metadata and removed with --unset-metadata.`);
|
|
86243
|
+
}
|
|
86244
|
+
unset2.add(key2);
|
|
86245
|
+
}
|
|
86246
|
+
if (unset2.size > 0 && options.clearMetadata) {
|
|
86247
|
+
throw new Error("--unset-metadata and --clear-metadata cannot be combined: --clear-metadata already removes every label.");
|
|
86248
|
+
}
|
|
86249
|
+
return set3.size > 0 || unset2.size > 0 ? { set: set3, unset: unset2 } : undefined;
|
|
86250
|
+
}
|
|
86251
|
+
function applyLabelEdit(current, edit) {
|
|
86252
|
+
const next = new Map(Object.entries(current).filter(([key2]) => !edit.unset.has(key2)));
|
|
86253
|
+
for (const [key2, value2] of edit.set)
|
|
86254
|
+
next.set(key2, value2);
|
|
86255
|
+
return Object.fromEntries(next);
|
|
86256
|
+
}
|
|
86257
|
+
function format(task) {
|
|
86258
|
+
const lines = [""];
|
|
86259
|
+
const title = task.title?.trim() ? sanitizeLabel(task.title) : import_picocolors63.default.dim("(untitled)");
|
|
86260
|
+
lines.push(` ${import_picocolors63.default.green("updated")} ${import_picocolors63.default.bold(title)}`);
|
|
86261
|
+
lines.push("");
|
|
86262
|
+
lines.push(` ${import_picocolors63.default.dim("task")} ${sanitizeLabel(task.id)}`);
|
|
86263
|
+
if (task.model !== undefined) {
|
|
86264
|
+
const model = task.model?.trim() ? sanitizeLabel(task.model) : import_picocolors63.default.dim("agent default");
|
|
86265
|
+
lines.push(` ${import_picocolors63.default.dim("model")} ${model}`);
|
|
86266
|
+
}
|
|
86267
|
+
const metadata = Object.entries(task.metadata ?? {});
|
|
86268
|
+
lines.push("");
|
|
86269
|
+
lines.push(` ${import_picocolors63.default.bold(import_picocolors63.default.dim("METADATA"))}`);
|
|
86270
|
+
if (metadata.length === 0) {
|
|
86271
|
+
lines.push(` ${import_picocolors63.default.dim("none")}`);
|
|
86272
|
+
}
|
|
86273
|
+
for (const [key2, value2] of metadata) {
|
|
86274
|
+
lines.push(` ${import_picocolors63.default.dim(sanitizeLabel(key2))} ${sanitizeLabel(value2)}`);
|
|
86275
|
+
}
|
|
86276
|
+
lines.push("");
|
|
86277
|
+
lines.push(` ${import_picocolors63.default.dim("read it with")} ${import_picocolors63.default.cyan(`brainbase task get ${sanitizeLabel(task.id)}`)}`, "");
|
|
86278
|
+
return lines.join(`
|
|
86279
|
+
`);
|
|
86280
|
+
}
|
|
86281
|
+
|
|
86282
|
+
// src/cli/task-create.ts
|
|
86115
86283
|
var DEFAULT_POLL_INTERVAL_MS2 = 2000;
|
|
86116
86284
|
async function createTask(input, options) {
|
|
86117
86285
|
return await masApi.createTask(input, options);
|
|
@@ -86164,6 +86332,7 @@ async function runTaskCreate(cwd2, options, dependencies = {}) {
|
|
|
86164
86332
|
const title = optionalValue(options.title, "--title");
|
|
86165
86333
|
const model = optionalValue(options.model, "--model");
|
|
86166
86334
|
const versionRef = optionalValue(options.version, "--version");
|
|
86335
|
+
const labels = parseLabelArgs(options.metadata);
|
|
86167
86336
|
const version2 = versionRef ? (await agentVersionsApi.resolve(agentId, versionRef)).version : undefined;
|
|
86168
86337
|
const input = {
|
|
86169
86338
|
agent_id: agentId,
|
|
@@ -86172,7 +86341,8 @@ async function runTaskCreate(cwd2, options, dependencies = {}) {
|
|
|
86172
86341
|
...title ? { title } : {},
|
|
86173
86342
|
...model ? { default_model: model } : {},
|
|
86174
86343
|
...interfaceId ? { interface_id: interfaceId } : {},
|
|
86175
|
-
...version2 && { agent_version_id: version2.id }
|
|
86344
|
+
...version2 && { agent_version_id: version2.id },
|
|
86345
|
+
...labels.size > 0 ? { metadata: Object.fromEntries(labels) } : {}
|
|
86176
86346
|
};
|
|
86177
86347
|
let created;
|
|
86178
86348
|
try {
|
|
@@ -86242,24 +86412,24 @@ async function waitForCreatedTask(created, options, dependencies, version2) {
|
|
|
86242
86412
|
return;
|
|
86243
86413
|
}
|
|
86244
86414
|
if (outcome.kind === "timeout") {
|
|
86245
|
-
console.log(
|
|
86415
|
+
console.log(import_picocolors64.default.yellow(`Timed out after ${options.timeoutSeconds}s with the task still ${status}.`));
|
|
86246
86416
|
return;
|
|
86247
86417
|
}
|
|
86248
86418
|
if (outcome.kind === "interrupted") {
|
|
86249
|
-
console.log(
|
|
86419
|
+
console.log(import_picocolors64.default.yellow("Interrupted. The task is still running."));
|
|
86250
86420
|
return;
|
|
86251
86421
|
}
|
|
86252
|
-
console.log(code === 0 ?
|
|
86422
|
+
console.log(code === 0 ? import_picocolors64.default.green("Task completed.") : import_picocolors64.default.red(`Task finished as ${status}.`));
|
|
86253
86423
|
} finally {
|
|
86254
86424
|
process.removeListener("SIGINT", onSigint);
|
|
86255
86425
|
}
|
|
86256
86426
|
}
|
|
86257
86427
|
|
|
86258
86428
|
// src/cli/task-get.ts
|
|
86259
|
-
var
|
|
86429
|
+
var import_picocolors66 = __toESM(require_picocolors(), 1);
|
|
86260
86430
|
|
|
86261
86431
|
// src/cli/task-list.ts
|
|
86262
|
-
var
|
|
86432
|
+
var import_picocolors65 = __toESM(require_picocolors(), 1);
|
|
86263
86433
|
|
|
86264
86434
|
// src/core/agent-names.ts
|
|
86265
86435
|
async function agentNames(ids) {
|
|
@@ -86283,64 +86453,87 @@ async function agentNames(ids) {
|
|
|
86283
86453
|
}
|
|
86284
86454
|
function agentLabel(id, names) {
|
|
86285
86455
|
const name = names.get(id.toLowerCase());
|
|
86286
|
-
|
|
86456
|
+
const safeId = sanitizeLabel(id);
|
|
86457
|
+
return name ? `${name} (${safeId})` : safeId;
|
|
86287
86458
|
}
|
|
86288
86459
|
|
|
86289
86460
|
// src/cli/task-list.ts
|
|
86290
86461
|
var INTERFACE_THREAD_METADATA_KEY = "brainbase_interface_id";
|
|
86291
86462
|
async function runTaskList(options) {
|
|
86463
|
+
const metadata = labelFilter(options);
|
|
86292
86464
|
if (!options.json)
|
|
86293
86465
|
banner("task list — recent tasks");
|
|
86294
86466
|
const tasks = await masApi.listTasks({
|
|
86295
86467
|
agentId: options.agentId,
|
|
86296
86468
|
limit: options.limit,
|
|
86297
|
-
...
|
|
86469
|
+
...Object.keys(metadata).length > 0 ? { metadata } : {}
|
|
86298
86470
|
});
|
|
86299
86471
|
if (options.json) {
|
|
86300
86472
|
console.log(JSON.stringify(tasks, null, 2));
|
|
86301
86473
|
return;
|
|
86302
86474
|
}
|
|
86303
86475
|
const names = await agentNames(tasks.map((task) => task.agent_id));
|
|
86304
|
-
|
|
86476
|
+
const filtered = (options.metadata?.length ?? 0) > 0;
|
|
86477
|
+
console.log(formatTaskList(tasks, names, options.agentId, options.interfaceId, filtered));
|
|
86305
86478
|
}
|
|
86306
|
-
function
|
|
86479
|
+
function labelFilter(options) {
|
|
86480
|
+
const labels = parseLabelArgs(options.metadata);
|
|
86481
|
+
for (const key2 of labels.keys()) {
|
|
86482
|
+
if (key2.includes(":")) {
|
|
86483
|
+
throw new Error(`--metadata cannot filter on "${key2}": a key with ":" cannot be matched.`);
|
|
86484
|
+
}
|
|
86485
|
+
}
|
|
86486
|
+
if (options.interfaceId) {
|
|
86487
|
+
if (labels.has(INTERFACE_THREAD_METADATA_KEY)) {
|
|
86488
|
+
throw new Error(`--interface already filters on ${INTERFACE_THREAD_METADATA_KEY}.`);
|
|
86489
|
+
}
|
|
86490
|
+
labels.set(INTERFACE_THREAD_METADATA_KEY, options.interfaceId);
|
|
86491
|
+
}
|
|
86492
|
+
return Object.fromEntries(labels);
|
|
86493
|
+
}
|
|
86494
|
+
function formatTaskList(tasks, names, agentId, interfaceId, labelFiltered = false) {
|
|
86307
86495
|
const lines = [""];
|
|
86496
|
+
if (tasks.length === 0 && labelFiltered) {
|
|
86497
|
+
lines.push(` ${import_picocolors65.default.dim("No tasks carry every label given with --metadata.")}`, "");
|
|
86498
|
+
return lines.join(`
|
|
86499
|
+
`);
|
|
86500
|
+
}
|
|
86308
86501
|
if (tasks.length === 0 && interfaceId) {
|
|
86309
86502
|
const id = sanitizeLabel(interfaceId);
|
|
86310
|
-
lines.push(` ${
|
|
86503
|
+
lines.push(` ${import_picocolors65.default.dim(`No build conversations for interface ${id}.`)}`, "", ` ${import_picocolors65.default.dim("start one with")} ${import_picocolors65.default.cyan(`brainbase interface build ${id} "..."`)}`, "");
|
|
86311
86504
|
return lines.join(`
|
|
86312
86505
|
`);
|
|
86313
86506
|
}
|
|
86314
86507
|
if (tasks.length === 0) {
|
|
86315
|
-
lines.push(` ${
|
|
86508
|
+
lines.push(` ${import_picocolors65.default.dim(agentId ? `No tasks for agent ${agentId}.` : "No tasks yet.")}`, "", ` ${import_picocolors65.default.dim("start one with")} ${import_picocolors65.default.cyan('brainbase task create --message "..."')}`, "");
|
|
86316
86509
|
return lines.join(`
|
|
86317
86510
|
`);
|
|
86318
86511
|
}
|
|
86319
86512
|
for (const task of tasks) {
|
|
86320
|
-
const title = sanitizeLabel(task.title ?? "").trim() ||
|
|
86321
|
-
lines.push(` ${statusLabel(task.status)} ${
|
|
86322
|
-
lines.push(` ${
|
|
86323
|
-
lines.push(` ${
|
|
86513
|
+
const title = sanitizeLabel(task.title ?? "").trim() || import_picocolors65.default.dim("(untitled)");
|
|
86514
|
+
lines.push(` ${statusLabel(task.status)} ${import_picocolors65.default.bold(title)}`);
|
|
86515
|
+
lines.push(` ${import_picocolors65.default.dim(sanitizeLabel(task.id))}`);
|
|
86516
|
+
lines.push(` ${import_picocolors65.default.dim(`agent ${agentLabel(task.agent_id, names)} · created ${sanitizeLabel(task.created_at)}`)}`);
|
|
86324
86517
|
lines.push("");
|
|
86325
86518
|
}
|
|
86326
|
-
lines.push(` ${
|
|
86519
|
+
lines.push(` ${import_picocolors65.default.dim("inspect one with")} ${import_picocolors65.default.cyan("brainbase task get <id>")}`, "");
|
|
86327
86520
|
return lines.join(`
|
|
86328
86521
|
`);
|
|
86329
86522
|
}
|
|
86330
86523
|
function statusLabel(status) {
|
|
86331
|
-
const padded = status.padEnd(14);
|
|
86524
|
+
const padded = sanitizeLabel(status).padEnd(14);
|
|
86332
86525
|
switch (status) {
|
|
86333
86526
|
case "success":
|
|
86334
|
-
return
|
|
86527
|
+
return import_picocolors65.default.green(padded);
|
|
86335
86528
|
case "fail":
|
|
86336
|
-
return
|
|
86529
|
+
return import_picocolors65.default.red(padded);
|
|
86337
86530
|
case "need_more_info":
|
|
86338
|
-
return
|
|
86531
|
+
return import_picocolors65.default.yellow(padded);
|
|
86339
86532
|
case "running":
|
|
86340
86533
|
case "initializing":
|
|
86341
|
-
return
|
|
86534
|
+
return import_picocolors65.default.cyan(padded);
|
|
86342
86535
|
default:
|
|
86343
|
-
return
|
|
86536
|
+
return import_picocolors65.default.dim(padded);
|
|
86344
86537
|
}
|
|
86345
86538
|
}
|
|
86346
86539
|
|
|
@@ -86357,7 +86550,7 @@ async function runTaskGet(taskId, options = {}) {
|
|
|
86357
86550
|
console.log(JSON.stringify(payload, null, 2));
|
|
86358
86551
|
return;
|
|
86359
86552
|
}
|
|
86360
|
-
console.log(
|
|
86553
|
+
console.log(format2(task, evals, await agentNames([task.agent_id])));
|
|
86361
86554
|
}
|
|
86362
86555
|
async function readEvalRuns(task) {
|
|
86363
86556
|
try {
|
|
@@ -86372,51 +86565,62 @@ async function readEvalRuns(task) {
|
|
|
86372
86565
|
throw error2;
|
|
86373
86566
|
}
|
|
86374
86567
|
}
|
|
86375
|
-
function
|
|
86568
|
+
function format2(task, evals, names) {
|
|
86376
86569
|
const lines = [""];
|
|
86377
|
-
const title = task.title
|
|
86378
|
-
|
|
86570
|
+
const title = sanitizeLabel(task.title ?? "").trim() || import_picocolors66.default.dim("(untitled)");
|
|
86571
|
+
const id = sanitizeLabel(task.id);
|
|
86572
|
+
lines.push(` ${statusLabel(task.status)} ${import_picocolors66.default.bold(title)}`);
|
|
86379
86573
|
lines.push("");
|
|
86380
|
-
lines.push(` ${
|
|
86381
|
-
lines.push(` ${
|
|
86382
|
-
|
|
86574
|
+
lines.push(` ${import_picocolors66.default.dim("task")} ${id}`);
|
|
86575
|
+
lines.push(` ${import_picocolors66.default.dim("agent")} ${agentLabel(task.agent_id, names)}`);
|
|
86576
|
+
if (task.model !== undefined) {
|
|
86577
|
+
const model = task.model?.trim() ? sanitizeLabel(task.model) : import_picocolors66.default.dim("agent default");
|
|
86578
|
+
lines.push(` ${import_picocolors66.default.dim("model")} ${model}`);
|
|
86579
|
+
}
|
|
86580
|
+
lines.push(` ${import_picocolors66.default.dim("created")} ${sanitizeLabel(task.created_at)}`);
|
|
86383
86581
|
if (task.parent_task_id) {
|
|
86384
|
-
lines.push(` ${
|
|
86582
|
+
lines.push(` ${import_picocolors66.default.dim("parent")} ${sanitizeLabel(task.parent_task_id)}`);
|
|
86385
86583
|
}
|
|
86386
86584
|
if (task.machine_id) {
|
|
86387
|
-
|
|
86585
|
+
const size2 = task.machine_size ? ` (size ${sanitizeLabel(task.machine_size)})` : "";
|
|
86586
|
+
lines.push(` ${import_picocolors66.default.dim("machine")} ${sanitizeLabel(task.machine_id)}${size2}`);
|
|
86388
86587
|
}
|
|
86389
86588
|
if (task.sandbox_id)
|
|
86390
|
-
lines.push(` ${
|
|
86391
|
-
const failure = failureSummary(task);
|
|
86589
|
+
lines.push(` ${import_picocolors66.default.dim("sandbox")} ${sanitizeLabel(task.sandbox_id)}`);
|
|
86590
|
+
const [failure, ...failureRest] = sanitizeLines(failureSummary(task) ?? "").filter((line2) => line2.trim());
|
|
86392
86591
|
if (failure) {
|
|
86592
|
+
const label3 = " failure ";
|
|
86393
86593
|
lines.push("");
|
|
86394
|
-
lines.push(` ${
|
|
86594
|
+
lines.push(` ${import_picocolors66.default.red("failure")} ${failure}`);
|
|
86595
|
+
for (const line2 of failureRest)
|
|
86596
|
+
lines.push(`${" ".repeat(label3.length)}${line2}`);
|
|
86395
86597
|
}
|
|
86396
86598
|
const metadata = Object.entries(task.metadata ?? {});
|
|
86397
86599
|
if (metadata.length > 0) {
|
|
86398
86600
|
lines.push("");
|
|
86399
|
-
lines.push(` ${
|
|
86601
|
+
lines.push(` ${import_picocolors66.default.bold(import_picocolors66.default.dim("METADATA"))}`);
|
|
86400
86602
|
for (const [key2, value2] of metadata) {
|
|
86401
|
-
lines.push(` ${
|
|
86603
|
+
lines.push(` ${import_picocolors66.default.dim(sanitizeLabel(key2))} ${sanitizeLabel(String(value2))}`);
|
|
86402
86604
|
}
|
|
86403
86605
|
}
|
|
86404
86606
|
lines.push("");
|
|
86405
|
-
lines.push(` ${
|
|
86607
|
+
lines.push(` ${import_picocolors66.default.bold(import_picocolors66.default.dim("EVAL VERDICTS"))}`);
|
|
86406
86608
|
if (evals.unavailable) {
|
|
86407
|
-
lines.push(` ${
|
|
86609
|
+
lines.push(` ${import_picocolors66.default.dim(sanitizeLabel(evals.unavailable))}`);
|
|
86408
86610
|
} else if (evals.runs.length === 0) {
|
|
86409
|
-
lines.push(` ${
|
|
86611
|
+
lines.push(` ${import_picocolors66.default.dim("none")}`);
|
|
86410
86612
|
} else {
|
|
86411
86613
|
for (const run of evals.runs) {
|
|
86412
|
-
const verdict = run.passed === true ?
|
|
86413
|
-
lines.push(` ${verdict} ${run.eval_slug ?? run.eval_id}`);
|
|
86414
|
-
|
|
86415
|
-
|
|
86614
|
+
const verdict = run.passed === true ? import_picocolors66.default.green("pass") : run.passed === false ? import_picocolors66.default.red("fail") : import_picocolors66.default.dim(sanitizeLabel(run.status));
|
|
86615
|
+
lines.push(` ${verdict} ${sanitizeLabel(run.eval_slug ?? run.eval_id)}`);
|
|
86616
|
+
for (const line2 of sanitizeLines(run.reasoning ?? "")) {
|
|
86617
|
+
if (line2.trim())
|
|
86618
|
+
lines.push(` ${import_picocolors66.default.dim(line2)}`);
|
|
86619
|
+
}
|
|
86416
86620
|
}
|
|
86417
86621
|
}
|
|
86418
86622
|
lines.push("");
|
|
86419
|
-
lines.push(` ${
|
|
86623
|
+
lines.push(` ${import_picocolors66.default.dim("read its transcript with")} ${import_picocolors66.default.cyan(`brainbase task logs ${id}`)}`, "");
|
|
86420
86624
|
return lines.join(`
|
|
86421
86625
|
`);
|
|
86422
86626
|
}
|
|
@@ -86433,7 +86637,7 @@ function failureSummary(task) {
|
|
|
86433
86637
|
}
|
|
86434
86638
|
|
|
86435
86639
|
// src/cli/task-logs.ts
|
|
86436
|
-
var
|
|
86640
|
+
var import_picocolors67 = __toESM(require_picocolors(), 1);
|
|
86437
86641
|
|
|
86438
86642
|
// src/core/task-events.ts
|
|
86439
86643
|
var DEFAULT_RETRY_BUDGET_MS = 60000;
|
|
@@ -86716,14 +86920,14 @@ async function runTaskLogs(taskId, options = {}, dependencies = {}) {
|
|
|
86716
86920
|
console.log(renderEvent(event, messages));
|
|
86717
86921
|
}
|
|
86718
86922
|
if (ordered.length === 0) {
|
|
86719
|
-
console.log(
|
|
86923
|
+
console.log(import_picocolors67.default.dim("No events for this task yet."));
|
|
86720
86924
|
}
|
|
86721
86925
|
}
|
|
86722
86926
|
async function followTranscript(taskId, options, dependencies) {
|
|
86723
86927
|
const backfill = options.limit === undefined ? "" : `?backfill=${options.limit}`;
|
|
86724
86928
|
const { url: url2, resolveBearer } = await masStreamTarget(`/tasks/${encodeURIComponent(taskId)}/events/stream${backfill}`);
|
|
86725
86929
|
if (!options.json) {
|
|
86726
|
-
console.log(
|
|
86930
|
+
console.log(import_picocolors67.default.dim(`Following task ${taskId} — Ctrl-C to stop.`));
|
|
86727
86931
|
}
|
|
86728
86932
|
const setExitCode = dependencies.setExitCode ?? ((code) => process.exitCode = code);
|
|
86729
86933
|
const controller = new AbortController;
|
|
@@ -86765,13 +86969,13 @@ async function followTranscript(taskId, options, dependencies) {
|
|
|
86765
86969
|
} else if (options.json) {
|
|
86766
86970
|
console.log(JSON.stringify(frame));
|
|
86767
86971
|
} else {
|
|
86768
|
-
console.log(
|
|
86972
|
+
console.log(import_picocolors67.default.dim(frame.type));
|
|
86769
86973
|
}
|
|
86770
86974
|
},
|
|
86771
86975
|
onOpen: () => settle.noteFrame(),
|
|
86772
86976
|
onReconnect: (reason) => {
|
|
86773
86977
|
settle.noteDisconnected();
|
|
86774
|
-
console.error(
|
|
86978
|
+
console.error(import_picocolors67.default.dim(`reconnecting — ${reason}`));
|
|
86775
86979
|
}
|
|
86776
86980
|
});
|
|
86777
86981
|
if (interruptCode !== undefined)
|
|
@@ -87104,137 +87308,6 @@ Omit --generation only for a deliberately new Stop.`;
|
|
|
87104
87308
|
`));
|
|
87105
87309
|
}
|
|
87106
87310
|
|
|
87107
|
-
// src/cli/task-update.ts
|
|
87108
|
-
var import_picocolors67 = __toESM(require_picocolors(), 1);
|
|
87109
|
-
var TASK_UPDATE_USAGE = "brainbase task update <task-id> [--title <text> | --clear-title] [--metadata key=value]... [--unset-metadata <key>]... [--clear-metadata] [--model <id>] [--json]";
|
|
87110
|
-
var TITLE_MAX = 200;
|
|
87111
|
-
var MODEL_UNSUPPORTED = "This control plane does not support changing a task's model yet.";
|
|
87112
|
-
async function runTaskUpdate(taskId, options) {
|
|
87113
|
-
const title = validTitle(options);
|
|
87114
|
-
const labels = validLabelEdit(options);
|
|
87115
|
-
const model = validModel(options);
|
|
87116
|
-
if (title === undefined && !labels && !options.clearMetadata && model === undefined) {
|
|
87117
|
-
throw new Error(`Nothing to update: pass --title, --clear-title, --metadata, --unset-metadata, --clear-metadata or --model.
|
|
87118
|
-
` + `Usage: ${TASK_UPDATE_USAGE}`);
|
|
87119
|
-
}
|
|
87120
|
-
const input = {};
|
|
87121
|
-
if (title !== undefined)
|
|
87122
|
-
input.title = title;
|
|
87123
|
-
if (options.clearMetadata) {
|
|
87124
|
-
input.metadata = Object.fromEntries(labels?.set ?? []);
|
|
87125
|
-
} else if (labels) {
|
|
87126
|
-
const current = await masApi.getTask(taskId);
|
|
87127
|
-
input.metadata = applyLabelEdit(current.metadata ?? {}, labels);
|
|
87128
|
-
}
|
|
87129
|
-
if (model !== undefined)
|
|
87130
|
-
input.model = model;
|
|
87131
|
-
let task;
|
|
87132
|
-
try {
|
|
87133
|
-
task = await masApi.updateTask(taskId, input);
|
|
87134
|
-
} catch (error2) {
|
|
87135
|
-
if (error2 instanceof ApiError && error2.status === 422 && rejectsBodyField(error2.body, "model")) {
|
|
87136
|
-
throw new ApiError(MODEL_UNSUPPORTED, error2.status, error2.body);
|
|
87137
|
-
}
|
|
87138
|
-
throw error2;
|
|
87139
|
-
}
|
|
87140
|
-
if (options.json) {
|
|
87141
|
-
console.log(JSON.stringify(task, null, 2));
|
|
87142
|
-
return;
|
|
87143
|
-
}
|
|
87144
|
-
banner("task update — rename or relabel a task");
|
|
87145
|
-
console.log(format2(task));
|
|
87146
|
-
}
|
|
87147
|
-
function validTitle(options) {
|
|
87148
|
-
if (options.clearTitle) {
|
|
87149
|
-
if (options.title !== undefined) {
|
|
87150
|
-
throw new Error("--title and --clear-title cannot be combined.");
|
|
87151
|
-
}
|
|
87152
|
-
return "";
|
|
87153
|
-
}
|
|
87154
|
-
if (options.title === undefined)
|
|
87155
|
-
return;
|
|
87156
|
-
const title = options.title.trim();
|
|
87157
|
-
if (!title) {
|
|
87158
|
-
throw new Error("--title must not be blank; use --clear-title to remove the title.");
|
|
87159
|
-
}
|
|
87160
|
-
if ([...title].length > TITLE_MAX) {
|
|
87161
|
-
throw new Error(`--title must be at most ${TITLE_MAX} characters.`);
|
|
87162
|
-
}
|
|
87163
|
-
return title;
|
|
87164
|
-
}
|
|
87165
|
-
function validModel(options) {
|
|
87166
|
-
if (options.model === undefined)
|
|
87167
|
-
return;
|
|
87168
|
-
const model = options.model.trim();
|
|
87169
|
-
if (!model)
|
|
87170
|
-
throw new Error("--model must not be blank.");
|
|
87171
|
-
if (!MODEL_ID_RE.test(model)) {
|
|
87172
|
-
throw new Error(`--model "${sanitizeLabel(model)}" is not a valid model id: use letters, digits and . _ - : / only, at most 128 characters.`);
|
|
87173
|
-
}
|
|
87174
|
-
return model;
|
|
87175
|
-
}
|
|
87176
|
-
function validLabelEdit(options) {
|
|
87177
|
-
const set3 = new Map;
|
|
87178
|
-
for (const raw of options.metadata ?? []) {
|
|
87179
|
-
const equals = raw.indexOf("=");
|
|
87180
|
-
if (equals < 0) {
|
|
87181
|
-
throw new Error(`--metadata expects key=value, got "${raw}".`);
|
|
87182
|
-
}
|
|
87183
|
-
const key2 = raw.slice(0, equals).trim();
|
|
87184
|
-
if (!key2) {
|
|
87185
|
-
throw new Error(`--metadata needs a non-empty key, got "${raw}".`);
|
|
87186
|
-
}
|
|
87187
|
-
if (set3.has(key2)) {
|
|
87188
|
-
throw new Error(`--metadata sets "${key2}" more than once.`);
|
|
87189
|
-
}
|
|
87190
|
-
set3.set(key2, raw.slice(equals + 1));
|
|
87191
|
-
}
|
|
87192
|
-
const unset2 = new Set;
|
|
87193
|
-
for (const raw of options.unsetMetadata ?? []) {
|
|
87194
|
-
const key2 = raw.trim();
|
|
87195
|
-
if (!key2)
|
|
87196
|
-
throw new Error("--unset-metadata needs a non-empty key.");
|
|
87197
|
-
if (set3.has(key2)) {
|
|
87198
|
-
throw new Error(`"${key2}" is both set with --metadata and removed with --unset-metadata.`);
|
|
87199
|
-
}
|
|
87200
|
-
unset2.add(key2);
|
|
87201
|
-
}
|
|
87202
|
-
if (unset2.size > 0 && options.clearMetadata) {
|
|
87203
|
-
throw new Error("--unset-metadata and --clear-metadata cannot be combined: --clear-metadata already removes every label.");
|
|
87204
|
-
}
|
|
87205
|
-
return set3.size > 0 || unset2.size > 0 ? { set: set3, unset: unset2 } : undefined;
|
|
87206
|
-
}
|
|
87207
|
-
function applyLabelEdit(current, edit) {
|
|
87208
|
-
const next = new Map(Object.entries(current).filter(([key2]) => !edit.unset.has(key2)));
|
|
87209
|
-
for (const [key2, value2] of edit.set)
|
|
87210
|
-
next.set(key2, value2);
|
|
87211
|
-
return Object.fromEntries(next);
|
|
87212
|
-
}
|
|
87213
|
-
function format2(task) {
|
|
87214
|
-
const lines = [""];
|
|
87215
|
-
const title = task.title?.trim() ? sanitizeLabel(task.title) : import_picocolors67.default.dim("(untitled)");
|
|
87216
|
-
lines.push(` ${import_picocolors67.default.green("updated")} ${import_picocolors67.default.bold(title)}`);
|
|
87217
|
-
lines.push("");
|
|
87218
|
-
lines.push(` ${import_picocolors67.default.dim("task")} ${sanitizeLabel(task.id)}`);
|
|
87219
|
-
if (task.model !== undefined) {
|
|
87220
|
-
const model = task.model?.trim() ? sanitizeLabel(task.model) : import_picocolors67.default.dim("agent default");
|
|
87221
|
-
lines.push(` ${import_picocolors67.default.dim("model")} ${model}`);
|
|
87222
|
-
}
|
|
87223
|
-
const metadata = Object.entries(task.metadata ?? {});
|
|
87224
|
-
lines.push("");
|
|
87225
|
-
lines.push(` ${import_picocolors67.default.bold(import_picocolors67.default.dim("METADATA"))}`);
|
|
87226
|
-
if (metadata.length === 0) {
|
|
87227
|
-
lines.push(` ${import_picocolors67.default.dim("none")}`);
|
|
87228
|
-
}
|
|
87229
|
-
for (const [key2, value2] of metadata) {
|
|
87230
|
-
lines.push(` ${import_picocolors67.default.dim(sanitizeLabel(key2))} ${sanitizeLabel(value2)}`);
|
|
87231
|
-
}
|
|
87232
|
-
lines.push("");
|
|
87233
|
-
lines.push(` ${import_picocolors67.default.dim("read it with")} ${import_picocolors67.default.cyan(`brainbase task get ${sanitizeLabel(task.id)}`)}`, "");
|
|
87234
|
-
return lines.join(`
|
|
87235
|
-
`);
|
|
87236
|
-
}
|
|
87237
|
-
|
|
87238
87311
|
// src/cli/task.ts
|
|
87239
87312
|
var VALUE_FLAGS = [
|
|
87240
87313
|
["--agent", "agentId"],
|
|
@@ -87246,9 +87319,11 @@ var VALUE_FLAGS = [
|
|
|
87246
87319
|
["--timeout", "timeout"]
|
|
87247
87320
|
];
|
|
87248
87321
|
var BOOLEAN_FLAGS = ["--json", "--wait"];
|
|
87322
|
+
var METADATA_FLAG = "--metadata";
|
|
87249
87323
|
var TASK_OPTION_NAMES = new Set([
|
|
87250
87324
|
...VALUE_FLAGS.map(([flag]) => flag),
|
|
87251
|
-
...BOOLEAN_FLAGS
|
|
87325
|
+
...BOOLEAN_FLAGS,
|
|
87326
|
+
METADATA_FLAG
|
|
87252
87327
|
]);
|
|
87253
87328
|
var HELP_FLAGS = new Set(["--help", "-h"]);
|
|
87254
87329
|
var LIST_LIMIT_MAX = 200;
|
|
@@ -87280,6 +87355,25 @@ function parseCreateArgs(args) {
|
|
|
87280
87355
|
options.wait = true;
|
|
87281
87356
|
continue;
|
|
87282
87357
|
}
|
|
87358
|
+
if (arg === METADATA_FLAG || arg.startsWith(`${METADATA_FLAG}=`)) {
|
|
87359
|
+
let value2;
|
|
87360
|
+
if (arg !== METADATA_FLAG) {
|
|
87361
|
+
value2 = arg.slice(METADATA_FLAG.length + 1);
|
|
87362
|
+
} else {
|
|
87363
|
+
value2 = args[index + 1];
|
|
87364
|
+
if (value2 === "--") {
|
|
87365
|
+
value2 = args[index + 2];
|
|
87366
|
+
index += 1;
|
|
87367
|
+
} else if (value2 !== undefined && TASK_OPTION_NAMES.has(value2)) {
|
|
87368
|
+
throw flagLikeValueError(METADATA_FLAG, value2);
|
|
87369
|
+
}
|
|
87370
|
+
if (value2 === undefined)
|
|
87371
|
+
throw new Error("--metadata expects key=value.");
|
|
87372
|
+
index += 1;
|
|
87373
|
+
}
|
|
87374
|
+
(options.metadata ??= []).push(value2);
|
|
87375
|
+
continue;
|
|
87376
|
+
}
|
|
87283
87377
|
let matched = false;
|
|
87284
87378
|
for (const [flag, option] of VALUE_FLAGS) {
|
|
87285
87379
|
if (arg === flag) {
|
|
@@ -87412,16 +87506,18 @@ async function dispatchTask(cwd2, sub, args, setJson) {
|
|
|
87412
87506
|
const parsed = parse6([
|
|
87413
87507
|
{ key: "agent", names: ["--agent"], kind: "value" },
|
|
87414
87508
|
{ key: "interface", names: ["--interface"], kind: "value" },
|
|
87509
|
+
{ key: "metadata", names: ["--metadata"], kind: "value", multiple: true },
|
|
87415
87510
|
{ key: "limit", names: ["--limit"], kind: "value" },
|
|
87416
87511
|
{ key: "json", names: ["--json"], kind: "boolean" }
|
|
87417
87512
|
]);
|
|
87418
87513
|
if (parsed.positionals.length > 0) {
|
|
87419
|
-
throw new Error("Usage: brainbase task list [--agent <id>] [--interface <id>] [--limit <n>] [--json]");
|
|
87514
|
+
throw new Error("Usage: brainbase task list [--agent <id>] [--interface <id>] [--metadata key=value]... [--limit <n>] [--json]");
|
|
87420
87515
|
}
|
|
87421
87516
|
const interfaceId = optionalValue(stringOption(parsed, "interface"), "--interface");
|
|
87422
87517
|
await runTaskList({
|
|
87423
87518
|
agentId: stringOption(parsed, "agent"),
|
|
87424
87519
|
interfaceId,
|
|
87520
|
+
metadata: stringOptions(parsed, "metadata"),
|
|
87425
87521
|
limit: positiveInteger(stringOption(parsed, "limit"), "--limit", LIST_LIMIT_MAX),
|
|
87426
87522
|
json: booleanOption(parsed, "json")
|
|
87427
87523
|
});
|
|
@@ -87473,6 +87569,7 @@ async function dispatchTask(cwd2, sub, args, setJson) {
|
|
|
87473
87569
|
{ key: "unsetMetadata", names: ["--unset-metadata"], kind: "value", multiple: true },
|
|
87474
87570
|
{ key: "clearMetadata", names: ["--clear-metadata"], kind: "boolean" },
|
|
87475
87571
|
{ key: "model", names: ["--model"], kind: "value" },
|
|
87572
|
+
{ key: "clearModel", names: ["--clear-model"], kind: "boolean" },
|
|
87476
87573
|
{ key: "json", names: ["--json"], kind: "boolean" },
|
|
87477
87574
|
{ key: "help", names: ["--help", "-h"], kind: "boolean" }
|
|
87478
87575
|
]);
|
|
@@ -87488,6 +87585,7 @@ async function dispatchTask(cwd2, sub, args, setJson) {
|
|
|
87488
87585
|
unsetMetadata: stringOptions(parsed, "unsetMetadata"),
|
|
87489
87586
|
clearMetadata: booleanOption(parsed, "clearMetadata"),
|
|
87490
87587
|
model: stringOption(parsed, "model"),
|
|
87588
|
+
clearModel: booleanOption(parsed, "clearModel"),
|
|
87491
87589
|
json: booleanOption(parsed, "json")
|
|
87492
87590
|
});
|
|
87493
87591
|
return;
|
|
@@ -87563,7 +87661,7 @@ function printHelp5() {
|
|
|
87563
87661
|
out.push(` ${import_picocolors68.default.cyan("logs")} ${import_picocolors68.default.dim("<task-id> [--follow]")} ${import_picocolors68.default.dim("one line per event in the task's transcript, or tail it live")}`);
|
|
87564
87662
|
out.push(` ${import_picocolors68.default.cyan("send")} ${import_picocolors68.default.dim("<task-id> <message>")} ${import_picocolors68.default.dim("send a follow-up, including while the agent is running")}`);
|
|
87565
87663
|
out.push(` ${import_picocolors68.default.cyan("stop")} ${import_picocolors68.default.dim("<task-id>")} ${import_picocolors68.default.dim("stop execution and cancel pending follow-ups, retaining their text")}`);
|
|
87566
|
-
out.push(` ${import_picocolors68.default.cyan("update")} ${import_picocolors68.default.dim("<task-id>")} ${import_picocolors68.default.dim("rename a task, change its metadata labels
|
|
87664
|
+
out.push(` ${import_picocolors68.default.cyan("update")} ${import_picocolors68.default.dim("<task-id>")} ${import_picocolors68.default.dim("rename a task, change its metadata labels, switch its model or reset it to the agent default, including while it runs")}`);
|
|
87567
87665
|
out.push(` ${import_picocolors68.default.cyan("delete")} ${import_picocolors68.default.dim("<task-id>")} ${import_picocolors68.default.dim("permanently delete a stopped task and tear down its sandbox (--yes to skip the prompt)")}`);
|
|
87568
87666
|
out.push("");
|
|
87569
87667
|
out.push(` ${import_picocolors68.default.bold("create flags")}`);
|
|
@@ -87573,12 +87671,14 @@ function printHelp5() {
|
|
|
87573
87671
|
out.push(` ${import_picocolors68.default.dim("--title <text>")} optional task title`);
|
|
87574
87672
|
out.push(` ${import_picocolors68.default.dim("--model <id>")} optional model override`);
|
|
87575
87673
|
out.push(` ${import_picocolors68.default.dim("--version <v>")} run a saved version of the agent: 12, v12 or a version id (\`agent versions list\`)`);
|
|
87674
|
+
out.push(` ${import_picocolors68.default.dim("--metadata key=value")} label the task (repeatable)`);
|
|
87576
87675
|
out.push(` ${import_picocolors68.default.dim("--wait")} block until the task finishes; exit 1 unless it succeeded`);
|
|
87577
87676
|
out.push(` ${import_picocolors68.default.dim("--timeout <secs>")} give up waiting after <secs> and exit 1 (needs --wait)`);
|
|
87578
87677
|
out.push("");
|
|
87579
87678
|
out.push(` ${import_picocolors68.default.bold("list flags")}`);
|
|
87580
87679
|
out.push(` ${import_picocolors68.default.dim("--agent <id>")} only this agent's tasks`);
|
|
87581
87680
|
out.push(` ${import_picocolors68.default.dim("--interface <id>")} only this interface's build conversations (hidden from a plain list)`);
|
|
87681
|
+
out.push(` ${import_picocolors68.default.dim("--metadata key=value")} only tasks carrying this label (repeatable; all must match)`);
|
|
87582
87682
|
out.push(` ${import_picocolors68.default.dim("--limit <n>")} cap the page (1-200, server default 50)`);
|
|
87583
87683
|
out.push("");
|
|
87584
87684
|
out.push(` ${import_picocolors68.default.bold("logs flags")}`);
|
|
@@ -87590,9 +87690,10 @@ function printHelp5() {
|
|
|
87590
87690
|
out.push(` ${import_picocolors68.default.dim("--clear-title")} remove the title; automatic titling may name the task again on a later turn`);
|
|
87591
87691
|
out.push(` ${import_picocolors68.default.dim("--metadata key=value")} set one label, keeping the others (repeatable)`);
|
|
87592
87692
|
out.push(` ${import_picocolors68.default.dim("--unset-metadata <key>")} remove one label (repeatable)`);
|
|
87693
|
+
out.push(` ${import_picocolors68.default.dim(" the server applies label edits in one step, so concurrent edits from other clients are kept")}`);
|
|
87593
87694
|
out.push(` ${import_picocolors68.default.dim("--clear-metadata")} remove every label; with --metadata, the labels become exactly those given`);
|
|
87594
|
-
out.push(` ${import_picocolors68.default.dim(" label edits read the current labels first, so two writers at once can overwrite each other")}`);
|
|
87595
87695
|
out.push(` ${import_picocolors68.default.dim("--model <id>")} switch the model the task's next turn runs on (the running turn keeps its model)`);
|
|
87696
|
+
out.push(` ${import_picocolors68.default.dim("--clear-model")} go back to the agent's default model from the next turn`);
|
|
87596
87697
|
out.push("");
|
|
87597
87698
|
out.push(` ${import_picocolors68.default.bold("send flags")}`);
|
|
87598
87699
|
out.push(` ${import_picocolors68.default.dim("--input-id <uuid>")} recover the same request using its original ID and identical message`);
|
|
@@ -97011,7 +97112,32 @@ async function runBenchmark(sub, args, write3 = (value2) => process.stdout.write
|
|
|
97011
97112
|
}
|
|
97012
97113
|
}
|
|
97013
97114
|
|
|
97115
|
+
// src/ui/console-streams.ts
|
|
97116
|
+
import { format as format3 } from "node:util";
|
|
97117
|
+
function routeConsoleThroughStreams() {
|
|
97118
|
+
if (typeof globalThis.Bun === "undefined")
|
|
97119
|
+
return;
|
|
97120
|
+
const writer = (stream) => (...args) => {
|
|
97121
|
+
if (!stream.writable)
|
|
97122
|
+
return;
|
|
97123
|
+
stream.write(`${format3(...args)}
|
|
97124
|
+
`);
|
|
97125
|
+
};
|
|
97126
|
+
console.log = writer(process.stdout);
|
|
97127
|
+
console.info = writer(process.stdout);
|
|
97128
|
+
console.debug = writer(process.stdout);
|
|
97129
|
+
console.warn = writer(process.stderr);
|
|
97130
|
+
console.error = writer(process.stderr);
|
|
97131
|
+
const ignoreClosedReader = (error2) => {
|
|
97132
|
+
if (error2.code !== "EPIPE")
|
|
97133
|
+
throw error2;
|
|
97134
|
+
};
|
|
97135
|
+
process.stdout.on("error", ignoreClosedReader);
|
|
97136
|
+
process.stderr.on("error", ignoreClosedReader);
|
|
97137
|
+
}
|
|
97138
|
+
|
|
97014
97139
|
// src/index.ts
|
|
97140
|
+
routeConsoleThroughStreams();
|
|
97015
97141
|
var PROTECTED = new Set([
|
|
97016
97142
|
"template",
|
|
97017
97143
|
"skill",
|
|
@@ -97096,12 +97222,12 @@ function help() {
|
|
|
97096
97222
|
out.push(divider("TASKS"));
|
|
97097
97223
|
out.push("");
|
|
97098
97224
|
out.push(` ${import_picocolors80.default.cyan("task create")} ${import_picocolors80.default.dim("--message <text>")} ${import_picocolors80.default.dim("create a managed task and start its first run (--wait to block on it; --interface <id> for a build conversation)")}`);
|
|
97099
|
-
out.push(` ${import_picocolors80.default.cyan("task list")} ${import_picocolors80.default.dim("recent tasks you can reach (--interface <id> for its build conversations)")}`);
|
|
97225
|
+
out.push(` ${import_picocolors80.default.cyan("task list")} ${import_picocolors80.default.dim("recent tasks you can reach (--metadata k=v to filter by label; --interface <id> for its build conversations)")}`);
|
|
97100
97226
|
out.push(` ${import_picocolors80.default.cyan("task get")} ${import_picocolors80.default.dim("<task-id>")} ${import_picocolors80.default.dim("one task: status, agent, machine, eval verdicts")}`);
|
|
97101
97227
|
out.push(` ${import_picocolors80.default.cyan("task logs")} ${import_picocolors80.default.dim("<task-id> [--follow]")} ${import_picocolors80.default.dim("one line per event in the task's transcript, or tail it live")}`);
|
|
97102
97228
|
out.push(` ${import_picocolors80.default.cyan("task send")} ${import_picocolors80.default.dim("<task-id> <message>")} ${import_picocolors80.default.dim("send a follow-up during execution, or queue it for the next turn")}`);
|
|
97103
97229
|
out.push(` ${import_picocolors80.default.cyan("task stop")} ${import_picocolors80.default.dim("<task-id>")} ${import_picocolors80.default.dim("stop execution and cancel pending follow-ups, retaining their text")}`);
|
|
97104
|
-
out.push(` ${import_picocolors80.default.cyan("task update")} ${import_picocolors80.default.dim("<task-id>")} ${import_picocolors80.default.dim("rename a task, change its metadata labels
|
|
97230
|
+
out.push(` ${import_picocolors80.default.cyan("task update")} ${import_picocolors80.default.dim("<task-id>")} ${import_picocolors80.default.dim("rename a task, change its metadata labels, switch its model or reset it to the agent default, including while it runs")}`);
|
|
97105
97231
|
out.push(` ${import_picocolors80.default.cyan("task delete")} ${import_picocolors80.default.dim("<task-id>")} ${import_picocolors80.default.dim("permanently delete a stopped task and tear down its sandbox")}`);
|
|
97106
97232
|
out.push("");
|
|
97107
97233
|
out.push(divider("INTERFACES"));
|
|
@@ -97197,10 +97323,11 @@ function help() {
|
|
|
97197
97323
|
out.push(` ${import_picocolors80.default.dim("--message <text>")} for task create: required first user message`);
|
|
97198
97324
|
out.push(` ${import_picocolors80.default.dim("--title <text>")} for task create: optional task title; for task update: the new title`);
|
|
97199
97325
|
out.push(` ${import_picocolors80.default.dim("--clear-title")} for task update: remove the title (automatic titling may name it again later)`);
|
|
97200
|
-
out.push(` ${import_picocolors80.default.dim("--metadata k=v")} for task update: set one label, keeping the others (repeatable)`);
|
|
97326
|
+
out.push(` ${import_picocolors80.default.dim("--metadata k=v")} for task create: label the task; for task list: only tasks with this label; for task update: set one label, keeping the others (all repeatable)`);
|
|
97201
97327
|
out.push(` ${import_picocolors80.default.dim("--unset-metadata <k>")} for task update: remove one label (repeatable)`);
|
|
97202
97328
|
out.push(` ${import_picocolors80.default.dim("--clear-metadata")} for task update: remove every label; with --metadata, keep only those given`);
|
|
97203
97329
|
out.push(` ${import_picocolors80.default.dim("--model <id>")} for task create: optional model override; for task update: switch the model the task's next turn runs on (the running turn keeps its model)`);
|
|
97330
|
+
out.push(` ${import_picocolors80.default.dim("--clear-model")} for task update: go back to the agent's default model from the next turn`);
|
|
97204
97331
|
out.push(` ${import_picocolors80.default.dim("--version <v>")} for task create: run a saved version of the agent (12, v12 or a version id)`);
|
|
97205
97332
|
out.push(` ${import_picocolors80.default.dim("--wait")} for task create: block until the task finishes; exit 1 unless it succeeded`);
|
|
97206
97333
|
out.push(` ${import_picocolors80.default.dim("--timeout <secs>")} for task create --wait: give up after <secs> and exit 1`);
|
|
@@ -97695,8 +97822,10 @@ ${didYouMean(cmd, COMMANDS3, "brainbase")}`);
|
|
|
97695
97822
|
process14.exit(1);
|
|
97696
97823
|
}
|
|
97697
97824
|
} catch (err) {
|
|
97825
|
+
const message2 = sanitizeLines(err.message).join(`
|
|
97826
|
+
`);
|
|
97698
97827
|
console.error(import_picocolors80.default.red(`
|
|
97699
|
-
${
|
|
97828
|
+
${message2}`));
|
|
97700
97829
|
if (err instanceof ApiError && err.status === 401 && !err.message.includes("brainbase login")) {
|
|
97701
97830
|
console.error(` Run ${import_picocolors80.default.cyan("brainbase login")} to connect this device.`);
|
|
97702
97831
|
}
|