@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/cli.js
CHANGED
|
@@ -25174,7 +25174,7 @@ var {
|
|
|
25174
25174
|
} = import_index.default;
|
|
25175
25175
|
|
|
25176
25176
|
// src/cli-version.ts
|
|
25177
|
-
var CLI_VERSION = "0.1.
|
|
25177
|
+
var CLI_VERSION = "0.1.48".length > 0 ? "0.1.48" : "0.0.0-dev";
|
|
25178
25178
|
|
|
25179
25179
|
// src/cli/defaults.ts
|
|
25180
25180
|
var DEFAULT_API_URL = process.env.BUILDAUTOMATON_API_URL ?? "https://api.buildautomaton.com";
|
|
@@ -25477,6 +25477,72 @@ function createCliE2eeRuntime(key) {
|
|
|
25477
25477
|
};
|
|
25478
25478
|
}
|
|
25479
25479
|
|
|
25480
|
+
// src/lib/e2ee/decrypt-stored-e2ee-content.ts
|
|
25481
|
+
function parseJsonObject(raw) {
|
|
25482
|
+
try {
|
|
25483
|
+
const parsed = JSON.parse(raw);
|
|
25484
|
+
if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
25485
|
+
return parsed;
|
|
25486
|
+
}
|
|
25487
|
+
} catch {
|
|
25488
|
+
return null;
|
|
25489
|
+
}
|
|
25490
|
+
return null;
|
|
25491
|
+
}
|
|
25492
|
+
function storedStringHasE2eeEnvelope(raw) {
|
|
25493
|
+
const record2 = parseJsonObject(raw);
|
|
25494
|
+
return record2 != null && isE2eeEnvelope(record2.ee);
|
|
25495
|
+
}
|
|
25496
|
+
function e2eeKeyIdFromStoredString(raw) {
|
|
25497
|
+
const record2 = parseJsonObject(raw);
|
|
25498
|
+
if (record2 != null && isE2eeEnvelope(record2.ee)) return record2.ee.k;
|
|
25499
|
+
return null;
|
|
25500
|
+
}
|
|
25501
|
+
function decryptStoredE2eeRecord(record2, e2ee) {
|
|
25502
|
+
if (!isE2eeEnvelope(record2.ee)) return record2;
|
|
25503
|
+
if (!e2ee) {
|
|
25504
|
+
throw new Error(`E2EE_REQUIRED:${record2.ee.k}`);
|
|
25505
|
+
}
|
|
25506
|
+
if (record2.ee.k !== e2ee.keyId) {
|
|
25507
|
+
throw new Error(`E2EE_KEY_MISMATCH:encrypted=${record2.ee.k}:cli=${e2ee.keyId}`);
|
|
25508
|
+
}
|
|
25509
|
+
return e2ee.decryptMessage(record2);
|
|
25510
|
+
}
|
|
25511
|
+
function formatCliE2eeDecryptError(error40, e2ee) {
|
|
25512
|
+
const message = error40 instanceof Error ? error40.message : String(error40);
|
|
25513
|
+
const required2 = /^E2EE_REQUIRED:(.+)$/.exec(message.trim());
|
|
25514
|
+
if (required2) {
|
|
25515
|
+
const keyId = required2[1]?.trim() || "unknown";
|
|
25516
|
+
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.`;
|
|
25517
|
+
}
|
|
25518
|
+
const mismatch = /^E2EE_KEY_MISMATCH:encrypted=(.+):cli=(.*)$/.exec(message.trim());
|
|
25519
|
+
if (mismatch) {
|
|
25520
|
+
const encryptedKeyId = mismatch[1]?.trim() || "unknown";
|
|
25521
|
+
const cliKeyId = mismatch[2]?.trim() || e2ee?.keyId || "none";
|
|
25522
|
+
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.`;
|
|
25523
|
+
}
|
|
25524
|
+
if (message.includes("E2EE key mismatch")) {
|
|
25525
|
+
return `Parent session content could not be decrypted: ${message}`;
|
|
25526
|
+
}
|
|
25527
|
+
return `Parent session content could not be decrypted: ${message}`;
|
|
25528
|
+
}
|
|
25529
|
+
function decryptCliE2eeTranscriptPayload(payload, e2ee) {
|
|
25530
|
+
const record2 = parseJsonObject(payload);
|
|
25531
|
+
if (!record2 || !isE2eeEnvelope(record2.ee)) return payload;
|
|
25532
|
+
const decrypted = decryptStoredE2eeRecord(record2, e2ee);
|
|
25533
|
+
if (typeof decrypted.payload === "string") return decrypted.payload;
|
|
25534
|
+
return JSON.stringify(decrypted.payload ?? decrypted);
|
|
25535
|
+
}
|
|
25536
|
+
function decryptCliE2eeMessageField(payload, field, e2ee) {
|
|
25537
|
+
if (payload == null) return null;
|
|
25538
|
+
const record2 = parseJsonObject(payload);
|
|
25539
|
+
if (!record2 || !isE2eeEnvelope(record2.ee)) return payload;
|
|
25540
|
+
const decrypted = decryptStoredE2eeRecord(record2, e2ee);
|
|
25541
|
+
const value = decrypted[field];
|
|
25542
|
+
if (value == null) return null;
|
|
25543
|
+
return typeof value === "string" ? value : JSON.stringify(value);
|
|
25544
|
+
}
|
|
25545
|
+
|
|
25480
25546
|
// src/e2e-certificates/certificates.ts
|
|
25481
25547
|
var E2E_CERTIFICATE_ALGORITHM = "A1";
|
|
25482
25548
|
var CERTIFICATE_FILE_EXTENSIONS = /* @__PURE__ */ new Set([".pem", ".key", ".crt"]);
|
|
@@ -36081,54 +36147,101 @@ function buildForkedSessionAgentPrompt(userPrompt, childSessionId, parentSession
|
|
|
36081
36147
|
].join("\n");
|
|
36082
36148
|
}
|
|
36083
36149
|
|
|
36084
|
-
// src/mcp/tools/session-history/
|
|
36150
|
+
// src/mcp/tools/session-history/cloud/internal-api.ts
|
|
36085
36151
|
function internalApiBase(cloudApiBaseUrl) {
|
|
36086
36152
|
return cloudApiBaseUrl.replace(/\/+$/, "");
|
|
36087
36153
|
}
|
|
36088
|
-
async function
|
|
36154
|
+
async function fetchInternalApiJson(params) {
|
|
36089
36155
|
const token = params.getCloudAccessToken();
|
|
36090
36156
|
if (!token) return { ok: false, error: "Missing cloud access token." };
|
|
36091
|
-
const url2 = `${internalApiBase(params.cloudApiBaseUrl)}
|
|
36157
|
+
const url2 = `${internalApiBase(params.cloudApiBaseUrl)}${params.path}`;
|
|
36092
36158
|
const res = await fetch(url2, { headers: { Authorization: `Bearer ${token}` } });
|
|
36093
36159
|
if (!res.ok) {
|
|
36094
36160
|
const t = await res.text().catch(() => "");
|
|
36095
|
-
return { ok: false, error:
|
|
36161
|
+
return { ok: false, error: `${params.errorLabel} (${res.status}): ${t.slice(0, 200)}` };
|
|
36096
36162
|
}
|
|
36097
36163
|
const data = await res.json().catch(() => null);
|
|
36098
|
-
if (!data) return { ok: false, error:
|
|
36164
|
+
if (!data) return { ok: false, error: `Invalid ${params.errorLabel.toLowerCase()} response.` };
|
|
36099
36165
|
return { ok: true, data };
|
|
36100
36166
|
}
|
|
36101
|
-
|
|
36102
|
-
|
|
36103
|
-
|
|
36104
|
-
|
|
36105
|
-
|
|
36106
|
-
|
|
36107
|
-
|
|
36108
|
-
|
|
36167
|
+
|
|
36168
|
+
// src/mcp/tools/session-history/cloud/fetch-session-meta.ts
|
|
36169
|
+
async function fetchCloudSessionMeta(params) {
|
|
36170
|
+
return fetchInternalApiJson({
|
|
36171
|
+
...params,
|
|
36172
|
+
path: `/internal/sessions/${encodeURIComponent(params.sessionId)}/meta`,
|
|
36173
|
+
errorLabel: "Session meta fetch failed"
|
|
36174
|
+
});
|
|
36175
|
+
}
|
|
36176
|
+
|
|
36177
|
+
// src/mcp/tools/session-history/cloud/decrypt-parent-prompt-turns.ts
|
|
36178
|
+
function assertE2eeRuntimeForEnvelope(raw, e2ee) {
|
|
36179
|
+
if (storedStringHasE2eeEnvelope(raw) && !e2ee) {
|
|
36180
|
+
throw new Error(`E2EE_REQUIRED:${e2eeKeyIdFromStoredString(raw) ?? "unknown"}`);
|
|
36109
36181
|
}
|
|
36110
|
-
const data = await res.json().catch(() => null);
|
|
36111
|
-
if (!data) return { ok: false, error: "Invalid parent prompts response." };
|
|
36112
|
-
return { ok: true, data };
|
|
36113
36182
|
}
|
|
36114
|
-
|
|
36115
|
-
|
|
36116
|
-
|
|
36117
|
-
|
|
36118
|
-
|
|
36119
|
-
|
|
36120
|
-
|
|
36121
|
-
|
|
36183
|
+
function decryptParentPromptTurns(turns, e2ee) {
|
|
36184
|
+
return turns.map((turn) => {
|
|
36185
|
+
const promptRaw = typeof turn.promptText === "string" ? turn.promptText : null;
|
|
36186
|
+
const titleRaw = typeof turn.title === "string" ? turn.title : null;
|
|
36187
|
+
if (promptRaw) assertE2eeRuntimeForEnvelope(promptRaw, e2ee);
|
|
36188
|
+
if (titleRaw) assertE2eeRuntimeForEnvelope(titleRaw, e2ee);
|
|
36189
|
+
return {
|
|
36190
|
+
...turn,
|
|
36191
|
+
promptText: decryptCliE2eeMessageField(promptRaw, "prompt", e2ee),
|
|
36192
|
+
title: decryptCliE2eeMessageField(titleRaw, "title", e2ee)
|
|
36193
|
+
};
|
|
36194
|
+
});
|
|
36195
|
+
}
|
|
36196
|
+
|
|
36197
|
+
// src/mcp/tools/session-history/cloud/fetch-parent-prompts.ts
|
|
36198
|
+
async function fetchCloudParentSessionPrompts(params) {
|
|
36199
|
+
const fetched = await fetchInternalApiJson({
|
|
36200
|
+
...params,
|
|
36201
|
+
path: `/internal/sessions/${encodeURIComponent(params.childSessionId)}/parent/prompts`,
|
|
36202
|
+
errorLabel: "Parent prompts fetch failed"
|
|
36203
|
+
});
|
|
36204
|
+
if (!fetched.ok) return fetched;
|
|
36205
|
+
const turns = Array.isArray(fetched.data.turns) ? fetched.data.turns : [];
|
|
36206
|
+
try {
|
|
36207
|
+
const decryptedTurns = decryptParentPromptTurns(turns, params.e2ee);
|
|
36208
|
+
return { ok: true, data: { ...fetched.data, turns: decryptedTurns } };
|
|
36209
|
+
} catch (error40) {
|
|
36210
|
+
return { ok: false, error: formatCliE2eeDecryptError(error40, params.e2ee) };
|
|
36122
36211
|
}
|
|
36123
|
-
|
|
36124
|
-
|
|
36212
|
+
}
|
|
36213
|
+
|
|
36214
|
+
// src/mcp/tools/session-history/cloud/format-parent-transcript-text.ts
|
|
36215
|
+
function formatParentTranscriptText(rows, e2ee) {
|
|
36125
36216
|
const lines = rows.map((row) => {
|
|
36126
36217
|
const kind = typeof row.kind === "string" ? row.kind : "event";
|
|
36127
|
-
const
|
|
36218
|
+
const rawPayload = typeof row.payload === "string" ? row.payload : JSON.stringify(row.payload ?? "");
|
|
36219
|
+
if (storedStringHasE2eeEnvelope(rawPayload) && !e2ee) {
|
|
36220
|
+
throw new Error(`E2EE_REQUIRED:${e2eeKeyIdFromStoredString(rawPayload) ?? "unknown"}`);
|
|
36221
|
+
}
|
|
36222
|
+
const payload = decryptCliE2eeTranscriptPayload(rawPayload, e2ee);
|
|
36128
36223
|
return `[${kind}] ${payload}`;
|
|
36129
36224
|
});
|
|
36130
|
-
return
|
|
36225
|
+
return lines.join("\n");
|
|
36226
|
+
}
|
|
36227
|
+
|
|
36228
|
+
// src/mcp/tools/session-history/cloud/fetch-parent-transcript.ts
|
|
36229
|
+
async function fetchCloudParentTurnTranscript(params) {
|
|
36230
|
+
const fetched = await fetchInternalApiJson({
|
|
36231
|
+
...params,
|
|
36232
|
+
path: `/internal/sessions/${encodeURIComponent(params.childSessionId)}/parent/turns/${encodeURIComponent(params.turnId)}/transcript`,
|
|
36233
|
+
errorLabel: "Transcript fetch failed"
|
|
36234
|
+
});
|
|
36235
|
+
if (!fetched.ok) return fetched;
|
|
36236
|
+
const rows = Array.isArray(fetched.data.transcript) ? fetched.data.transcript : [];
|
|
36237
|
+
try {
|
|
36238
|
+
return { ok: true, text: formatParentTranscriptText(rows, params.e2ee) };
|
|
36239
|
+
} catch (error40) {
|
|
36240
|
+
return { ok: false, error: formatCliE2eeDecryptError(error40, params.e2ee) };
|
|
36241
|
+
}
|
|
36131
36242
|
}
|
|
36243
|
+
|
|
36244
|
+
// src/mcp/tools/session-history/cloud/resolve-parent-session-id.ts
|
|
36132
36245
|
async function resolveParentSessionIdForChild(params) {
|
|
36133
36246
|
const meta = await fetchCloudSessionMeta({
|
|
36134
36247
|
sessionId: params.childSessionId,
|
|
@@ -42423,9 +42536,74 @@ async function warmupAgentCapabilitiesOnConnect(params) {
|
|
|
42423
42536
|
})();
|
|
42424
42537
|
}
|
|
42425
42538
|
|
|
42426
|
-
// src/mcp/tools/session-history/fork-
|
|
42539
|
+
// src/mcp/tools/session-history/fork/mcp-text-result.ts
|
|
42540
|
+
function mcpTextResult(text, isError = false) {
|
|
42541
|
+
return { content: [{ type: "text", text }], ...isError ? { isError: true } : {} };
|
|
42542
|
+
}
|
|
42543
|
+
|
|
42544
|
+
// src/mcp/tools/session-history/fork/call-get-parent-session-turn-transcript.ts
|
|
42545
|
+
async function callGetParentSessionTurnTranscriptTool(ctx, cloud, childSessionId, args) {
|
|
42546
|
+
const turnId = typeof args.turnId === "string" ? args.turnId.trim() : "";
|
|
42547
|
+
if (!turnId) return mcpTextResult("turnId is required.", true);
|
|
42548
|
+
const transcript = await fetchCloudParentTurnTranscript({
|
|
42549
|
+
childSessionId,
|
|
42550
|
+
turnId,
|
|
42551
|
+
cloudApiBaseUrl: cloud.cloudApiBaseUrl,
|
|
42552
|
+
getCloudAccessToken: cloud.getCloudAccessToken,
|
|
42553
|
+
e2ee: ctx.e2ee
|
|
42554
|
+
});
|
|
42555
|
+
if (!transcript.ok) return mcpTextResult(transcript.error, true);
|
|
42556
|
+
return mcpTextResult(transcript.text);
|
|
42557
|
+
}
|
|
42558
|
+
|
|
42559
|
+
// src/mcp/tools/session-history/fork/call-list-parent-session-prompts.ts
|
|
42560
|
+
async function callListParentSessionPromptsTool(ctx, cloud, childSessionId, parentSessionId) {
|
|
42561
|
+
const detail = await fetchCloudParentSessionPrompts({
|
|
42562
|
+
childSessionId,
|
|
42563
|
+
cloudApiBaseUrl: cloud.cloudApiBaseUrl,
|
|
42564
|
+
getCloudAccessToken: cloud.getCloudAccessToken,
|
|
42565
|
+
e2ee: ctx.e2ee
|
|
42566
|
+
});
|
|
42567
|
+
if (!detail.ok) return mcpTextResult(detail.error, true);
|
|
42568
|
+
const turns = Array.isArray(detail.data.turns) ? detail.data.turns : [];
|
|
42569
|
+
const payload = turns.map((t) => ({
|
|
42570
|
+
turnId: typeof t.turnId === "string" ? t.turnId : "",
|
|
42571
|
+
title: typeof t.title === "string" ? t.title : null,
|
|
42572
|
+
status: typeof t.status === "string" ? t.status : null,
|
|
42573
|
+
promptText: typeof t.promptText === "string" ? t.promptText : null
|
|
42574
|
+
}));
|
|
42575
|
+
return mcpTextResult(JSON.stringify({ parentSessionId, turns: payload }, null, 2));
|
|
42576
|
+
}
|
|
42577
|
+
|
|
42578
|
+
// src/mcp/tools/session-history/fork/tool-names.ts
|
|
42427
42579
|
var LIST_PARENT_SESSION_PROMPTS_TOOL = "list_parent_session_prompts";
|
|
42428
42580
|
var GET_PARENT_SESSION_TURN_TRANSCRIPT_TOOL = "get_parent_session_turn_transcript";
|
|
42581
|
+
|
|
42582
|
+
// src/mcp/tools/session-history/fork/call-fork-session-mcp-tool.ts
|
|
42583
|
+
async function callForkSessionMcpTool(ctx, cloud, name, args) {
|
|
42584
|
+
const childSessionId = ctx.sessionId.trim();
|
|
42585
|
+
if (!childSessionId) {
|
|
42586
|
+
return mcpTextResult("sessionId is required.", true);
|
|
42587
|
+
}
|
|
42588
|
+
const parentResolved = await resolveParentSessionIdForChild({
|
|
42589
|
+
childSessionId,
|
|
42590
|
+
cloudApiBaseUrl: cloud.cloudApiBaseUrl,
|
|
42591
|
+
getCloudAccessToken: cloud.getCloudAccessToken
|
|
42592
|
+
});
|
|
42593
|
+
if (!parentResolved.ok) {
|
|
42594
|
+
return mcpTextResult(parentResolved.error, true);
|
|
42595
|
+
}
|
|
42596
|
+
const parentSessionId = parentResolved.parentSessionId;
|
|
42597
|
+
if (name === LIST_PARENT_SESSION_PROMPTS_TOOL) {
|
|
42598
|
+
return callListParentSessionPromptsTool(ctx, cloud, childSessionId, parentSessionId);
|
|
42599
|
+
}
|
|
42600
|
+
if (name === GET_PARENT_SESSION_TURN_TRANSCRIPT_TOOL) {
|
|
42601
|
+
return callGetParentSessionTurnTranscriptTool(ctx, cloud, childSessionId, args);
|
|
42602
|
+
}
|
|
42603
|
+
return mcpTextResult(`Unknown fork session tool: ${name}`, true);
|
|
42604
|
+
}
|
|
42605
|
+
|
|
42606
|
+
// src/mcp/tools/session-history/fork/tool-definitions.ts
|
|
42429
42607
|
var SESSION_ID_SCHEMA = {
|
|
42430
42608
|
type: "string",
|
|
42431
42609
|
description: "Id of this forked (child) session \u2014 not the parent session id. Required on every tool call."
|
|
@@ -42455,57 +42633,11 @@ var FORK_SESSION_MCP_TOOL_DEFINITIONS = [
|
|
|
42455
42633
|
}
|
|
42456
42634
|
}
|
|
42457
42635
|
];
|
|
42458
|
-
|
|
42459
|
-
|
|
42460
|
-
}
|
|
42636
|
+
|
|
42637
|
+
// src/mcp/tools/session-history/fork/is-fork-session-mcp-tool-name.ts
|
|
42461
42638
|
function isForkSessionMcpToolName(name) {
|
|
42462
42639
|
return name === LIST_PARENT_SESSION_PROMPTS_TOOL || name === GET_PARENT_SESSION_TURN_TRANSCRIPT_TOOL;
|
|
42463
42640
|
}
|
|
42464
|
-
async function callForkSessionMcpTool(ctx, cloud, name, args) {
|
|
42465
|
-
const childSessionId = ctx.sessionId.trim();
|
|
42466
|
-
if (!childSessionId) {
|
|
42467
|
-
return textResult("sessionId is required.", true);
|
|
42468
|
-
}
|
|
42469
|
-
const parentResolved = await resolveParentSessionIdForChild({
|
|
42470
|
-
childSessionId,
|
|
42471
|
-
cloudApiBaseUrl: cloud.cloudApiBaseUrl,
|
|
42472
|
-
getCloudAccessToken: cloud.getCloudAccessToken
|
|
42473
|
-
});
|
|
42474
|
-
if (!parentResolved.ok) {
|
|
42475
|
-
return textResult(parentResolved.error, true);
|
|
42476
|
-
}
|
|
42477
|
-
const parentSessionId = parentResolved.parentSessionId;
|
|
42478
|
-
if (name === LIST_PARENT_SESSION_PROMPTS_TOOL) {
|
|
42479
|
-
const detail = await fetchCloudParentSessionPrompts({
|
|
42480
|
-
childSessionId,
|
|
42481
|
-
cloudApiBaseUrl: cloud.cloudApiBaseUrl,
|
|
42482
|
-
getCloudAccessToken: cloud.getCloudAccessToken
|
|
42483
|
-
});
|
|
42484
|
-
if (!detail.ok) return textResult(detail.error, true);
|
|
42485
|
-
const turns = Array.isArray(detail.data.turns) ? detail.data.turns : [];
|
|
42486
|
-
const payload = turns.map((t) => ({
|
|
42487
|
-
turnId: typeof t.turnId === "string" ? t.turnId : "",
|
|
42488
|
-
title: typeof t.title === "string" ? t.title : null,
|
|
42489
|
-
status: typeof t.status === "string" ? t.status : null,
|
|
42490
|
-
promptText: typeof t.promptText === "string" ? t.promptText : null
|
|
42491
|
-
}));
|
|
42492
|
-
return textResult(JSON.stringify({ parentSessionId, turns: payload }, null, 2));
|
|
42493
|
-
}
|
|
42494
|
-
if (name === GET_PARENT_SESSION_TURN_TRANSCRIPT_TOOL) {
|
|
42495
|
-
const turnId = typeof args.turnId === "string" ? args.turnId.trim() : "";
|
|
42496
|
-
if (!turnId) return textResult("turnId is required.", true);
|
|
42497
|
-
const transcript = await fetchCloudParentTurnTranscript({
|
|
42498
|
-
childSessionId,
|
|
42499
|
-
turnId,
|
|
42500
|
-
cloudApiBaseUrl: cloud.cloudApiBaseUrl,
|
|
42501
|
-
getCloudAccessToken: cloud.getCloudAccessToken,
|
|
42502
|
-
e2ee: ctx.e2ee
|
|
42503
|
-
});
|
|
42504
|
-
if (!transcript.ok) return textResult(transcript.error, true);
|
|
42505
|
-
return textResult(transcript.text);
|
|
42506
|
-
}
|
|
42507
|
-
return textResult(`Unknown fork session tool: ${name}`, true);
|
|
42508
|
-
}
|
|
42509
42641
|
|
|
42510
42642
|
// src/mcp/bridge-mcp-tools.ts
|
|
42511
42643
|
function requireCloud(shared) {
|