@buildautomaton/cli 0.1.16 → 0.1.18
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 +743 -84
- package/dist/cli.js.map +4 -4
- package/dist/index.js +749 -110
- package/dist/index.js.map +4 -4
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -28776,6 +28776,498 @@ async function collectTurnGitDiffFromPreTurnSnapshot(options) {
|
|
|
28776
28776
|
}
|
|
28777
28777
|
}
|
|
28778
28778
|
|
|
28779
|
+
// ../types/dist/index.js
|
|
28780
|
+
init_zod();
|
|
28781
|
+
init_zod();
|
|
28782
|
+
init_zod();
|
|
28783
|
+
init_zod();
|
|
28784
|
+
init_zod();
|
|
28785
|
+
init_zod();
|
|
28786
|
+
init_zod();
|
|
28787
|
+
init_zod();
|
|
28788
|
+
init_zod();
|
|
28789
|
+
init_zod();
|
|
28790
|
+
init_zod();
|
|
28791
|
+
init_zod();
|
|
28792
|
+
var WorkItemStatusSchema = external_exports.enum(["backlog", "in-progress", "completed"]);
|
|
28793
|
+
var WorkItemProgressSchema = external_exports.object({
|
|
28794
|
+
remainingCriteria: external_exports.array(external_exports.string()).default([]),
|
|
28795
|
+
openQuestions: external_exports.array(external_exports.string()).default([]),
|
|
28796
|
+
assignedTo: external_exports.enum(["agent", "human-product", "human-expert"]).optional()
|
|
28797
|
+
});
|
|
28798
|
+
var ChangeSchema = external_exports.object({
|
|
28799
|
+
id: external_exports.string(),
|
|
28800
|
+
description: external_exports.string(),
|
|
28801
|
+
buildingBlockId: external_exports.string(),
|
|
28802
|
+
buildingBlockType: external_exports.enum(["function", "workflow", "connector", "ui-component", "app-fragment", "application", "project"]),
|
|
28803
|
+
action: external_exports.enum(["create", "update", "split", "combine"])
|
|
28804
|
+
});
|
|
28805
|
+
var CompletionCriterionSchema = external_exports.object({
|
|
28806
|
+
id: external_exports.string(),
|
|
28807
|
+
description: external_exports.string(),
|
|
28808
|
+
type: external_exports.enum(["write-code", "write-tests", "verify-tests", "other"]),
|
|
28809
|
+
verified: external_exports.boolean().default(false)
|
|
28810
|
+
});
|
|
28811
|
+
var WorkItemPrioritySchema = external_exports.enum(["low", "medium", "high", "critical"]);
|
|
28812
|
+
var IterationPhaseSchema = external_exports.enum(["analysis", "implementation", "verify", "reprioritize", "completed"]);
|
|
28813
|
+
var WorkItemDependencySchema = external_exports.object({
|
|
28814
|
+
type: external_exports.enum(["work-item"]),
|
|
28815
|
+
id: external_exports.string()
|
|
28816
|
+
});
|
|
28817
|
+
var WorkItemSchema = external_exports.object({
|
|
28818
|
+
id: external_exports.string(),
|
|
28819
|
+
sessionId: external_exports.string().optional(),
|
|
28820
|
+
summary: external_exports.string().optional(),
|
|
28821
|
+
description: external_exports.string(),
|
|
28822
|
+
status: WorkItemStatusSchema,
|
|
28823
|
+
buildingBlockId: external_exports.string().optional(),
|
|
28824
|
+
buildingBlockType: external_exports.enum(["function", "workflow", "connector", "ui-component", "app-fragment", "application", "project"]),
|
|
28825
|
+
changes: external_exports.array(ChangeSchema).default([]),
|
|
28826
|
+
completionCriteria: external_exports.array(CompletionCriterionSchema).default([]),
|
|
28827
|
+
priority: WorkItemPrioritySchema.default("medium"),
|
|
28828
|
+
dependencies: external_exports.array(WorkItemDependencySchema).default([]),
|
|
28829
|
+
assignedToUserId: external_exports.string().optional()
|
|
28830
|
+
});
|
|
28831
|
+
var UserWorkspaceProfileSchema = external_exports.object({
|
|
28832
|
+
id: external_exports.string(),
|
|
28833
|
+
workspaceId: external_exports.string(),
|
|
28834
|
+
userId: external_exports.string(),
|
|
28835
|
+
roleDescription: external_exports.string().optional(),
|
|
28836
|
+
expertiseAreas: external_exports.array(external_exports.string()),
|
|
28837
|
+
preferences: external_exports.record(external_exports.unknown()).optional(),
|
|
28838
|
+
learnings: external_exports.array(external_exports.string())
|
|
28839
|
+
});
|
|
28840
|
+
var WorkspaceOwnerInfoSchema = external_exports.object({
|
|
28841
|
+
ownerId: external_exports.string(),
|
|
28842
|
+
ownerName: external_exports.string().optional(),
|
|
28843
|
+
ownerEmail: external_exports.string().optional(),
|
|
28844
|
+
ownerProfilePictureUrl: external_exports.string().optional()
|
|
28845
|
+
});
|
|
28846
|
+
var WorkspaceRuntimeEntrySchema = external_exports.object({
|
|
28847
|
+
workspaceId: external_exports.string(),
|
|
28848
|
+
path: external_exports.string(),
|
|
28849
|
+
name: external_exports.string().optional(),
|
|
28850
|
+
owner: WorkspaceOwnerInfoSchema.optional(),
|
|
28851
|
+
isOwner: external_exports.boolean().optional()
|
|
28852
|
+
});
|
|
28853
|
+
var ProjectContextSchema = external_exports.object({
|
|
28854
|
+
projectId: external_exports.string(),
|
|
28855
|
+
context: external_exports.record(external_exports.unknown()).default({}),
|
|
28856
|
+
updatedAt: external_exports.string()
|
|
28857
|
+
});
|
|
28858
|
+
var WebSocketMessageTypeSchema = external_exports.enum([
|
|
28859
|
+
"plan-update",
|
|
28860
|
+
"work-item-update",
|
|
28861
|
+
"work-item-added",
|
|
28862
|
+
"work-item-removed",
|
|
28863
|
+
"project-processing-start",
|
|
28864
|
+
"project-processing-update",
|
|
28865
|
+
"project-processing-complete",
|
|
28866
|
+
"project-processing-error",
|
|
28867
|
+
"file-tool-request",
|
|
28868
|
+
"file-tool-response",
|
|
28869
|
+
"file-generated"
|
|
28870
|
+
]);
|
|
28871
|
+
var WebSocketMessageSchema = external_exports.object({
|
|
28872
|
+
type: WebSocketMessageTypeSchema,
|
|
28873
|
+
contextId: external_exports.string().optional(),
|
|
28874
|
+
data: external_exports.any().optional(),
|
|
28875
|
+
error: external_exports.string().optional()
|
|
28876
|
+
});
|
|
28877
|
+
var CheckpointKindSchema = external_exports.enum(["daily", "weekly", "overall"]);
|
|
28878
|
+
var CheckpointSummarySchema = external_exports.object({
|
|
28879
|
+
id: external_exports.string(),
|
|
28880
|
+
kind: CheckpointKindSchema,
|
|
28881
|
+
/** ISO date for daily (YYYY-MM-DD), ISO week for weekly, null for overall */
|
|
28882
|
+
periodKey: external_exports.string().nullable(),
|
|
28883
|
+
summary: external_exports.string(),
|
|
28884
|
+
createdAt: external_exports.string(),
|
|
28885
|
+
updatedAt: external_exports.string()
|
|
28886
|
+
});
|
|
28887
|
+
var ThreadMetaSchema = external_exports.object({
|
|
28888
|
+
threadId: external_exports.string(),
|
|
28889
|
+
workspaceId: external_exports.string(),
|
|
28890
|
+
/** External source (e.g. slack, discord); null if internal-only */
|
|
28891
|
+
externalSource: external_exports.string().nullable(),
|
|
28892
|
+
/** Id in the external system (e.g. channel_id + thread_ts) */
|
|
28893
|
+
externalId: external_exports.string().nullable(),
|
|
28894
|
+
title: external_exports.string().optional(),
|
|
28895
|
+
createdAt: external_exports.string(),
|
|
28896
|
+
updatedAt: external_exports.string()
|
|
28897
|
+
});
|
|
28898
|
+
var ThreadMessageSchema = external_exports.object({
|
|
28899
|
+
messageId: external_exports.string(),
|
|
28900
|
+
threadId: external_exports.string(),
|
|
28901
|
+
/** Role: user, assistant, system */
|
|
28902
|
+
role: external_exports.enum(["user", "assistant", "system"]),
|
|
28903
|
+
content: external_exports.string(),
|
|
28904
|
+
/** Optional reference to a ContentItem (e.g. doc, Notion page) */
|
|
28905
|
+
contentItemId: external_exports.string().nullable(),
|
|
28906
|
+
/** External message id if synced from external chat */
|
|
28907
|
+
externalId: external_exports.string().nullable(),
|
|
28908
|
+
createdAt: external_exports.string(),
|
|
28909
|
+
updatedAt: external_exports.string()
|
|
28910
|
+
});
|
|
28911
|
+
var ThreadCheckpointSummarySchema = CheckpointSummarySchema.extend({
|
|
28912
|
+
threadId: external_exports.string()
|
|
28913
|
+
});
|
|
28914
|
+
var ContentSourceSchema = external_exports.enum(["notion", "doc", "slack_thread", "other"]);
|
|
28915
|
+
var ContentItemMetaSchema = external_exports.object({
|
|
28916
|
+
contentId: external_exports.string(),
|
|
28917
|
+
workspaceId: external_exports.string(),
|
|
28918
|
+
source: ContentSourceSchema,
|
|
28919
|
+
/** Id in the external system (e.g. Notion page id, doc url) */
|
|
28920
|
+
externalId: external_exports.string(),
|
|
28921
|
+
/** If source is slack_thread, points to Thread DO id */
|
|
28922
|
+
threadId: external_exports.string().nullable(),
|
|
28923
|
+
title: external_exports.string().optional(),
|
|
28924
|
+
createdAt: external_exports.string(),
|
|
28925
|
+
updatedAt: external_exports.string()
|
|
28926
|
+
});
|
|
28927
|
+
var ContentStorageRefSchema = external_exports.object({
|
|
28928
|
+
storageKey: external_exports.string(),
|
|
28929
|
+
/** Optional: mime type or format hint */
|
|
28930
|
+
contentType: external_exports.string().optional()
|
|
28931
|
+
});
|
|
28932
|
+
var ContentCheckpointSummarySchema = CheckpointSummarySchema.extend({
|
|
28933
|
+
contentId: external_exports.string()
|
|
28934
|
+
});
|
|
28935
|
+
var StoryMetaSchema = external_exports.object({
|
|
28936
|
+
storyId: external_exports.string(),
|
|
28937
|
+
workspaceId: external_exports.string(),
|
|
28938
|
+
title: external_exports.string(),
|
|
28939
|
+
/** feature | bug | epic */
|
|
28940
|
+
kind: external_exports.enum(["feature", "bug", "epic"]).default("feature"),
|
|
28941
|
+
createdAt: external_exports.string(),
|
|
28942
|
+
updatedAt: external_exports.string()
|
|
28943
|
+
});
|
|
28944
|
+
var StoryContentItemRefSchema = external_exports.object({
|
|
28945
|
+
id: external_exports.string(),
|
|
28946
|
+
storyId: external_exports.string(),
|
|
28947
|
+
contentItemId: external_exports.string(),
|
|
28948
|
+
/** Snapshot summary when added to story (or updated) */
|
|
28949
|
+
summary: external_exports.string(),
|
|
28950
|
+
orderIndex: external_exports.number().default(0),
|
|
28951
|
+
createdAt: external_exports.string(),
|
|
28952
|
+
updatedAt: external_exports.string()
|
|
28953
|
+
});
|
|
28954
|
+
var StoryCheckpointSummarySchema = CheckpointSummarySchema.extend({
|
|
28955
|
+
storyId: external_exports.string()
|
|
28956
|
+
});
|
|
28957
|
+
var BUILTIN_SESSION_CHANGE_SUMMARY_FOLLOW_UP_CATALOG_PROMPT_ID = "__builtin_change_summary__";
|
|
28958
|
+
var SessionMetaSchema = external_exports.object({
|
|
28959
|
+
sessionId: external_exports.string(),
|
|
28960
|
+
workspaceId: external_exports.string(),
|
|
28961
|
+
title: external_exports.string().optional(),
|
|
28962
|
+
createdAt: external_exports.string(),
|
|
28963
|
+
updatedAt: external_exports.string()
|
|
28964
|
+
});
|
|
28965
|
+
var SessionPromptSchema = external_exports.object({
|
|
28966
|
+
id: external_exports.string(),
|
|
28967
|
+
sessionId: external_exports.string(),
|
|
28968
|
+
/** text | resource */
|
|
28969
|
+
type: external_exports.enum(["text", "resource"]).default("text"),
|
|
28970
|
+
text: external_exports.string().optional(),
|
|
28971
|
+
resourceUri: external_exports.string().optional(),
|
|
28972
|
+
createdAt: external_exports.string()
|
|
28973
|
+
});
|
|
28974
|
+
var SessionResponseSchema = external_exports.object({
|
|
28975
|
+
id: external_exports.string(),
|
|
28976
|
+
sessionId: external_exports.string(),
|
|
28977
|
+
promptId: external_exports.string(),
|
|
28978
|
+
/** message | completion */
|
|
28979
|
+
kind: external_exports.enum(["message", "completion"]),
|
|
28980
|
+
content: external_exports.string().optional(),
|
|
28981
|
+
/** For completion: stopReason etc. */
|
|
28982
|
+
stopReason: external_exports.string().optional(),
|
|
28983
|
+
createdAt: external_exports.string()
|
|
28984
|
+
});
|
|
28985
|
+
var SessionToolCallSchema = external_exports.object({
|
|
28986
|
+
id: external_exports.string(),
|
|
28987
|
+
sessionId: external_exports.string(),
|
|
28988
|
+
promptId: external_exports.string(),
|
|
28989
|
+
name: external_exports.string(),
|
|
28990
|
+
params: external_exports.record(external_exports.unknown()).optional(),
|
|
28991
|
+
result: external_exports.record(external_exports.unknown()).optional(),
|
|
28992
|
+
createdAt: external_exports.string()
|
|
28993
|
+
});
|
|
28994
|
+
var SessionThreadRefSchema = external_exports.object({
|
|
28995
|
+
sessionId: external_exports.string(),
|
|
28996
|
+
threadId: external_exports.string(),
|
|
28997
|
+
addedAt: external_exports.string()
|
|
28998
|
+
});
|
|
28999
|
+
function normalizeRepoRelativePath(p) {
|
|
29000
|
+
let t = p.trim().replace(/\\/g, "/");
|
|
29001
|
+
while (t.startsWith("./")) t = t.slice(2);
|
|
29002
|
+
return t.replace(/\/+/g, "/");
|
|
29003
|
+
}
|
|
29004
|
+
function resolveChangeSummaryPathAgainstAllowed(rawPath, allowed) {
|
|
29005
|
+
const trimmed2 = rawPath.trim();
|
|
29006
|
+
if (!trimmed2) return null;
|
|
29007
|
+
if (allowed.has(trimmed2)) return trimmed2;
|
|
29008
|
+
const n = normalizeRepoRelativePath(trimmed2);
|
|
29009
|
+
if (allowed.has(n)) return n;
|
|
29010
|
+
for (const a of allowed) {
|
|
29011
|
+
if (normalizeRepoRelativePath(a) === n) return a;
|
|
29012
|
+
}
|
|
29013
|
+
return null;
|
|
29014
|
+
}
|
|
29015
|
+
function clampSummaryToAtMostTwoLines(summary) {
|
|
29016
|
+
const lines = summary.split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0);
|
|
29017
|
+
return lines.slice(0, 2).join("\n");
|
|
29018
|
+
}
|
|
29019
|
+
function parseChangeSummaryJson(raw, allowedPaths, options) {
|
|
29020
|
+
if (raw == null || raw.trim() === "") return [];
|
|
29021
|
+
let text = raw.trim();
|
|
29022
|
+
const fence = text.match(/```(?:json)?\s*([\s\S]*?)```/i);
|
|
29023
|
+
if (fence?.[1]) text = fence[1].trim();
|
|
29024
|
+
let parsed;
|
|
29025
|
+
try {
|
|
29026
|
+
parsed = JSON.parse(text);
|
|
29027
|
+
} catch {
|
|
29028
|
+
const start = text.indexOf("[");
|
|
29029
|
+
const end = text.lastIndexOf("]");
|
|
29030
|
+
if (start < 0 || end <= start) return [];
|
|
29031
|
+
try {
|
|
29032
|
+
parsed = JSON.parse(text.slice(start, end + 1));
|
|
29033
|
+
} catch {
|
|
29034
|
+
return [];
|
|
29035
|
+
}
|
|
29036
|
+
}
|
|
29037
|
+
const rows = [];
|
|
29038
|
+
let arr = [];
|
|
29039
|
+
if (Array.isArray(parsed)) {
|
|
29040
|
+
arr = parsed;
|
|
29041
|
+
} else if (parsed && typeof parsed === "object" && Array.isArray(parsed.files)) {
|
|
29042
|
+
arr = parsed.files;
|
|
29043
|
+
}
|
|
29044
|
+
const skip = options?.skipPathAllowlist === true;
|
|
29045
|
+
for (const item of arr) {
|
|
29046
|
+
if (!item || typeof item !== "object") continue;
|
|
29047
|
+
const o = item;
|
|
29048
|
+
const rawPath = typeof o.path === "string" ? o.path.trim() : "";
|
|
29049
|
+
const summary = typeof o.summary === "string" ? o.summary.trim() : "";
|
|
29050
|
+
if (!rawPath || !summary) continue;
|
|
29051
|
+
const path32 = skip ? normalizeRepoRelativePath(rawPath) || rawPath : resolveChangeSummaryPathAgainstAllowed(rawPath, allowedPaths);
|
|
29052
|
+
if (!path32) continue;
|
|
29053
|
+
rows.push({ path: path32, summary: clampSummaryToAtMostTwoLines(summary) });
|
|
29054
|
+
}
|
|
29055
|
+
return rows;
|
|
29056
|
+
}
|
|
29057
|
+
var PATCH_PREVIEW_MAX = 12e3;
|
|
29058
|
+
function clip(s, max) {
|
|
29059
|
+
if (s.length <= max) return s;
|
|
29060
|
+
return `${s.slice(0, max)}
|
|
29061
|
+
|
|
29062
|
+
\u2026(truncated, ${s.length - max} more characters)`;
|
|
29063
|
+
}
|
|
29064
|
+
function buildSessionChangeSummaryPrompt(files) {
|
|
29065
|
+
const lines = [
|
|
29066
|
+
"You are the same agent that produced the changes below. Summarize **your own** edits so a reader can scan them quickly.",
|
|
29067
|
+
"",
|
|
29068
|
+
"Write in second person (you / your): what you changed in each path and why it matters.",
|
|
29069
|
+
"",
|
|
29070
|
+
"Each summary must be **very concise**: **one line** of plain text, or **at most two short lines** (use a single line break between the two if needed). No bullets, no paragraphs.",
|
|
29071
|
+
"",
|
|
29072
|
+
"## How to format your reply (machine parsing)",
|
|
29073
|
+
"",
|
|
29074
|
+
"- Put the machine-readable part **only** inside a **markdown fenced code block** whose opening fence is exactly ```json on its own line. Close the block with ``` on its own line after the JSON.",
|
|
29075
|
+
"- Inside that fence: **nothing except** one valid JSON value \u2014 the array described below. No trailing commentary inside the fence.",
|
|
29076
|
+
"- **Do not** attach prose to the JSON on the same line (wrong: `Only one file\u2026page.tsx.[{\u2026}]`). Wrong: any sentence that ends with `.` immediately before `[`. Put a blank line before the ```json line.",
|
|
29077
|
+
"- If you add optional plain English before the fence (e.g. one short sentence), keep it **separate**: end that sentence, blank line, then ```json.",
|
|
29078
|
+
'- In each `"summary"` string, avoid raw double-quote characters, or escape them as `\\"` so the JSON parses.',
|
|
29079
|
+
"",
|
|
29080
|
+
"JSON shape **inside the fence** (array only):",
|
|
29081
|
+
'[{"path":"<file path exactly as given>","summary":"<one line, or two short lines separated by \\n>"}]',
|
|
29082
|
+
"",
|
|
29083
|
+
"Rules:",
|
|
29084
|
+
"- Include **exactly one** object per file path listed below (same path strings).",
|
|
29085
|
+
"- If a path is a removed directory, state briefly what you removed.",
|
|
29086
|
+
"- Do not invent paths; use only the paths provided.",
|
|
29087
|
+
"",
|
|
29088
|
+
"## Files you changed",
|
|
29089
|
+
""
|
|
29090
|
+
];
|
|
29091
|
+
for (const f of files) {
|
|
29092
|
+
lines.push(`### ${f.path}`);
|
|
29093
|
+
if (f.directoryRemoved) {
|
|
29094
|
+
lines.push("(directory removed)");
|
|
29095
|
+
lines.push("");
|
|
29096
|
+
continue;
|
|
29097
|
+
}
|
|
29098
|
+
if (f.patchContent && f.patchContent.trim() !== "") {
|
|
29099
|
+
lines.push("```diff");
|
|
29100
|
+
lines.push(clip(f.patchContent.trim(), PATCH_PREVIEW_MAX));
|
|
29101
|
+
lines.push("```");
|
|
29102
|
+
} else if (f.oldText != null || f.newText != null) {
|
|
29103
|
+
const oldT = (f.oldText ?? "").trim();
|
|
29104
|
+
const newT = (f.newText ?? "").trim();
|
|
29105
|
+
lines.push("Previous snippet:", clip(oldT, 6e3));
|
|
29106
|
+
lines.push("New snippet:", clip(newT, 6e3));
|
|
29107
|
+
} else {
|
|
29108
|
+
lines.push("(no diff body stored for this path)");
|
|
29109
|
+
}
|
|
29110
|
+
lines.push("");
|
|
29111
|
+
}
|
|
29112
|
+
return lines.join("\n");
|
|
29113
|
+
}
|
|
29114
|
+
function defaultRichness(c) {
|
|
29115
|
+
const patch = typeof c.patchContent === "string" ? c.patchContent.length : 0;
|
|
29116
|
+
const nt = typeof c.newText === "string" ? c.newText.length : 0;
|
|
29117
|
+
const ot = typeof c.oldText === "string" ? c.oldText.length : 0;
|
|
29118
|
+
const dir = c.directoryRemoved === true ? 8 : 0;
|
|
29119
|
+
return (patch > 0 ? 4 : 0) + (nt > 0 ? 2 : 0) + (ot > 0 ? 1 : 0) + dir;
|
|
29120
|
+
}
|
|
29121
|
+
function dedupeSessionFileChangesByPath(items, richness = (item) => defaultRichness(item)) {
|
|
29122
|
+
const byPath = /* @__PURE__ */ new Map();
|
|
29123
|
+
for (const item of items) {
|
|
29124
|
+
const p = typeof item.path === "string" ? item.path.trim() : "";
|
|
29125
|
+
if (!p) continue;
|
|
29126
|
+
const prev = byPath.get(p);
|
|
29127
|
+
if (!prev || richness(item) >= richness(prev)) byPath.set(p, item);
|
|
29128
|
+
}
|
|
29129
|
+
return Array.from(byPath.entries()).sort(([a], [b]) => a.localeCompare(b)).map(([, v]) => v);
|
|
29130
|
+
}
|
|
29131
|
+
var ArtifactMetaSchema = external_exports.object({
|
|
29132
|
+
artifactId: external_exports.string(),
|
|
29133
|
+
workspaceId: external_exports.string(),
|
|
29134
|
+
/** Slug for permalink: /workspaces/:wid/artifacts/:slug */
|
|
29135
|
+
permalinkSlug: external_exports.string(),
|
|
29136
|
+
title: external_exports.string(),
|
|
29137
|
+
/** e.g. summary_report, build_log */
|
|
29138
|
+
type: external_exports.string().default("report"),
|
|
29139
|
+
/** Optional session that produced this artifact */
|
|
29140
|
+
sessionId: external_exports.string().nullable(),
|
|
29141
|
+
createdAt: external_exports.string(),
|
|
29142
|
+
updatedAt: external_exports.string()
|
|
29143
|
+
});
|
|
29144
|
+
var TemplateMetaSchema = external_exports.object({
|
|
29145
|
+
templateId: external_exports.string(),
|
|
29146
|
+
workspaceId: external_exports.string(),
|
|
29147
|
+
name: external_exports.string(),
|
|
29148
|
+
/** e.g. summary_report, build_log */
|
|
29149
|
+
artifactType: external_exports.string().optional(),
|
|
29150
|
+
createdAt: external_exports.string(),
|
|
29151
|
+
updatedAt: external_exports.string()
|
|
29152
|
+
});
|
|
29153
|
+
var GitRepoMetaSchema = external_exports.object({
|
|
29154
|
+
/** Stable id for the repo (e.g. hash of normalized canonical URL). Used for DO idFromName. */
|
|
29155
|
+
repoId: external_exports.string(),
|
|
29156
|
+
/** Canonical external URL (e.g. https://github.com/org/repo). Normalize before storing. */
|
|
29157
|
+
canonicalUrl: external_exports.string().url(),
|
|
29158
|
+
/** Optional workspace this repo was first linked in. */
|
|
29159
|
+
workspaceId: external_exports.string().nullable(),
|
|
29160
|
+
displayName: external_exports.string().optional(),
|
|
29161
|
+
createdAt: external_exports.string(),
|
|
29162
|
+
updatedAt: external_exports.string()
|
|
29163
|
+
});
|
|
29164
|
+
|
|
29165
|
+
// src/agents/acp/put-summarize-change-summaries.ts
|
|
29166
|
+
async function putEncryptedChangeSummaryRows(params) {
|
|
29167
|
+
const base = params.apiBaseUrl.replace(/\/+$/, "");
|
|
29168
|
+
const entries = params.rows.map(({ path: path32, summary }) => {
|
|
29169
|
+
const enc = params.e2ee.encryptFields({ summary }, ["summary"]);
|
|
29170
|
+
return { path: path32, summary: JSON.stringify(enc) };
|
|
29171
|
+
});
|
|
29172
|
+
const res = await fetch(
|
|
29173
|
+
`${base}/api/sessions/${encodeURIComponent(params.sessionId)}/follow-ups/summarize-changes`,
|
|
29174
|
+
{
|
|
29175
|
+
method: "PUT",
|
|
29176
|
+
headers: {
|
|
29177
|
+
Authorization: `Bearer ${params.authToken}`,
|
|
29178
|
+
"Content-Type": "application/json"
|
|
29179
|
+
},
|
|
29180
|
+
body: JSON.stringify({ entries })
|
|
29181
|
+
}
|
|
29182
|
+
);
|
|
29183
|
+
if (!res.ok) {
|
|
29184
|
+
const t = await res.text();
|
|
29185
|
+
throw new Error(`PUT summarize-changes summaries failed ${res.status}: ${t.slice(0, 500)}`);
|
|
29186
|
+
}
|
|
29187
|
+
}
|
|
29188
|
+
|
|
29189
|
+
// src/agents/acp/maybe-upload-e2ee-session-change-summaries.ts
|
|
29190
|
+
async function maybeUploadE2eeSessionChangeSummariesAfterAgentSuccess(params) {
|
|
29191
|
+
const {
|
|
29192
|
+
sessionId,
|
|
29193
|
+
runId,
|
|
29194
|
+
resultSuccess,
|
|
29195
|
+
output,
|
|
29196
|
+
e2ee,
|
|
29197
|
+
cloudApiBaseUrl,
|
|
29198
|
+
getCloudAccessToken,
|
|
29199
|
+
followUpCatalogPromptId,
|
|
29200
|
+
sessionChangeSummaryFilePaths,
|
|
29201
|
+
log: log2
|
|
29202
|
+
} = params;
|
|
29203
|
+
const outputStr = typeof output === "string" ? output : "";
|
|
29204
|
+
if (!sessionId) {
|
|
29205
|
+
return;
|
|
29206
|
+
}
|
|
29207
|
+
if (!runId) {
|
|
29208
|
+
return;
|
|
29209
|
+
}
|
|
29210
|
+
if (!resultSuccess) {
|
|
29211
|
+
return;
|
|
29212
|
+
}
|
|
29213
|
+
if (!e2ee) {
|
|
29214
|
+
return;
|
|
29215
|
+
}
|
|
29216
|
+
if (!cloudApiBaseUrl) {
|
|
29217
|
+
return;
|
|
29218
|
+
}
|
|
29219
|
+
if (!getCloudAccessToken) {
|
|
29220
|
+
return;
|
|
29221
|
+
}
|
|
29222
|
+
if (followUpCatalogPromptId !== BUILTIN_SESSION_CHANGE_SUMMARY_FOLLOW_UP_CATALOG_PROMPT_ID) {
|
|
29223
|
+
return;
|
|
29224
|
+
}
|
|
29225
|
+
if (!sessionChangeSummaryFilePaths || sessionChangeSummaryFilePaths.length === 0) {
|
|
29226
|
+
return;
|
|
29227
|
+
}
|
|
29228
|
+
if (outputStr.trim() === "") {
|
|
29229
|
+
return;
|
|
29230
|
+
}
|
|
29231
|
+
const allowed = /* @__PURE__ */ new Set();
|
|
29232
|
+
for (const p of sessionChangeSummaryFilePaths) {
|
|
29233
|
+
const t = p.trim();
|
|
29234
|
+
if (!t) continue;
|
|
29235
|
+
allowed.add(t);
|
|
29236
|
+
allowed.add(normalizeRepoRelativePath(t));
|
|
29237
|
+
}
|
|
29238
|
+
const rows = parseChangeSummaryJson(outputStr, allowed);
|
|
29239
|
+
if (rows.length === 0) {
|
|
29240
|
+
return;
|
|
29241
|
+
}
|
|
29242
|
+
const token = getCloudAccessToken();
|
|
29243
|
+
if (!token) {
|
|
29244
|
+
return;
|
|
29245
|
+
}
|
|
29246
|
+
try {
|
|
29247
|
+
await putEncryptedChangeSummaryRows({
|
|
29248
|
+
apiBaseUrl: cloudApiBaseUrl,
|
|
29249
|
+
authToken: token,
|
|
29250
|
+
sessionId,
|
|
29251
|
+
e2ee,
|
|
29252
|
+
rows
|
|
29253
|
+
});
|
|
29254
|
+
} catch (uploadErr) {
|
|
29255
|
+
log2(
|
|
29256
|
+
`[Agent] Encrypted change summary upload failed: ${uploadErr instanceof Error ? uploadErr.message : String(uploadErr)}`
|
|
29257
|
+
);
|
|
29258
|
+
}
|
|
29259
|
+
}
|
|
29260
|
+
|
|
29261
|
+
// src/agents/acp/send-prompt-result-augment.ts
|
|
29262
|
+
function augmentPromptResultAuthFields(agentType, errorText) {
|
|
29263
|
+
const err = errorText ?? "";
|
|
29264
|
+
const at = agentType ?? null;
|
|
29265
|
+
const evaluated = Boolean(at && err.trim());
|
|
29266
|
+
const suggestsAuth = evaluated && at ? localAgentErrorSuggestsAuth(at, err) : false;
|
|
29267
|
+
if (!suggestsAuth || !agentType) return {};
|
|
29268
|
+
return { agentAuthRequired: true, agentType };
|
|
29269
|
+
}
|
|
29270
|
+
|
|
28779
29271
|
// src/agents/acp/send-prompt-to-agent.ts
|
|
28780
29272
|
async function sendPromptToAgent(options) {
|
|
28781
29273
|
const {
|
|
@@ -28788,16 +29280,13 @@ async function sendPromptToAgent(options) {
|
|
|
28788
29280
|
agentCwd,
|
|
28789
29281
|
sendResult: sendResult2,
|
|
28790
29282
|
sendSessionUpdate,
|
|
28791
|
-
log: log2
|
|
29283
|
+
log: log2,
|
|
29284
|
+
followUpCatalogPromptId,
|
|
29285
|
+
sessionChangeSummaryFilePaths,
|
|
29286
|
+
cloudApiBaseUrl,
|
|
29287
|
+
getCloudAccessToken,
|
|
29288
|
+
e2ee
|
|
28792
29289
|
} = options;
|
|
28793
|
-
function augmentAuthFields(errorText) {
|
|
28794
|
-
const err = errorText ?? "";
|
|
28795
|
-
const at = agentType ?? null;
|
|
28796
|
-
const evaluated = Boolean(at && err.trim());
|
|
28797
|
-
const suggestsAuth = evaluated && at ? localAgentErrorSuggestsAuth(at, err) : false;
|
|
28798
|
-
if (!suggestsAuth || !agentType) return {};
|
|
28799
|
-
return { agentAuthRequired: true, agentType };
|
|
28800
|
-
}
|
|
28801
29290
|
try {
|
|
28802
29291
|
const result = await handle.sendPrompt(promptText, {});
|
|
28803
29292
|
if (sessionId && runId && sendSessionUpdate && agentCwd && result.success) {
|
|
@@ -28809,6 +29298,18 @@ async function sendPromptToAgent(options) {
|
|
|
28809
29298
|
log: log2
|
|
28810
29299
|
});
|
|
28811
29300
|
}
|
|
29301
|
+
await maybeUploadE2eeSessionChangeSummariesAfterAgentSuccess({
|
|
29302
|
+
sessionId,
|
|
29303
|
+
runId,
|
|
29304
|
+
resultSuccess: result.success === true,
|
|
29305
|
+
output: result.output,
|
|
29306
|
+
e2ee,
|
|
29307
|
+
cloudApiBaseUrl,
|
|
29308
|
+
getCloudAccessToken,
|
|
29309
|
+
followUpCatalogPromptId,
|
|
29310
|
+
sessionChangeSummaryFilePaths,
|
|
29311
|
+
log: log2
|
|
29312
|
+
});
|
|
28812
29313
|
const errStr = typeof result.error === "string" ? result.error : void 0;
|
|
28813
29314
|
sendResult2({
|
|
28814
29315
|
type: "prompt_result",
|
|
@@ -28816,7 +29317,8 @@ async function sendPromptToAgent(options) {
|
|
|
28816
29317
|
...sessionId ? { sessionId } : {},
|
|
28817
29318
|
...runId ? { runId } : {},
|
|
28818
29319
|
...result,
|
|
28819
|
-
...
|
|
29320
|
+
...followUpCatalogPromptId != null && followUpCatalogPromptId !== "" ? { followUpCatalogPromptId } : {},
|
|
29321
|
+
...augmentPromptResultAuthFields(agentType, errStr)
|
|
28820
29322
|
});
|
|
28821
29323
|
if (!result.success) {
|
|
28822
29324
|
log2(
|
|
@@ -28833,7 +29335,8 @@ async function sendPromptToAgent(options) {
|
|
|
28833
29335
|
...runId ? { runId } : {},
|
|
28834
29336
|
success: false,
|
|
28835
29337
|
error: errMsg,
|
|
28836
|
-
...
|
|
29338
|
+
...followUpCatalogPromptId != null && followUpCatalogPromptId !== "" ? { followUpCatalogPromptId } : {},
|
|
29339
|
+
...augmentPromptResultAuthFields(agentType, errMsg)
|
|
28837
29340
|
});
|
|
28838
29341
|
}
|
|
28839
29342
|
}
|
|
@@ -30141,7 +30644,12 @@ async function createAcpManager(options) {
|
|
|
30141
30644
|
agentType,
|
|
30142
30645
|
cwd,
|
|
30143
30646
|
sendResult: sendResult2,
|
|
30144
|
-
sendSessionUpdate
|
|
30647
|
+
sendSessionUpdate,
|
|
30648
|
+
followUpCatalogPromptId,
|
|
30649
|
+
sessionChangeSummaryFilePaths,
|
|
30650
|
+
cloudApiBaseUrl,
|
|
30651
|
+
getCloudAccessToken,
|
|
30652
|
+
e2ee
|
|
30145
30653
|
} = opts;
|
|
30146
30654
|
const preferredForPrompt = agentType ?? backendFallbackAgentType ?? null;
|
|
30147
30655
|
pendingCancelRunId = void 0;
|
|
@@ -30205,7 +30713,12 @@ async function createAcpManager(options) {
|
|
|
30205
30713
|
agentCwd: cwd,
|
|
30206
30714
|
sendResult: sendResult2,
|
|
30207
30715
|
sendSessionUpdate,
|
|
30208
|
-
log: log2
|
|
30716
|
+
log: log2,
|
|
30717
|
+
followUpCatalogPromptId,
|
|
30718
|
+
sessionChangeSummaryFilePaths,
|
|
30719
|
+
cloudApiBaseUrl,
|
|
30720
|
+
getCloudAccessToken,
|
|
30721
|
+
e2ee
|
|
30209
30722
|
});
|
|
30210
30723
|
}
|
|
30211
30724
|
void run().finally(() => {
|
|
@@ -32864,6 +33377,42 @@ var handleAgentConfigMessage = (msg, deps) => {
|
|
|
32864
33377
|
|
|
32865
33378
|
// src/agents/acp/from-bridge/handle-bridge-prompt.ts
|
|
32866
33379
|
import * as path28 from "node:path";
|
|
33380
|
+
|
|
33381
|
+
// src/agents/acp/from-bridge/bridge-prompt-wiring.ts
|
|
33382
|
+
function createBridgePromptSenders(deps, getWs) {
|
|
33383
|
+
const sendBridgeMessage = (message, encryptedFields = []) => {
|
|
33384
|
+
const s = getWs();
|
|
33385
|
+
if (!s) return false;
|
|
33386
|
+
const wire = deps.e2ee && encryptedFields.length > 0 ? deps.e2ee.encryptFields(message, encryptedFields) : message;
|
|
33387
|
+
sendWsMessage(s, wire);
|
|
33388
|
+
return true;
|
|
33389
|
+
};
|
|
33390
|
+
const sendResult2 = (result) => {
|
|
33391
|
+
const skipEncryptForChangeSummaryFollowUp = result.type === "prompt_result" && result.followUpCatalogPromptId === BUILTIN_SESSION_CHANGE_SUMMARY_FOLLOW_UP_CATALOG_PROMPT_ID;
|
|
33392
|
+
const encryptedFields = result.type === "prompt_result" && !skipEncryptForChangeSummaryFollowUp ? ["output", "error"] : [];
|
|
33393
|
+
sendBridgeMessage(result, encryptedFields);
|
|
33394
|
+
};
|
|
33395
|
+
const sendSessionUpdate = (payload) => {
|
|
33396
|
+
const s = getWs();
|
|
33397
|
+
if (!s) {
|
|
33398
|
+
deps.log("[Bridge service] Session update not sent: not connected to the bridge.");
|
|
33399
|
+
return;
|
|
33400
|
+
}
|
|
33401
|
+
const p = payload;
|
|
33402
|
+
const wire = p.type === "session_update" && deps.e2ee ? deps.e2ee.encryptFields(payload, ["payload"]) : p.type === "session_file_change" && deps.e2ee ? deps.e2ee.encryptFields(payload, [
|
|
33403
|
+
"path",
|
|
33404
|
+
"oldText",
|
|
33405
|
+
"newText",
|
|
33406
|
+
"patchContent",
|
|
33407
|
+
"isDirectory",
|
|
33408
|
+
"directoryRemoved"
|
|
33409
|
+
]) : payload;
|
|
33410
|
+
sendWsMessage(s, wire);
|
|
33411
|
+
};
|
|
33412
|
+
return { sendBridgeMessage, sendResult: sendResult2, sendSessionUpdate };
|
|
33413
|
+
}
|
|
33414
|
+
|
|
33415
|
+
// src/agents/acp/from-bridge/bridge-prompt-preamble.ts
|
|
32867
33416
|
import { execFile as execFile10 } from "node:child_process";
|
|
32868
33417
|
import { promisify as promisify10 } from "node:util";
|
|
32869
33418
|
|
|
@@ -32922,7 +33471,7 @@ async function resolveBridgeQueueBindFields(options) {
|
|
|
32922
33471
|
return { canonicalQueueKey, repoId, cwdAbs };
|
|
32923
33472
|
}
|
|
32924
33473
|
|
|
32925
|
-
// src/agents/acp/from-bridge/
|
|
33474
|
+
// src/agents/acp/from-bridge/bridge-prompt-preamble.ts
|
|
32926
33475
|
var execFileAsync9 = promisify10(execFile10);
|
|
32927
33476
|
async function readGitBranch(cwd) {
|
|
32928
33477
|
try {
|
|
@@ -32933,6 +33482,158 @@ async function readGitBranch(cwd) {
|
|
|
32933
33482
|
return null;
|
|
32934
33483
|
}
|
|
32935
33484
|
}
|
|
33485
|
+
async function runBridgePromptPreamble(params) {
|
|
33486
|
+
const { getWs, log: log2, sessionWorktreeManager, sessionId, runId, effectiveCwd } = params;
|
|
33487
|
+
const s = getWs();
|
|
33488
|
+
const worktreePaths = sessionWorktreeManager.getWorktreePathsForSession(sessionId) ?? [];
|
|
33489
|
+
const repoRoots = await resolveSnapshotRepoRoots({
|
|
33490
|
+
worktreePaths,
|
|
33491
|
+
fallbackCwd: effectiveCwd,
|
|
33492
|
+
log: log2
|
|
33493
|
+
});
|
|
33494
|
+
if (s && sessionId) {
|
|
33495
|
+
const bind = await resolveBridgeQueueBindFields({
|
|
33496
|
+
effectiveCwd,
|
|
33497
|
+
worktreePaths,
|
|
33498
|
+
primaryRepoRoots: repoRoots,
|
|
33499
|
+
log: log2
|
|
33500
|
+
});
|
|
33501
|
+
if (bind) {
|
|
33502
|
+
sendWsMessage(s, {
|
|
33503
|
+
type: "bridge_queue_bind",
|
|
33504
|
+
sessionId,
|
|
33505
|
+
canonicalQueueKey: bind.canonicalQueueKey,
|
|
33506
|
+
repoId: bind.repoId,
|
|
33507
|
+
cwdAbs: bind.cwdAbs
|
|
33508
|
+
});
|
|
33509
|
+
}
|
|
33510
|
+
}
|
|
33511
|
+
if (s && sessionId) {
|
|
33512
|
+
const cliGitBranch = await readGitBranch(effectiveCwd);
|
|
33513
|
+
sendWsMessage(s, {
|
|
33514
|
+
type: "session_git_context_report",
|
|
33515
|
+
sessionId,
|
|
33516
|
+
cliGitBranch,
|
|
33517
|
+
agentUsesWorktree: sessionWorktreeManager.usesWorktreeSession(sessionId)
|
|
33518
|
+
});
|
|
33519
|
+
}
|
|
33520
|
+
if (s && sessionId && runId) {
|
|
33521
|
+
const cap = repoRoots.length > 0 ? await capturePreTurnSnapshot({ runId, repoRoots, agentCwd: effectiveCwd, log: log2 }) : { ok: false, error: "No git repos" };
|
|
33522
|
+
sendWsMessage(s, {
|
|
33523
|
+
type: "pre_turn_snapshot_report",
|
|
33524
|
+
sessionId,
|
|
33525
|
+
turnId: runId,
|
|
33526
|
+
captured: cap.ok
|
|
33527
|
+
});
|
|
33528
|
+
}
|
|
33529
|
+
}
|
|
33530
|
+
function parseChangeSummarySnapshots(raw) {
|
|
33531
|
+
if (!Array.isArray(raw) || raw.length === 0) return void 0;
|
|
33532
|
+
const out = [];
|
|
33533
|
+
for (const item of raw) {
|
|
33534
|
+
if (!item || typeof item !== "object") continue;
|
|
33535
|
+
const o = item;
|
|
33536
|
+
const path32 = typeof o.path === "string" && o.path.trim() !== "" ? o.path.trim() : "";
|
|
33537
|
+
if (!path32) continue;
|
|
33538
|
+
const row = { path: path32 };
|
|
33539
|
+
if (typeof o.patchContent === "string") row.patchContent = o.patchContent;
|
|
33540
|
+
if (typeof o.oldText === "string") row.oldText = o.oldText;
|
|
33541
|
+
if (typeof o.newText === "string") row.newText = o.newText;
|
|
33542
|
+
if (o.directoryRemoved === true) row.directoryRemoved = true;
|
|
33543
|
+
out.push(row);
|
|
33544
|
+
}
|
|
33545
|
+
return out.length > 0 ? out : void 0;
|
|
33546
|
+
}
|
|
33547
|
+
function parseFollowUpFieldsFromPromptMessage(msg) {
|
|
33548
|
+
const followUpCatalogPromptId = typeof msg.followUpCatalogPromptId === "string" && msg.followUpCatalogPromptId.trim() !== "" ? msg.followUpCatalogPromptId.trim() : null;
|
|
33549
|
+
const rawPaths = msg.sessionChangeSummaryFilePaths;
|
|
33550
|
+
const sessionChangeSummaryFilePaths = Array.isArray(rawPaths) ? rawPaths.filter((p) => typeof p === "string" && p.trim() !== "").map((p) => p.trim()) : void 0;
|
|
33551
|
+
const sessionChangeSummaryFileSnapshots = parseChangeSummarySnapshots(msg.sessionChangeSummaryFileSnapshots);
|
|
33552
|
+
return { followUpCatalogPromptId, sessionChangeSummaryFilePaths, sessionChangeSummaryFileSnapshots };
|
|
33553
|
+
}
|
|
33554
|
+
|
|
33555
|
+
// ../e2ee/src/constants.ts
|
|
33556
|
+
var E2EE_NONCE_BYTES = 12;
|
|
33557
|
+
|
|
33558
|
+
// ../e2ee/src/types.ts
|
|
33559
|
+
function isE2eeEnvelope(value) {
|
|
33560
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
|
|
33561
|
+
const o = value;
|
|
33562
|
+
return typeof o.k === "string" && typeof o.n === "string" && typeof o.c === "string";
|
|
33563
|
+
}
|
|
33564
|
+
|
|
33565
|
+
// ../e2ee/src/encoding.ts
|
|
33566
|
+
function base64UrlEncode(bytes) {
|
|
33567
|
+
let binary = "";
|
|
33568
|
+
for (let i = 0; i < bytes.length; i += 1) binary += String.fromCharCode(bytes[i]);
|
|
33569
|
+
const b64 = btoa(binary);
|
|
33570
|
+
return b64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
|
|
33571
|
+
}
|
|
33572
|
+
function base64UrlDecode(value) {
|
|
33573
|
+
const b64 = value.replace(/-/g, "+").replace(/_/g, "/");
|
|
33574
|
+
const padded = b64 + "=".repeat((4 - b64.length % 4) % 4);
|
|
33575
|
+
const binary = atob(padded);
|
|
33576
|
+
const out = new Uint8Array(binary.length);
|
|
33577
|
+
for (let i = 0; i < binary.length; i += 1) out[i] = binary.charCodeAt(i);
|
|
33578
|
+
return out;
|
|
33579
|
+
}
|
|
33580
|
+
|
|
33581
|
+
// src/agents/acp/change-summary/decrypt-change-summary-file-input.ts
|
|
33582
|
+
function decryptChangeSummaryFileInput(row, e2ee) {
|
|
33583
|
+
if (!e2ee) return row;
|
|
33584
|
+
for (const field of ["path", "patchContent", "oldText", "newText"]) {
|
|
33585
|
+
const raw = row[field];
|
|
33586
|
+
if (typeof raw !== "string" || raw.trim() === "") continue;
|
|
33587
|
+
let o;
|
|
33588
|
+
try {
|
|
33589
|
+
o = JSON.parse(raw);
|
|
33590
|
+
} catch {
|
|
33591
|
+
continue;
|
|
33592
|
+
}
|
|
33593
|
+
if (!isE2eeEnvelope(o.ee)) continue;
|
|
33594
|
+
try {
|
|
33595
|
+
const d = e2ee.decryptMessage(o);
|
|
33596
|
+
const out = {
|
|
33597
|
+
path: typeof d.path === "string" ? d.path : row.path
|
|
33598
|
+
};
|
|
33599
|
+
if (d.directoryRemoved === true) out.directoryRemoved = true;
|
|
33600
|
+
else if (row.directoryRemoved === true) out.directoryRemoved = true;
|
|
33601
|
+
if (typeof d.patchContent === "string") out.patchContent = d.patchContent;
|
|
33602
|
+
else if (typeof row.patchContent === "string" && row.patchContent !== raw) out.patchContent = row.patchContent;
|
|
33603
|
+
if (typeof d.oldText === "string") out.oldText = d.oldText;
|
|
33604
|
+
else if (typeof row.oldText === "string") out.oldText = row.oldText;
|
|
33605
|
+
if (typeof d.newText === "string") out.newText = d.newText;
|
|
33606
|
+
else if (typeof row.newText === "string") out.newText = row.newText;
|
|
33607
|
+
return out;
|
|
33608
|
+
} catch {
|
|
33609
|
+
return row;
|
|
33610
|
+
}
|
|
33611
|
+
}
|
|
33612
|
+
return row;
|
|
33613
|
+
}
|
|
33614
|
+
|
|
33615
|
+
// src/agents/acp/change-summary/resolve-change-summary-prompt-for-agent.ts
|
|
33616
|
+
function hasSummarizePayload(f) {
|
|
33617
|
+
return f.directoryRemoved === true || f.patchContent != null && f.patchContent.trim() !== "" || f.oldText != null && f.oldText.trim() !== "" || f.newText != null && f.newText.trim() !== "";
|
|
33618
|
+
}
|
|
33619
|
+
function resolveChangeSummaryPromptForAgent(params) {
|
|
33620
|
+
const isBuiltin = params.followUpCatalogPromptId === BUILTIN_SESSION_CHANGE_SUMMARY_FOLLOW_UP_CATALOG_PROMPT_ID;
|
|
33621
|
+
const snaps = params.sessionChangeSummaryFileSnapshots;
|
|
33622
|
+
if (!isBuiltin || !snaps || snaps.length === 0) {
|
|
33623
|
+
return { promptText: params.bridgePromptText, sessionChangeSummaryFilePaths: void 0 };
|
|
33624
|
+
}
|
|
33625
|
+
const decrypted = dedupeSessionFileChangesByPath(snaps.map((row) => decryptChangeSummaryFileInput(row, params.e2ee)));
|
|
33626
|
+
const withPayload = decrypted.filter(hasSummarizePayload);
|
|
33627
|
+
if (withPayload.length === 0) {
|
|
33628
|
+
return { promptText: params.bridgePromptText, sessionChangeSummaryFilePaths: void 0 };
|
|
33629
|
+
}
|
|
33630
|
+
return {
|
|
33631
|
+
promptText: buildSessionChangeSummaryPrompt(withPayload),
|
|
33632
|
+
sessionChangeSummaryFilePaths: withPayload.map((f) => f.path)
|
|
33633
|
+
};
|
|
33634
|
+
}
|
|
33635
|
+
|
|
33636
|
+
// src/agents/acp/from-bridge/handle-bridge-prompt.ts
|
|
32936
33637
|
function handleBridgePrompt(msg, deps) {
|
|
32937
33638
|
const { getWs, log: log2, acpManager, sessionWorktreeManager } = deps;
|
|
32938
33639
|
const rawPrompt = msg.prompt;
|
|
@@ -32940,13 +33641,7 @@ function handleBridgePrompt(msg, deps) {
|
|
|
32940
33641
|
const sessionId = msg.sessionId;
|
|
32941
33642
|
const runId = typeof msg.runId === "string" ? msg.runId : void 0;
|
|
32942
33643
|
const promptId = typeof msg.id === "string" ? msg.id : void 0;
|
|
32943
|
-
const sendBridgeMessage
|
|
32944
|
-
const s = getWs();
|
|
32945
|
-
if (!s) return false;
|
|
32946
|
-
const wire = deps.e2ee && encryptedFields.length > 0 ? deps.e2ee.encryptFields(message, encryptedFields) : message;
|
|
32947
|
-
sendWsMessage(s, wire);
|
|
32948
|
-
return true;
|
|
32949
|
-
};
|
|
33644
|
+
const { sendBridgeMessage, sendResult: sendResult2, sendSessionUpdate } = createBridgePromptSenders(deps, getWs);
|
|
32950
33645
|
if (!promptText.trim()) {
|
|
32951
33646
|
log2(
|
|
32952
33647
|
`[Bridge service] Prompt ignored: empty or missing prompt text (session ${typeof msg.sessionId === "string" ? msg.sessionId.slice(0, 8) : "\u2014"}\u2026, run ${typeof msg.runId === "string" ? msg.runId.slice(0, 8) : "\u2014"}\u2026).`
|
|
@@ -32969,72 +33664,35 @@ function handleBridgePrompt(msg, deps) {
|
|
|
32969
33664
|
const agentType = typeof msg.agentType === "string" && msg.agentType.trim() ? msg.agentType.trim() : void 0;
|
|
32970
33665
|
const mode = typeof msg.mode === "string" && msg.mode.trim() ? msg.mode.trim() : void 0;
|
|
32971
33666
|
acpManager.logPromptReceivedFromBridge({ agentType, mode });
|
|
32972
|
-
const sendResult2 = (result) => {
|
|
32973
|
-
sendBridgeMessage(result, result.type === "prompt_result" ? ["output", "error"] : []);
|
|
32974
|
-
};
|
|
32975
|
-
const sendSessionUpdate = (payload) => {
|
|
32976
|
-
const s = getWs();
|
|
32977
|
-
if (!s) {
|
|
32978
|
-
log2("[Bridge service] Session update not sent: not connected to the bridge.");
|
|
32979
|
-
return;
|
|
32980
|
-
}
|
|
32981
|
-
const p = payload;
|
|
32982
|
-
const wire = p.type === "session_update" && deps.e2ee ? deps.e2ee.encryptFields(payload, ["payload"]) : p.type === "session_file_change" && deps.e2ee ? deps.e2ee.encryptFields(payload, [
|
|
32983
|
-
"path",
|
|
32984
|
-
"oldText",
|
|
32985
|
-
"newText",
|
|
32986
|
-
"patchContent",
|
|
32987
|
-
"isDirectory",
|
|
32988
|
-
"directoryRemoved"
|
|
32989
|
-
]) : payload;
|
|
32990
|
-
sendWsMessage(s, wire);
|
|
32991
|
-
};
|
|
32992
33667
|
async function preambleAndPrompt(resolvedCwd) {
|
|
32993
|
-
const s = getWs();
|
|
32994
33668
|
const effectiveCwd = path28.resolve(resolvedCwd ?? getBridgeWorkspaceDirectory());
|
|
32995
|
-
|
|
32996
|
-
|
|
32997
|
-
|
|
32998
|
-
|
|
32999
|
-
|
|
33669
|
+
await runBridgePromptPreamble({
|
|
33670
|
+
getWs,
|
|
33671
|
+
log: log2,
|
|
33672
|
+
sessionWorktreeManager,
|
|
33673
|
+
sessionId,
|
|
33674
|
+
runId,
|
|
33675
|
+
effectiveCwd
|
|
33000
33676
|
});
|
|
33001
|
-
|
|
33002
|
-
|
|
33003
|
-
|
|
33004
|
-
|
|
33005
|
-
|
|
33006
|
-
|
|
33007
|
-
|
|
33008
|
-
|
|
33009
|
-
|
|
33010
|
-
|
|
33011
|
-
|
|
33012
|
-
|
|
33013
|
-
|
|
33014
|
-
|
|
33015
|
-
|
|
33016
|
-
}
|
|
33017
|
-
}
|
|
33018
|
-
if (s && sessionId) {
|
|
33019
|
-
const cliGitBranch = await readGitBranch(effectiveCwd);
|
|
33020
|
-
sendWsMessage(s, {
|
|
33021
|
-
type: "session_git_context_report",
|
|
33022
|
-
sessionId,
|
|
33023
|
-
cliGitBranch,
|
|
33024
|
-
agentUsesWorktree: sessionWorktreeManager.usesWorktreeSession(sessionId)
|
|
33025
|
-
});
|
|
33026
|
-
}
|
|
33027
|
-
if (s && sessionId && runId) {
|
|
33028
|
-
const cap = repoRoots.length > 0 ? await capturePreTurnSnapshot({ runId, repoRoots, agentCwd: effectiveCwd, log: log2 }) : { ok: false, error: "No git repos" };
|
|
33029
|
-
sendWsMessage(s, {
|
|
33030
|
-
type: "pre_turn_snapshot_report",
|
|
33031
|
-
sessionId,
|
|
33032
|
-
turnId: runId,
|
|
33033
|
-
captured: cap.ok
|
|
33034
|
-
});
|
|
33677
|
+
const {
|
|
33678
|
+
followUpCatalogPromptId,
|
|
33679
|
+
sessionChangeSummaryFilePaths: pathsFromBridge,
|
|
33680
|
+
sessionChangeSummaryFileSnapshots
|
|
33681
|
+
} = parseFollowUpFieldsFromPromptMessage(msg);
|
|
33682
|
+
const { promptText: resolvedPromptText, sessionChangeSummaryFilePaths } = resolveChangeSummaryPromptForAgent({
|
|
33683
|
+
followUpCatalogPromptId,
|
|
33684
|
+
sessionChangeSummaryFileSnapshots,
|
|
33685
|
+
bridgePromptText: promptText,
|
|
33686
|
+
e2ee: deps.e2ee
|
|
33687
|
+
});
|
|
33688
|
+
if (sessionChangeSummaryFileSnapshots && sessionChangeSummaryFileSnapshots.length > 0 && resolvedPromptText === promptText) {
|
|
33689
|
+
deps.log(
|
|
33690
|
+
"[Agent] Change-summary snapshots were present but the prompt was not rebuilt (decrypt failed or empty payloads); sending the bridge prompt as-is."
|
|
33691
|
+
);
|
|
33035
33692
|
}
|
|
33693
|
+
const pathsForUpload = sessionChangeSummaryFilePaths ?? pathsFromBridge;
|
|
33036
33694
|
acpManager.handlePrompt({
|
|
33037
|
-
promptText,
|
|
33695
|
+
promptText: resolvedPromptText,
|
|
33038
33696
|
promptId: msg.id,
|
|
33039
33697
|
sessionId,
|
|
33040
33698
|
runId,
|
|
@@ -33042,7 +33700,12 @@ function handleBridgePrompt(msg, deps) {
|
|
|
33042
33700
|
agentType,
|
|
33043
33701
|
cwd: effectiveCwd,
|
|
33044
33702
|
sendResult: sendResult2,
|
|
33045
|
-
sendSessionUpdate
|
|
33703
|
+
sendSessionUpdate,
|
|
33704
|
+
followUpCatalogPromptId,
|
|
33705
|
+
sessionChangeSummaryFilePaths: pathsForUpload,
|
|
33706
|
+
cloudApiBaseUrl: deps.cloudApiBaseUrl,
|
|
33707
|
+
getCloudAccessToken: deps.getCloudAccessToken,
|
|
33708
|
+
e2ee: deps.e2ee
|
|
33046
33709
|
});
|
|
33047
33710
|
}
|
|
33048
33711
|
void sessionWorktreeManager.resolveCwdForPrompt(sessionId, { isNewSession, sessionWorktreesEnabled }).then((cwd) => preambleAndPrompt(cwd)).catch((err) => {
|
|
@@ -33907,32 +34570,6 @@ function createMainBridgeWebSocketLifecycle(params) {
|
|
|
33907
34570
|
return { connect };
|
|
33908
34571
|
}
|
|
33909
34572
|
|
|
33910
|
-
// ../e2ee/src/constants.ts
|
|
33911
|
-
var E2EE_NONCE_BYTES = 12;
|
|
33912
|
-
|
|
33913
|
-
// ../e2ee/src/types.ts
|
|
33914
|
-
function isE2eeEnvelope(value) {
|
|
33915
|
-
if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
|
|
33916
|
-
const o = value;
|
|
33917
|
-
return typeof o.k === "string" && typeof o.n === "string" && typeof o.c === "string";
|
|
33918
|
-
}
|
|
33919
|
-
|
|
33920
|
-
// ../e2ee/src/encoding.ts
|
|
33921
|
-
function base64UrlEncode(bytes) {
|
|
33922
|
-
let binary = "";
|
|
33923
|
-
for (let i = 0; i < bytes.length; i += 1) binary += String.fromCharCode(bytes[i]);
|
|
33924
|
-
const b64 = btoa(binary);
|
|
33925
|
-
return b64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
|
|
33926
|
-
}
|
|
33927
|
-
function base64UrlDecode(value) {
|
|
33928
|
-
const b64 = value.replace(/-/g, "+").replace(/_/g, "/");
|
|
33929
|
-
const padded = b64 + "=".repeat((4 - b64.length % 4) % 4);
|
|
33930
|
-
const binary = atob(padded);
|
|
33931
|
-
const out = new Uint8Array(binary.length);
|
|
33932
|
-
for (let i = 0; i < binary.length; i += 1) out[i] = binary.charCodeAt(i);
|
|
33933
|
-
return out;
|
|
33934
|
-
}
|
|
33935
|
-
|
|
33936
34573
|
// src/lib/e2ee/cli-e2ee-runtime.ts
|
|
33937
34574
|
import { createCipheriv, createDecipheriv, randomBytes } from "node:crypto";
|
|
33938
34575
|
function nonceFromCounter(prefix, counter) {
|
|
@@ -34055,7 +34692,9 @@ async function createBridgeConnection(options) {
|
|
|
34055
34692
|
sendLocalSkillsReport,
|
|
34056
34693
|
reportAutoDetectedAgents,
|
|
34057
34694
|
devServerManager,
|
|
34058
|
-
e2ee
|
|
34695
|
+
e2ee,
|
|
34696
|
+
cloudApiBaseUrl: apiUrl,
|
|
34697
|
+
getCloudAccessToken: () => tokens.accessToken
|
|
34059
34698
|
};
|
|
34060
34699
|
const { connect } = createMainBridgeWebSocketLifecycle({
|
|
34061
34700
|
state,
|