@brainbase-labs/cli 0.16.5 → 0.18.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 -5
- package/dist/index.js +1086 -533
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -35141,7 +35141,7 @@ var require_dist2 = __commonJS((exports, module) => {
|
|
|
35141
35141
|
});
|
|
35142
35142
|
|
|
35143
35143
|
// src/index.ts
|
|
35144
|
-
var
|
|
35144
|
+
var import_picocolors48 = __toESM(require_picocolors(), 1);
|
|
35145
35145
|
import process14 from "node:process";
|
|
35146
35146
|
import fs79 from "node:fs";
|
|
35147
35147
|
|
|
@@ -36008,7 +36008,7 @@ function padStart(s, n) {
|
|
|
36008
36008
|
// package.json
|
|
36009
36009
|
var package_default = {
|
|
36010
36010
|
name: "@brainbase-labs/cli",
|
|
36011
|
-
version: "0.
|
|
36011
|
+
version: "0.18.0",
|
|
36012
36012
|
description: "Pack, share, and install agent templates across harnesses (Claude Code, Codex, ...).",
|
|
36013
36013
|
type: "module",
|
|
36014
36014
|
bin: {
|
|
@@ -53841,9 +53841,80 @@ function apiErrorMessage(body, status) {
|
|
|
53841
53841
|
return `HTTP ${status}`;
|
|
53842
53842
|
}
|
|
53843
53843
|
|
|
53844
|
+
// src/core/token.ts
|
|
53845
|
+
import path57 from "node:path";
|
|
53846
|
+
import fs47 from "node:fs";
|
|
53847
|
+
var TOKEN_FILE = path57.join(BRAINBASE_HOME, "token.json");
|
|
53848
|
+
var TOKEN_PREFIX = "bbpat_";
|
|
53849
|
+
var TOKEN_PREFIX_LEN = 14;
|
|
53850
|
+
function tokenPrefix(token) {
|
|
53851
|
+
if (!token.startsWith(TOKEN_PREFIX)) {
|
|
53852
|
+
throw new Error(`not a brainbase PAT: missing ${TOKEN_PREFIX} prefix`);
|
|
53853
|
+
}
|
|
53854
|
+
return token.slice(0, TOKEN_PREFIX_LEN);
|
|
53855
|
+
}
|
|
53856
|
+
function isValidTokenFormat(token) {
|
|
53857
|
+
if (typeof token !== "string")
|
|
53858
|
+
return false;
|
|
53859
|
+
if (!token.startsWith(TOKEN_PREFIX))
|
|
53860
|
+
return false;
|
|
53861
|
+
return /^bbpat_[A-Za-z0-9]{20,}$/.test(token);
|
|
53862
|
+
}
|
|
53863
|
+
var StoredTokenSchema = exports_external.object({
|
|
53864
|
+
schemaVersion: exports_external.literal(1),
|
|
53865
|
+
token: exports_external.string(),
|
|
53866
|
+
prefix: exports_external.string(),
|
|
53867
|
+
name: exports_external.string().optional(),
|
|
53868
|
+
createdAt: exports_external.string()
|
|
53869
|
+
});
|
|
53870
|
+
function readToken() {
|
|
53871
|
+
if (!exists(TOKEN_FILE))
|
|
53872
|
+
return null;
|
|
53873
|
+
try {
|
|
53874
|
+
return StoredTokenSchema.parse(readJson(TOKEN_FILE));
|
|
53875
|
+
} catch {
|
|
53876
|
+
return null;
|
|
53877
|
+
}
|
|
53878
|
+
}
|
|
53879
|
+
function writeToken(token, name) {
|
|
53880
|
+
if (!isValidTokenFormat(token)) {
|
|
53881
|
+
throw new Error("refusing to store token: invalid format");
|
|
53882
|
+
}
|
|
53883
|
+
ensureDir(BRAINBASE_HOME);
|
|
53884
|
+
const stored = {
|
|
53885
|
+
schemaVersion: 1,
|
|
53886
|
+
token,
|
|
53887
|
+
prefix: tokenPrefix(token),
|
|
53888
|
+
name,
|
|
53889
|
+
createdAt: new Date().toISOString()
|
|
53890
|
+
};
|
|
53891
|
+
writeJson(TOKEN_FILE, stored);
|
|
53892
|
+
try {
|
|
53893
|
+
fs47.chmodSync(TOKEN_FILE, 384);
|
|
53894
|
+
} catch {}
|
|
53895
|
+
return stored;
|
|
53896
|
+
}
|
|
53897
|
+
function clearToken() {
|
|
53898
|
+
if (exists(TOKEN_FILE))
|
|
53899
|
+
fs47.rmSync(TOKEN_FILE);
|
|
53900
|
+
}
|
|
53901
|
+
|
|
53844
53902
|
// src/core/api.ts
|
|
53845
53903
|
var DEFAULT_CONTROL_PLANE_BASE = "https://api.brainbaselabs.com";
|
|
53846
53904
|
var DEFAULT_PROXY_BASE = "https://api.v1.brainbaselabs.com";
|
|
53905
|
+
var MAS_IN_PROGRESS_MAX_WAIT_MS = 15000;
|
|
53906
|
+
var MAS_REQUEST_TIMEOUT_MS = 30000;
|
|
53907
|
+
var MAS_MIN_RETRY_DELAY_MS = 100;
|
|
53908
|
+
var MAS_MAX_RETRY_DELAY_MS = 2000;
|
|
53909
|
+
var DEFINITELY_UNSENT_NETWORK_CODES = new Set([
|
|
53910
|
+
"ConnectionRefused",
|
|
53911
|
+
"ECONNREFUSED",
|
|
53912
|
+
"ENOTFOUND",
|
|
53913
|
+
"EAI_AGAIN",
|
|
53914
|
+
"ERR_INVALID_URL",
|
|
53915
|
+
"FailedToOpenSocket",
|
|
53916
|
+
"UND_ERR_CONNECT_TIMEOUT"
|
|
53917
|
+
]);
|
|
53847
53918
|
|
|
53848
53919
|
class ApiError extends Error {
|
|
53849
53920
|
status;
|
|
@@ -53855,6 +53926,17 @@ class ApiError extends Error {
|
|
|
53855
53926
|
this.name = "ApiError";
|
|
53856
53927
|
}
|
|
53857
53928
|
}
|
|
53929
|
+
|
|
53930
|
+
class NetworkApiError extends ApiError {
|
|
53931
|
+
definitelyUnsent;
|
|
53932
|
+
constructor(message, definitelyUnsent) {
|
|
53933
|
+
super(message);
|
|
53934
|
+
this.definitelyUnsent = definitelyUnsent;
|
|
53935
|
+
}
|
|
53936
|
+
}
|
|
53937
|
+
|
|
53938
|
+
class TaskRecoveryDeadlineError extends ApiError {
|
|
53939
|
+
}
|
|
53858
53940
|
function normalizeControlPlaneUrl(url) {
|
|
53859
53941
|
const normalized = url?.trim().replace(/\/+$/, "");
|
|
53860
53942
|
return normalized || DEFAULT_CONTROL_PLANE_BASE;
|
|
@@ -53870,10 +53952,17 @@ function controlPlaneBaseUrl(session) {
|
|
|
53870
53952
|
}
|
|
53871
53953
|
return normalizeControlPlaneUrl(session?.control_plane_url);
|
|
53872
53954
|
}
|
|
53955
|
+
function masControlPlaneBaseUrl(session) {
|
|
53956
|
+
const controlPlane = process.env.BRAINBASE_CONTROL_PLANE_URL?.trim();
|
|
53957
|
+
return normalizeControlPlaneUrl(controlPlane || session?.control_plane_url);
|
|
53958
|
+
}
|
|
53873
53959
|
function apiBase(session) {
|
|
53874
53960
|
const suffix = usesLegacyControlPlane() ? "/api/cli" : "/v2/cli";
|
|
53875
53961
|
return `${controlPlaneBaseUrl(session)}${suffix}`;
|
|
53876
53962
|
}
|
|
53963
|
+
function masApiBase(session) {
|
|
53964
|
+
return `${masControlPlaneBaseUrl(session)}/v2`;
|
|
53965
|
+
}
|
|
53877
53966
|
function usesLegacyControlPlane() {
|
|
53878
53967
|
return !process.env.BRAINBASE_CONTROL_PLANE_URL?.trim() && !!process.env.BRAINBASE_API_URL?.trim();
|
|
53879
53968
|
}
|
|
@@ -53903,6 +53992,53 @@ async function resolveCredential() {
|
|
|
53903
53992
|
const status = authStatus();
|
|
53904
53993
|
throw new ApiError(status.ok ? "CLI authentication changed while this command was starting; retry it" : status.reason ?? "not logged in", 401);
|
|
53905
53994
|
}
|
|
53995
|
+
async function resolveMasCredential() {
|
|
53996
|
+
const configuredSession = readAuth();
|
|
53997
|
+
try {
|
|
53998
|
+
return await resolveCredential();
|
|
53999
|
+
} catch (error) {
|
|
54000
|
+
if (!(error instanceof ApiError && error.status === 401)) {
|
|
54001
|
+
throw error;
|
|
54002
|
+
}
|
|
54003
|
+
if (configuredSession || readAuth()) {
|
|
54004
|
+
if (readToken()) {
|
|
54005
|
+
throw new ApiError(`${error.message}. A stored PAT is available but will not be used while a login session is configured. Run \`brainbase logout\` to use the stored PAT, or \`brainbase login\` to refresh the session.`, 401);
|
|
54006
|
+
}
|
|
54007
|
+
throw error;
|
|
54008
|
+
}
|
|
54009
|
+
}
|
|
54010
|
+
const storedToken = readToken();
|
|
54011
|
+
if (storedToken) {
|
|
54012
|
+
return {
|
|
54013
|
+
bearer: storedToken.token,
|
|
54014
|
+
session: null,
|
|
54015
|
+
source: "stored_pat"
|
|
54016
|
+
};
|
|
54017
|
+
}
|
|
54018
|
+
const status = authStatus();
|
|
54019
|
+
throw new ApiError(status.ok ? "CLI authentication changed while this command was starting; retry it" : status.reason ?? "not logged in", 401);
|
|
54020
|
+
}
|
|
54021
|
+
function networkErrorCode(error) {
|
|
54022
|
+
if (!error || typeof error !== "object")
|
|
54023
|
+
return;
|
|
54024
|
+
const code = error.code;
|
|
54025
|
+
if (typeof code === "string")
|
|
54026
|
+
return code;
|
|
54027
|
+
const cause = error.cause;
|
|
54028
|
+
if (!cause || typeof cause !== "object")
|
|
54029
|
+
return;
|
|
54030
|
+
const causeCode = cause.code;
|
|
54031
|
+
return typeof causeCode === "string" ? causeCode : undefined;
|
|
54032
|
+
}
|
|
54033
|
+
function isDefinitelyUnsentNetworkError(error) {
|
|
54034
|
+
const code = networkErrorCode(error);
|
|
54035
|
+
if (DEFINITELY_UNSENT_NETWORK_CODES.has(code ?? ""))
|
|
54036
|
+
return true;
|
|
54037
|
+
if (!error || typeof error !== "object")
|
|
54038
|
+
return false;
|
|
54039
|
+
const cause = error.cause;
|
|
54040
|
+
return !!cause && typeof cause === "object" && cause.message === "bad port";
|
|
54041
|
+
}
|
|
53906
54042
|
async function sendRequest(url, init, bearer) {
|
|
53907
54043
|
const headers = new Headers(init.headers);
|
|
53908
54044
|
if (!headers.has("Authorization")) {
|
|
@@ -53916,7 +54052,7 @@ async function sendRequest(url, init, bearer) {
|
|
|
53916
54052
|
try {
|
|
53917
54053
|
return await fetch(url, { ...init, headers });
|
|
53918
54054
|
} catch (err) {
|
|
53919
|
-
throw new
|
|
54055
|
+
throw new NetworkApiError(`Network error: ${err.message}`, isDefinitelyUnsentNetworkError(err));
|
|
53920
54056
|
}
|
|
53921
54057
|
}
|
|
53922
54058
|
async function sendWithAuthRetry(session, send) {
|
|
@@ -53945,6 +54081,160 @@ async function request(pathname, init = {}) {
|
|
|
53945
54081
|
}
|
|
53946
54082
|
return body;
|
|
53947
54083
|
}
|
|
54084
|
+
function masApiErrorMessage(body, status) {
|
|
54085
|
+
if (body && typeof body === "object") {
|
|
54086
|
+
const obj = body;
|
|
54087
|
+
if (typeof obj.error === "string" && obj.error.trim() && typeof obj.message === "string" && obj.message.trim()) {
|
|
54088
|
+
const error = obj.error.trim();
|
|
54089
|
+
const message = obj.message.trim();
|
|
54090
|
+
return error === message ? message : `${error}: ${message}`;
|
|
54091
|
+
}
|
|
54092
|
+
for (const key2 of ["detail", "error", "message"]) {
|
|
54093
|
+
const value = obj[key2];
|
|
54094
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
54095
|
+
continue;
|
|
54096
|
+
const nested = value;
|
|
54097
|
+
for (const nestedKey of ["message", "detail", "error"]) {
|
|
54098
|
+
const message = nested[nestedKey];
|
|
54099
|
+
if (typeof message === "string" && message.trim()) {
|
|
54100
|
+
return message.trim();
|
|
54101
|
+
}
|
|
54102
|
+
}
|
|
54103
|
+
}
|
|
54104
|
+
}
|
|
54105
|
+
return apiErrorMessage(body, status);
|
|
54106
|
+
}
|
|
54107
|
+
function masRetryDelayMs(retryAfterHeader, fallbackMs) {
|
|
54108
|
+
const normalized = retryAfterHeader?.trim();
|
|
54109
|
+
if (!normalized)
|
|
54110
|
+
return fallbackMs;
|
|
54111
|
+
const retryAfterSeconds = Number(normalized);
|
|
54112
|
+
if (!Number.isFinite(retryAfterSeconds) || retryAfterSeconds < 0) {
|
|
54113
|
+
return fallbackMs;
|
|
54114
|
+
}
|
|
54115
|
+
return Math.min(MAS_MAX_RETRY_DELAY_MS, Math.max(MAS_MIN_RETRY_DELAY_MS, retryAfterSeconds * 1000));
|
|
54116
|
+
}
|
|
54117
|
+
function parseMasTaskCreateResponse(body) {
|
|
54118
|
+
if (!body || typeof body !== "object") {
|
|
54119
|
+
throw new ApiError("Task creation may have succeeded, but MAS returned an invalid response. Check your tasks before running this command again.", undefined, body);
|
|
54120
|
+
}
|
|
54121
|
+
const task = body;
|
|
54122
|
+
if (typeof task.id !== "string" || !task.id.trim() || typeof task.agent_id !== "string" || !task.agent_id.trim() || typeof task.status !== "string" || !task.status.trim()) {
|
|
54123
|
+
throw new ApiError("Task creation may have succeeded, but MAS returned an invalid response. Check your tasks before running this command again.", undefined, body);
|
|
54124
|
+
}
|
|
54125
|
+
return {
|
|
54126
|
+
id: task.id,
|
|
54127
|
+
agent_id: task.agent_id,
|
|
54128
|
+
status: task.status
|
|
54129
|
+
};
|
|
54130
|
+
}
|
|
54131
|
+
async function masRequest(pathname, init) {
|
|
54132
|
+
const credential = await resolveMasCredential();
|
|
54133
|
+
let currentSession = credential.session;
|
|
54134
|
+
let ambiguousNetworkRetriesRemaining = 1;
|
|
54135
|
+
let requestMayHaveSucceeded = false;
|
|
54136
|
+
let transientHttpRetriesRemaining = 1;
|
|
54137
|
+
let recoveryDeadline = null;
|
|
54138
|
+
let recoveryTaskId = null;
|
|
54139
|
+
const recoveryRequestTimeoutMs = () => {
|
|
54140
|
+
if (recoveryDeadline === null)
|
|
54141
|
+
return MAS_REQUEST_TIMEOUT_MS;
|
|
54142
|
+
const remainingMs = recoveryDeadline - Date.now();
|
|
54143
|
+
if (remainingMs <= 0) {
|
|
54144
|
+
throw new TaskRecoveryDeadlineError(recoveryTaskId ? `Task ${recoveryTaskId} is still being processed. Check its status before starting another task.` : "Task creation may still be processing. Check your tasks before running this command again.");
|
|
54145
|
+
}
|
|
54146
|
+
return Math.min(MAS_REQUEST_TIMEOUT_MS, remainingMs);
|
|
54147
|
+
};
|
|
54148
|
+
while (true) {
|
|
54149
|
+
const retrySession = credential.source === "session" ? currentSession : null;
|
|
54150
|
+
let res;
|
|
54151
|
+
try {
|
|
54152
|
+
res = await sendWithAuthRetry(retrySession, async (refreshed) => {
|
|
54153
|
+
if (refreshed)
|
|
54154
|
+
currentSession = refreshed;
|
|
54155
|
+
while (true) {
|
|
54156
|
+
const signal = AbortSignal.timeout(recoveryRequestTimeoutMs());
|
|
54157
|
+
try {
|
|
54158
|
+
return await sendRequest(`${masApiBase(currentSession)}${pathname}`, {
|
|
54159
|
+
...init,
|
|
54160
|
+
signal
|
|
54161
|
+
}, currentSession?.access_token ?? credential.bearer);
|
|
54162
|
+
} catch (error) {
|
|
54163
|
+
if (error instanceof NetworkApiError && error.definitelyUnsent) {
|
|
54164
|
+
throw error;
|
|
54165
|
+
}
|
|
54166
|
+
if (ambiguousNetworkRetriesRemaining === 0)
|
|
54167
|
+
throw error;
|
|
54168
|
+
requestMayHaveSucceeded = true;
|
|
54169
|
+
ambiguousNetworkRetriesRemaining -= 1;
|
|
54170
|
+
}
|
|
54171
|
+
}
|
|
54172
|
+
});
|
|
54173
|
+
} catch (error) {
|
|
54174
|
+
if (error instanceof TaskRecoveryDeadlineError)
|
|
54175
|
+
throw error;
|
|
54176
|
+
if (recoveryTaskId || recoveryDeadline !== null || requestMayHaveSucceeded) {
|
|
54177
|
+
throw new ApiError(recoveryTaskId ? `Task ${recoveryTaskId} may still be processing. Check its status before starting another task. ${error.message}` : `Task creation may still be processing. Check your tasks before running this command again. ${error.message}`);
|
|
54178
|
+
}
|
|
54179
|
+
throw error;
|
|
54180
|
+
}
|
|
54181
|
+
let text2;
|
|
54182
|
+
try {
|
|
54183
|
+
text2 = await res.text();
|
|
54184
|
+
} catch (error) {
|
|
54185
|
+
if (ambiguousNetworkRetriesRemaining > 0) {
|
|
54186
|
+
requestMayHaveSucceeded = true;
|
|
54187
|
+
ambiguousNetworkRetriesRemaining -= 1;
|
|
54188
|
+
continue;
|
|
54189
|
+
}
|
|
54190
|
+
throw new ApiError(recoveryTaskId ? `Task ${recoveryTaskId} may still be processing. Check its status before starting another task. ${error.message}` : recoveryDeadline !== null || requestMayHaveSucceeded ? `Task creation may still be processing. Check your tasks before running this command again. ${error.message}` : `Network error while reading response: ${error.message}`);
|
|
54191
|
+
}
|
|
54192
|
+
let body = text2;
|
|
54193
|
+
try {
|
|
54194
|
+
body = text2 ? JSON.parse(text2) : null;
|
|
54195
|
+
} catch {}
|
|
54196
|
+
const detail = body && typeof body === "object" ? body.detail : null;
|
|
54197
|
+
const detailObject = detail && typeof detail === "object" ? detail : null;
|
|
54198
|
+
const code = detailObject?.code;
|
|
54199
|
+
if (res.status === 409 && code === "idempotency_request_in_progress") {
|
|
54200
|
+
if (typeof detailObject?.task_id === "string") {
|
|
54201
|
+
recoveryTaskId = detailObject.task_id;
|
|
54202
|
+
}
|
|
54203
|
+
recoveryDeadline ??= Date.now() + MAS_IN_PROGRESS_MAX_WAIT_MS;
|
|
54204
|
+
const delayMs = masRetryDelayMs(res.headers.get("Retry-After"), 1000);
|
|
54205
|
+
if (Date.now() + delayMs >= recoveryDeadline) {
|
|
54206
|
+
throw new ApiError(recoveryTaskId ? `Task ${recoveryTaskId} is still being processed. Check its status before starting another task.` : masApiErrorMessage(body, res.status), res.status, body);
|
|
54207
|
+
}
|
|
54208
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
54209
|
+
continue;
|
|
54210
|
+
}
|
|
54211
|
+
if (res.status >= 500 && transientHttpRetriesRemaining > 0) {
|
|
54212
|
+
transientHttpRetriesRemaining -= 1;
|
|
54213
|
+
requestMayHaveSucceeded = true;
|
|
54214
|
+
const delayMs = masRetryDelayMs(res.headers.get("Retry-After"), 250);
|
|
54215
|
+
if (recoveryDeadline !== null && Date.now() + delayMs >= recoveryDeadline) {
|
|
54216
|
+
throw new TaskRecoveryDeadlineError(recoveryTaskId ? `Task ${recoveryTaskId} is still being processed. Check its status before starting another task.` : "Task creation may still be processing. Check your tasks before running this command again.");
|
|
54217
|
+
}
|
|
54218
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
54219
|
+
continue;
|
|
54220
|
+
}
|
|
54221
|
+
if (!res.ok) {
|
|
54222
|
+
const message = masApiErrorMessage(body, res.status);
|
|
54223
|
+
throw new ApiError(res.status >= 500 ? `${message} Task creation may still be processing; check your tasks before running this command again.` : message, res.status, body);
|
|
54224
|
+
}
|
|
54225
|
+
return body;
|
|
54226
|
+
}
|
|
54227
|
+
}
|
|
54228
|
+
var masApi = {
|
|
54229
|
+
async createTask(input, options) {
|
|
54230
|
+
const body = await masRequest("/tasks", {
|
|
54231
|
+
method: "POST",
|
|
54232
|
+
headers: { "Idempotency-Key": options.idempotencyKey },
|
|
54233
|
+
body: JSON.stringify(input)
|
|
54234
|
+
});
|
|
54235
|
+
return parseMasTaskCreateResponse(body);
|
|
54236
|
+
}
|
|
54237
|
+
};
|
|
53948
54238
|
var api = {
|
|
53949
54239
|
listOrgs() {
|
|
53950
54240
|
return request("/orgs");
|
|
@@ -53958,6 +54248,22 @@ var api = {
|
|
|
53958
54248
|
body: JSON.stringify({ name })
|
|
53959
54249
|
});
|
|
53960
54250
|
},
|
|
54251
|
+
async listAgents(orgId, teamId) {
|
|
54252
|
+
const path58 = `/orgs/${encodeURIComponent(orgId)}/teams/${encodeURIComponent(teamId)}/agents`;
|
|
54253
|
+
let body;
|
|
54254
|
+
try {
|
|
54255
|
+
body = await request(path58);
|
|
54256
|
+
} catch (err) {
|
|
54257
|
+
if (err instanceof ApiError && err.status === 404) {
|
|
54258
|
+
throw new ApiError("This control plane does not support listing agents yet. Update the server, or use the web app to find the agent id.", 404, err.body);
|
|
54259
|
+
}
|
|
54260
|
+
throw err;
|
|
54261
|
+
}
|
|
54262
|
+
if (!Array.isArray(body)) {
|
|
54263
|
+
throw new ApiError(`Unexpected response listing agents: expected an array from ${path58}.`, undefined, body);
|
|
54264
|
+
}
|
|
54265
|
+
return body;
|
|
54266
|
+
},
|
|
53961
54267
|
createAgent(input) {
|
|
53962
54268
|
if (usesLegacyControlPlane() && (input.machine_kind !== undefined || input.default_model !== undefined)) {
|
|
53963
54269
|
return Promise.reject(legacyAgentConfigError());
|
|
@@ -54059,64 +54365,6 @@ function proxyBaseUrl(session) {
|
|
|
54059
54365
|
return DEFAULT_PROXY_BASE.replace(/\/+$/, "");
|
|
54060
54366
|
}
|
|
54061
54367
|
|
|
54062
|
-
// src/core/token.ts
|
|
54063
|
-
import path57 from "node:path";
|
|
54064
|
-
import fs47 from "node:fs";
|
|
54065
|
-
var TOKEN_FILE = path57.join(BRAINBASE_HOME, "token.json");
|
|
54066
|
-
var TOKEN_PREFIX = "bbpat_";
|
|
54067
|
-
var TOKEN_PREFIX_LEN = 14;
|
|
54068
|
-
function tokenPrefix(token) {
|
|
54069
|
-
if (!token.startsWith(TOKEN_PREFIX)) {
|
|
54070
|
-
throw new Error(`not a brainbase PAT: missing ${TOKEN_PREFIX} prefix`);
|
|
54071
|
-
}
|
|
54072
|
-
return token.slice(0, TOKEN_PREFIX_LEN);
|
|
54073
|
-
}
|
|
54074
|
-
function isValidTokenFormat(token) {
|
|
54075
|
-
if (typeof token !== "string")
|
|
54076
|
-
return false;
|
|
54077
|
-
if (!token.startsWith(TOKEN_PREFIX))
|
|
54078
|
-
return false;
|
|
54079
|
-
return /^bbpat_[A-Za-z0-9]{20,}$/.test(token);
|
|
54080
|
-
}
|
|
54081
|
-
var StoredTokenSchema = exports_external.object({
|
|
54082
|
-
schemaVersion: exports_external.literal(1),
|
|
54083
|
-
token: exports_external.string(),
|
|
54084
|
-
prefix: exports_external.string(),
|
|
54085
|
-
name: exports_external.string().optional(),
|
|
54086
|
-
createdAt: exports_external.string()
|
|
54087
|
-
});
|
|
54088
|
-
function readToken() {
|
|
54089
|
-
if (!exists(TOKEN_FILE))
|
|
54090
|
-
return null;
|
|
54091
|
-
try {
|
|
54092
|
-
return StoredTokenSchema.parse(readJson(TOKEN_FILE));
|
|
54093
|
-
} catch {
|
|
54094
|
-
return null;
|
|
54095
|
-
}
|
|
54096
|
-
}
|
|
54097
|
-
function writeToken(token, name) {
|
|
54098
|
-
if (!isValidTokenFormat(token)) {
|
|
54099
|
-
throw new Error("refusing to store token: invalid format");
|
|
54100
|
-
}
|
|
54101
|
-
ensureDir(BRAINBASE_HOME);
|
|
54102
|
-
const stored = {
|
|
54103
|
-
schemaVersion: 1,
|
|
54104
|
-
token,
|
|
54105
|
-
prefix: tokenPrefix(token),
|
|
54106
|
-
name,
|
|
54107
|
-
createdAt: new Date().toISOString()
|
|
54108
|
-
};
|
|
54109
|
-
writeJson(TOKEN_FILE, stored);
|
|
54110
|
-
try {
|
|
54111
|
-
fs47.chmodSync(TOKEN_FILE, 384);
|
|
54112
|
-
} catch {}
|
|
54113
|
-
return stored;
|
|
54114
|
-
}
|
|
54115
|
-
function clearToken() {
|
|
54116
|
-
if (exists(TOKEN_FILE))
|
|
54117
|
-
fs47.rmSync(TOKEN_FILE);
|
|
54118
|
-
}
|
|
54119
|
-
|
|
54120
54368
|
// src/core/registry-client.ts
|
|
54121
54369
|
var DEFAULT_BASE = "https://api.v1.brainbaselabs.com";
|
|
54122
54370
|
function baseUrl(session) {
|
|
@@ -62795,7 +63043,7 @@ function runHarnessInstall(harnessId, components, opts, agentName) {
|
|
|
62795
63043
|
}
|
|
62796
63044
|
|
|
62797
63045
|
// src/cli/agent.ts
|
|
62798
|
-
var
|
|
63046
|
+
var import_picocolors34 = __toESM(require_picocolors(), 1);
|
|
62799
63047
|
|
|
62800
63048
|
// src/cli/agent-pull.ts
|
|
62801
63049
|
import { spawn as spawn2 } from "node:child_process";
|
|
@@ -65104,7 +65352,7 @@ function formatExport(shell, key2, value) {
|
|
|
65104
65352
|
|
|
65105
65353
|
// src/cli/agent-create.ts
|
|
65106
65354
|
import path81 from "node:path";
|
|
65107
|
-
var
|
|
65355
|
+
var import_picocolors32 = __toESM(require_picocolors(), 1);
|
|
65108
65356
|
|
|
65109
65357
|
// src/ui/box.ts
|
|
65110
65358
|
var import_picocolors30 = __toESM(require_picocolors(), 1);
|
|
@@ -65130,110 +65378,189 @@ function tip(text2, indent = 2) {
|
|
|
65130
65378
|
return " ".repeat(indent) + import_picocolors30.default.dim("›") + " " + import_picocolors30.default.dim(text2);
|
|
65131
65379
|
}
|
|
65132
65380
|
|
|
65133
|
-
// src/
|
|
65134
|
-
|
|
65135
|
-
|
|
65136
|
-
|
|
65137
|
-
|
|
65138
|
-
|
|
65139
|
-
if (manifest.id) {
|
|
65140
|
-
f2.warn(`This folder already belongs to an agent — ${import_picocolors31.default.bold(manifest.agent.name)} (${import_picocolors31.default.dim(manifest.id)}).`);
|
|
65141
|
-
f2.info(`If you want to detach it, run ${import_picocolors31.default.cyan("brainbase unlink")} first; or move to a different directory.`);
|
|
65142
|
-
return;
|
|
65381
|
+
// src/core/org-team.ts
|
|
65382
|
+
var import_picocolors31 = __toESM(require_picocolors(), 1);
|
|
65383
|
+
class OrgTeamError extends Error {
|
|
65384
|
+
constructor(message) {
|
|
65385
|
+
super(message);
|
|
65386
|
+
this.name = "OrgTeamError";
|
|
65143
65387
|
}
|
|
65144
|
-
|
|
65145
|
-
|
|
65146
|
-
|
|
65388
|
+
}
|
|
65389
|
+
async function loading(announce, message, done, fetch2) {
|
|
65390
|
+
if (!announce)
|
|
65391
|
+
return await fetch2();
|
|
65392
|
+
const sp = de();
|
|
65393
|
+
sp.start(message);
|
|
65147
65394
|
try {
|
|
65148
|
-
|
|
65395
|
+
const value = await fetch2();
|
|
65396
|
+
sp.stop(done(value));
|
|
65397
|
+
return value;
|
|
65149
65398
|
} catch (err) {
|
|
65150
|
-
|
|
65151
|
-
|
|
65152
|
-
|
|
65399
|
+
sp.stop("Failed.");
|
|
65400
|
+
throw err;
|
|
65401
|
+
}
|
|
65402
|
+
}
|
|
65403
|
+
async function chooseOne(opts) {
|
|
65404
|
+
if (!opts.allowPrompt) {
|
|
65405
|
+
throw new NonInteractiveError(`${opts.message} cannot be answered while emitting JSON. ${opts.flagHint}`);
|
|
65153
65406
|
}
|
|
65154
|
-
|
|
65407
|
+
return await select({
|
|
65408
|
+
message: opts.message,
|
|
65409
|
+
options: opts.options,
|
|
65410
|
+
flagHint: opts.flagHint
|
|
65411
|
+
});
|
|
65412
|
+
}
|
|
65413
|
+
async function resolveOrg(orgRef, opts = {}) {
|
|
65414
|
+
if (orgRef === "") {
|
|
65415
|
+
throw new OrgTeamError("--org needs a value: an organization id or slug.");
|
|
65416
|
+
}
|
|
65417
|
+
const orgs = await loading(opts.announce, "Loading your organizations…", (found) => `Found ${found.length} organization${found.length === 1 ? "" : "s"}.`, () => api.listOrgs());
|
|
65155
65418
|
if (orgs.length === 0) {
|
|
65156
|
-
|
|
65157
|
-
$e("Create one on the web app first, then come back.");
|
|
65158
|
-
return;
|
|
65419
|
+
throw new OrgTeamError("You are not a member of any organization. Create one in the web app first.");
|
|
65159
65420
|
}
|
|
65160
|
-
|
|
65161
|
-
|
|
65162
|
-
const found = orgs.find((o2) => o2.id === args.orgId || o2.slug === args.orgId);
|
|
65421
|
+
if (orgRef) {
|
|
65422
|
+
const found = orgs.find((o2) => o2.id === orgRef || o2.slug === orgRef);
|
|
65163
65423
|
if (!found) {
|
|
65164
|
-
|
|
65165
|
-
return;
|
|
65424
|
+
throw new OrgTeamError(`Org ${orgRef} not found, or you're not a member of it.`);
|
|
65166
65425
|
}
|
|
65167
|
-
|
|
65168
|
-
} else if (orgs.length === 1) {
|
|
65169
|
-
org = orgs[0];
|
|
65170
|
-
f2.info(`Using organization ${import_picocolors31.default.bold(org.name)}.`);
|
|
65171
|
-
} else {
|
|
65172
|
-
const orgId = await select({
|
|
65173
|
-
message: "Pick an organization",
|
|
65174
|
-
options: orgs.map((o2) => ({ value: o2.id, label: o2.name, hint: o2.role })),
|
|
65175
|
-
flagHint: "Pass --org <id-or-slug> to choose non-interactively."
|
|
65176
|
-
});
|
|
65177
|
-
org = orgs.find((o2) => o2.id === orgId);
|
|
65426
|
+
return found;
|
|
65178
65427
|
}
|
|
65179
|
-
|
|
65180
|
-
|
|
65181
|
-
|
|
65182
|
-
|
|
65183
|
-
|
|
65184
|
-
} catch (err) {
|
|
65185
|
-
teamsSpinner.stop("Failed.");
|
|
65186
|
-
handleApiError4(err);
|
|
65187
|
-
return;
|
|
65428
|
+
if (orgs.length === 1) {
|
|
65429
|
+
const org = orgs[0];
|
|
65430
|
+
if (opts.announce)
|
|
65431
|
+
f2.info(`Using organization ${import_picocolors31.default.bold(org.name)}.`);
|
|
65432
|
+
return org;
|
|
65188
65433
|
}
|
|
65189
|
-
|
|
65190
|
-
|
|
65434
|
+
const orgId = await chooseOne({
|
|
65435
|
+
message: "Which organization?",
|
|
65436
|
+
options: orgs.map((o2) => ({ value: o2.id, label: o2.name, hint: o2.role })),
|
|
65437
|
+
flagHint: "Pass --org <id-or-slug>.",
|
|
65438
|
+
allowPrompt: opts.allowPrompt !== false
|
|
65439
|
+
});
|
|
65440
|
+
return orgs.find((o2) => o2.id === orgId);
|
|
65441
|
+
}
|
|
65442
|
+
function canOfferTeamCreation(opts) {
|
|
65443
|
+
return !!opts.offerCreateTeam && opts.allowPrompt !== false && opts.interactive;
|
|
65444
|
+
}
|
|
65445
|
+
function shouldAutoPickLoneTeam(opts) {
|
|
65446
|
+
return opts.teamCount === 1 && !opts.canCreate;
|
|
65447
|
+
}
|
|
65448
|
+
async function resolveOrgAndTeam(args) {
|
|
65449
|
+
if (args.orgId === "") {
|
|
65450
|
+
throw new OrgTeamError("--org needs a value: an organization id or slug.");
|
|
65451
|
+
}
|
|
65452
|
+
if (args.teamId === "") {
|
|
65453
|
+
throw new OrgTeamError("--team needs a value: a team id.");
|
|
65454
|
+
}
|
|
65455
|
+
if (args.teamId && !args.orgId) {
|
|
65456
|
+
return await findTeamAcrossOrgs(args.teamId);
|
|
65457
|
+
}
|
|
65458
|
+
const org = await resolveOrg(args.orgId, {
|
|
65459
|
+
allowPrompt: args.allowPrompt,
|
|
65460
|
+
announce: args.announce
|
|
65461
|
+
});
|
|
65462
|
+
const teams = await loading(args.announce, `Loading teams in ${org.name}…`, (found) => `Found ${found.length} team${found.length === 1 ? "" : "s"}.`, () => api.listTeams(org.id));
|
|
65191
65463
|
if (args.teamId) {
|
|
65192
65464
|
const found = teams.find((t) => t.id === args.teamId);
|
|
65193
65465
|
if (!found) {
|
|
65194
|
-
|
|
65195
|
-
return;
|
|
65466
|
+
throw new OrgTeamError(`Team ${args.teamId} not found in ${org.name}.`);
|
|
65196
65467
|
}
|
|
65197
|
-
team
|
|
65198
|
-
}
|
|
65199
|
-
|
|
65200
|
-
|
|
65468
|
+
return { org, team: found };
|
|
65469
|
+
}
|
|
65470
|
+
const canCreate = canOfferTeamCreation({
|
|
65471
|
+
offerCreateTeam: args.offerCreateTeam,
|
|
65472
|
+
allowPrompt: args.allowPrompt,
|
|
65473
|
+
interactive: isInteractive()
|
|
65474
|
+
});
|
|
65475
|
+
if (teams.length === 0 && !canCreate) {
|
|
65476
|
+
throw new OrgTeamError(`${org.name} has no teams yet. Create one in the web app first.`);
|
|
65477
|
+
}
|
|
65478
|
+
if (shouldAutoPickLoneTeam({ teamCount: teams.length, canCreate })) {
|
|
65479
|
+
const team = teams[0];
|
|
65480
|
+
if (args.announce)
|
|
65201
65481
|
f2.info(`Using team ${import_picocolors31.default.bold(team.name)}.`);
|
|
65202
|
-
|
|
65203
|
-
|
|
65204
|
-
|
|
65205
|
-
|
|
65206
|
-
|
|
65207
|
-
|
|
65208
|
-
|
|
65209
|
-
|
|
65210
|
-
{ value: "__new__", label: "+ Create a new team" }
|
|
65211
|
-
];
|
|
65212
|
-
const teamChoice = await ie({
|
|
65213
|
-
message: "Pick a team (or create one)",
|
|
65214
|
-
options: teamOptions
|
|
65482
|
+
return { org, team };
|
|
65483
|
+
}
|
|
65484
|
+
if (!canCreate) {
|
|
65485
|
+
const teamId = await chooseOne({
|
|
65486
|
+
message: "Which team?",
|
|
65487
|
+
options: teams.map((t) => ({ value: t.id, label: t.name, hint: t.role })),
|
|
65488
|
+
flagHint: "Pass --team <id>.",
|
|
65489
|
+
allowPrompt: args.allowPrompt !== false
|
|
65215
65490
|
});
|
|
65216
|
-
|
|
65217
|
-
|
|
65218
|
-
|
|
65219
|
-
|
|
65220
|
-
|
|
65221
|
-
|
|
65222
|
-
|
|
65223
|
-
|
|
65224
|
-
|
|
65225
|
-
|
|
65226
|
-
|
|
65227
|
-
|
|
65228
|
-
|
|
65229
|
-
|
|
65230
|
-
|
|
65231
|
-
|
|
65232
|
-
|
|
65491
|
+
return { org, team: teams.find((t) => t.id === teamId) };
|
|
65492
|
+
}
|
|
65493
|
+
return { org, team: await pickOrCreateTeam(org, teams) };
|
|
65494
|
+
}
|
|
65495
|
+
var CREATE_TEAM = "__new__";
|
|
65496
|
+
async function pickOrCreateTeam(org, teams) {
|
|
65497
|
+
const picked = ensureNotCancelled(await ie({
|
|
65498
|
+
message: "Pick a team (or create one)",
|
|
65499
|
+
options: [
|
|
65500
|
+
...teams.map((t) => ({ value: t.id, label: t.name, hint: t.role })),
|
|
65501
|
+
{ value: CREATE_TEAM, label: "+ Create a new team" }
|
|
65502
|
+
]
|
|
65503
|
+
}));
|
|
65504
|
+
if (picked !== CREATE_TEAM)
|
|
65505
|
+
return teams.find((t) => t.id === picked);
|
|
65506
|
+
const name = ensureNotCancelled(await te({
|
|
65507
|
+
message: "New team name",
|
|
65508
|
+
validate: (v3) => !v3?.trim() ? "Required" : undefined
|
|
65509
|
+
}));
|
|
65510
|
+
return await loading(true, "Creating team…", (created) => `Created team ${import_picocolors31.default.bold(created.name)}.`, () => api.createTeam(org.id, name.trim()));
|
|
65511
|
+
}
|
|
65512
|
+
async function findTeamAcrossOrgs(teamId) {
|
|
65513
|
+
const orgs = await api.listOrgs();
|
|
65514
|
+
if (orgs.length === 0) {
|
|
65515
|
+
throw new OrgTeamError("You are not a member of any organization.");
|
|
65516
|
+
}
|
|
65517
|
+
const { resolved, failures } = await listTeamsPerOrg(orgs);
|
|
65518
|
+
for (const { org, teams } of resolved) {
|
|
65519
|
+
const team = teams.find((t) => t.id === teamId);
|
|
65520
|
+
if (team)
|
|
65521
|
+
return { org, team };
|
|
65522
|
+
}
|
|
65523
|
+
if (failures.length > 0)
|
|
65524
|
+
throw failures[0].error;
|
|
65525
|
+
throw new OrgTeamError(`Team ${teamId} not found in any of your organizations. Run \`brainbase team list\` to see the ids you can use.`);
|
|
65526
|
+
}
|
|
65527
|
+
async function listTeamsPerOrg(orgs) {
|
|
65528
|
+
const settled = await Promise.allSettled(orgs.map((org) => api.listTeams(org.id)));
|
|
65529
|
+
const entries = [];
|
|
65530
|
+
const resolved = [];
|
|
65531
|
+
const failures = [];
|
|
65532
|
+
settled.forEach((outcome, index) => {
|
|
65533
|
+
const org = orgs[index];
|
|
65534
|
+
if (outcome.status === "fulfilled") {
|
|
65535
|
+
const entry = { org, teams: outcome.value };
|
|
65536
|
+
entries.push(entry);
|
|
65537
|
+
resolved.push(entry);
|
|
65233
65538
|
} else {
|
|
65234
|
-
|
|
65539
|
+
const error = outcome.reason;
|
|
65540
|
+
entries.push({ org, teams: [], error: error.message });
|
|
65541
|
+
failures.push({ org, error });
|
|
65235
65542
|
}
|
|
65543
|
+
});
|
|
65544
|
+
return { entries, resolved, failures };
|
|
65545
|
+
}
|
|
65546
|
+
|
|
65547
|
+
// src/cli/agent-create.ts
|
|
65548
|
+
async function runAgentCreate(cwd2, args) {
|
|
65549
|
+
banner("agent create — claim a brainbase.agent.yaml and link this folder");
|
|
65550
|
+
let manifest = await loadOrScaffoldManifest(cwd2, args);
|
|
65551
|
+
if (!manifest)
|
|
65552
|
+
return;
|
|
65553
|
+
if (manifest.id) {
|
|
65554
|
+
f2.warn(`This folder already belongs to an agent — ${import_picocolors32.default.bold(manifest.agent.name)} (${import_picocolors32.default.dim(manifest.id)}).`);
|
|
65555
|
+
f2.info(`If you want to detach it, run ${import_picocolors32.default.cyan("brainbase unlink")} first; or move to a different directory.`);
|
|
65556
|
+
return;
|
|
65236
65557
|
}
|
|
65558
|
+
const { org, team } = await resolveOrgAndTeam({
|
|
65559
|
+
orgId: args.orgId,
|
|
65560
|
+
teamId: args.teamId,
|
|
65561
|
+
announce: true,
|
|
65562
|
+
offerCreateTeam: true
|
|
65563
|
+
});
|
|
65237
65564
|
const harness = normalizeHarnessId(args.harness ?? manifest.harness ?? await pickHarness2(cwd2));
|
|
65238
65565
|
let agentName = args.name?.trim() || manifest.agent.name.trim();
|
|
65239
65566
|
if (!agentName) {
|
|
@@ -65256,11 +65583,11 @@ async function runAgentCreate(cwd2, args) {
|
|
|
65256
65583
|
}
|
|
65257
65584
|
if (!autoProceed(args.yes)) {
|
|
65258
65585
|
le([
|
|
65259
|
-
`${
|
|
65260
|
-
`${
|
|
65261
|
-
`${
|
|
65262
|
-
`${
|
|
65263
|
-
...tagline ? [`${
|
|
65586
|
+
`${import_picocolors32.default.dim("org")} ${import_picocolors32.default.bold(org.name)}`,
|
|
65587
|
+
`${import_picocolors32.default.dim("team")} ${import_picocolors32.default.bold(team.name)}`,
|
|
65588
|
+
`${import_picocolors32.default.dim("harness")} ${import_picocolors32.default.bold(harness)}`,
|
|
65589
|
+
`${import_picocolors32.default.dim("agent")} ${import_picocolors32.default.bold(agentName)}`,
|
|
65590
|
+
...tagline ? [`${import_picocolors32.default.dim("tagline")} ${tagline}`] : []
|
|
65264
65591
|
].join(`
|
|
65265
65592
|
`), "Will create");
|
|
65266
65593
|
const confirmed = await se({ message: "Create this agent?", initialValue: true });
|
|
@@ -65274,7 +65601,7 @@ async function runAgentCreate(cwd2, args) {
|
|
|
65274
65601
|
const body = resolveEntrypoint(cwd2, manifest);
|
|
65275
65602
|
if (body === null) {
|
|
65276
65603
|
if (manifest.entrypoint.file) {
|
|
65277
|
-
f2.error(`Entrypoint file ${
|
|
65604
|
+
f2.error(`Entrypoint file ${import_picocolors32.default.bold(manifest.entrypoint.file)} not found.`);
|
|
65278
65605
|
} else {
|
|
65279
65606
|
f2.error("Entrypoint block is empty.");
|
|
65280
65607
|
}
|
|
@@ -65296,10 +65623,11 @@ async function runAgentCreate(cwd2, args) {
|
|
|
65296
65623
|
...manifest.machine_kind !== undefined ? { machine_kind: manifest.machine_kind } : {},
|
|
65297
65624
|
...manifest.default_model !== undefined ? { default_model: manifest.default_model } : {}
|
|
65298
65625
|
});
|
|
65299
|
-
createSpinner.stop(`Created ${
|
|
65626
|
+
createSpinner.stop(`Created ${import_picocolors32.default.bold(agent.name)}.`);
|
|
65300
65627
|
} catch (err) {
|
|
65301
65628
|
createSpinner.stop("Failed.");
|
|
65302
65629
|
handleApiError4(err);
|
|
65630
|
+
process.exitCode = 1;
|
|
65303
65631
|
return;
|
|
65304
65632
|
}
|
|
65305
65633
|
const machineConfigMissing = manifest.machine_kind !== undefined && agent.machine_kind !== manifest.machine_kind;
|
|
@@ -65312,15 +65640,15 @@ async function runAgentCreate(cwd2, args) {
|
|
|
65312
65640
|
...machineConfigMissing ? ["machine_kind"] : [],
|
|
65313
65641
|
...modelConfigMissing ? ["default_model"] : []
|
|
65314
65642
|
];
|
|
65315
|
-
f2.error(`Agent ${
|
|
65643
|
+
f2.error(`Agent ${import_picocolors32.default.bold(agent.id)} was created, but this control plane did not apply ${fields.join(" / ")}.`);
|
|
65316
65644
|
if (machineConfigMissing) {
|
|
65317
65645
|
if (agent.machine_kind) {
|
|
65318
|
-
f2.info(`machine_kind is immutable. Run ${
|
|
65646
|
+
f2.info(`machine_kind is immutable. Run ${import_picocolors32.default.cyan("brainbase agent pull --force")} to accept ${agent.machine_kind}, or delete this agent and recreate it after upgrading the control plane.`);
|
|
65319
65647
|
} else {
|
|
65320
65648
|
f2.info("machine_kind is immutable and this server did not report the provider it created. Upgrade the control plane, delete this agent, and recreate it.");
|
|
65321
65649
|
}
|
|
65322
65650
|
} else {
|
|
65323
|
-
f2.info(`Upgrade the control plane, then run ${
|
|
65651
|
+
f2.info(`Upgrade the control plane, then run ${import_picocolors32.default.cyan("brainbase agent push")} to apply default_model.`);
|
|
65324
65652
|
}
|
|
65325
65653
|
process.exitCode = 1;
|
|
65326
65654
|
return;
|
|
@@ -65334,12 +65662,12 @@ async function runAgentCreate(cwd2, args) {
|
|
|
65334
65662
|
wantsTracking = true;
|
|
65335
65663
|
} else if (!isInteractive()) {
|
|
65336
65664
|
wantsTracking = false;
|
|
65337
|
-
f2.info(`Tracking left off (non-interactive). Re-run with ${
|
|
65665
|
+
f2.info(`Tracking left off (non-interactive). Re-run with ${import_picocolors32.default.cyan("--track")} to route ${harness} LLM traffic through brainbase.`);
|
|
65338
65666
|
} else if (args.yes) {
|
|
65339
65667
|
wantsTracking = true;
|
|
65340
65668
|
} else {
|
|
65341
65669
|
const ans = await se({
|
|
65342
|
-
message: `Track ${harness} conversations on the brainbase platform? ${
|
|
65670
|
+
message: `Track ${harness} conversations on the brainbase platform? ${import_picocolors32.default.dim("(routes LLM calls through brainbase so they appear under this agent)")}`,
|
|
65343
65671
|
initialValue: true
|
|
65344
65672
|
});
|
|
65345
65673
|
wantsTracking = ensureNotCancelled(ans);
|
|
@@ -65399,7 +65727,7 @@ async function runAgentCreate(cwd2, args) {
|
|
|
65399
65727
|
if (hasContent) {
|
|
65400
65728
|
const outgoing = await buildOutgoingComponents(cwd2, manifest, null);
|
|
65401
65729
|
if (outgoing === null) {
|
|
65402
|
-
f2.warn(`Agent created, but local content wasn't uploaded. Fix the issue above and run ${
|
|
65730
|
+
f2.warn(`Agent created, but local content wasn't uploaded. Fix the issue above and run ${import_picocolors32.default.cyan("brainbase agent push")}.`);
|
|
65403
65731
|
} else if (outgoing.length > 0) {
|
|
65404
65732
|
const pushSpinner = de();
|
|
65405
65733
|
pushSpinner.start("Pushing local content…");
|
|
@@ -65413,9 +65741,9 @@ async function runAgentCreate(cwd2, args) {
|
|
|
65413
65741
|
} catch (err) {
|
|
65414
65742
|
pushSpinner.stop("Failed.");
|
|
65415
65743
|
if (err instanceof ApiError) {
|
|
65416
|
-
f2.warn(`Content upload failed: ${err.message}. Run ${
|
|
65744
|
+
f2.warn(`Content upload failed: ${err.message}. Run ${import_picocolors32.default.cyan("brainbase agent push")} to retry.`);
|
|
65417
65745
|
} else {
|
|
65418
|
-
f2.warn(`Content upload failed: ${err.message}. Run ${
|
|
65746
|
+
f2.warn(`Content upload failed: ${err.message}. Run ${import_picocolors32.default.cyan("brainbase agent push")} to retry.`);
|
|
65419
65747
|
}
|
|
65420
65748
|
}
|
|
65421
65749
|
}
|
|
@@ -65453,7 +65781,7 @@ async function runAgentCreate(cwd2, args) {
|
|
|
65453
65781
|
}
|
|
65454
65782
|
};
|
|
65455
65783
|
writeSyncState(cwd2, state);
|
|
65456
|
-
$e(`Created ${
|
|
65784
|
+
$e(`Created ${import_picocolors32.default.bold(agent.name)} and linked this folder.`);
|
|
65457
65785
|
await showResultCard({
|
|
65458
65786
|
title: "CREATED",
|
|
65459
65787
|
tone: "ok",
|
|
@@ -65466,9 +65794,9 @@ async function runAgentCreate(cwd2, args) {
|
|
|
65466
65794
|
});
|
|
65467
65795
|
console.log();
|
|
65468
65796
|
if (tracking && harness === "codex") {
|
|
65469
|
-
console.log(tip(`Run ${
|
|
65797
|
+
console.log(tip(`Run ${import_picocolors32.default.cyan("codex")} once in this folder and approve trust ${import_picocolors32.default.dim("— Codex only loads project-scope config in trusted projects.")}`));
|
|
65470
65798
|
}
|
|
65471
|
-
console.log(tip(`brainbase agent unpack ${
|
|
65799
|
+
console.log(tip(`brainbase agent unpack ${import_picocolors32.default.dim("— install harness files (skills/mcps) under .claude/, .codex/, …")}`));
|
|
65472
65800
|
console.log();
|
|
65473
65801
|
}
|
|
65474
65802
|
async function loadOrScaffoldManifest(cwd2, args) {
|
|
@@ -65480,13 +65808,13 @@ async function loadOrScaffoldManifest(cwd2, args) {
|
|
|
65480
65808
|
return null;
|
|
65481
65809
|
}
|
|
65482
65810
|
}
|
|
65483
|
-
f2.warn(`No ${
|
|
65811
|
+
f2.warn(`No ${import_picocolors32.default.bold(AGENT_MANIFEST_FILE)} here.`);
|
|
65484
65812
|
if (!args.yes) {
|
|
65485
65813
|
if (!isInteractive()) {
|
|
65486
65814
|
throw new NonInteractiveError(`No ${AGENT_MANIFEST_FILE} here. Create one first, or re-run with --yes to scaffold a minimal one.`);
|
|
65487
65815
|
}
|
|
65488
65816
|
const ans = await se({
|
|
65489
|
-
message: `Scaffold a minimal ${
|
|
65817
|
+
message: `Scaffold a minimal ${import_picocolors32.default.bold(AGENT_MANIFEST_FILE)} and continue?`,
|
|
65490
65818
|
initialValue: true
|
|
65491
65819
|
});
|
|
65492
65820
|
if (!ensureNotCancelled(ans)) {
|
|
@@ -65507,7 +65835,7 @@ async function loadOrScaffoldManifest(cwd2, args) {
|
|
|
65507
65835
|
};
|
|
65508
65836
|
try {
|
|
65509
65837
|
writeManifest(cwd2, scaffold);
|
|
65510
|
-
f2.info(`Wrote ${
|
|
65838
|
+
f2.info(`Wrote ${import_picocolors32.default.bold(AGENT_MANIFEST_FILE)}.`);
|
|
65511
65839
|
} catch (err) {
|
|
65512
65840
|
f2.error(`Failed to write manifest: ${err.message}`);
|
|
65513
65841
|
return null;
|
|
@@ -65518,7 +65846,7 @@ async function pickHarness2(cwd2) {
|
|
|
65518
65846
|
const detections = await detectHarnesses(cwd2);
|
|
65519
65847
|
const detected = detections.filter((d3) => d3.detection.detected);
|
|
65520
65848
|
if (detected.length === 1) {
|
|
65521
|
-
f2.info(`Detected harness: ${
|
|
65849
|
+
f2.info(`Detected harness: ${import_picocolors32.default.bold(detected[0].adapter.displayName)}.`);
|
|
65522
65850
|
return detected[0].adapter.id;
|
|
65523
65851
|
}
|
|
65524
65852
|
return await select({
|
|
@@ -65544,6 +65872,46 @@ function handleApiError4(err) {
|
|
|
65544
65872
|
$e("Aborted.");
|
|
65545
65873
|
}
|
|
65546
65874
|
|
|
65875
|
+
// src/cli/agent-list.ts
|
|
65876
|
+
var import_picocolors33 = __toESM(require_picocolors(), 1);
|
|
65877
|
+
async function runAgentList(args) {
|
|
65878
|
+
if (!args.json)
|
|
65879
|
+
banner("agent list — agents in this team");
|
|
65880
|
+
const { org, team } = await resolveOrgAndTeam({
|
|
65881
|
+
orgId: args.orgId,
|
|
65882
|
+
teamId: args.teamId,
|
|
65883
|
+
allowPrompt: !args.json,
|
|
65884
|
+
announce: !args.json
|
|
65885
|
+
});
|
|
65886
|
+
const agents = await api.listAgents(org.id, team.id);
|
|
65887
|
+
if (args.json) {
|
|
65888
|
+
console.log(JSON.stringify(agents, null, 2));
|
|
65889
|
+
return;
|
|
65890
|
+
}
|
|
65891
|
+
console.log(formatAgentList(agents, { orgName: org.name, teamName: team.name }));
|
|
65892
|
+
}
|
|
65893
|
+
function formatAgentList(agents, labels) {
|
|
65894
|
+
const lines = [""];
|
|
65895
|
+
if (agents.length === 0) {
|
|
65896
|
+
lines.push(` ${import_picocolors33.default.dim(`No agents in ${labels.orgName} → ${labels.teamName} yet.`)}`, "", ` ${import_picocolors33.default.dim("create one with")} ${import_picocolors33.default.cyan("brainbase agent create")}`, "");
|
|
65897
|
+
return lines.join(`
|
|
65898
|
+
`);
|
|
65899
|
+
}
|
|
65900
|
+
for (const agent of agents) {
|
|
65901
|
+
lines.push(` ${import_picocolors33.default.bold(agent.name)} ${import_picocolors33.default.dim(agent.slug)}`);
|
|
65902
|
+
if (agent.tagline)
|
|
65903
|
+
lines.push(` ${import_picocolors33.default.dim(agent.tagline)}`);
|
|
65904
|
+
const meta = [agent.harness, agent.machine_kind, agent.default_model].filter((value) => !!value).join(" · ");
|
|
65905
|
+
if (meta)
|
|
65906
|
+
lines.push(` ${import_picocolors33.default.dim(meta)}`);
|
|
65907
|
+
lines.push(` ${import_picocolors33.default.dim(agent.id)}`);
|
|
65908
|
+
lines.push("");
|
|
65909
|
+
}
|
|
65910
|
+
lines.push(` ${import_picocolors33.default.dim("link this folder to one with")} ${import_picocolors33.default.cyan("brainbase link --agent <id>")}`, "");
|
|
65911
|
+
return lines.join(`
|
|
65912
|
+
`);
|
|
65913
|
+
}
|
|
65914
|
+
|
|
65547
65915
|
// src/cli/agent.ts
|
|
65548
65916
|
async function runAgent(cwd2, sub, args, opts) {
|
|
65549
65917
|
if (args.some((arg) => arg === "--help" || arg === "-h")) {
|
|
@@ -65563,6 +65931,13 @@ async function runAgent(cwd2, sub, args, opts) {
|
|
|
65563
65931
|
track: opts.track
|
|
65564
65932
|
});
|
|
65565
65933
|
return;
|
|
65934
|
+
case "list":
|
|
65935
|
+
await runAgentList({
|
|
65936
|
+
orgId: opts.orgId,
|
|
65937
|
+
teamId: opts.teamId,
|
|
65938
|
+
json: opts.json
|
|
65939
|
+
});
|
|
65940
|
+
return;
|
|
65566
65941
|
case "pull":
|
|
65567
65942
|
await runAgentPull(cwd2, {
|
|
65568
65943
|
yes: opts.yes,
|
|
@@ -65606,26 +65981,111 @@ async function runAgent(cwd2, sub, args, opts) {
|
|
|
65606
65981
|
function printHelp() {
|
|
65607
65982
|
const out = [];
|
|
65608
65983
|
out.push("");
|
|
65609
|
-
out.push(` ${
|
|
65984
|
+
out.push(` ${import_picocolors34.default.bold("brainbase agent")} ${import_picocolors34.default.dim("<sub> [options]")}`);
|
|
65610
65985
|
out.push("");
|
|
65611
|
-
out.push(` ${
|
|
65612
|
-
out.push(` ${
|
|
65613
|
-
out.push(` ${
|
|
65614
|
-
out.push(` ${
|
|
65615
|
-
out.push(` ${
|
|
65616
|
-
out.push(` ${
|
|
65986
|
+
out.push(` ${import_picocolors34.default.cyan("list")} ${import_picocolors34.default.dim("show the agents in a team, with the ids `brainbase link` takes (--json for scripts)")}`);
|
|
65987
|
+
out.push(` ${import_picocolors34.default.cyan("create")} ${import_picocolors34.default.dim("claim an unclaimed brainbase.agent.yaml and create the cloud agent")}`);
|
|
65988
|
+
out.push(` ${import_picocolors34.default.cyan("pull")} ${import_picocolors34.default.dim("[<id>]")} ${import_picocolors34.default.dim("apply cloud changes into this folder — pass <id> to switch (--force to override); --run-entrypoint to also execute the agent entrypoint")}`);
|
|
65989
|
+
out.push(` ${import_picocolors34.default.cyan("push")} ${import_picocolors34.default.dim("send local changes to the cloud — instructions, playbooks, skills, MCPs, entrypoint (--force to overwrite cloud-side conflicts with local)")}`);
|
|
65990
|
+
out.push(` ${import_picocolors34.default.cyan("unpack")} ${import_picocolors34.default.dim("install the claimed agent into a harness layout (--harness to override)")}`);
|
|
65991
|
+
out.push(` ${import_picocolors34.default.cyan("status")} ${import_picocolors34.default.dim("show what would push and what would pull")}`);
|
|
65992
|
+
out.push(` ${import_picocolors34.default.cyan("env")} ${import_picocolors34.default.dim('print export statements — use with `eval "$(brainbase agent env)"`')}`);
|
|
65993
|
+
out.push("");
|
|
65994
|
+
console.log(out.join(`
|
|
65995
|
+
`));
|
|
65996
|
+
}
|
|
65997
|
+
|
|
65998
|
+
// src/cli/team.ts
|
|
65999
|
+
var import_picocolors36 = __toESM(require_picocolors(), 1);
|
|
66000
|
+
|
|
66001
|
+
// src/cli/team-list.ts
|
|
66002
|
+
var import_picocolors35 = __toESM(require_picocolors(), 1);
|
|
66003
|
+
async function runTeamList(args) {
|
|
66004
|
+
if (!args.json)
|
|
66005
|
+
banner("team list — teams you can put agents in");
|
|
66006
|
+
const orgs = args.orgId !== undefined ? [await resolveOrg(args.orgId)] : await api.listOrgs();
|
|
66007
|
+
const { entries, resolved, failures } = await listTeamsPerOrg(orgs);
|
|
66008
|
+
if (resolved.length === 0 && failures.length > 0)
|
|
66009
|
+
throw failures[0].error;
|
|
66010
|
+
if (args.json) {
|
|
66011
|
+
for (const { org, error } of failures) {
|
|
66012
|
+
console.error(`Could not load teams in ${org.name}: ${error.message}`);
|
|
66013
|
+
}
|
|
66014
|
+
console.log(JSON.stringify(entries, null, 2));
|
|
66015
|
+
return;
|
|
66016
|
+
}
|
|
66017
|
+
console.log(formatTeamList(entries));
|
|
66018
|
+
}
|
|
66019
|
+
function formatTeamList(grouped) {
|
|
66020
|
+
const lines = [""];
|
|
66021
|
+
if (grouped.length === 0) {
|
|
66022
|
+
lines.push(` ${import_picocolors35.default.dim("You are not a member of any organization.")}`, "");
|
|
66023
|
+
return lines.join(`
|
|
66024
|
+
`);
|
|
66025
|
+
}
|
|
66026
|
+
const nameWidth = Math.max(...grouped.flatMap(({ teams }) => teams.map((t) => t.name.length)), 0);
|
|
66027
|
+
for (const { org, teams, error } of grouped) {
|
|
66028
|
+
const slug = org.slug ? ` ${import_picocolors35.default.dim(org.slug)}` : "";
|
|
66029
|
+
lines.push(` ${import_picocolors35.default.bold(org.name)}${slug}`);
|
|
66030
|
+
if (error) {
|
|
66031
|
+
lines.push(` ${import_picocolors35.default.red(`could not load teams: ${error}`)}`);
|
|
66032
|
+
} else if (teams.length === 0) {
|
|
66033
|
+
lines.push(` ${import_picocolors35.default.dim("no teams yet — create one in the web app")}`);
|
|
66034
|
+
}
|
|
66035
|
+
for (const team of teams) {
|
|
66036
|
+
lines.push(` ${team.name.padEnd(nameWidth)} ${import_picocolors35.default.dim(team.id)}`);
|
|
66037
|
+
}
|
|
66038
|
+
lines.push("");
|
|
66039
|
+
}
|
|
66040
|
+
lines.push(` ${import_picocolors35.default.dim("list a team’s agents with")} ${import_picocolors35.default.cyan("brainbase agent list --team <id>")}`, "");
|
|
66041
|
+
return lines.join(`
|
|
66042
|
+
`);
|
|
66043
|
+
}
|
|
66044
|
+
|
|
66045
|
+
// src/cli/team.ts
|
|
66046
|
+
async function runTeam(sub, args, opts) {
|
|
66047
|
+
if (args.some((arg) => arg === "--help" || arg === "-h")) {
|
|
66048
|
+
printHelp2();
|
|
66049
|
+
return;
|
|
66050
|
+
}
|
|
66051
|
+
switch (sub) {
|
|
66052
|
+
case "list":
|
|
66053
|
+
await runTeamList({ orgId: opts.orgId, json: opts.json });
|
|
66054
|
+
return;
|
|
66055
|
+
case undefined:
|
|
66056
|
+
case "help":
|
|
66057
|
+
case "-h":
|
|
66058
|
+
case "--help":
|
|
66059
|
+
printHelp2();
|
|
66060
|
+
return;
|
|
66061
|
+
default:
|
|
66062
|
+
console.error(`Unknown team subcommand: ${sub}
|
|
66063
|
+
`);
|
|
66064
|
+
printHelp2();
|
|
66065
|
+
process.exit(1);
|
|
66066
|
+
}
|
|
66067
|
+
}
|
|
66068
|
+
function printHelp2() {
|
|
66069
|
+
const out = [];
|
|
66070
|
+
out.push("");
|
|
66071
|
+
out.push(` ${import_picocolors36.default.bold("brainbase team")} ${import_picocolors36.default.dim("<sub> [options]")}`);
|
|
66072
|
+
out.push("");
|
|
66073
|
+
out.push(` ${import_picocolors36.default.cyan("list")} ${import_picocolors36.default.dim("show the teams you can create agents in, grouped by organization")}`);
|
|
66074
|
+
out.push("");
|
|
66075
|
+
out.push(` ${import_picocolors36.default.dim("--org <id-or-slug>")} ${import_picocolors36.default.dim("limit to one organization")}`);
|
|
66076
|
+
out.push(` ${import_picocolors36.default.dim("--json")} ${import_picocolors36.default.dim("machine-readable output")}`);
|
|
65617
66077
|
out.push("");
|
|
65618
66078
|
console.log(out.join(`
|
|
65619
66079
|
`));
|
|
65620
66080
|
}
|
|
65621
66081
|
|
|
65622
66082
|
// src/cli/orchestration.ts
|
|
65623
|
-
var
|
|
66083
|
+
var import_picocolors43 = __toESM(require_picocolors(), 1);
|
|
65624
66084
|
|
|
65625
66085
|
// src/cli/orchestration-pull.ts
|
|
65626
66086
|
import path85 from "node:path";
|
|
65627
66087
|
import fs76 from "node:fs";
|
|
65628
|
-
var
|
|
66088
|
+
var import_picocolors37 = __toESM(require_picocolors(), 1);
|
|
65629
66089
|
|
|
65630
66090
|
// src/core/orchestration-manifest.ts
|
|
65631
66091
|
import path82 from "node:path";
|
|
@@ -66128,8 +66588,8 @@ async function runOrchestrationPull(cwd2, args) {
|
|
|
66128
66588
|
orchId = args.orchestrationId;
|
|
66129
66589
|
} else {
|
|
66130
66590
|
f2.warn("This folder is not linked to any orchestration.");
|
|
66131
|
-
f2.info(`Run ${
|
|
66132
|
-
or ${
|
|
66591
|
+
f2.info(`Run ${import_picocolors37.default.cyan("brainbase orchestration pull <id>")} with an orchestration id,
|
|
66592
|
+
or ${import_picocolors37.default.cyan("brainbase orchestration list")} to find one.`);
|
|
66133
66593
|
return;
|
|
66134
66594
|
}
|
|
66135
66595
|
const sp = de();
|
|
@@ -66148,24 +66608,24 @@ async function runOrchestrationPull(cwd2, args) {
|
|
|
66148
66608
|
const slugFor = (agentId) => slugByAgent.get(agentId) ?? agentId;
|
|
66149
66609
|
const planLines = [];
|
|
66150
66610
|
planLines.push("");
|
|
66151
|
-
planLines.push(` ${
|
|
66611
|
+
planLines.push(` ${import_picocolors37.default.bold(cloud.name)} ${import_picocolors37.default.dim(`(${cloud.id})`)}`);
|
|
66152
66612
|
if (cloud.description)
|
|
66153
|
-
planLines.push(` ${
|
|
66613
|
+
planLines.push(` ${import_picocolors37.default.dim(cloud.description)}`);
|
|
66154
66614
|
planLines.push("");
|
|
66155
|
-
planLines.push(` ${
|
|
66615
|
+
planLines.push(` ${import_picocolors37.default.dim("members:")}`);
|
|
66156
66616
|
for (const m3 of cloud.members) {
|
|
66157
66617
|
const skipped = !m3.manifest;
|
|
66158
|
-
const tail2 = skipped ?
|
|
66159
|
-
planLines.push(` ${
|
|
66618
|
+
const tail2 = skipped ? import_picocolors37.default.red(" (manifest unavailable — skipped)") : "";
|
|
66619
|
+
planLines.push(` ${import_picocolors37.default.cyan("•")} ${import_picocolors37.default.bold(slugFor(m3.agent_id))} ${import_picocolors37.default.dim(`(${m3.name})`)}${tail2}`);
|
|
66160
66620
|
}
|
|
66161
66621
|
if (cloud.edges.length) {
|
|
66162
66622
|
planLines.push("");
|
|
66163
|
-
planLines.push(` ${
|
|
66623
|
+
planLines.push(` ${import_picocolors37.default.dim("edges:")}`);
|
|
66164
66624
|
for (const e2 of cloud.edges) {
|
|
66165
66625
|
const from = slugFor(e2.from_agent_id);
|
|
66166
66626
|
const to2 = slugFor(e2.to_agent_id);
|
|
66167
|
-
const desc = e2.description ? ` ${
|
|
66168
|
-
planLines.push(` ${
|
|
66627
|
+
const desc = e2.description ? ` ${import_picocolors37.default.dim("— " + e2.description)}` : "";
|
|
66628
|
+
planLines.push(` ${import_picocolors37.default.cyan(from)} ${import_picocolors37.default.dim("→")} ${import_picocolors37.default.cyan(to2)}${desc}`);
|
|
66169
66629
|
}
|
|
66170
66630
|
}
|
|
66171
66631
|
planLines.push("");
|
|
@@ -66174,7 +66634,7 @@ async function runOrchestrationPull(cwd2, args) {
|
|
|
66174
66634
|
const isRefresh = !!existingLink;
|
|
66175
66635
|
if (!autoProceed(args.yes) && !isRefresh) {
|
|
66176
66636
|
const ok = await se({
|
|
66177
|
-
message: `Pull into ${
|
|
66637
|
+
message: `Pull into ${import_picocolors37.default.bold(cwd2)}?`,
|
|
66178
66638
|
initialValue: true
|
|
66179
66639
|
});
|
|
66180
66640
|
if (!ensureNotCancelled(ok)) {
|
|
@@ -66218,7 +66678,7 @@ async function runOrchestrationPull(cwd2, args) {
|
|
|
66218
66678
|
scope: "project",
|
|
66219
66679
|
pullSecrets: true
|
|
66220
66680
|
});
|
|
66221
|
-
memberSp.stop(`Installed ${
|
|
66681
|
+
memberSp.stop(`Installed ${import_picocolors37.default.bold(slug)} ${import_picocolors37.default.dim(`(${m3.manifest.components.length} components)`)}.`);
|
|
66222
66682
|
installedMembers.push({
|
|
66223
66683
|
agent_id: m3.agent_id,
|
|
66224
66684
|
slug,
|
|
@@ -66279,7 +66739,7 @@ async function runOrchestrationPull(cwd2, args) {
|
|
|
66279
66739
|
payload_schema: e2.payload_schema ?? {}
|
|
66280
66740
|
}))
|
|
66281
66741
|
});
|
|
66282
|
-
$e(`Pulled ${cloud.name} at revision ${cloud.revision} into ${path85.basename(cwd2)}/ ${
|
|
66742
|
+
$e(`Pulled ${cloud.name} at revision ${cloud.revision} into ${path85.basename(cwd2)}/ ${import_picocolors37.default.dim(`(${installedMembers.length}/${cloud.members.length} members)`)}.`);
|
|
66283
66743
|
}
|
|
66284
66744
|
function handleApiError5(err) {
|
|
66285
66745
|
if (err instanceof ApiError) {
|
|
@@ -66296,7 +66756,7 @@ function handleApiError5(err) {
|
|
|
66296
66756
|
}
|
|
66297
66757
|
|
|
66298
66758
|
// src/cli/orchestration-push.ts
|
|
66299
|
-
var
|
|
66759
|
+
var import_picocolors38 = __toESM(require_picocolors(), 1);
|
|
66300
66760
|
|
|
66301
66761
|
// src/core/orchestration-outgoing.ts
|
|
66302
66762
|
function buildOrchestrationGraphPayload(manifest, slugToAgentId) {
|
|
@@ -66366,12 +66826,12 @@ async function runOrchestrationPush(cwd2, args) {
|
|
|
66366
66826
|
const link2 = readOrchLink(cwd2);
|
|
66367
66827
|
if (!link2) {
|
|
66368
66828
|
f2.warn("This folder is not linked to any orchestration.");
|
|
66369
|
-
f2.info(`Run ${
|
|
66829
|
+
f2.info(`Run ${import_picocolors38.default.cyan("brainbase orchestration pull <id>")} first.`);
|
|
66370
66830
|
return;
|
|
66371
66831
|
}
|
|
66372
66832
|
if (!hasOrchManifest(cwd2)) {
|
|
66373
|
-
f2.warn(`No ${
|
|
66374
|
-
f2.info(`Run ${
|
|
66833
|
+
f2.warn(`No ${import_picocolors38.default.bold(ORCH_MANIFEST_FILE)} here.`);
|
|
66834
|
+
f2.info(`Run ${import_picocolors38.default.cyan("brainbase orchestration pull")} to materialise the manifest before pushing.`);
|
|
66375
66835
|
return;
|
|
66376
66836
|
}
|
|
66377
66837
|
let manifest;
|
|
@@ -66395,7 +66855,7 @@ async function runOrchestrationPush(cwd2, args) {
|
|
|
66395
66855
|
}
|
|
66396
66856
|
if (missing.length) {
|
|
66397
66857
|
f2.error(`Missing local checkouts for: ${missing.join(", ")}.`);
|
|
66398
|
-
f2.info(`Run ${
|
|
66858
|
+
f2.info(`Run ${import_picocolors38.default.cyan("brainbase orchestration pull")} to materialise the missing folders.`);
|
|
66399
66859
|
return;
|
|
66400
66860
|
}
|
|
66401
66861
|
let graph;
|
|
@@ -66407,13 +66867,13 @@ async function runOrchestrationPush(cwd2, args) {
|
|
|
66407
66867
|
return;
|
|
66408
66868
|
}
|
|
66409
66869
|
const plan = [""];
|
|
66410
|
-
plan.push(` ${
|
|
66411
|
-
plan.push(` ${
|
|
66870
|
+
plan.push(` ${import_picocolors38.default.bold(link2.name)} ${import_picocolors38.default.dim(`(${link2.orchestration_id})`)}`);
|
|
66871
|
+
plan.push(` ${import_picocolors38.default.dim(`${manifest.members.length} member${manifest.members.length === 1 ? "" : "s"}, ${manifest.edges.length} edge${manifest.edges.length === 1 ? "" : "s"}, ${graph.triggers.length} trigger${graph.triggers.length === 1 ? "" : "s"}`)}`);
|
|
66412
66872
|
plan.push("");
|
|
66413
66873
|
if (!args.graphOnly) {
|
|
66414
|
-
plan.push(` ${
|
|
66874
|
+
plan.push(` ${import_picocolors38.default.dim("per-member agent push:")}`);
|
|
66415
66875
|
for (const m3 of manifest.members) {
|
|
66416
|
-
plan.push(` ${
|
|
66876
|
+
plan.push(` ${import_picocolors38.default.cyan("•")} ${import_picocolors38.default.bold(m3.slug)}`);
|
|
66417
66877
|
}
|
|
66418
66878
|
plan.push("");
|
|
66419
66879
|
}
|
|
@@ -66433,7 +66893,7 @@ async function runOrchestrationPush(cwd2, args) {
|
|
|
66433
66893
|
for (const m3 of manifest.members) {
|
|
66434
66894
|
const dir = memberDir(cwd2, m3.slug);
|
|
66435
66895
|
console.log("");
|
|
66436
|
-
console.log(`${
|
|
66896
|
+
console.log(`${import_picocolors38.default.dim("───")} ${import_picocolors38.default.bold(m3.slug)} ${import_picocolors38.default.dim("───")}`);
|
|
66437
66897
|
try {
|
|
66438
66898
|
await runAgentPush(dir, { yes: true });
|
|
66439
66899
|
} catch (err) {
|
|
@@ -66491,7 +66951,7 @@ function handleApiError6(err) {
|
|
|
66491
66951
|
f2.error("You do not have access to this orchestration.");
|
|
66492
66952
|
} else if (err.status === 409) {
|
|
66493
66953
|
f2.error(err.message);
|
|
66494
|
-
f2.info(`Run ${
|
|
66954
|
+
f2.info(`Run ${import_picocolors38.default.cyan("brainbase orchestration pull")} to reconcile, then push again.`);
|
|
66495
66955
|
} else {
|
|
66496
66956
|
f2.error(err.message);
|
|
66497
66957
|
}
|
|
@@ -66501,13 +66961,13 @@ function handleApiError6(err) {
|
|
|
66501
66961
|
}
|
|
66502
66962
|
|
|
66503
66963
|
// src/cli/orchestration-status.ts
|
|
66504
|
-
var
|
|
66964
|
+
var import_picocolors39 = __toESM(require_picocolors(), 1);
|
|
66505
66965
|
async function runOrchestrationStatus(cwd2) {
|
|
66506
66966
|
banner("orchestration status — what changed locally, remotely, both");
|
|
66507
66967
|
const link2 = readOrchLink(cwd2);
|
|
66508
66968
|
if (!link2) {
|
|
66509
66969
|
f2.warn("This folder is not linked to any orchestration.");
|
|
66510
|
-
f2.info(`Run ${
|
|
66970
|
+
f2.info(`Run ${import_picocolors39.default.cyan("brainbase orchestration pull <id>")} first.`);
|
|
66511
66971
|
return;
|
|
66512
66972
|
}
|
|
66513
66973
|
const localManifest = hasOrchManifest(cwd2) ? readOrchManifest(cwd2) : null;
|
|
@@ -66530,8 +66990,8 @@ async function runOrchestrationStatus(cwd2) {
|
|
|
66530
66990
|
}
|
|
66531
66991
|
const lines = [];
|
|
66532
66992
|
lines.push("");
|
|
66533
|
-
lines.push(` ${
|
|
66534
|
-
lines.push(` ${
|
|
66993
|
+
lines.push(` ${import_picocolors39.default.bold(link2.name)} ${import_picocolors39.default.dim(`(${link2.orchestration_id})`)}`);
|
|
66994
|
+
lines.push(` ${import_picocolors39.default.dim("revision")} cloud ${cloud.revision}${lock ? ` · lock ${lock.revision}` : " · never pulled"}`);
|
|
66535
66995
|
lines.push("");
|
|
66536
66996
|
const localSlugByAgentId = new Map;
|
|
66537
66997
|
for (const m3 of localManifest?.members ?? []) {
|
|
@@ -66545,12 +67005,12 @@ async function runOrchestrationStatus(cwd2) {
|
|
|
66545
67005
|
const membersAdded = [...localMemberSet].filter((s3) => !cloudMemberSet.has(s3));
|
|
66546
67006
|
const membersRemoved = [...cloudMemberSet].filter((s3) => !localMemberSet.has(s3));
|
|
66547
67007
|
if (membersAdded.length || membersRemoved.length) {
|
|
66548
|
-
lines.push(` ${
|
|
67008
|
+
lines.push(` ${import_picocolors39.default.bold("members")}`);
|
|
66549
67009
|
for (const slug of membersAdded) {
|
|
66550
|
-
lines.push(` ${
|
|
67010
|
+
lines.push(` ${import_picocolors39.default.yellow("→ push")} added in yaml: ${import_picocolors39.default.bold(slug)}`);
|
|
66551
67011
|
}
|
|
66552
67012
|
for (const slug of membersRemoved) {
|
|
66553
|
-
lines.push(` ${
|
|
67013
|
+
lines.push(` ${import_picocolors39.default.cyan("← pull")} added on cloud: ${import_picocolors39.default.bold(slug)}`);
|
|
66554
67014
|
}
|
|
66555
67015
|
lines.push("");
|
|
66556
67016
|
}
|
|
@@ -66565,11 +67025,11 @@ async function runOrchestrationStatus(cwd2) {
|
|
|
66565
67025
|
const edgesAdded = [...localEdges.keys()].filter((k3) => !cloudEdges.has(k3));
|
|
66566
67026
|
const edgesRemoved = [...cloudEdges.keys()].filter((k3) => !localEdges.has(k3));
|
|
66567
67027
|
if (edgesAdded.length || edgesRemoved.length) {
|
|
66568
|
-
lines.push(` ${
|
|
67028
|
+
lines.push(` ${import_picocolors39.default.bold("edges")}`);
|
|
66569
67029
|
for (const k3 of edgesAdded)
|
|
66570
|
-
lines.push(` ${
|
|
67030
|
+
lines.push(` ${import_picocolors39.default.yellow("→ push")} added in yaml: ${k3}`);
|
|
66571
67031
|
for (const k3 of edgesRemoved)
|
|
66572
|
-
lines.push(` ${
|
|
67032
|
+
lines.push(` ${import_picocolors39.default.cyan("← pull")} added on cloud: ${k3}`);
|
|
66573
67033
|
lines.push("");
|
|
66574
67034
|
}
|
|
66575
67035
|
const cloudTriggerKey = (t) => {
|
|
@@ -66607,11 +67067,11 @@ async function runOrchestrationStatus(cwd2) {
|
|
|
66607
67067
|
const triggersAdded = [...localTriggers.keys()].filter((k3) => !cloudTriggers.has(k3));
|
|
66608
67068
|
const triggersRemoved = [...cloudTriggers.keys()].filter((k3) => !localTriggers.has(k3));
|
|
66609
67069
|
if (triggersAdded.length || triggersRemoved.length) {
|
|
66610
|
-
lines.push(` ${
|
|
67070
|
+
lines.push(` ${import_picocolors39.default.bold("schedule triggers")}`);
|
|
66611
67071
|
for (const k3 of triggersAdded)
|
|
66612
|
-
lines.push(` ${
|
|
67072
|
+
lines.push(` ${import_picocolors39.default.yellow("→ push")} added/changed in yaml: ${localTriggers.get(k3) ?? k3}`);
|
|
66613
67073
|
for (const k3 of triggersRemoved)
|
|
66614
|
-
lines.push(` ${
|
|
67074
|
+
lines.push(` ${import_picocolors39.default.cyan("← pull")} added/changed on cloud: ${cloudTriggers.get(k3) ?? k3}`);
|
|
66615
67075
|
lines.push("");
|
|
66616
67076
|
}
|
|
66617
67077
|
const lockByAgentId = new Map((lock?.members ?? []).map((m3) => [m3.agent_id, m3]));
|
|
@@ -66634,27 +67094,27 @@ async function runOrchestrationStatus(cwd2) {
|
|
|
66634
67094
|
}
|
|
66635
67095
|
}
|
|
66636
67096
|
if (memberDrift.length) {
|
|
66637
|
-
lines.push(` ${
|
|
67097
|
+
lines.push(` ${import_picocolors39.default.bold("member content drift")}`);
|
|
66638
67098
|
for (const d3 of memberDrift) {
|
|
66639
|
-
lines.push(` ${
|
|
67099
|
+
lines.push(` ${import_picocolors39.default.cyan("?")} ${import_picocolors39.default.bold(d3.slug)} ${import_picocolors39.default.dim("— " + d3.reason)}`);
|
|
66640
67100
|
}
|
|
66641
|
-
lines.push(` ${
|
|
67101
|
+
lines.push(` ${import_picocolors39.default.dim("cd into each member folder and run")} ${import_picocolors39.default.cyan("brainbase agent status")}`);
|
|
66642
67102
|
lines.push("");
|
|
66643
67103
|
}
|
|
66644
67104
|
const revisionDrift = lock?.revision != null && cloud.revision !== lock.revision;
|
|
66645
67105
|
if (revisionDrift) {
|
|
66646
|
-
lines.push(` ${
|
|
66647
|
-
lines.push(` ${
|
|
67106
|
+
lines.push(` ${import_picocolors39.default.bold("cloud revision")}`);
|
|
67107
|
+
lines.push(` ${import_picocolors39.default.cyan("← pull")} cloud changed since last pull: ${import_picocolors39.default.dim(`lock ${lock.revision} → cloud ${cloud.revision}`)}`);
|
|
66648
67108
|
lines.push("");
|
|
66649
67109
|
}
|
|
66650
67110
|
if (!membersAdded.length && !membersRemoved.length && !edgesAdded.length && !edgesRemoved.length && !triggersAdded.length && !triggersRemoved.length && !memberDrift.length && !revisionDrift) {
|
|
66651
|
-
lines.push(` ${
|
|
67111
|
+
lines.push(` ${import_picocolors39.default.green("✓")} everything is in sync`);
|
|
66652
67112
|
lines.push("");
|
|
66653
67113
|
console.log(lines.join(`
|
|
66654
67114
|
`));
|
|
66655
67115
|
return;
|
|
66656
67116
|
}
|
|
66657
|
-
lines.push(` ${
|
|
67117
|
+
lines.push(` ${import_picocolors39.default.dim("run")} ${import_picocolors39.default.cyan("brainbase orchestration pull")} ${import_picocolors39.default.dim("to apply cloud changes,")} ${import_picocolors39.default.cyan("brainbase orchestration push")} ${import_picocolors39.default.dim("to send yours")}`);
|
|
66658
67118
|
lines.push("");
|
|
66659
67119
|
console.log(lines.join(`
|
|
66660
67120
|
`));
|
|
@@ -66669,108 +67129,45 @@ function stableJson(value) {
|
|
|
66669
67129
|
}
|
|
66670
67130
|
|
|
66671
67131
|
// src/cli/orchestration-list.ts
|
|
66672
|
-
var
|
|
67132
|
+
var import_picocolors40 = __toESM(require_picocolors(), 1);
|
|
66673
67133
|
async function runOrchestrationList(args) {
|
|
66674
67134
|
banner("orchestration list — orchestrations under a team");
|
|
66675
|
-
|
|
66676
|
-
|
|
66677
|
-
|
|
66678
|
-
|
|
66679
|
-
|
|
66680
|
-
orgs = await api.listOrgs();
|
|
66681
|
-
} catch (err) {
|
|
66682
|
-
handleApiError7(err);
|
|
66683
|
-
return;
|
|
66684
|
-
}
|
|
66685
|
-
if (orgs.length === 0) {
|
|
66686
|
-
f2.warn("You are not a member of any organization.");
|
|
66687
|
-
return;
|
|
66688
|
-
}
|
|
66689
|
-
if (orgId) {
|
|
66690
|
-
const found = orgs.find((o2) => o2.id === orgId || o2.slug === orgId);
|
|
66691
|
-
if (!found) {
|
|
66692
|
-
f2.error(`Org ${orgId} not found or you're not a member.`);
|
|
66693
|
-
return;
|
|
66694
|
-
}
|
|
66695
|
-
orgId = found.id;
|
|
66696
|
-
} else if (orgs.length === 1) {
|
|
66697
|
-
orgId = orgs[0].id;
|
|
66698
|
-
} else {
|
|
66699
|
-
orgId = await select({
|
|
66700
|
-
message: "Which organization?",
|
|
66701
|
-
options: orgs.map((o2) => ({ value: o2.id, label: o2.name, hint: o2.role })),
|
|
66702
|
-
flagHint: "Pass --org <id-or-slug>."
|
|
66703
|
-
});
|
|
66704
|
-
}
|
|
66705
|
-
}
|
|
66706
|
-
if (!teamId) {
|
|
66707
|
-
let teams;
|
|
66708
|
-
try {
|
|
66709
|
-
teams = await api.listTeams(orgId);
|
|
66710
|
-
} catch (err) {
|
|
66711
|
-
handleApiError7(err);
|
|
66712
|
-
return;
|
|
66713
|
-
}
|
|
66714
|
-
if (teams.length === 0) {
|
|
66715
|
-
f2.warn("No teams under this organization. Create one in the web app first.");
|
|
66716
|
-
return;
|
|
66717
|
-
}
|
|
66718
|
-
if (teams.length === 1) {
|
|
66719
|
-
teamId = teams[0].id;
|
|
66720
|
-
} else {
|
|
66721
|
-
teamId = await select({
|
|
66722
|
-
message: "Which team?",
|
|
66723
|
-
options: teams.map((t) => ({ value: t.id, label: t.name })),
|
|
66724
|
-
flagHint: "Pass --team <id>."
|
|
66725
|
-
});
|
|
66726
|
-
}
|
|
66727
|
-
}
|
|
66728
|
-
let items;
|
|
67135
|
+
const { org, team } = await resolveOrgAndTeam({
|
|
67136
|
+
orgId: args.orgId,
|
|
67137
|
+
teamId: args.teamId,
|
|
67138
|
+
announce: true
|
|
67139
|
+
});
|
|
66729
67140
|
const sp = de();
|
|
66730
67141
|
sp.start("Fetching orchestrations…");
|
|
67142
|
+
let items;
|
|
66731
67143
|
try {
|
|
66732
|
-
items = await api.listOrchestrations(
|
|
66733
|
-
sp.stop(`${items.length} orchestration${items.length === 1 ? "" : "s"}.`);
|
|
67144
|
+
items = await api.listOrchestrations(org.id, team.id);
|
|
66734
67145
|
} catch (err) {
|
|
66735
67146
|
sp.stop("Failed.");
|
|
66736
|
-
|
|
66737
|
-
return;
|
|
67147
|
+
throw err;
|
|
66738
67148
|
}
|
|
67149
|
+
sp.stop(`${items.length} orchestration${items.length === 1 ? "" : "s"}.`);
|
|
66739
67150
|
if (items.length === 0) {
|
|
66740
67151
|
f2.info("This team has no orchestrations yet.");
|
|
66741
67152
|
return;
|
|
66742
67153
|
}
|
|
66743
67154
|
const lines = [""];
|
|
66744
67155
|
for (const o2 of items) {
|
|
66745
|
-
lines.push(` ${
|
|
67156
|
+
lines.push(` ${import_picocolors40.default.bold(o2.name)} ${import_picocolors40.default.dim(o2.id)}`);
|
|
66746
67157
|
if (o2.description)
|
|
66747
|
-
lines.push(` ${
|
|
66748
|
-
lines.push(` ${
|
|
67158
|
+
lines.push(` ${import_picocolors40.default.dim(o2.description)}`);
|
|
67159
|
+
lines.push(` ${import_picocolors40.default.dim(`${o2.member_count} member${o2.member_count === 1 ? "" : "s"} · ${o2.edge_count} edge${o2.edge_count === 1 ? "" : "s"}`)}`);
|
|
66749
67160
|
lines.push("");
|
|
66750
67161
|
}
|
|
66751
|
-
lines.push(` ${
|
|
67162
|
+
lines.push(` ${import_picocolors40.default.dim("pull one with")} ${import_picocolors40.default.cyan("brainbase orchestration pull <id>")}`);
|
|
66752
67163
|
lines.push("");
|
|
66753
67164
|
console.log(lines.join(`
|
|
66754
67165
|
`));
|
|
66755
67166
|
}
|
|
66756
|
-
function isUuid(value) {
|
|
66757
|
-
return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-9a-f][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);
|
|
66758
|
-
}
|
|
66759
|
-
function handleApiError7(err) {
|
|
66760
|
-
if (err instanceof ApiError) {
|
|
66761
|
-
if (err.status === 401) {
|
|
66762
|
-
f2.error("Your session is invalid. Run `brainbase login` and try again.");
|
|
66763
|
-
} else {
|
|
66764
|
-
f2.error(err.message);
|
|
66765
|
-
}
|
|
66766
|
-
} else {
|
|
66767
|
-
f2.error(err.message);
|
|
66768
|
-
}
|
|
66769
|
-
}
|
|
66770
67167
|
|
|
66771
67168
|
// src/cli/orchestration-add-agent.ts
|
|
66772
67169
|
import fs77 from "node:fs";
|
|
66773
|
-
var
|
|
67170
|
+
var import_picocolors41 = __toESM(require_picocolors(), 1);
|
|
66774
67171
|
|
|
66775
67172
|
// src/core/orchestration-add.ts
|
|
66776
67173
|
function resolveOrgIdForGroup(groupId, orgsWithTeams) {
|
|
@@ -66835,7 +67232,7 @@ async function runOrchestrationAddAgent(cwd2, args) {
|
|
|
66835
67232
|
const link2 = readOrchLink(cwd2);
|
|
66836
67233
|
if (!link2 || !hasOrchManifest(cwd2)) {
|
|
66837
67234
|
f2.warn("This folder is not a linked orchestration.");
|
|
66838
|
-
f2.info(`Run ${
|
|
67235
|
+
f2.info(`Run ${import_picocolors41.default.cyan("brainbase orchestration pull <id>")} first.`);
|
|
66839
67236
|
return;
|
|
66840
67237
|
}
|
|
66841
67238
|
let manifest;
|
|
@@ -66861,7 +67258,7 @@ async function runOrchestrationAddAgent(cwd2, args) {
|
|
|
66861
67258
|
while (manifest.members.some((m3) => m3.slug === candidate) || fs77.existsSync(memberDir(cwd2, candidate))) {
|
|
66862
67259
|
candidate = `${slug}-${++n}`;
|
|
66863
67260
|
}
|
|
66864
|
-
f2.info(`Slug ${
|
|
67261
|
+
f2.info(`Slug ${import_picocolors41.default.bold(slug)} is taken — using ${import_picocolors41.default.bold(candidate)}.`);
|
|
66865
67262
|
slug = candidate;
|
|
66866
67263
|
}
|
|
66867
67264
|
let payloadSchema;
|
|
@@ -66885,7 +67282,7 @@ async function runOrchestrationAddAgent(cwd2, args) {
|
|
|
66885
67282
|
const resolved = resolveOrgIdForGroup(link2.group_id, orgsWithTeams);
|
|
66886
67283
|
if (!resolved) {
|
|
66887
67284
|
sp.stop("Failed.");
|
|
66888
|
-
f2.error(`Could not find an org that owns group ${
|
|
67285
|
+
f2.error(`Could not find an org that owns group ${import_picocolors41.default.bold(link2.group_id)}. ` + `Pass ${import_picocolors41.default.cyan("--org <id>")} explicitly.`);
|
|
66889
67286
|
return;
|
|
66890
67287
|
}
|
|
66891
67288
|
orgId = resolved;
|
|
@@ -66902,14 +67299,14 @@ async function runOrchestrationAddAgent(cwd2, args) {
|
|
|
66902
67299
|
if (from.length === 0 && to2.length === 0 && isInteractive() && manifest.members.length > 0) {
|
|
66903
67300
|
const memberOptions = manifest.members.map((m3) => ({ value: m3.slug, label: m3.slug }));
|
|
66904
67301
|
const pickedFrom = await ae({
|
|
66905
|
-
message: `Connect ${
|
|
67302
|
+
message: `Connect ${import_picocolors41.default.bold(slug)} FROM which member(s)? — edges INTO ${slug} (space to select, enter to skip)`,
|
|
66906
67303
|
options: memberOptions,
|
|
66907
67304
|
required: false
|
|
66908
67305
|
});
|
|
66909
67306
|
if (Array.isArray(pickedFrom))
|
|
66910
67307
|
from = pickedFrom;
|
|
66911
67308
|
const pickedTo = await ae({
|
|
66912
|
-
message: `Connect ${
|
|
67309
|
+
message: `Connect ${import_picocolors41.default.bold(slug)} TO which member(s)? — edges OUT of ${slug} (space to select, enter to skip)`,
|
|
66913
67310
|
options: memberOptions,
|
|
66914
67311
|
required: false
|
|
66915
67312
|
});
|
|
@@ -66948,23 +67345,23 @@ async function runOrchestrationAddAgent(cwd2, args) {
|
|
|
66948
67345
|
}
|
|
66949
67346
|
writeOrchManifest(cwd2, updated);
|
|
66950
67347
|
if (args.noPush) {
|
|
66951
|
-
f2.info(`Manifest updated. Run ${
|
|
67348
|
+
f2.info(`Manifest updated. Run ${import_picocolors41.default.cyan("brainbase orchestration push")} to apply.`);
|
|
66952
67349
|
return;
|
|
66953
67350
|
}
|
|
66954
67351
|
await runOrchestrationPush(cwd2, { yes: true, graphOnly: true });
|
|
66955
67352
|
}
|
|
66956
67353
|
|
|
66957
67354
|
// src/cli/orchestration-create.ts
|
|
66958
|
-
var
|
|
67355
|
+
var import_picocolors42 = __toESM(require_picocolors(), 1);
|
|
66959
67356
|
async function runOrchestrationCreate(cwd2, args) {
|
|
66960
67357
|
banner("orchestration create — claim a brainbase-orchestration.yaml");
|
|
66961
67358
|
if (readOrchLink(cwd2)) {
|
|
66962
67359
|
f2.warn("This folder is already linked to an orchestration.");
|
|
66963
|
-
f2.info(`Run ${
|
|
67360
|
+
f2.info(`Run ${import_picocolors42.default.cyan("brainbase orchestration push")} to update it.`);
|
|
66964
67361
|
return;
|
|
66965
67362
|
}
|
|
66966
67363
|
if (!hasOrchManifest(cwd2)) {
|
|
66967
|
-
f2.warn(`No ${
|
|
67364
|
+
f2.warn(`No ${import_picocolors42.default.bold(ORCH_MANIFEST_FILE)} here.`);
|
|
66968
67365
|
f2.info(`Create one, or pull an existing orchestration first.`);
|
|
66969
67366
|
return;
|
|
66970
67367
|
}
|
|
@@ -66990,15 +67387,17 @@ async function runOrchestrationCreate(cwd2, args) {
|
|
|
66990
67387
|
process.exitCode = 1;
|
|
66991
67388
|
return;
|
|
66992
67389
|
}
|
|
66993
|
-
const target = await resolveOrgAndTeam(
|
|
66994
|
-
|
|
66995
|
-
|
|
67390
|
+
const target = await resolveOrgAndTeam({
|
|
67391
|
+
orgId: args.orgId,
|
|
67392
|
+
teamId: args.teamId,
|
|
67393
|
+
announce: true
|
|
67394
|
+
});
|
|
66996
67395
|
const plan = [
|
|
66997
67396
|
"",
|
|
66998
|
-
` ${
|
|
66999
|
-
` ${
|
|
67000
|
-
` ${
|
|
67001
|
-
` ${
|
|
67397
|
+
` ${import_picocolors42.default.bold(manifest.orchestration.name)}`,
|
|
67398
|
+
` ${import_picocolors42.default.dim("org")} ${import_picocolors42.default.bold(target.org.name)}`,
|
|
67399
|
+
` ${import_picocolors42.default.dim("team")} ${import_picocolors42.default.bold(target.team.name)}`,
|
|
67400
|
+
` ${import_picocolors42.default.dim("graph")} ${manifest.members.length} member${manifest.members.length === 1 ? "" : "s"}, ${manifest.edges.length} edge${manifest.edges.length === 1 ? "" : "s"}, ${graph.triggers.length} trigger${graph.triggers.length === 1 ? "" : "s"}`,
|
|
67002
67401
|
""
|
|
67003
67402
|
];
|
|
67004
67403
|
console.log(plan.join(`
|
|
@@ -67028,7 +67427,7 @@ async function runOrchestrationCreate(cwd2, args) {
|
|
|
67028
67427
|
edges: graph.edges,
|
|
67029
67428
|
triggers: graph.triggers
|
|
67030
67429
|
});
|
|
67031
|
-
sp.stop(`Created ${
|
|
67430
|
+
sp.stop(`Created ${import_picocolors42.default.bold(created.name)}.`);
|
|
67032
67431
|
writeOrchLink(cwd2, {
|
|
67033
67432
|
schemaVersion: 1,
|
|
67034
67433
|
orchestration_id: created.id,
|
|
@@ -67059,92 +67458,11 @@ async function runOrchestrationCreate(cwd2, args) {
|
|
|
67059
67458
|
$e(`Created ${created.name} at revision ${created.revision}.`);
|
|
67060
67459
|
} catch (err) {
|
|
67061
67460
|
sp.stop("Failed.");
|
|
67062
|
-
|
|
67063
|
-
process.exitCode = 1;
|
|
67064
|
-
}
|
|
67065
|
-
}
|
|
67066
|
-
async function resolveOrgAndTeam(args) {
|
|
67067
|
-
const orgsSpinner = de();
|
|
67068
|
-
orgsSpinner.start("Loading your organizations…");
|
|
67069
|
-
let orgs;
|
|
67070
|
-
try {
|
|
67071
|
-
orgs = await api.listOrgs();
|
|
67072
|
-
} catch (err) {
|
|
67073
|
-
orgsSpinner.stop("Failed.");
|
|
67074
|
-
handleApiError8(err);
|
|
67075
|
-
process.exitCode = 1;
|
|
67076
|
-
return null;
|
|
67077
|
-
}
|
|
67078
|
-
orgsSpinner.stop(`Found ${orgs.length} organization${orgs.length === 1 ? "" : "s"}.`);
|
|
67079
|
-
if (orgs.length === 0) {
|
|
67080
|
-
f2.warn("You are not in any organizations yet.");
|
|
67081
|
-
process.exitCode = 1;
|
|
67082
|
-
return null;
|
|
67083
|
-
}
|
|
67084
|
-
let org;
|
|
67085
|
-
if (args.orgId) {
|
|
67086
|
-
const found = orgs.find((o2) => o2.id === args.orgId || o2.slug === args.orgId);
|
|
67087
|
-
if (!found) {
|
|
67088
|
-
f2.error(`Org ${args.orgId} not found or you're not a member.`);
|
|
67089
|
-
process.exitCode = 1;
|
|
67090
|
-
return null;
|
|
67091
|
-
}
|
|
67092
|
-
org = found;
|
|
67093
|
-
} else if (orgs.length === 1) {
|
|
67094
|
-
org = orgs[0];
|
|
67095
|
-
f2.info(`Using organization ${import_picocolors38.default.bold(org.name)}.`);
|
|
67096
|
-
} else if (!isInteractive()) {
|
|
67097
|
-
throw new NonInteractiveError("Multiple organizations. Pass --org <id-or-slug> to choose non-interactively.");
|
|
67098
|
-
} else {
|
|
67099
|
-
const orgId = await select({
|
|
67100
|
-
message: "Pick an organization",
|
|
67101
|
-
options: orgs.map((o2) => ({ value: o2.id, label: o2.name, hint: o2.role })),
|
|
67102
|
-
flagHint: "Pass --org <id-or-slug> to choose non-interactively."
|
|
67103
|
-
});
|
|
67104
|
-
org = orgs.find((o2) => o2.id === orgId);
|
|
67105
|
-
}
|
|
67106
|
-
const teamsSpinner = de();
|
|
67107
|
-
teamsSpinner.start(`Loading teams in ${org.name}…`);
|
|
67108
|
-
let teams;
|
|
67109
|
-
try {
|
|
67110
|
-
teams = await api.listTeams(org.id);
|
|
67111
|
-
} catch (err) {
|
|
67112
|
-
teamsSpinner.stop("Failed.");
|
|
67113
|
-
handleApiError8(err);
|
|
67114
|
-
process.exitCode = 1;
|
|
67115
|
-
return null;
|
|
67116
|
-
}
|
|
67117
|
-
teamsSpinner.stop(`Found ${teams.length} team${teams.length === 1 ? "" : "s"}.`);
|
|
67118
|
-
if (teams.length === 0) {
|
|
67119
|
-
f2.warn(`No teams in ${org.name} yet.`);
|
|
67461
|
+
handleApiError7(err);
|
|
67120
67462
|
process.exitCode = 1;
|
|
67121
|
-
return null;
|
|
67122
|
-
}
|
|
67123
|
-
let team;
|
|
67124
|
-
if (args.teamId) {
|
|
67125
|
-
const found = teams.find((t) => t.id === args.teamId);
|
|
67126
|
-
if (!found) {
|
|
67127
|
-
f2.error(`Team ${args.teamId} not found in this org.`);
|
|
67128
|
-
process.exitCode = 1;
|
|
67129
|
-
return null;
|
|
67130
|
-
}
|
|
67131
|
-
team = found;
|
|
67132
|
-
} else if (teams.length === 1) {
|
|
67133
|
-
team = teams[0];
|
|
67134
|
-
f2.info(`Using team ${import_picocolors38.default.bold(team.name)}.`);
|
|
67135
|
-
} else if (!isInteractive()) {
|
|
67136
|
-
throw new NonInteractiveError("Multiple teams. Pass --team <id> to choose non-interactively.");
|
|
67137
|
-
} else {
|
|
67138
|
-
const teamId = await select({
|
|
67139
|
-
message: "Pick a team",
|
|
67140
|
-
options: teams.map((t) => ({ value: t.id, label: t.name, hint: t.role })),
|
|
67141
|
-
flagHint: "Pass --team <id> to choose non-interactively."
|
|
67142
|
-
});
|
|
67143
|
-
team = teams.find((t) => t.id === teamId);
|
|
67144
67463
|
}
|
|
67145
|
-
return { org, team };
|
|
67146
67464
|
}
|
|
67147
|
-
function
|
|
67465
|
+
function handleApiError7(err) {
|
|
67148
67466
|
if (err instanceof ApiError) {
|
|
67149
67467
|
if (err.status === 401) {
|
|
67150
67468
|
f2.error("Your session is invalid. Run `brainbase login` and try again.");
|
|
@@ -67161,7 +67479,7 @@ function handleApiError8(err) {
|
|
|
67161
67479
|
// src/cli/orchestration.ts
|
|
67162
67480
|
async function runOrchestration(cwd2, sub, args, opts) {
|
|
67163
67481
|
if (args.some((arg) => arg === "--help" || arg === "-h")) {
|
|
67164
|
-
|
|
67482
|
+
printHelp3();
|
|
67165
67483
|
return;
|
|
67166
67484
|
}
|
|
67167
67485
|
switch (sub) {
|
|
@@ -67210,33 +67528,33 @@ async function runOrchestration(cwd2, sub, args, opts) {
|
|
|
67210
67528
|
case "help":
|
|
67211
67529
|
case "-h":
|
|
67212
67530
|
case "--help":
|
|
67213
|
-
|
|
67531
|
+
printHelp3();
|
|
67214
67532
|
return;
|
|
67215
67533
|
default:
|
|
67216
67534
|
console.error(`Unknown orchestration subcommand: ${sub}
|
|
67217
67535
|
`);
|
|
67218
|
-
|
|
67536
|
+
printHelp3();
|
|
67219
67537
|
process.exit(1);
|
|
67220
67538
|
}
|
|
67221
67539
|
}
|
|
67222
|
-
function
|
|
67540
|
+
function printHelp3() {
|
|
67223
67541
|
const out = [];
|
|
67224
67542
|
out.push("");
|
|
67225
|
-
out.push(` ${
|
|
67543
|
+
out.push(` ${import_picocolors43.default.bold("brainbase orchestration")} ${import_picocolors43.default.dim("<sub> [options]")}`);
|
|
67226
67544
|
out.push("");
|
|
67227
|
-
out.push(` ${
|
|
67228
|
-
out.push(` ${
|
|
67229
|
-
out.push(` ${
|
|
67230
|
-
out.push(` ${
|
|
67231
|
-
out.push(` ${
|
|
67232
|
-
out.push(` ${
|
|
67545
|
+
out.push(` ${import_picocolors43.default.cyan("create")} ${import_picocolors43.default.dim("claim a local orchestration manifest and create it in the cloud")}`);
|
|
67546
|
+
out.push(` ${import_picocolors43.default.cyan("pull")} ${import_picocolors43.default.dim("<id>")} ${import_picocolors43.default.dim("fetch orchestration + every member agent into this folder")}`);
|
|
67547
|
+
out.push(` ${import_picocolors43.default.cyan("push")} ${import_picocolors43.default.dim("push each member, then update the orchestration graph")}`);
|
|
67548
|
+
out.push(` ${import_picocolors43.default.cyan("add-agent")} ${import_picocolors43.default.dim("<name>")} ${import_picocolors43.default.dim("create a member agent, wire edges (--from/--to), and push")}`);
|
|
67549
|
+
out.push(` ${import_picocolors43.default.cyan("status")} ${import_picocolors43.default.dim("show what would push and what would pull")}`);
|
|
67550
|
+
out.push(` ${import_picocolors43.default.cyan("list")} ${import_picocolors43.default.dim("list orchestrations under a team")}`);
|
|
67233
67551
|
out.push("");
|
|
67234
|
-
out.push(` ${
|
|
67235
|
-
out.push(` ${
|
|
67236
|
-
out.push(` ${
|
|
67237
|
-
out.push(` ${
|
|
67238
|
-
out.push(` ${
|
|
67239
|
-
out.push(` ${
|
|
67552
|
+
out.push(` ${import_picocolors43.default.bold("Flags")}`);
|
|
67553
|
+
out.push(` ${import_picocolors43.default.dim("--yes, -y")} skip confirmations`);
|
|
67554
|
+
out.push(` ${import_picocolors43.default.dim("--harness <id>")} harness for newly-created member folders (default claude-code)`);
|
|
67555
|
+
out.push(` ${import_picocolors43.default.dim("--graph-only")} for push: only update members + edges, skip per-member push`);
|
|
67556
|
+
out.push(` ${import_picocolors43.default.dim("--org <id>")} for create/list: org id or slug (CLI vocab — DB teams.id)`);
|
|
67557
|
+
out.push(` ${import_picocolors43.default.dim("--team <id>")} for create/list: team id (CLI vocab — DB groups.id)`);
|
|
67240
67558
|
out.push("");
|
|
67241
67559
|
console.log(out.join(`
|
|
67242
67560
|
`));
|
|
@@ -67281,16 +67599,16 @@ async function runRun(cwd2, args) {
|
|
|
67281
67599
|
}
|
|
67282
67600
|
|
|
67283
67601
|
// src/cli/publish.ts
|
|
67284
|
-
var
|
|
67602
|
+
var import_picocolors44 = __toESM(require_picocolors(), 1);
|
|
67285
67603
|
async function runPublish(cwd2, _args) {
|
|
67286
67604
|
banner("publish — send your changes to the team");
|
|
67287
67605
|
const link2 = readLink(cwd2);
|
|
67288
67606
|
if (!link2) {
|
|
67289
67607
|
f2.warn("This folder is not linked to any agent.");
|
|
67290
|
-
f2.info(`Run ${
|
|
67608
|
+
f2.info(`Run ${import_picocolors44.default.cyan("brainbase link")} first.`);
|
|
67291
67609
|
return;
|
|
67292
67610
|
}
|
|
67293
|
-
f2.info(`${
|
|
67611
|
+
f2.info(`${import_picocolors44.default.bold("publish")} is coming soon — for now, edit the agent on the web app and run ${import_picocolors44.default.cyan("brainbase sync")} to bring changes here.`);
|
|
67294
67612
|
}
|
|
67295
67613
|
|
|
67296
67614
|
// src/ui/ink/StatusCard.tsx
|
|
@@ -67588,7 +67906,7 @@ async function runStatus(cwd2) {
|
|
|
67588
67906
|
}
|
|
67589
67907
|
|
|
67590
67908
|
// src/cli/token.ts
|
|
67591
|
-
var
|
|
67909
|
+
var import_picocolors45 = __toESM(require_picocolors(), 1);
|
|
67592
67910
|
|
|
67593
67911
|
// src/ui/ink/TokenCards.tsx
|
|
67594
67912
|
var jsx_dev_runtime17 = __toESM(require_jsx_dev_runtime(), 1);
|
|
@@ -67882,7 +68200,7 @@ async function runTokenRevoke(args) {
|
|
|
67882
68200
|
}
|
|
67883
68201
|
if (!autoProceed(args.yes)) {
|
|
67884
68202
|
const ok = await se({
|
|
67885
|
-
message: `Revoke token ${
|
|
68203
|
+
message: `Revoke token ${import_picocolors45.default.bold(args.id)}? CIs and machines using it will stop working.`,
|
|
67886
68204
|
initialValue: false
|
|
67887
68205
|
});
|
|
67888
68206
|
if (!ensureNotCancelled(ok))
|
|
@@ -67897,7 +68215,7 @@ async function runTokenRevoke(args) {
|
|
|
67897
68215
|
}
|
|
67898
68216
|
async function runTokenClear() {
|
|
67899
68217
|
if (!readToken()) {
|
|
67900
|
-
console.log(
|
|
68218
|
+
console.log(import_picocolors45.default.dim("No local token stored."));
|
|
67901
68219
|
return;
|
|
67902
68220
|
}
|
|
67903
68221
|
clearToken();
|
|
@@ -67948,24 +68266,24 @@ async function runToken(sub, rest2, args) {
|
|
|
67948
68266
|
function printTokenHelp() {
|
|
67949
68267
|
const out = [];
|
|
67950
68268
|
out.push("");
|
|
67951
|
-
out.push(` ${
|
|
68269
|
+
out.push(` ${import_picocolors45.default.bold("brainbase token")} ${import_picocolors45.default.dim("<command>")}`);
|
|
67952
68270
|
out.push("");
|
|
67953
|
-
out.push(` ${
|
|
67954
|
-
out.push(` ${
|
|
67955
|
-
out.push(` ${
|
|
67956
|
-
out.push(` ${
|
|
68271
|
+
out.push(` ${import_picocolors45.default.cyan("create")} ${import_picocolors45.default.dim("issue a new long-lived CLI key (PAT)")}`);
|
|
68272
|
+
out.push(` ${import_picocolors45.default.cyan("list")} ${import_picocolors45.default.dim("show your active tokens")}`);
|
|
68273
|
+
out.push(` ${import_picocolors45.default.cyan("revoke")} ${import_picocolors45.default.dim("<id>")} ${import_picocolors45.default.dim("revoke a token by id")}`);
|
|
68274
|
+
out.push(` ${import_picocolors45.default.cyan("clear")} ${import_picocolors45.default.dim("forget the local token (does not revoke)")}`);
|
|
67957
68275
|
out.push("");
|
|
67958
|
-
out.push(` ${
|
|
67959
|
-
out.push(` ${
|
|
67960
|
-
out.push(` ${
|
|
67961
|
-
out.push(` ${
|
|
68276
|
+
out.push(` ${import_picocolors45.default.bold("create flags")}`);
|
|
68277
|
+
out.push(` ${import_picocolors45.default.cyan("--name, -n")} ${import_picocolors45.default.dim("<label>")} ${import_picocolors45.default.dim("token label (prompted if omitted)")}`);
|
|
68278
|
+
out.push(` ${import_picocolors45.default.cyan("--scopes")} ${import_picocolors45.default.dim("<list>")} ${import_picocolors45.default.dim("comma-separated; allowed: read, publish, admin")}`);
|
|
68279
|
+
out.push(` ${import_picocolors45.default.dim("default: read,publish")}`);
|
|
67962
68280
|
out.push("");
|
|
67963
68281
|
console.log(out.join(`
|
|
67964
68282
|
`));
|
|
67965
68283
|
}
|
|
67966
68284
|
|
|
67967
68285
|
// src/cli/mcp.ts
|
|
67968
|
-
var
|
|
68286
|
+
var import_picocolors46 = __toESM(require_picocolors(), 1);
|
|
67969
68287
|
|
|
67970
68288
|
// src/core/mcp-check/collect-servers.ts
|
|
67971
68289
|
import path86 from "node:path";
|
|
@@ -76313,17 +76631,17 @@ async function runMcpCheck(cwd2, options) {
|
|
|
76313
76631
|
function renderHuman(report) {
|
|
76314
76632
|
const lines = [];
|
|
76315
76633
|
if (report.check_status === "skipped") {
|
|
76316
|
-
lines.push(
|
|
76634
|
+
lines.push(import_picocolors46.default.dim("No MCP servers configured — nothing to check."));
|
|
76317
76635
|
return lines.join(`
|
|
76318
76636
|
`) + `
|
|
76319
76637
|
`;
|
|
76320
76638
|
}
|
|
76321
76639
|
for (const s3 of report.servers) {
|
|
76322
|
-
const mark = s3.status === "ok" ?
|
|
76323
|
-
const detail = s3.status === "ok" ?
|
|
76640
|
+
const mark = s3.status === "ok" ? import_picocolors46.default.green("✓") : s3.status === "auth_failed" ? import_picocolors46.default.red("✗") : import_picocolors46.default.yellow("⚠");
|
|
76641
|
+
const detail = s3.status === "ok" ? import_picocolors46.default.dim(`${s3.tool_count} tool${s3.tool_count === 1 ? "" : "s"}`) : import_picocolors46.default.dim(s3.status + (s3.error ? ` — ${s3.error}` : ""));
|
|
76324
76642
|
lines.push(` ${mark} ${s3.name} ${detail}`);
|
|
76325
76643
|
}
|
|
76326
|
-
const summary = report.check_status === "ok" ?
|
|
76644
|
+
const summary = report.check_status === "ok" ? import_picocolors46.default.green("All MCP servers connected.") : import_picocolors46.default.yellow("Some MCP servers are unhealthy.");
|
|
76327
76645
|
lines.push("", summary);
|
|
76328
76646
|
return lines.join(`
|
|
76329
76647
|
`) + `
|
|
@@ -76345,6 +76663,210 @@ async function runMcp(cwd2, sub, _argv, options) {
|
|
|
76345
76663
|
}
|
|
76346
76664
|
}
|
|
76347
76665
|
|
|
76666
|
+
// src/cli/task.ts
|
|
76667
|
+
var import_picocolors47 = __toESM(require_picocolors(), 1);
|
|
76668
|
+
|
|
76669
|
+
// src/cli/task-create.ts
|
|
76670
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
76671
|
+
async function createTask(input, options) {
|
|
76672
|
+
return await masApi.createTask(input, options);
|
|
76673
|
+
}
|
|
76674
|
+
function requiredValue(value, flag) {
|
|
76675
|
+
const normalized = value?.trim();
|
|
76676
|
+
if (!normalized) {
|
|
76677
|
+
throw new Error(`${flag} is required and must not be blank.`);
|
|
76678
|
+
}
|
|
76679
|
+
return normalized;
|
|
76680
|
+
}
|
|
76681
|
+
function optionalValue(value, flag) {
|
|
76682
|
+
if (value === undefined)
|
|
76683
|
+
return;
|
|
76684
|
+
const normalized = value.trim();
|
|
76685
|
+
if (!normalized) {
|
|
76686
|
+
throw new Error(`${flag} must not be blank when provided.`);
|
|
76687
|
+
}
|
|
76688
|
+
return normalized;
|
|
76689
|
+
}
|
|
76690
|
+
function resolveAgentId(cwd2, agentId, readLocalManifest) {
|
|
76691
|
+
if (agentId !== undefined) {
|
|
76692
|
+
return requiredValue(agentId, "--agent");
|
|
76693
|
+
}
|
|
76694
|
+
const manifest = readLocalManifest(cwd2);
|
|
76695
|
+
if (!manifest?.id) {
|
|
76696
|
+
throw new Error("No claimed agent found in brainbase.agent.yaml. Run `brainbase agent create` first, or pass --agent <id>.");
|
|
76697
|
+
}
|
|
76698
|
+
return manifest.id;
|
|
76699
|
+
}
|
|
76700
|
+
function isPublishScopeError(error2) {
|
|
76701
|
+
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
76702
|
+
const body = error2 && typeof error2 === "object" && "body" in error2 ? JSON.stringify(error2.body) : "";
|
|
76703
|
+
return /PAT lacks required scope:\s*publish/i.test(`${message} ${body}`);
|
|
76704
|
+
}
|
|
76705
|
+
async function runTaskCreate(cwd2, options, dependencies = {}) {
|
|
76706
|
+
const idempotencyKey = (dependencies.randomUUID ?? randomUUID2)();
|
|
76707
|
+
const message = requiredValue(options.message, "--message");
|
|
76708
|
+
const agentId = resolveAgentId(cwd2, options.agentId, dependencies.readManifest ?? readManifest);
|
|
76709
|
+
const title = optionalValue(options.title, "--title");
|
|
76710
|
+
const model = optionalValue(options.model, "--model");
|
|
76711
|
+
const input = {
|
|
76712
|
+
agent_id: agentId,
|
|
76713
|
+
initial_messages: [{ role: "user", content: message }],
|
|
76714
|
+
auto_run: true,
|
|
76715
|
+
...title ? { title } : {},
|
|
76716
|
+
...model ? { default_model: model } : {}
|
|
76717
|
+
};
|
|
76718
|
+
let created;
|
|
76719
|
+
try {
|
|
76720
|
+
created = await (dependencies.createTask ?? createTask)(input, {
|
|
76721
|
+
idempotencyKey
|
|
76722
|
+
});
|
|
76723
|
+
} catch (error2) {
|
|
76724
|
+
if (isPublishScopeError(error2)) {
|
|
76725
|
+
throw new Error("PAT lacks required scope: publish. Mint a replacement with `brainbase token create --scopes read,publish` and try again.");
|
|
76726
|
+
}
|
|
76727
|
+
throw error2;
|
|
76728
|
+
}
|
|
76729
|
+
if (options.json) {
|
|
76730
|
+
console.log(JSON.stringify({
|
|
76731
|
+
task_id: created.id,
|
|
76732
|
+
agent_id: created.agent_id,
|
|
76733
|
+
status: created.status
|
|
76734
|
+
}));
|
|
76735
|
+
return;
|
|
76736
|
+
}
|
|
76737
|
+
console.log([
|
|
76738
|
+
`Task ID: ${created.id}`,
|
|
76739
|
+
`Agent ID: ${created.agent_id}`,
|
|
76740
|
+
`Status: ${created.status}`,
|
|
76741
|
+
"First run accepted."
|
|
76742
|
+
].join(`
|
|
76743
|
+
`));
|
|
76744
|
+
}
|
|
76745
|
+
|
|
76746
|
+
// src/cli/task.ts
|
|
76747
|
+
var VALUE_FLAGS = [
|
|
76748
|
+
["--agent", "agentId"],
|
|
76749
|
+
["--message", "message"],
|
|
76750
|
+
["--title", "title"],
|
|
76751
|
+
["--model", "model"]
|
|
76752
|
+
];
|
|
76753
|
+
var TASK_OPTION_NAMES = new Set([
|
|
76754
|
+
...VALUE_FLAGS.map(([flag]) => flag),
|
|
76755
|
+
"--json"
|
|
76756
|
+
]);
|
|
76757
|
+
var HELP_FLAGS = new Set(["--help", "-h"]);
|
|
76758
|
+
function missingValueError(flag) {
|
|
76759
|
+
if (flag === "--message" || flag === "--agent") {
|
|
76760
|
+
return new Error(`${flag} is required and must not be blank.`);
|
|
76761
|
+
}
|
|
76762
|
+
return new Error(`${flag} must not be blank when provided.`);
|
|
76763
|
+
}
|
|
76764
|
+
function flagLikeValueError(flag, value) {
|
|
76765
|
+
return new Error(`${flag} requires a value. If you meant the literal "${value}", use ${flag}=${value} or ${flag} -- ${value}.`);
|
|
76766
|
+
}
|
|
76767
|
+
function parseCreateArgs(args) {
|
|
76768
|
+
const options = {};
|
|
76769
|
+
const seen = new Set;
|
|
76770
|
+
for (let index = 0;index < args.length; index += 1) {
|
|
76771
|
+
const arg = args[index];
|
|
76772
|
+
if (HELP_FLAGS.has(arg)) {
|
|
76773
|
+
return { help: true, options };
|
|
76774
|
+
}
|
|
76775
|
+
if (arg === "--json") {
|
|
76776
|
+
if (seen.has(arg)) {
|
|
76777
|
+
throw new Error(`Duplicate task create option: ${arg}`);
|
|
76778
|
+
}
|
|
76779
|
+
seen.add(arg);
|
|
76780
|
+
options.json = true;
|
|
76781
|
+
continue;
|
|
76782
|
+
}
|
|
76783
|
+
let matched = false;
|
|
76784
|
+
for (const [flag, option] of VALUE_FLAGS) {
|
|
76785
|
+
if (arg === flag) {
|
|
76786
|
+
if (seen.has(flag)) {
|
|
76787
|
+
throw new Error(`Duplicate task create option: ${flag}`);
|
|
76788
|
+
}
|
|
76789
|
+
seen.add(flag);
|
|
76790
|
+
let value = args[index + 1];
|
|
76791
|
+
if (value === undefined) {
|
|
76792
|
+
throw missingValueError(flag);
|
|
76793
|
+
}
|
|
76794
|
+
if (value === "--") {
|
|
76795
|
+
value = args[index + 2];
|
|
76796
|
+
if (value === undefined)
|
|
76797
|
+
throw missingValueError(flag);
|
|
76798
|
+
index += 1;
|
|
76799
|
+
} else if (HELP_FLAGS.has(value) && (option === "agentId" || option === "model")) {
|
|
76800
|
+
return { help: true, options };
|
|
76801
|
+
} else if (TASK_OPTION_NAMES.has(value)) {
|
|
76802
|
+
throw flagLikeValueError(flag, value);
|
|
76803
|
+
}
|
|
76804
|
+
options[option] = value;
|
|
76805
|
+
index += 1;
|
|
76806
|
+
matched = true;
|
|
76807
|
+
break;
|
|
76808
|
+
}
|
|
76809
|
+
const prefix = `${flag}=`;
|
|
76810
|
+
if (arg.startsWith(prefix)) {
|
|
76811
|
+
if (seen.has(flag)) {
|
|
76812
|
+
throw new Error(`Duplicate task create option: ${flag}`);
|
|
76813
|
+
}
|
|
76814
|
+
seen.add(flag);
|
|
76815
|
+
options[option] = arg.slice(prefix.length);
|
|
76816
|
+
matched = true;
|
|
76817
|
+
break;
|
|
76818
|
+
}
|
|
76819
|
+
}
|
|
76820
|
+
if (!matched) {
|
|
76821
|
+
throw new Error(`Unknown task create argument: ${arg}`);
|
|
76822
|
+
}
|
|
76823
|
+
}
|
|
76824
|
+
return { help: false, options };
|
|
76825
|
+
}
|
|
76826
|
+
async function runTask(cwd2, sub, args) {
|
|
76827
|
+
switch (sub) {
|
|
76828
|
+
case "create": {
|
|
76829
|
+
const parsed = parseCreateArgs(args);
|
|
76830
|
+
if (parsed.help) {
|
|
76831
|
+
printHelp4();
|
|
76832
|
+
return;
|
|
76833
|
+
}
|
|
76834
|
+
await runTaskCreate(cwd2, parsed.options);
|
|
76835
|
+
return;
|
|
76836
|
+
}
|
|
76837
|
+
case undefined:
|
|
76838
|
+
case "help":
|
|
76839
|
+
case "-h":
|
|
76840
|
+
case "--help":
|
|
76841
|
+
printHelp4();
|
|
76842
|
+
return;
|
|
76843
|
+
default:
|
|
76844
|
+
console.error(`Unknown task subcommand: ${sub}
|
|
76845
|
+
`);
|
|
76846
|
+
printHelp4();
|
|
76847
|
+
process.exit(1);
|
|
76848
|
+
}
|
|
76849
|
+
}
|
|
76850
|
+
function printHelp4() {
|
|
76851
|
+
const out = [];
|
|
76852
|
+
out.push("");
|
|
76853
|
+
out.push(` ${import_picocolors47.default.bold("brainbase task")} ${import_picocolors47.default.dim("<sub> [options]")}`);
|
|
76854
|
+
out.push("");
|
|
76855
|
+
out.push(` ${import_picocolors47.default.cyan("create")} ${import_picocolors47.default.dim("--message <text>")} ${import_picocolors47.default.dim("create a task and start its first run")}`);
|
|
76856
|
+
out.push("");
|
|
76857
|
+
out.push(` ${import_picocolors47.default.bold("create flags")}`);
|
|
76858
|
+
out.push(` ${import_picocolors47.default.dim("--message <text>")} required first user message`);
|
|
76859
|
+
out.push(` ${import_picocolors47.default.dim("--agent <id>")} override the claimed agent in brainbase.agent.yaml`);
|
|
76860
|
+
out.push(` ${import_picocolors47.default.dim("--title <text>")} optional task title`);
|
|
76861
|
+
out.push(` ${import_picocolors47.default.dim("--model <id>")} optional model override`);
|
|
76862
|
+
out.push(` ${import_picocolors47.default.dim("--json")} print task_id, agent_id, and status as JSON`);
|
|
76863
|
+
out.push("");
|
|
76864
|
+
out.push(` ${import_picocolors47.default.dim("Flag-like values:")} use ${import_picocolors47.default.cyan("--flag=value")} or ${import_picocolors47.default.cyan("--flag -- <value>")}`);
|
|
76865
|
+
out.push("");
|
|
76866
|
+
console.log(out.join(`
|
|
76867
|
+
`));
|
|
76868
|
+
}
|
|
76869
|
+
|
|
76348
76870
|
// src/index.ts
|
|
76349
76871
|
var PROTECTED = new Set([
|
|
76350
76872
|
"template",
|
|
@@ -76365,100 +76887,115 @@ var STORED_PAT_COMMANDS = new Set([
|
|
|
76365
76887
|
function help() {
|
|
76366
76888
|
const out = [];
|
|
76367
76889
|
out.push("");
|
|
76368
|
-
out.push(` ${brandTint("◆")} ${
|
|
76369
|
-
out.push(` ${
|
|
76890
|
+
out.push(` ${brandTint("◆")} ${import_picocolors48.default.bold("brainbase")} ${import_picocolors48.default.dim(`v${VERSION}`)}`);
|
|
76891
|
+
out.push(` ${import_picocolors48.default.dim("connect your local agent to the brainbase platform")}`);
|
|
76370
76892
|
out.push("");
|
|
76371
76893
|
out.push(divider("USAGE"));
|
|
76372
76894
|
out.push("");
|
|
76373
|
-
out.push(` ${
|
|
76895
|
+
out.push(` ${import_picocolors48.default.bold("brainbase")} ${import_picocolors48.default.dim("<command> [options]")}`);
|
|
76374
76896
|
out.push("");
|
|
76375
76897
|
out.push(divider("AUTH"));
|
|
76376
76898
|
out.push("");
|
|
76377
|
-
out.push(` ${
|
|
76378
|
-
out.push(` ${
|
|
76379
|
-
out.push(` ${
|
|
76899
|
+
out.push(` ${import_picocolors48.default.cyan("login")} ${import_picocolors48.default.dim(" open the web app and connect this device")}`);
|
|
76900
|
+
out.push(` ${import_picocolors48.default.cyan("logout")} ${import_picocolors48.default.dim(" clear the local session")}`);
|
|
76901
|
+
out.push(` ${import_picocolors48.default.cyan("whoami")} ${import_picocolors48.default.dim(" show the current user")}`);
|
|
76902
|
+
out.push("");
|
|
76903
|
+
out.push(divider("DISCOVERY"));
|
|
76904
|
+
out.push("");
|
|
76905
|
+
out.push(` ${import_picocolors48.default.cyan("team list")} ${import_picocolors48.default.dim("show the teams you can create agents in")}`);
|
|
76906
|
+
out.push(` ${import_picocolors48.default.cyan("agent list")} ${import_picocolors48.default.dim("show a team's agents and their ids")}`);
|
|
76380
76907
|
out.push("");
|
|
76381
76908
|
out.push(divider("LINKED AGENT"));
|
|
76382
76909
|
out.push("");
|
|
76383
|
-
out.push(` ${
|
|
76384
|
-
out.push(` ${
|
|
76385
|
-
out.push(` ${
|
|
76386
|
-
out.push(` ${
|
|
76387
|
-
out.push(` ${
|
|
76388
|
-
out.push(` ${
|
|
76389
|
-
out.push(` ${
|
|
76390
|
-
out.push(` ${
|
|
76391
|
-
out.push(` ${
|
|
76392
|
-
out.push(` ${
|
|
76910
|
+
out.push(` ${import_picocolors48.default.cyan("agent create")} ${import_picocolors48.default.dim("claim an unclaimed brainbase.agent.yaml and create the cloud agent")}`);
|
|
76911
|
+
out.push(` ${import_picocolors48.default.cyan("agent pull")} ${import_picocolors48.default.dim("[<id>]")} ${import_picocolors48.default.dim("bring cloud changes into this folder (--force to override; --run-entrypoint to also execute the agent entrypoint)")}`);
|
|
76912
|
+
out.push(` ${import_picocolors48.default.cyan("agent push")} ${import_picocolors48.default.dim("send local changes to the cloud (--force to overwrite cloud-side conflicts with local)")}`);
|
|
76913
|
+
out.push(` ${import_picocolors48.default.cyan("agent unpack")} ${import_picocolors48.default.dim("install the claimed agent into a harness layout")}`);
|
|
76914
|
+
out.push(` ${import_picocolors48.default.cyan("link")} ${import_picocolors48.default.dim("attach this folder to an existing agent")}`);
|
|
76915
|
+
out.push(` ${import_picocolors48.default.cyan("agent status")} ${import_picocolors48.default.dim("show what would pull and what would push")}`);
|
|
76916
|
+
out.push(` ${import_picocolors48.default.cyan("agent env")} ${import_picocolors48.default.dim("print export lines for `eval $(brainbase agent env)`")}`);
|
|
76917
|
+
out.push(` ${import_picocolors48.default.cyan("run")} ${import_picocolors48.default.dim("<cmd> [args...]")} ${import_picocolors48.default.dim("run <cmd> with secrets.env loaded into env")}`);
|
|
76918
|
+
out.push(` ${import_picocolors48.default.cyan("status")} ${import_picocolors48.default.dim("show what this folder is linked to")}`);
|
|
76919
|
+
out.push(` ${import_picocolors48.default.cyan("unlink")} ${import_picocolors48.default.dim("disconnect this folder")}`);
|
|
76920
|
+
out.push("");
|
|
76921
|
+
out.push(divider("TASKS"));
|
|
76922
|
+
out.push("");
|
|
76923
|
+
out.push(` ${import_picocolors48.default.cyan("task create")} ${import_picocolors48.default.dim("--message <text>")} ${import_picocolors48.default.dim("create a managed task and start its first run")}`);
|
|
76393
76924
|
out.push("");
|
|
76394
76925
|
out.push(divider("ORCHESTRATIONS"));
|
|
76395
76926
|
out.push("");
|
|
76396
|
-
out.push(` ${
|
|
76397
|
-
out.push(` ${
|
|
76398
|
-
out.push(` ${
|
|
76399
|
-
out.push(` ${
|
|
76400
|
-
out.push(` ${
|
|
76927
|
+
out.push(` ${import_picocolors48.default.cyan("orchestration create")} ${import_picocolors48.default.dim("claim a local orchestration manifest and create it in the cloud")}`);
|
|
76928
|
+
out.push(` ${import_picocolors48.default.cyan("orchestration list")} ${import_picocolors48.default.dim("list orchestrations under a team")}`);
|
|
76929
|
+
out.push(` ${import_picocolors48.default.cyan("orchestration pull")} ${import_picocolors48.default.dim("<id>")} ${import_picocolors48.default.dim("recursively fetch an orchestration + every member agent")}`);
|
|
76930
|
+
out.push(` ${import_picocolors48.default.cyan("orchestration push")} ${import_picocolors48.default.dim("recursively push each member, then update the graph")}`);
|
|
76931
|
+
out.push(` ${import_picocolors48.default.cyan("orchestration status")} ${import_picocolors48.default.dim("show what would push and what would pull")}`);
|
|
76401
76932
|
out.push("");
|
|
76402
76933
|
out.push(divider("TEMPLATES"));
|
|
76403
76934
|
out.push("");
|
|
76404
|
-
out.push(` ${
|
|
76405
|
-
out.push(` ${
|
|
76406
|
-
out.push(` ${
|
|
76407
|
-
out.push(` ${
|
|
76408
|
-
out.push(` ${
|
|
76409
|
-
out.push(` ${
|
|
76410
|
-
out.push(` ${
|
|
76935
|
+
out.push(` ${import_picocolors48.default.cyan("template pack")} ${import_picocolors48.default.dim("bundle the current agent into a template")}`);
|
|
76936
|
+
out.push(` ${import_picocolors48.default.cyan("template publish")} ${import_picocolors48.default.dim("upload a template to the registry")}`);
|
|
76937
|
+
out.push(` ${import_picocolors48.default.cyan("template search")} ${import_picocolors48.default.dim("[query]")} ${import_picocolors48.default.dim("search the registry")}`);
|
|
76938
|
+
out.push(` ${import_picocolors48.default.cyan("template info")} ${import_picocolors48.default.dim("<creator/slug>")} ${import_picocolors48.default.dim("show registry details for a template")}`);
|
|
76939
|
+
out.push(` ${import_picocolors48.default.cyan("template onboard")} ${import_picocolors48.default.dim("<creator/slug>")} ${import_picocolors48.default.dim("install (or refresh) a template")}`);
|
|
76940
|
+
out.push(` ${import_picocolors48.default.cyan("template list")} ${import_picocolors48.default.dim("show installed templates")}`);
|
|
76941
|
+
out.push(` ${import_picocolors48.default.cyan("template remove")} ${import_picocolors48.default.dim("<creator/slug>")} ${import_picocolors48.default.dim("uninstall a template")}`);
|
|
76411
76942
|
out.push("");
|
|
76412
76943
|
out.push(divider("SKILLS"));
|
|
76413
76944
|
out.push("");
|
|
76414
|
-
out.push(` ${
|
|
76415
|
-
out.push(` ${
|
|
76416
|
-
out.push(` ${
|
|
76417
|
-
out.push(` ${
|
|
76418
|
-
out.push(` ${
|
|
76419
|
-
out.push(` ${
|
|
76420
|
-
out.push(` ${
|
|
76945
|
+
out.push(` ${import_picocolors48.default.cyan("skill add")} ${import_picocolors48.default.dim("<source>")} ${import_picocolors48.default.dim("install a skill (github / git / brainbase)")}`);
|
|
76946
|
+
out.push(` ${import_picocolors48.default.cyan("skill list")} ${import_picocolors48.default.dim("show locally installed skills + their source")}`);
|
|
76947
|
+
out.push(` ${import_picocolors48.default.cyan("skill update")} ${import_picocolors48.default.dim("<slug>")} ${import_picocolors48.default.dim("re-fetch a skill from its recorded source")}`);
|
|
76948
|
+
out.push(` ${import_picocolors48.default.cyan("skill remove")} ${import_picocolors48.default.dim("<slug>")} ${import_picocolors48.default.dim("uninstall a skill")}`);
|
|
76949
|
+
out.push(` ${import_picocolors48.default.cyan("skill search")} ${import_picocolors48.default.dim("[query]")} ${import_picocolors48.default.dim("search the brainbase skill registry")}`);
|
|
76950
|
+
out.push(` ${import_picocolors48.default.cyan("skill info")} ${import_picocolors48.default.dim("<creator/slug>")} ${import_picocolors48.default.dim("show registry details for a skill")}`);
|
|
76951
|
+
out.push(` ${import_picocolors48.default.cyan("skill publish")} ${import_picocolors48.default.dim("[dir]")} ${import_picocolors48.default.dim("publish a SKILL.md folder (defaults to .)")}`);
|
|
76421
76952
|
out.push("");
|
|
76422
76953
|
out.push(divider("CLI TOKENS"));
|
|
76423
76954
|
out.push("");
|
|
76424
|
-
out.push(` ${
|
|
76425
|
-
out.push(` ${
|
|
76426
|
-
out.push(` ${
|
|
76955
|
+
out.push(` ${import_picocolors48.default.cyan("token create")} ${import_picocolors48.default.dim("issue a long-lived CLI key for CI / scripts")}`);
|
|
76956
|
+
out.push(` ${import_picocolors48.default.cyan("token list")} ${import_picocolors48.default.dim("show your active tokens")}`);
|
|
76957
|
+
out.push(` ${import_picocolors48.default.cyan("token revoke")} ${import_picocolors48.default.dim("<id>")} ${import_picocolors48.default.dim("revoke a token")}`);
|
|
76427
76958
|
out.push("");
|
|
76428
76959
|
out.push(divider("MCP"));
|
|
76429
76960
|
out.push("");
|
|
76430
|
-
out.push(` ${
|
|
76961
|
+
out.push(` ${import_picocolors48.default.cyan("mcp check")} ${import_picocolors48.default.dim("[--json]")} ${import_picocolors48.default.dim("verify MCP server connectivity through the brainbase proxy (runs at sandbox bootstrap)")}`);
|
|
76431
76962
|
out.push("");
|
|
76432
76963
|
out.push(divider("FLAGS"));
|
|
76433
76964
|
out.push("");
|
|
76434
|
-
out.push(` ${
|
|
76435
|
-
out.push(` ${
|
|
76436
|
-
out.push(` ${
|
|
76437
|
-
out.push(` ${
|
|
76438
|
-
out.push(` ${
|
|
76439
|
-
out.push(` ${
|
|
76440
|
-
out.push(` ${
|
|
76441
|
-
out.push(` ${
|
|
76442
|
-
out.push(` ${
|
|
76965
|
+
out.push(` ${import_picocolors48.default.dim("--harness <id>")} force harness for onboard / sync (e.g. claude-code)`);
|
|
76966
|
+
out.push(` ${import_picocolors48.default.dim("--scope <s>")} force scope: global | project`);
|
|
76967
|
+
out.push(` ${import_picocolors48.default.dim("--yes, -y")} skip confirmations / auto-overwrite`);
|
|
76968
|
+
out.push(` ${import_picocolors48.default.dim("--agent <id>")} for link/task create: use this agent id explicitly`);
|
|
76969
|
+
out.push(` ${import_picocolors48.default.dim("--message <text>")} for task create: required first user message`);
|
|
76970
|
+
out.push(` ${import_picocolors48.default.dim("--title <text>")} for task create: optional task title`);
|
|
76971
|
+
out.push(` ${import_picocolors48.default.dim("--model <id>")} for task create: optional model override`);
|
|
76972
|
+
out.push(` ${import_picocolors48.default.dim("--org <id-or-slug>")} pick the organization (team/agent list, agent create, orchestration create/list)`);
|
|
76973
|
+
out.push(` ${import_picocolors48.default.dim("--team <id>")} pick the team, same commands (works without --org)`);
|
|
76974
|
+
out.push(` ${import_picocolors48.default.dim("--json")} for team/agent list, task create, mcp check: machine-readable output`);
|
|
76975
|
+
out.push(` ${import_picocolors48.default.dim("--no-tracking")} for link: skip routing LLM traffic through brainbase`);
|
|
76976
|
+
out.push(` ${import_picocolors48.default.dim("--track")} for agent create: enable tracking non-interactively (off without a TTY)`);
|
|
76977
|
+
out.push(` ${import_picocolors48.default.dim("--shell <sh|fish>")} for agent env: pick output format (auto-detected from $SHELL)`);
|
|
76978
|
+
out.push(` ${import_picocolors48.default.dim("--all")} for template list: include installs from other folders`);
|
|
76979
|
+
out.push(` ${import_picocolors48.default.dim("--web <url>")} for login: web app URL (default https://app.brainbaselabs.com)`);
|
|
76443
76980
|
out.push("");
|
|
76444
76981
|
out.push(divider("ENV"));
|
|
76445
76982
|
out.push("");
|
|
76446
|
-
out.push(` ${
|
|
76447
|
-
out.push(` ${
|
|
76448
|
-
out.push(` ${
|
|
76449
|
-
out.push(` ${
|
|
76450
|
-
out.push(` ${
|
|
76451
|
-
out.push(` ${
|
|
76452
|
-
out.push(` ${
|
|
76453
|
-
out.push(` ${
|
|
76454
|
-
out.push(` ${
|
|
76455
|
-
out.push(` ${
|
|
76983
|
+
out.push(` ${import_picocolors48.default.dim("BRAINBASE_HOME")} override the local config dir (default ~/.brainbase)`);
|
|
76984
|
+
out.push(` ${import_picocolors48.default.dim("BRAINBASE_WEB_URL")} override the web app URL used by login`);
|
|
76985
|
+
out.push(` ${import_picocolors48.default.dim("BRAINBASE_CONTROL_PLANE_URL")} override the MAS host (/v2/cli; task create uses /v2/tasks)`);
|
|
76986
|
+
out.push(` ${import_picocolors48.default.dim("BRAINBASE_API_URL")} legacy KLS host override (uses /api/cli; proxy/registry fallback)`);
|
|
76987
|
+
out.push(` ${import_picocolors48.default.dim("BRAINBASE_PROXY_URL")} override the model-proxy URL used by harness traffic (default https://api.v1.brainbaselabs.com)`);
|
|
76988
|
+
out.push(` ${import_picocolors48.default.dim("BRAINBASE_REGISTRY_URL")} override the registry API URL (default https://api.v1.brainbaselabs.com)`);
|
|
76989
|
+
out.push(` ${import_picocolors48.default.dim("BRAINBASE_TOKEN")} long-lived CLI PAT (overrides token.json)`);
|
|
76990
|
+
out.push(` ${import_picocolors48.default.dim("BRAINBASE_SKIP_AUTH")} bypass the auth gate for development`);
|
|
76991
|
+
out.push(` ${import_picocolors48.default.dim("BRAINBASE_NON_INTERACTIVE")} force non-interactive mode — skip/auto-default prompts (CI & agents)`);
|
|
76992
|
+
out.push(` ${import_picocolors48.default.dim("BRAINBASE_RUN_ENTRYPOINT")} =1 → agent pull executes the agent entrypoint (sandbox boots; or pass --run-entrypoint)`);
|
|
76456
76993
|
out.push("");
|
|
76457
76994
|
out.push(divider("HARNESSES"));
|
|
76458
76995
|
out.push("");
|
|
76459
|
-
out.push(` ${
|
|
76460
|
-
out.push(` ${
|
|
76461
|
-
out.push(` ${
|
|
76996
|
+
out.push(` ${import_picocolors48.default.dim("•")} ${import_picocolors48.default.bold("claude-code")} ${import_picocolors48.default.dim("skills, mcps, agents, commands, playbooks, instructions, files")}`);
|
|
76997
|
+
out.push(` ${import_picocolors48.default.dim("•")} ${import_picocolors48.default.bold("codex")} ${import_picocolors48.default.dim("skills, mcps, commands, playbooks, instructions, files")}`);
|
|
76998
|
+
out.push(` ${import_picocolors48.default.dim("•")} ${import_picocolors48.default.bold("kafka")} ${import_picocolors48.default.dim("skills, mcps, agents, commands, playbooks, instructions, files")}`);
|
|
76462
76999
|
out.push("");
|
|
76463
77000
|
console.log(out.join(`
|
|
76464
77001
|
`));
|
|
@@ -76522,13 +77059,13 @@ async function requireAuth(cmd) {
|
|
|
76522
77059
|
if (STORED_PAT_COMMANDS.has(cmd) && readToken())
|
|
76523
77060
|
return;
|
|
76524
77061
|
console.error("");
|
|
76525
|
-
console.error(` ${brandTint("◆")} ${
|
|
77062
|
+
console.error(` ${brandTint("◆")} ${import_picocolors48.default.bold("brainbase")}`);
|
|
76526
77063
|
console.error("");
|
|
76527
|
-
console.error(` ${
|
|
77064
|
+
console.error(` ${import_picocolors48.default.red("✗")} You need to sign in to use ${import_picocolors48.default.bold("brainbase " + cmd)}.`);
|
|
76528
77065
|
if (status.reason)
|
|
76529
|
-
console.error(` ${
|
|
77066
|
+
console.error(` ${import_picocolors48.default.dim(status.reason)}`);
|
|
76530
77067
|
console.error("");
|
|
76531
|
-
console.error(` Run ${
|
|
77068
|
+
console.error(` Run ${import_picocolors48.default.cyan("brainbase login")} to connect this device.`);
|
|
76532
77069
|
console.error("");
|
|
76533
77070
|
process14.exit(1);
|
|
76534
77071
|
}
|
|
@@ -76551,36 +77088,37 @@ async function main() {
|
|
|
76551
77088
|
await runRun(cwd2, argv);
|
|
76552
77089
|
return;
|
|
76553
77090
|
}
|
|
76554
|
-
const
|
|
76555
|
-
const
|
|
76556
|
-
const
|
|
76557
|
-
const
|
|
76558
|
-
const
|
|
76559
|
-
const
|
|
76560
|
-
const
|
|
76561
|
-
const
|
|
76562
|
-
const
|
|
77091
|
+
const sharedArgs = cmd === "task" ? [] : argv;
|
|
77092
|
+
const yes = hasFlag2(sharedArgs, "--yes", "-y");
|
|
77093
|
+
const all = hasFlag2(sharedArgs, "--all");
|
|
77094
|
+
const harness = getFlag(sharedArgs, "--harness");
|
|
77095
|
+
const scopeFlag = getFlag(sharedArgs, "--scope");
|
|
77096
|
+
const web = getFlag(sharedArgs, "--web");
|
|
77097
|
+
const visibility = getFlag(sharedArgs, "--visibility");
|
|
77098
|
+
const category = getFlag(sharedArgs, "--category");
|
|
77099
|
+
const target = getFlag(sharedArgs, "--target");
|
|
77100
|
+
const pageRaw = getFlag(sharedArgs, "--page");
|
|
76563
77101
|
const page = pageRaw && /^\d+$/.test(pageRaw) ? Number(pageRaw) : undefined;
|
|
76564
|
-
const asSlug = getFlag(
|
|
76565
|
-
const agentFlag = getFlag(
|
|
76566
|
-
const shellFlag = getFlag(
|
|
76567
|
-
const noTracking = hasFlag2(
|
|
76568
|
-
const track = hasFlag2(
|
|
76569
|
-
const forceFlag = hasFlag2(
|
|
76570
|
-
const runEntrypointFlag = hasFlag2(
|
|
76571
|
-
const graphOnlyFlag = hasFlag2(
|
|
76572
|
-
const nameFlag = getFlag(
|
|
76573
|
-
const skillVersionFlag = getFlag(
|
|
76574
|
-
const taglineFlag = getFlag(
|
|
76575
|
-
const orgIdFlag = getFlag(
|
|
76576
|
-
const teamIdFlag = getFlag(
|
|
76577
|
-
const fromFlags = getFlagAll(
|
|
76578
|
-
const toFlags = getFlagAll(
|
|
76579
|
-
const descriptionFlag = getFlag(
|
|
76580
|
-
const schemaFlag = getFlag(
|
|
76581
|
-
const noPushFlag = hasFlag2(
|
|
76582
|
-
const jsonFlag = hasFlag2(
|
|
76583
|
-
const acpFlag = hasFlag2(
|
|
77102
|
+
const asSlug = getFlag(sharedArgs, "--as");
|
|
77103
|
+
const agentFlag = getFlag(sharedArgs, "--agent");
|
|
77104
|
+
const shellFlag = getFlag(sharedArgs, "--shell");
|
|
77105
|
+
const noTracking = hasFlag2(sharedArgs, "--no-tracking");
|
|
77106
|
+
const track = hasFlag2(sharedArgs, "--track");
|
|
77107
|
+
const forceFlag = hasFlag2(sharedArgs, "--force");
|
|
77108
|
+
const runEntrypointFlag = hasFlag2(sharedArgs, "--run-entrypoint");
|
|
77109
|
+
const graphOnlyFlag = hasFlag2(sharedArgs, "--graph-only");
|
|
77110
|
+
const nameFlag = getFlag(sharedArgs, "--name");
|
|
77111
|
+
const skillVersionFlag = getFlag(sharedArgs, "--skill-version");
|
|
77112
|
+
const taglineFlag = getFlag(sharedArgs, "--tagline");
|
|
77113
|
+
const orgIdFlag = getFlag(sharedArgs, "--org");
|
|
77114
|
+
const teamIdFlag = getFlag(sharedArgs, "--team");
|
|
77115
|
+
const fromFlags = getFlagAll(sharedArgs, "--from");
|
|
77116
|
+
const toFlags = getFlagAll(sharedArgs, "--to");
|
|
77117
|
+
const descriptionFlag = getFlag(sharedArgs, "--description");
|
|
77118
|
+
const schemaFlag = getFlag(sharedArgs, "--schema");
|
|
77119
|
+
const noPushFlag = hasFlag2(sharedArgs, "--no-push");
|
|
77120
|
+
const jsonFlag = hasFlag2(sharedArgs, "--json");
|
|
77121
|
+
const acpFlag = hasFlag2(sharedArgs, "--acp");
|
|
76584
77122
|
ensureSkillResolversRegistered();
|
|
76585
77123
|
await requireAuth(cmd);
|
|
76586
77124
|
try {
|
|
@@ -76652,6 +77190,7 @@ async function main() {
|
|
|
76652
77190
|
const sub = argv.shift();
|
|
76653
77191
|
await runAgent(cwd2, sub, argv, {
|
|
76654
77192
|
yes,
|
|
77193
|
+
json: jsonFlag,
|
|
76655
77194
|
scope: scopeFlag,
|
|
76656
77195
|
shell: shellFlag,
|
|
76657
77196
|
harness,
|
|
@@ -76667,6 +77206,17 @@ async function main() {
|
|
|
76667
77206
|
});
|
|
76668
77207
|
break;
|
|
76669
77208
|
}
|
|
77209
|
+
case "team":
|
|
77210
|
+
case "teams": {
|
|
77211
|
+
const sub = argv.shift();
|
|
77212
|
+
await runTeam(sub, argv, { orgId: orgIdFlag, json: jsonFlag });
|
|
77213
|
+
break;
|
|
77214
|
+
}
|
|
77215
|
+
case "task": {
|
|
77216
|
+
const sub = argv.shift();
|
|
77217
|
+
await runTask(cwd2, sub, argv);
|
|
77218
|
+
break;
|
|
77219
|
+
}
|
|
76670
77220
|
case "orchestration":
|
|
76671
77221
|
case "orch": {
|
|
76672
77222
|
const sub = argv.shift();
|
|
@@ -76706,8 +77256,11 @@ async function main() {
|
|
|
76706
77256
|
process14.exit(1);
|
|
76707
77257
|
}
|
|
76708
77258
|
} catch (err) {
|
|
76709
|
-
console.error(
|
|
77259
|
+
console.error(import_picocolors48.default.red(`
|
|
76710
77260
|
${err.message}`));
|
|
77261
|
+
if (err instanceof ApiError && err.status === 401) {
|
|
77262
|
+
console.error(` Run ${import_picocolors48.default.cyan("brainbase login")} to connect this device.`);
|
|
77263
|
+
}
|
|
76711
77264
|
if (process14.env.BRAINBASE_DEBUG)
|
|
76712
77265
|
console.error(err.stack);
|
|
76713
77266
|
process14.exit(1);
|