@buildautomaton/cli 0.1.47 → 0.1.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +210 -78
- package/dist/cli.js.map +4 -4
- package/dist/index.js +210 -78
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -24469,7 +24469,7 @@ function installBridgeProcessResilience() {
|
|
|
24469
24469
|
}
|
|
24470
24470
|
|
|
24471
24471
|
// src/cli-version.ts
|
|
24472
|
-
var CLI_VERSION = "0.1.
|
|
24472
|
+
var CLI_VERSION = "0.1.48".length > 0 ? "0.1.48" : "0.0.0-dev";
|
|
24473
24473
|
|
|
24474
24474
|
// src/connection/heartbeat/constants.ts
|
|
24475
24475
|
var BRIDGE_APP_HEARTBEAT_INTERVAL_MS = 1e4;
|
|
@@ -33121,54 +33121,167 @@ function buildForkedSessionAgentPrompt(userPrompt, childSessionId, parentSession
|
|
|
33121
33121
|
].join("\n");
|
|
33122
33122
|
}
|
|
33123
33123
|
|
|
33124
|
-
// src/mcp/tools/session-history/
|
|
33124
|
+
// src/mcp/tools/session-history/cloud/internal-api.ts
|
|
33125
33125
|
function internalApiBase(cloudApiBaseUrl) {
|
|
33126
33126
|
return cloudApiBaseUrl.replace(/\/+$/, "");
|
|
33127
33127
|
}
|
|
33128
|
-
async function
|
|
33128
|
+
async function fetchInternalApiJson(params) {
|
|
33129
33129
|
const token = params.getCloudAccessToken();
|
|
33130
33130
|
if (!token) return { ok: false, error: "Missing cloud access token." };
|
|
33131
|
-
const url2 = `${internalApiBase(params.cloudApiBaseUrl)}
|
|
33131
|
+
const url2 = `${internalApiBase(params.cloudApiBaseUrl)}${params.path}`;
|
|
33132
33132
|
const res = await fetch(url2, { headers: { Authorization: `Bearer ${token}` } });
|
|
33133
33133
|
if (!res.ok) {
|
|
33134
33134
|
const t = await res.text().catch(() => "");
|
|
33135
|
-
return { ok: false, error:
|
|
33135
|
+
return { ok: false, error: `${params.errorLabel} (${res.status}): ${t.slice(0, 200)}` };
|
|
33136
33136
|
}
|
|
33137
33137
|
const data = await res.json().catch(() => null);
|
|
33138
|
-
if (!data) return { ok: false, error:
|
|
33138
|
+
if (!data) return { ok: false, error: `Invalid ${params.errorLabel.toLowerCase()} response.` };
|
|
33139
33139
|
return { ok: true, data };
|
|
33140
33140
|
}
|
|
33141
|
-
|
|
33142
|
-
|
|
33143
|
-
|
|
33144
|
-
|
|
33145
|
-
|
|
33146
|
-
|
|
33147
|
-
|
|
33148
|
-
|
|
33141
|
+
|
|
33142
|
+
// src/mcp/tools/session-history/cloud/fetch-session-meta.ts
|
|
33143
|
+
async function fetchCloudSessionMeta(params) {
|
|
33144
|
+
return fetchInternalApiJson({
|
|
33145
|
+
...params,
|
|
33146
|
+
path: `/internal/sessions/${encodeURIComponent(params.sessionId)}/meta`,
|
|
33147
|
+
errorLabel: "Session meta fetch failed"
|
|
33148
|
+
});
|
|
33149
|
+
}
|
|
33150
|
+
|
|
33151
|
+
// src/lib/e2ee/decrypt-stored-e2ee-content.ts
|
|
33152
|
+
function parseJsonObject(raw) {
|
|
33153
|
+
try {
|
|
33154
|
+
const parsed = JSON.parse(raw);
|
|
33155
|
+
if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
33156
|
+
return parsed;
|
|
33157
|
+
}
|
|
33158
|
+
} catch {
|
|
33159
|
+
return null;
|
|
33149
33160
|
}
|
|
33150
|
-
|
|
33151
|
-
if (!data) return { ok: false, error: "Invalid parent prompts response." };
|
|
33152
|
-
return { ok: true, data };
|
|
33161
|
+
return null;
|
|
33153
33162
|
}
|
|
33154
|
-
|
|
33155
|
-
const
|
|
33156
|
-
|
|
33157
|
-
|
|
33158
|
-
|
|
33159
|
-
|
|
33160
|
-
|
|
33161
|
-
|
|
33163
|
+
function storedStringHasE2eeEnvelope(raw) {
|
|
33164
|
+
const record2 = parseJsonObject(raw);
|
|
33165
|
+
return record2 != null && isE2eeEnvelope(record2.ee);
|
|
33166
|
+
}
|
|
33167
|
+
function e2eeKeyIdFromStoredString(raw) {
|
|
33168
|
+
const record2 = parseJsonObject(raw);
|
|
33169
|
+
if (record2 != null && isE2eeEnvelope(record2.ee)) return record2.ee.k;
|
|
33170
|
+
return null;
|
|
33171
|
+
}
|
|
33172
|
+
function decryptStoredE2eeRecord(record2, e2ee) {
|
|
33173
|
+
if (!isE2eeEnvelope(record2.ee)) return record2;
|
|
33174
|
+
if (!e2ee) {
|
|
33175
|
+
throw new Error(`E2EE_REQUIRED:${record2.ee.k}`);
|
|
33176
|
+
}
|
|
33177
|
+
if (record2.ee.k !== e2ee.keyId) {
|
|
33178
|
+
throw new Error(`E2EE_KEY_MISMATCH:encrypted=${record2.ee.k}:cli=${e2ee.keyId}`);
|
|
33179
|
+
}
|
|
33180
|
+
return e2ee.decryptMessage(record2);
|
|
33181
|
+
}
|
|
33182
|
+
function formatCliE2eeDecryptError(error40, e2ee) {
|
|
33183
|
+
const message = error40 instanceof Error ? error40.message : String(error40);
|
|
33184
|
+
const required2 = /^E2EE_REQUIRED:(.+)$/.exec(message.trim());
|
|
33185
|
+
if (required2) {
|
|
33186
|
+
const keyId = required2[1]?.trim() || "unknown";
|
|
33187
|
+
return `Parent session content is encrypted (key ${keyId}) but this bridge was not started with E2EE certificates. Restart the CLI with your E2EE certificate to read fork parent history.`;
|
|
33188
|
+
}
|
|
33189
|
+
const mismatch = /^E2EE_KEY_MISMATCH:encrypted=(.+):cli=(.*)$/.exec(message.trim());
|
|
33190
|
+
if (mismatch) {
|
|
33191
|
+
const encryptedKeyId = mismatch[1]?.trim() || "unknown";
|
|
33192
|
+
const cliKeyId = mismatch[2]?.trim() || e2ee?.keyId || "none";
|
|
33193
|
+
return `Parent session content is encrypted with key ${encryptedKeyId}, but this bridge certificate key is ${cliKeyId}. Use the same E2EE certificate that was used for the parent session.`;
|
|
33194
|
+
}
|
|
33195
|
+
if (message.includes("E2EE key mismatch")) {
|
|
33196
|
+
return `Parent session content could not be decrypted: ${message}`;
|
|
33197
|
+
}
|
|
33198
|
+
return `Parent session content could not be decrypted: ${message}`;
|
|
33199
|
+
}
|
|
33200
|
+
function decryptCliE2eeTranscriptPayload(payload, e2ee) {
|
|
33201
|
+
const record2 = parseJsonObject(payload);
|
|
33202
|
+
if (!record2 || !isE2eeEnvelope(record2.ee)) return payload;
|
|
33203
|
+
const decrypted = decryptStoredE2eeRecord(record2, e2ee);
|
|
33204
|
+
if (typeof decrypted.payload === "string") return decrypted.payload;
|
|
33205
|
+
return JSON.stringify(decrypted.payload ?? decrypted);
|
|
33206
|
+
}
|
|
33207
|
+
function decryptCliE2eeMessageField(payload, field, e2ee) {
|
|
33208
|
+
if (payload == null) return null;
|
|
33209
|
+
const record2 = parseJsonObject(payload);
|
|
33210
|
+
if (!record2 || !isE2eeEnvelope(record2.ee)) return payload;
|
|
33211
|
+
const decrypted = decryptStoredE2eeRecord(record2, e2ee);
|
|
33212
|
+
const value = decrypted[field];
|
|
33213
|
+
if (value == null) return null;
|
|
33214
|
+
return typeof value === "string" ? value : JSON.stringify(value);
|
|
33215
|
+
}
|
|
33216
|
+
|
|
33217
|
+
// src/mcp/tools/session-history/cloud/decrypt-parent-prompt-turns.ts
|
|
33218
|
+
function assertE2eeRuntimeForEnvelope(raw, e2ee) {
|
|
33219
|
+
if (storedStringHasE2eeEnvelope(raw) && !e2ee) {
|
|
33220
|
+
throw new Error(`E2EE_REQUIRED:${e2eeKeyIdFromStoredString(raw) ?? "unknown"}`);
|
|
33221
|
+
}
|
|
33222
|
+
}
|
|
33223
|
+
function decryptParentPromptTurns(turns, e2ee) {
|
|
33224
|
+
return turns.map((turn) => {
|
|
33225
|
+
const promptRaw = typeof turn.promptText === "string" ? turn.promptText : null;
|
|
33226
|
+
const titleRaw = typeof turn.title === "string" ? turn.title : null;
|
|
33227
|
+
if (promptRaw) assertE2eeRuntimeForEnvelope(promptRaw, e2ee);
|
|
33228
|
+
if (titleRaw) assertE2eeRuntimeForEnvelope(titleRaw, e2ee);
|
|
33229
|
+
return {
|
|
33230
|
+
...turn,
|
|
33231
|
+
promptText: decryptCliE2eeMessageField(promptRaw, "prompt", e2ee),
|
|
33232
|
+
title: decryptCliE2eeMessageField(titleRaw, "title", e2ee)
|
|
33233
|
+
};
|
|
33234
|
+
});
|
|
33235
|
+
}
|
|
33236
|
+
|
|
33237
|
+
// src/mcp/tools/session-history/cloud/fetch-parent-prompts.ts
|
|
33238
|
+
async function fetchCloudParentSessionPrompts(params) {
|
|
33239
|
+
const fetched = await fetchInternalApiJson({
|
|
33240
|
+
...params,
|
|
33241
|
+
path: `/internal/sessions/${encodeURIComponent(params.childSessionId)}/parent/prompts`,
|
|
33242
|
+
errorLabel: "Parent prompts fetch failed"
|
|
33243
|
+
});
|
|
33244
|
+
if (!fetched.ok) return fetched;
|
|
33245
|
+
const turns = Array.isArray(fetched.data.turns) ? fetched.data.turns : [];
|
|
33246
|
+
try {
|
|
33247
|
+
const decryptedTurns = decryptParentPromptTurns(turns, params.e2ee);
|
|
33248
|
+
return { ok: true, data: { ...fetched.data, turns: decryptedTurns } };
|
|
33249
|
+
} catch (error40) {
|
|
33250
|
+
return { ok: false, error: formatCliE2eeDecryptError(error40, params.e2ee) };
|
|
33162
33251
|
}
|
|
33163
|
-
|
|
33164
|
-
|
|
33252
|
+
}
|
|
33253
|
+
|
|
33254
|
+
// src/mcp/tools/session-history/cloud/format-parent-transcript-text.ts
|
|
33255
|
+
function formatParentTranscriptText(rows, e2ee) {
|
|
33165
33256
|
const lines = rows.map((row) => {
|
|
33166
33257
|
const kind = typeof row.kind === "string" ? row.kind : "event";
|
|
33167
|
-
const
|
|
33258
|
+
const rawPayload = typeof row.payload === "string" ? row.payload : JSON.stringify(row.payload ?? "");
|
|
33259
|
+
if (storedStringHasE2eeEnvelope(rawPayload) && !e2ee) {
|
|
33260
|
+
throw new Error(`E2EE_REQUIRED:${e2eeKeyIdFromStoredString(rawPayload) ?? "unknown"}`);
|
|
33261
|
+
}
|
|
33262
|
+
const payload = decryptCliE2eeTranscriptPayload(rawPayload, e2ee);
|
|
33168
33263
|
return `[${kind}] ${payload}`;
|
|
33169
33264
|
});
|
|
33170
|
-
return
|
|
33265
|
+
return lines.join("\n");
|
|
33171
33266
|
}
|
|
33267
|
+
|
|
33268
|
+
// src/mcp/tools/session-history/cloud/fetch-parent-transcript.ts
|
|
33269
|
+
async function fetchCloudParentTurnTranscript(params) {
|
|
33270
|
+
const fetched = await fetchInternalApiJson({
|
|
33271
|
+
...params,
|
|
33272
|
+
path: `/internal/sessions/${encodeURIComponent(params.childSessionId)}/parent/turns/${encodeURIComponent(params.turnId)}/transcript`,
|
|
33273
|
+
errorLabel: "Transcript fetch failed"
|
|
33274
|
+
});
|
|
33275
|
+
if (!fetched.ok) return fetched;
|
|
33276
|
+
const rows = Array.isArray(fetched.data.transcript) ? fetched.data.transcript : [];
|
|
33277
|
+
try {
|
|
33278
|
+
return { ok: true, text: formatParentTranscriptText(rows, params.e2ee) };
|
|
33279
|
+
} catch (error40) {
|
|
33280
|
+
return { ok: false, error: formatCliE2eeDecryptError(error40, params.e2ee) };
|
|
33281
|
+
}
|
|
33282
|
+
}
|
|
33283
|
+
|
|
33284
|
+
// src/mcp/tools/session-history/cloud/resolve-parent-session-id.ts
|
|
33172
33285
|
async function resolveParentSessionIdForChild(params) {
|
|
33173
33286
|
const meta = await fetchCloudSessionMeta({
|
|
33174
33287
|
sessionId: params.childSessionId,
|
|
@@ -39200,9 +39313,74 @@ async function warmupAgentCapabilitiesOnConnect(params) {
|
|
|
39200
39313
|
})();
|
|
39201
39314
|
}
|
|
39202
39315
|
|
|
39203
|
-
// src/mcp/tools/session-history/fork-
|
|
39316
|
+
// src/mcp/tools/session-history/fork/mcp-text-result.ts
|
|
39317
|
+
function mcpTextResult(text, isError = false) {
|
|
39318
|
+
return { content: [{ type: "text", text }], ...isError ? { isError: true } : {} };
|
|
39319
|
+
}
|
|
39320
|
+
|
|
39321
|
+
// src/mcp/tools/session-history/fork/call-get-parent-session-turn-transcript.ts
|
|
39322
|
+
async function callGetParentSessionTurnTranscriptTool(ctx, cloud, childSessionId, args) {
|
|
39323
|
+
const turnId = typeof args.turnId === "string" ? args.turnId.trim() : "";
|
|
39324
|
+
if (!turnId) return mcpTextResult("turnId is required.", true);
|
|
39325
|
+
const transcript = await fetchCloudParentTurnTranscript({
|
|
39326
|
+
childSessionId,
|
|
39327
|
+
turnId,
|
|
39328
|
+
cloudApiBaseUrl: cloud.cloudApiBaseUrl,
|
|
39329
|
+
getCloudAccessToken: cloud.getCloudAccessToken,
|
|
39330
|
+
e2ee: ctx.e2ee
|
|
39331
|
+
});
|
|
39332
|
+
if (!transcript.ok) return mcpTextResult(transcript.error, true);
|
|
39333
|
+
return mcpTextResult(transcript.text);
|
|
39334
|
+
}
|
|
39335
|
+
|
|
39336
|
+
// src/mcp/tools/session-history/fork/call-list-parent-session-prompts.ts
|
|
39337
|
+
async function callListParentSessionPromptsTool(ctx, cloud, childSessionId, parentSessionId) {
|
|
39338
|
+
const detail = await fetchCloudParentSessionPrompts({
|
|
39339
|
+
childSessionId,
|
|
39340
|
+
cloudApiBaseUrl: cloud.cloudApiBaseUrl,
|
|
39341
|
+
getCloudAccessToken: cloud.getCloudAccessToken,
|
|
39342
|
+
e2ee: ctx.e2ee
|
|
39343
|
+
});
|
|
39344
|
+
if (!detail.ok) return mcpTextResult(detail.error, true);
|
|
39345
|
+
const turns = Array.isArray(detail.data.turns) ? detail.data.turns : [];
|
|
39346
|
+
const payload = turns.map((t) => ({
|
|
39347
|
+
turnId: typeof t.turnId === "string" ? t.turnId : "",
|
|
39348
|
+
title: typeof t.title === "string" ? t.title : null,
|
|
39349
|
+
status: typeof t.status === "string" ? t.status : null,
|
|
39350
|
+
promptText: typeof t.promptText === "string" ? t.promptText : null
|
|
39351
|
+
}));
|
|
39352
|
+
return mcpTextResult(JSON.stringify({ parentSessionId, turns: payload }, null, 2));
|
|
39353
|
+
}
|
|
39354
|
+
|
|
39355
|
+
// src/mcp/tools/session-history/fork/tool-names.ts
|
|
39204
39356
|
var LIST_PARENT_SESSION_PROMPTS_TOOL = "list_parent_session_prompts";
|
|
39205
39357
|
var GET_PARENT_SESSION_TURN_TRANSCRIPT_TOOL = "get_parent_session_turn_transcript";
|
|
39358
|
+
|
|
39359
|
+
// src/mcp/tools/session-history/fork/call-fork-session-mcp-tool.ts
|
|
39360
|
+
async function callForkSessionMcpTool(ctx, cloud, name, args) {
|
|
39361
|
+
const childSessionId = ctx.sessionId.trim();
|
|
39362
|
+
if (!childSessionId) {
|
|
39363
|
+
return mcpTextResult("sessionId is required.", true);
|
|
39364
|
+
}
|
|
39365
|
+
const parentResolved = await resolveParentSessionIdForChild({
|
|
39366
|
+
childSessionId,
|
|
39367
|
+
cloudApiBaseUrl: cloud.cloudApiBaseUrl,
|
|
39368
|
+
getCloudAccessToken: cloud.getCloudAccessToken
|
|
39369
|
+
});
|
|
39370
|
+
if (!parentResolved.ok) {
|
|
39371
|
+
return mcpTextResult(parentResolved.error, true);
|
|
39372
|
+
}
|
|
39373
|
+
const parentSessionId = parentResolved.parentSessionId;
|
|
39374
|
+
if (name === LIST_PARENT_SESSION_PROMPTS_TOOL) {
|
|
39375
|
+
return callListParentSessionPromptsTool(ctx, cloud, childSessionId, parentSessionId);
|
|
39376
|
+
}
|
|
39377
|
+
if (name === GET_PARENT_SESSION_TURN_TRANSCRIPT_TOOL) {
|
|
39378
|
+
return callGetParentSessionTurnTranscriptTool(ctx, cloud, childSessionId, args);
|
|
39379
|
+
}
|
|
39380
|
+
return mcpTextResult(`Unknown fork session tool: ${name}`, true);
|
|
39381
|
+
}
|
|
39382
|
+
|
|
39383
|
+
// src/mcp/tools/session-history/fork/tool-definitions.ts
|
|
39206
39384
|
var SESSION_ID_SCHEMA = {
|
|
39207
39385
|
type: "string",
|
|
39208
39386
|
description: "Id of this forked (child) session \u2014 not the parent session id. Required on every tool call."
|
|
@@ -39232,57 +39410,11 @@ var FORK_SESSION_MCP_TOOL_DEFINITIONS = [
|
|
|
39232
39410
|
}
|
|
39233
39411
|
}
|
|
39234
39412
|
];
|
|
39235
|
-
|
|
39236
|
-
|
|
39237
|
-
}
|
|
39413
|
+
|
|
39414
|
+
// src/mcp/tools/session-history/fork/is-fork-session-mcp-tool-name.ts
|
|
39238
39415
|
function isForkSessionMcpToolName(name) {
|
|
39239
39416
|
return name === LIST_PARENT_SESSION_PROMPTS_TOOL || name === GET_PARENT_SESSION_TURN_TRANSCRIPT_TOOL;
|
|
39240
39417
|
}
|
|
39241
|
-
async function callForkSessionMcpTool(ctx, cloud, name, args) {
|
|
39242
|
-
const childSessionId = ctx.sessionId.trim();
|
|
39243
|
-
if (!childSessionId) {
|
|
39244
|
-
return textResult("sessionId is required.", true);
|
|
39245
|
-
}
|
|
39246
|
-
const parentResolved = await resolveParentSessionIdForChild({
|
|
39247
|
-
childSessionId,
|
|
39248
|
-
cloudApiBaseUrl: cloud.cloudApiBaseUrl,
|
|
39249
|
-
getCloudAccessToken: cloud.getCloudAccessToken
|
|
39250
|
-
});
|
|
39251
|
-
if (!parentResolved.ok) {
|
|
39252
|
-
return textResult(parentResolved.error, true);
|
|
39253
|
-
}
|
|
39254
|
-
const parentSessionId = parentResolved.parentSessionId;
|
|
39255
|
-
if (name === LIST_PARENT_SESSION_PROMPTS_TOOL) {
|
|
39256
|
-
const detail = await fetchCloudParentSessionPrompts({
|
|
39257
|
-
childSessionId,
|
|
39258
|
-
cloudApiBaseUrl: cloud.cloudApiBaseUrl,
|
|
39259
|
-
getCloudAccessToken: cloud.getCloudAccessToken
|
|
39260
|
-
});
|
|
39261
|
-
if (!detail.ok) return textResult(detail.error, true);
|
|
39262
|
-
const turns = Array.isArray(detail.data.turns) ? detail.data.turns : [];
|
|
39263
|
-
const payload = turns.map((t) => ({
|
|
39264
|
-
turnId: typeof t.turnId === "string" ? t.turnId : "",
|
|
39265
|
-
title: typeof t.title === "string" ? t.title : null,
|
|
39266
|
-
status: typeof t.status === "string" ? t.status : null,
|
|
39267
|
-
promptText: typeof t.promptText === "string" ? t.promptText : null
|
|
39268
|
-
}));
|
|
39269
|
-
return textResult(JSON.stringify({ parentSessionId, turns: payload }, null, 2));
|
|
39270
|
-
}
|
|
39271
|
-
if (name === GET_PARENT_SESSION_TURN_TRANSCRIPT_TOOL) {
|
|
39272
|
-
const turnId = typeof args.turnId === "string" ? args.turnId.trim() : "";
|
|
39273
|
-
if (!turnId) return textResult("turnId is required.", true);
|
|
39274
|
-
const transcript = await fetchCloudParentTurnTranscript({
|
|
39275
|
-
childSessionId,
|
|
39276
|
-
turnId,
|
|
39277
|
-
cloudApiBaseUrl: cloud.cloudApiBaseUrl,
|
|
39278
|
-
getCloudAccessToken: cloud.getCloudAccessToken,
|
|
39279
|
-
e2ee: ctx.e2ee
|
|
39280
|
-
});
|
|
39281
|
-
if (!transcript.ok) return textResult(transcript.error, true);
|
|
39282
|
-
return textResult(transcript.text);
|
|
39283
|
-
}
|
|
39284
|
-
return textResult(`Unknown fork session tool: ${name}`, true);
|
|
39285
|
-
}
|
|
39286
39418
|
|
|
39287
39419
|
// src/mcp/bridge-mcp-tools.ts
|
|
39288
39420
|
function requireCloud(shared) {
|