@buildautomaton/cli 0.1.41 → 0.1.43
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 +102 -115
- package/dist/cli.js.map +4 -4
- package/dist/index.js +493 -506
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -22636,342 +22636,6 @@ function enrichAcpPermissionRpcResultFromRequestParams(result, params) {
|
|
|
22636
22636
|
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
22637
22637
|
import { dirname } from "node:path";
|
|
22638
22638
|
|
|
22639
|
-
// src/files/diff/unified-diff.ts
|
|
22640
|
-
function computeLineDiff(oldText, newText) {
|
|
22641
|
-
const oldLines = oldText.split("\n");
|
|
22642
|
-
const newLines = newText.split("\n");
|
|
22643
|
-
const m = oldLines.length;
|
|
22644
|
-
const n = newLines.length;
|
|
22645
|
-
const dp = Array(m + 1);
|
|
22646
|
-
for (let i2 = 0; i2 <= m; i2++) dp[i2] = Array(n + 1).fill(0);
|
|
22647
|
-
for (let i2 = 1; i2 <= m; i2++) {
|
|
22648
|
-
for (let j2 = 1; j2 <= n; j2++) {
|
|
22649
|
-
if (oldLines[i2 - 1] === newLines[j2 - 1]) {
|
|
22650
|
-
dp[i2][j2] = dp[i2 - 1][j2 - 1] + 1;
|
|
22651
|
-
} else {
|
|
22652
|
-
dp[i2][j2] = Math.max(dp[i2 - 1][j2], dp[i2][j2 - 1]);
|
|
22653
|
-
}
|
|
22654
|
-
}
|
|
22655
|
-
}
|
|
22656
|
-
const result = [];
|
|
22657
|
-
let i = m;
|
|
22658
|
-
let j = n;
|
|
22659
|
-
while (i > 0 || j > 0) {
|
|
22660
|
-
if (i > 0 && j > 0 && oldLines[i - 1] === newLines[j - 1]) {
|
|
22661
|
-
result.unshift({ type: "context", line: oldLines[i - 1] });
|
|
22662
|
-
i--;
|
|
22663
|
-
j--;
|
|
22664
|
-
} else if (j > 0 && (i === 0 || dp[i][j - 1] >= dp[i - 1][j])) {
|
|
22665
|
-
result.unshift({ type: "add", line: newLines[j - 1] });
|
|
22666
|
-
j--;
|
|
22667
|
-
} else {
|
|
22668
|
-
result.unshift({ type: "remove", line: oldLines[i - 1] });
|
|
22669
|
-
i--;
|
|
22670
|
-
}
|
|
22671
|
-
}
|
|
22672
|
-
return result;
|
|
22673
|
-
}
|
|
22674
|
-
function editSnippetToUnifiedDiff(filePath, oldText, newText) {
|
|
22675
|
-
const lines = computeLineDiff(oldText, newText);
|
|
22676
|
-
const out = [`--- ${filePath}`, `+++ ${filePath}`];
|
|
22677
|
-
for (const d of lines) {
|
|
22678
|
-
if (d.type === "add") out.push(`+${d.line}`);
|
|
22679
|
-
else if (d.type === "remove") out.push(`-${d.line}`);
|
|
22680
|
-
else out.push(` ${d.line}`);
|
|
22681
|
-
}
|
|
22682
|
-
return out.join("\n");
|
|
22683
|
-
}
|
|
22684
|
-
|
|
22685
|
-
// src/agents/acp/safe-fs-path.ts
|
|
22686
|
-
import * as path2 from "node:path";
|
|
22687
|
-
function resolveSafePathUnderCwd(cwd, filePath) {
|
|
22688
|
-
const trimmed2 = filePath.trim();
|
|
22689
|
-
if (!trimmed2) return null;
|
|
22690
|
-
const normalizedCwd = path2.resolve(cwd);
|
|
22691
|
-
const resolved = path2.isAbsolute(trimmed2) ? path2.normalize(trimmed2) : path2.resolve(normalizedCwd, trimmed2);
|
|
22692
|
-
const rel = path2.relative(normalizedCwd, resolved);
|
|
22693
|
-
if (rel.startsWith("..") || path2.isAbsolute(rel)) return null;
|
|
22694
|
-
return resolved;
|
|
22695
|
-
}
|
|
22696
|
-
function toDisplayPathRelativeToCwd(cwd, absolutePath) {
|
|
22697
|
-
const normalizedCwd = path2.resolve(cwd);
|
|
22698
|
-
const rel = path2.relative(normalizedCwd, path2.resolve(absolutePath));
|
|
22699
|
-
if (!rel || rel === "") return path2.basename(absolutePath);
|
|
22700
|
-
return rel.split(path2.sep).join("/");
|
|
22701
|
-
}
|
|
22702
|
-
|
|
22703
|
-
// src/agents/acp/clients/shared/acp-fs-read-write.ts
|
|
22704
|
-
function sliceFileContentForAcp(content, line, limit) {
|
|
22705
|
-
if (line == null && limit == null) return content;
|
|
22706
|
-
const lines = content.split("\n");
|
|
22707
|
-
const start = line != null && line > 0 ? line - 1 : 0;
|
|
22708
|
-
const end = limit != null && limit > 0 ? start + limit : lines.length;
|
|
22709
|
-
return lines.slice(start, end).join("\n");
|
|
22710
|
-
}
|
|
22711
|
-
function acpReadTextFileInProcess(ctx, filePath, line, limit) {
|
|
22712
|
-
const resolvedPath = resolveSafePathUnderCwd(ctx.cwd, filePath);
|
|
22713
|
-
if (!resolvedPath) throw new Error("Invalid or disallowed path");
|
|
22714
|
-
try {
|
|
22715
|
-
let content = readFileSync(resolvedPath, "utf8");
|
|
22716
|
-
content = sliceFileContentForAcp(content, line, limit);
|
|
22717
|
-
return { content };
|
|
22718
|
-
} catch (e) {
|
|
22719
|
-
if (e.code === "ENOENT") return { content: "" };
|
|
22720
|
-
throw e;
|
|
22721
|
-
}
|
|
22722
|
-
}
|
|
22723
|
-
function acpWriteTextFileInProcess(ctx, filePath, newText) {
|
|
22724
|
-
const resolvedPath = resolveSafePathUnderCwd(ctx.cwd, filePath);
|
|
22725
|
-
if (!resolvedPath) throw new Error("Invalid or disallowed path");
|
|
22726
|
-
let oldText = "";
|
|
22727
|
-
try {
|
|
22728
|
-
oldText = readFileSync(resolvedPath, "utf8");
|
|
22729
|
-
} catch (e) {
|
|
22730
|
-
if (e.code !== "ENOENT") throw e;
|
|
22731
|
-
}
|
|
22732
|
-
mkdirSync(dirname(resolvedPath), { recursive: true });
|
|
22733
|
-
writeFileSync(resolvedPath, newText, "utf8");
|
|
22734
|
-
const displayPath = toDisplayPathRelativeToCwd(ctx.cwd, resolvedPath);
|
|
22735
|
-
const patchContent = editSnippetToUnifiedDiff(displayPath, oldText, newText);
|
|
22736
|
-
ctx.onFileChange?.({ path: displayPath, oldText, newText, patchContent });
|
|
22737
|
-
return {};
|
|
22738
|
-
}
|
|
22739
|
-
|
|
22740
|
-
// src/agents/acp/clients/shared/dispatch-session-update.ts
|
|
22741
|
-
function dispatchAcpSessionUpdate(opts) {
|
|
22742
|
-
const { flatPayload, onAcpConfigOptionsUpdated, onSessionUpdate, suppressLoadReplay } = opts;
|
|
22743
|
-
const su = flatPayload.sessionUpdate ?? flatPayload.session_update;
|
|
22744
|
-
if (su === "config_option_update") {
|
|
22745
|
-
const co = flatPayload.configOptions;
|
|
22746
|
-
if (Array.isArray(co)) onAcpConfigOptionsUpdated?.(co);
|
|
22747
|
-
return;
|
|
22748
|
-
}
|
|
22749
|
-
if (suppressLoadReplay()) return;
|
|
22750
|
-
onSessionUpdate?.(flatPayload);
|
|
22751
|
-
}
|
|
22752
|
-
|
|
22753
|
-
// src/agents/acp/clients/shared/flatten-sdk-session-notification.ts
|
|
22754
|
-
function flattenSdkSessionNotificationParams(params) {
|
|
22755
|
-
return { sessionId: params.sessionId, ...params.update };
|
|
22756
|
-
}
|
|
22757
|
-
|
|
22758
|
-
// src/agents/acp/clients/kiro-sdk-ext-notifications.ts
|
|
22759
|
-
function createKiroSdkExtNotificationHandler(options) {
|
|
22760
|
-
const { onSessionUpdate } = options;
|
|
22761
|
-
return async (method, params) => {
|
|
22762
|
-
if (method === "_kiro.dev/metadata") {
|
|
22763
|
-
const p = params && typeof params === "object" ? params : {};
|
|
22764
|
-
const pct = p.contextUsagePercentage;
|
|
22765
|
-
if (typeof pct !== "number" || !Number.isFinite(pct) || !onSessionUpdate) return;
|
|
22766
|
-
onSessionUpdate({
|
|
22767
|
-
sessionUpdate: "context_usage",
|
|
22768
|
-
contextUsagePercentage: pct
|
|
22769
|
-
});
|
|
22770
|
-
return;
|
|
22771
|
-
}
|
|
22772
|
-
};
|
|
22773
|
-
}
|
|
22774
|
-
|
|
22775
|
-
// src/agents/acp/clients/sdk/sdk-stdio-ext-notifications.ts
|
|
22776
|
-
var noopExtNotification = async () => {
|
|
22777
|
-
};
|
|
22778
|
-
function createSdkStdioExtNotificationHandler(options) {
|
|
22779
|
-
const { backendAgentType, onSessionUpdate } = options;
|
|
22780
|
-
switch (backendAgentType) {
|
|
22781
|
-
case "kiro-acp":
|
|
22782
|
-
return createKiroSdkExtNotificationHandler({ onSessionUpdate });
|
|
22783
|
-
default:
|
|
22784
|
-
return noopExtNotification;
|
|
22785
|
-
}
|
|
22786
|
-
}
|
|
22787
|
-
|
|
22788
|
-
// src/agents/acp/clients/sdk/sdk-stdio-permission-request-handshake.ts
|
|
22789
|
-
function awaitSdkStdioPermissionRequestHandshake(params) {
|
|
22790
|
-
const { requestId, paramsRecord, pending, onRequest } = params;
|
|
22791
|
-
return new Promise((resolve20) => {
|
|
22792
|
-
pending.set(requestId, { resolve: resolve20, params: paramsRecord });
|
|
22793
|
-
if (onRequest == null) {
|
|
22794
|
-
pending.delete(requestId);
|
|
22795
|
-
resolve20({ outcome: { outcome: "denied" } });
|
|
22796
|
-
return;
|
|
22797
|
-
}
|
|
22798
|
-
try {
|
|
22799
|
-
onRequest({
|
|
22800
|
-
requestId,
|
|
22801
|
-
method: "session/request_permission",
|
|
22802
|
-
params: paramsRecord
|
|
22803
|
-
});
|
|
22804
|
-
} catch {
|
|
22805
|
-
}
|
|
22806
|
-
});
|
|
22807
|
-
}
|
|
22808
|
-
|
|
22809
|
-
// src/agents/acp/clients/sdk/sdk-stdio-permission-pending.ts
|
|
22810
|
-
function resolvePendingSdkStdioPermissionCancellations(pending) {
|
|
22811
|
-
for (const [id, entry] of [...pending.entries()]) {
|
|
22812
|
-
pending.delete(id);
|
|
22813
|
-
entry.resolve({ outcome: { outcome: "cancelled" } });
|
|
22814
|
-
}
|
|
22815
|
-
}
|
|
22816
|
-
|
|
22817
|
-
// src/agents/acp/clients/sdk/sdk-stdio-connection-client.ts
|
|
22818
|
-
function createSdkStdioConnectionClient(deps) {
|
|
22819
|
-
const { backendAgentType, onSessionUpdate, onRequest, sessionCtx, pendingPermissionReplies } = deps;
|
|
22820
|
-
const extNotification = createSdkStdioExtNotificationHandler({
|
|
22821
|
-
backendAgentType,
|
|
22822
|
-
onSessionUpdate
|
|
22823
|
-
});
|
|
22824
|
-
let permissionSeq = 0;
|
|
22825
|
-
return (_agent) => ({
|
|
22826
|
-
async requestPermission(params) {
|
|
22827
|
-
const requestId = `perm-${++permissionSeq}`;
|
|
22828
|
-
const paramsRecord = params != null && typeof params === "object" ? params : {};
|
|
22829
|
-
return await awaitSdkStdioPermissionRequestHandshake({
|
|
22830
|
-
requestId,
|
|
22831
|
-
paramsRecord,
|
|
22832
|
-
pending: pendingPermissionReplies,
|
|
22833
|
-
onRequest
|
|
22834
|
-
});
|
|
22835
|
-
},
|
|
22836
|
-
async readTextFile(params) {
|
|
22837
|
-
return acpReadTextFileInProcess(sessionCtx, params.path, params.line, params.limit);
|
|
22838
|
-
},
|
|
22839
|
-
async writeTextFile(params) {
|
|
22840
|
-
return acpWriteTextFileInProcess(sessionCtx, params.path, params.content);
|
|
22841
|
-
},
|
|
22842
|
-
async sessionUpdate(params) {
|
|
22843
|
-
const bridged = flattenSdkSessionNotificationParams(params);
|
|
22844
|
-
dispatchAcpSessionUpdate({
|
|
22845
|
-
flatPayload: bridged,
|
|
22846
|
-
onAcpConfigOptionsUpdated: sessionCtx.onAcpConfigOptionsUpdated,
|
|
22847
|
-
onSessionUpdate,
|
|
22848
|
-
suppressLoadReplay: () => sessionCtx.suppressLoadReplay.value
|
|
22849
|
-
});
|
|
22850
|
-
},
|
|
22851
|
-
async extNotification(method, params) {
|
|
22852
|
-
await extNotification(method, params);
|
|
22853
|
-
}
|
|
22854
|
-
});
|
|
22855
|
-
}
|
|
22856
|
-
function resolveSdkStdioPermissionRequest(pendingPermissionReplies, requestId, result) {
|
|
22857
|
-
const entry = pendingPermissionReplies.get(requestId);
|
|
22858
|
-
if (!entry) return;
|
|
22859
|
-
pendingPermissionReplies.delete(requestId);
|
|
22860
|
-
const enriched = enrichAcpPermissionRpcResultFromRequestParams(result, entry.params);
|
|
22861
|
-
entry.resolve(enriched);
|
|
22862
|
-
}
|
|
22863
|
-
|
|
22864
|
-
// src/agents/acp/clients/sdk/create-sdk-stdio-handle.ts
|
|
22865
|
-
function createSdkStdioHandle(options) {
|
|
22866
|
-
let teardownStarted = false;
|
|
22867
|
-
async function disconnectGracefully() {
|
|
22868
|
-
if (teardownStarted) return;
|
|
22869
|
-
teardownStarted = true;
|
|
22870
|
-
await gracefulAcpSubprocessDisconnect({
|
|
22871
|
-
child: options.child,
|
|
22872
|
-
sessionId: options.sessionId,
|
|
22873
|
-
transport: options.transport,
|
|
22874
|
-
resolvePendingPermissionCancellations: () => resolvePendingSdkStdioPermissionCancellations(options.pendingPermissionReplies)
|
|
22875
|
-
});
|
|
22876
|
-
}
|
|
22877
|
-
return {
|
|
22878
|
-
sessionId: options.sessionId,
|
|
22879
|
-
async sendPrompt(prompt, sendOptions) {
|
|
22880
|
-
const imgs = sendOptions?.images?.map((im) => ({
|
|
22881
|
-
type: "image",
|
|
22882
|
-
mimeType: im.mimeType,
|
|
22883
|
-
data: im.dataBase64
|
|
22884
|
-
}));
|
|
22885
|
-
return sendAcpPromptViaTransport(
|
|
22886
|
-
options.transport,
|
|
22887
|
-
options.sessionCtx,
|
|
22888
|
-
options.sessionId,
|
|
22889
|
-
prompt,
|
|
22890
|
-
imgs
|
|
22891
|
-
);
|
|
22892
|
-
},
|
|
22893
|
-
async cancel() {
|
|
22894
|
-
resolvePendingSdkStdioPermissionCancellations(options.pendingPermissionReplies);
|
|
22895
|
-
try {
|
|
22896
|
-
await options.transport.cancelSession(options.sessionId);
|
|
22897
|
-
} catch {
|
|
22898
|
-
}
|
|
22899
|
-
if (options.killSubprocessAfterCancelMs != null && options.killSubprocessAfterCancelMs >= 0) {
|
|
22900
|
-
const t = setTimeout(() => {
|
|
22901
|
-
if (options.child.exitCode == null && options.child.signalCode == null) {
|
|
22902
|
-
void disconnectGracefully();
|
|
22903
|
-
}
|
|
22904
|
-
}, options.killSubprocessAfterCancelMs);
|
|
22905
|
-
t.unref?.();
|
|
22906
|
-
}
|
|
22907
|
-
},
|
|
22908
|
-
resolveRequest(requestId, result) {
|
|
22909
|
-
resolveSdkStdioPermissionRequest(options.pendingPermissionReplies, requestId, result);
|
|
22910
|
-
},
|
|
22911
|
-
disconnectGracefully,
|
|
22912
|
-
disconnect() {
|
|
22913
|
-
void disconnectGracefully();
|
|
22914
|
-
}
|
|
22915
|
-
};
|
|
22916
|
-
}
|
|
22917
|
-
|
|
22918
|
-
// src/cli-log-level.ts
|
|
22919
|
-
var verbosity = "info";
|
|
22920
|
-
function setCliLogVerbosity(level) {
|
|
22921
|
-
verbosity = level;
|
|
22922
|
-
}
|
|
22923
|
-
function getCliLogVerbosity() {
|
|
22924
|
-
return verbosity;
|
|
22925
|
-
}
|
|
22926
|
-
function isCliTrace() {
|
|
22927
|
-
return verbosity === "trace";
|
|
22928
|
-
}
|
|
22929
|
-
|
|
22930
|
-
// src/log.ts
|
|
22931
|
-
function timestampPrefix() {
|
|
22932
|
-
const time3 = (/* @__PURE__ */ new Date()).toISOString().slice(11, 19);
|
|
22933
|
-
return `[${time3}]`;
|
|
22934
|
-
}
|
|
22935
|
-
function log(line) {
|
|
22936
|
-
console.log(`${timestampPrefix()} ${line}`);
|
|
22937
|
-
}
|
|
22938
|
-
function logImmediate(line) {
|
|
22939
|
-
process.stdout.write(`${timestampPrefix()} ${line}
|
|
22940
|
-
`);
|
|
22941
|
-
}
|
|
22942
|
-
function logDebug(line) {
|
|
22943
|
-
const v = getCliLogVerbosity();
|
|
22944
|
-
if (v !== "debug" && v !== "trace") return;
|
|
22945
|
-
console.log(`${timestampPrefix()} [debug] ${line}`);
|
|
22946
|
-
}
|
|
22947
|
-
function logTrace(line) {
|
|
22948
|
-
if (getCliLogVerbosity() !== "trace") return;
|
|
22949
|
-
console.log(`${timestampPrefix()} [trace] ${line}`);
|
|
22950
|
-
}
|
|
22951
|
-
|
|
22952
|
-
// src/agents/acp/clients/sdk/create-sdk-stdio-session-context.ts
|
|
22953
|
-
function createSdkStdioSessionContext(options) {
|
|
22954
|
-
const suppressLoadReplayRef = { value: false };
|
|
22955
|
-
return {
|
|
22956
|
-
cwd: options.cwd,
|
|
22957
|
-
onFileChange: options.onFileChange,
|
|
22958
|
-
mcpServers: [],
|
|
22959
|
-
persistedAcpSessionId: options.persistedAcpSessionId,
|
|
22960
|
-
agentLabel: "ACP",
|
|
22961
|
-
suppressLoadReplay: suppressLoadReplayRef,
|
|
22962
|
-
backendAgentType: options.backendAgentType ?? null,
|
|
22963
|
-
agentConfig: options.agentConfig,
|
|
22964
|
-
getActiveConfigOptions: options.getActiveConfigOptions,
|
|
22965
|
-
onAcpSessionEstablished: options.onAcpSessionEstablished,
|
|
22966
|
-
onAcpConfigOptionsUpdated: options.onAcpConfigOptionsUpdated,
|
|
22967
|
-
logDebug,
|
|
22968
|
-
getStderrText: () => options.stderrCapture.getText()
|
|
22969
|
-
};
|
|
22970
|
-
}
|
|
22971
|
-
|
|
22972
|
-
// src/agents/acp/clients/sdk/sdk-stdio-bootstrap-connection.ts
|
|
22973
|
-
import { Readable, Writable } from "node:stream";
|
|
22974
|
-
|
|
22975
22639
|
// ../types/src/work-items.ts
|
|
22976
22640
|
init_zod();
|
|
22977
22641
|
var WorkItemStatusSchema = external_exports.enum(["backlog", "in-progress", "completed"]);
|
|
@@ -23335,30 +22999,123 @@ function buildSessionChangeSummaryPrompt(files) {
|
|
|
23335
22999
|
lines.push("Previous snippet:", clip(oldT, 6e3));
|
|
23336
23000
|
lines.push("New snippet:", clip(newT, 6e3));
|
|
23337
23001
|
} else {
|
|
23338
|
-
lines.push("(no diff body stored for this path)");
|
|
23002
|
+
lines.push("(no diff body stored for this path)");
|
|
23003
|
+
}
|
|
23004
|
+
lines.push("");
|
|
23005
|
+
}
|
|
23006
|
+
return lines.join("\n");
|
|
23007
|
+
}
|
|
23008
|
+
|
|
23009
|
+
// ../types/src/dedupe-session-file-changes-by-path.ts
|
|
23010
|
+
function defaultRichness(c) {
|
|
23011
|
+
const patch = typeof c.patchContent === "string" ? c.patchContent.length : 0;
|
|
23012
|
+
const nt = typeof c.newText === "string" ? c.newText.length : 0;
|
|
23013
|
+
const ot = typeof c.oldText === "string" ? c.oldText.length : 0;
|
|
23014
|
+
const dir = c.directoryRemoved === true ? 8 : 0;
|
|
23015
|
+
return (patch > 0 ? 4 : 0) + (nt > 0 ? 2 : 0) + (ot > 0 ? 1 : 0) + dir;
|
|
23016
|
+
}
|
|
23017
|
+
function dedupeSessionFileChangesByPath(items, richness = (item) => defaultRichness(item)) {
|
|
23018
|
+
const byPath = /* @__PURE__ */ new Map();
|
|
23019
|
+
for (const item of items) {
|
|
23020
|
+
const p = typeof item.path === "string" ? item.path.trim() : "";
|
|
23021
|
+
if (!p) continue;
|
|
23022
|
+
const prev = byPath.get(p);
|
|
23023
|
+
if (!prev || richness(item) >= richness(prev)) byPath.set(p, item);
|
|
23024
|
+
}
|
|
23025
|
+
return Array.from(byPath.entries()).sort(([a], [b]) => a.localeCompare(b)).map(([, v]) => v);
|
|
23026
|
+
}
|
|
23027
|
+
|
|
23028
|
+
// ../types/src/diff/line-diff.ts
|
|
23029
|
+
function normalizeDiffLineText(line) {
|
|
23030
|
+
return line.replace(/\r$/, "").replace(/\s*\\s*$/, "");
|
|
23031
|
+
}
|
|
23032
|
+
function normalizePatchContent(patch) {
|
|
23033
|
+
return patch.replace(/^\n+/, "").replace(/\n+$/, "");
|
|
23034
|
+
}
|
|
23035
|
+
function splitTextIntoDiffLines(text) {
|
|
23036
|
+
if (text.length === 0) return [];
|
|
23037
|
+
const lines = text.split("\n").map((line) => normalizeDiffLineText(line));
|
|
23038
|
+
if (text.endsWith("\n") && lines.at(-1) === "") {
|
|
23039
|
+
lines.pop();
|
|
23040
|
+
}
|
|
23041
|
+
return lines;
|
|
23042
|
+
}
|
|
23043
|
+
function createEofNewlineDiffLine(change) {
|
|
23044
|
+
return {
|
|
23045
|
+
type: change === "added" ? "add" : "remove",
|
|
23046
|
+
line: "",
|
|
23047
|
+
oldLineNo: null,
|
|
23048
|
+
newLineNo: null,
|
|
23049
|
+
eofNewlineChange: change
|
|
23050
|
+
};
|
|
23051
|
+
}
|
|
23052
|
+
function hasSameLogicalLines(left, right) {
|
|
23053
|
+
return left.length === right.length && left.every((line, index) => line === right[index]);
|
|
23054
|
+
}
|
|
23055
|
+
function detectEofNewlineChange(oldText, newText, oldLines, newLines) {
|
|
23056
|
+
if (!hasSameLogicalLines(oldLines, newLines) || oldLines.length === 0) return null;
|
|
23057
|
+
if (!oldText.endsWith("\n") && newText.endsWith("\n")) return "added";
|
|
23058
|
+
if (oldText.endsWith("\n") && !newText.endsWith("\n")) return "removed";
|
|
23059
|
+
return null;
|
|
23060
|
+
}
|
|
23061
|
+
function computeLineDiff(oldText, newText) {
|
|
23062
|
+
const oldLines = splitTextIntoDiffLines(oldText);
|
|
23063
|
+
const newLines = splitTextIntoDiffLines(newText);
|
|
23064
|
+
const m = oldLines.length;
|
|
23065
|
+
const n = newLines.length;
|
|
23066
|
+
const dp = Array(m + 1);
|
|
23067
|
+
for (let i2 = 0; i2 <= m; i2++) dp[i2] = Array(n + 1).fill(0);
|
|
23068
|
+
for (let i2 = 1; i2 <= m; i2++) {
|
|
23069
|
+
for (let j2 = 1; j2 <= n; j2++) {
|
|
23070
|
+
if (oldLines[i2 - 1] === newLines[j2 - 1]) {
|
|
23071
|
+
dp[i2][j2] = dp[i2 - 1][j2 - 1] + 1;
|
|
23072
|
+
} else {
|
|
23073
|
+
dp[i2][j2] = Math.max(dp[i2 - 1][j2], dp[i2][j2 - 1]);
|
|
23074
|
+
}
|
|
23075
|
+
}
|
|
23076
|
+
}
|
|
23077
|
+
const result = [];
|
|
23078
|
+
let i = m;
|
|
23079
|
+
let j = n;
|
|
23080
|
+
while (i > 0 || j > 0) {
|
|
23081
|
+
if (i > 0 && j > 0 && oldLines[i - 1] === newLines[j - 1]) {
|
|
23082
|
+
result.unshift({ type: "context", line: oldLines[i - 1] });
|
|
23083
|
+
i--;
|
|
23084
|
+
j--;
|
|
23085
|
+
} else if (j > 0 && (i === 0 || dp[i][j - 1] >= dp[i - 1][j])) {
|
|
23086
|
+
result.unshift({ type: "add", line: newLines[j - 1] });
|
|
23087
|
+
j--;
|
|
23088
|
+
} else {
|
|
23089
|
+
result.unshift({ type: "remove", line: oldLines[i - 1] });
|
|
23090
|
+
i--;
|
|
23339
23091
|
}
|
|
23340
|
-
lines.push("");
|
|
23341
23092
|
}
|
|
23342
|
-
|
|
23343
|
-
|
|
23344
|
-
|
|
23345
|
-
// ../types/src/dedupe-session-file-changes-by-path.ts
|
|
23346
|
-
function defaultRichness(c) {
|
|
23347
|
-
const patch = typeof c.patchContent === "string" ? c.patchContent.length : 0;
|
|
23348
|
-
const nt = typeof c.newText === "string" ? c.newText.length : 0;
|
|
23349
|
-
const ot = typeof c.oldText === "string" ? c.oldText.length : 0;
|
|
23350
|
-
const dir = c.directoryRemoved === true ? 8 : 0;
|
|
23351
|
-
return (patch > 0 ? 4 : 0) + (nt > 0 ? 2 : 0) + (ot > 0 ? 1 : 0) + dir;
|
|
23093
|
+
const eofNewlineChange = detectEofNewlineChange(oldText, newText, oldLines, newLines);
|
|
23094
|
+
if (eofNewlineChange) result.push(createEofNewlineDiffLine(eofNewlineChange));
|
|
23095
|
+
return result;
|
|
23352
23096
|
}
|
|
23353
|
-
function
|
|
23354
|
-
const
|
|
23355
|
-
|
|
23356
|
-
|
|
23357
|
-
if (
|
|
23358
|
-
|
|
23359
|
-
|
|
23097
|
+
function editSnippetToUnifiedDiff(filePath, oldText, newText) {
|
|
23098
|
+
const lines = computeLineDiff(oldText, newText);
|
|
23099
|
+
const out = [`--- ${filePath}`, `+++ ${filePath}`];
|
|
23100
|
+
for (const d of lines) {
|
|
23101
|
+
if (d.eofNewlineChange) {
|
|
23102
|
+
const previous = out.at(-1);
|
|
23103
|
+
if (previous?.startsWith(" ")) {
|
|
23104
|
+
const line = previous.slice(1);
|
|
23105
|
+
out.pop();
|
|
23106
|
+
if (d.eofNewlineChange === "added") {
|
|
23107
|
+
out.push(`-${line}`, "\", `+${line}`);
|
|
23108
|
+
} else {
|
|
23109
|
+
out.push(`-${line}`, `+${line}`, "\");
|
|
23110
|
+
}
|
|
23111
|
+
continue;
|
|
23112
|
+
}
|
|
23113
|
+
}
|
|
23114
|
+
if (d.type === "add") out.push(`+${d.line}`);
|
|
23115
|
+
else if (d.type === "remove") out.push(`-${d.line}`);
|
|
23116
|
+
else out.push(` ${d.line}`);
|
|
23360
23117
|
}
|
|
23361
|
-
return
|
|
23118
|
+
return out.join("\n");
|
|
23362
23119
|
}
|
|
23363
23120
|
|
|
23364
23121
|
// ../types/src/artifacts.ts
|
|
@@ -23427,102 +23184,392 @@ function normalizeCodexPermissionModeInput(raw) {
|
|
|
23427
23184
|
return isCodexPermissionMode(t) ? t : null;
|
|
23428
23185
|
}
|
|
23429
23186
|
|
|
23430
|
-
// ../types/src/cli-permission-mode.ts
|
|
23431
|
-
var CLI_PERMISSION_MODE_DEFAULT = "default";
|
|
23432
|
-
var CLI_PERMISSION_MODE_DANGEROUS = "dangerous";
|
|
23433
|
-
function normalizeCliPermissionModeInput(raw) {
|
|
23434
|
-
if (typeof raw !== "string") return CLI_PERMISSION_MODE_DEFAULT;
|
|
23435
|
-
const t = raw.trim();
|
|
23436
|
-
if (t === CLI_PERMISSION_MODE_DANGEROUS) return CLI_PERMISSION_MODE_DANGEROUS;
|
|
23437
|
-
if (t === "standard") return CLI_PERMISSION_MODE_DEFAULT;
|
|
23438
|
-
return CLI_PERMISSION_MODE_DEFAULT;
|
|
23187
|
+
// ../types/src/cli-permission-mode.ts
|
|
23188
|
+
var CLI_PERMISSION_MODE_DEFAULT = "default";
|
|
23189
|
+
var CLI_PERMISSION_MODE_DANGEROUS = "dangerous";
|
|
23190
|
+
function normalizeCliPermissionModeInput(raw) {
|
|
23191
|
+
if (typeof raw !== "string") return CLI_PERMISSION_MODE_DEFAULT;
|
|
23192
|
+
const t = raw.trim();
|
|
23193
|
+
if (t === CLI_PERMISSION_MODE_DANGEROUS) return CLI_PERMISSION_MODE_DANGEROUS;
|
|
23194
|
+
if (t === "standard") return CLI_PERMISSION_MODE_DEFAULT;
|
|
23195
|
+
return CLI_PERMISSION_MODE_DEFAULT;
|
|
23196
|
+
}
|
|
23197
|
+
|
|
23198
|
+
// ../types/src/acp-permission-auto-approve.ts
|
|
23199
|
+
function isRejectKind(kind) {
|
|
23200
|
+
return kind === "reject_once" || kind === "reject_always";
|
|
23201
|
+
}
|
|
23202
|
+
function normalizeOptions(raw) {
|
|
23203
|
+
if (!Array.isArray(raw)) return [];
|
|
23204
|
+
const out = [];
|
|
23205
|
+
for (const item of raw) {
|
|
23206
|
+
if (item == null || typeof item !== "object" || Array.isArray(item)) continue;
|
|
23207
|
+
const o = item;
|
|
23208
|
+
const rawId = o.optionId ?? o.id;
|
|
23209
|
+
const optionId = typeof rawId === "string" && rawId.trim() !== "" ? rawId.trim() : typeof rawId === "number" && Number.isFinite(rawId) ? String(rawId) : "";
|
|
23210
|
+
if (!optionId) continue;
|
|
23211
|
+
const kind = typeof o.kind === "string" ? o.kind : void 0;
|
|
23212
|
+
out.push({ optionId, ...kind ? { kind } : {} });
|
|
23213
|
+
}
|
|
23214
|
+
return out;
|
|
23215
|
+
}
|
|
23216
|
+
function pickAllowOption(options) {
|
|
23217
|
+
const nonReject = options.filter((o) => !isRejectKind(o.kind));
|
|
23218
|
+
if (nonReject.length === 0) return null;
|
|
23219
|
+
const allowOnce = nonReject.find((o) => o.kind === "allow_once");
|
|
23220
|
+
if (allowOnce) return allowOnce;
|
|
23221
|
+
const notAlways = nonReject.filter((o) => o.kind !== "allow_always");
|
|
23222
|
+
if (notAlways.length > 0) return notAlways[0] ?? null;
|
|
23223
|
+
return nonReject.find((o) => o.kind === "allow_always") ?? nonReject[0] ?? null;
|
|
23224
|
+
}
|
|
23225
|
+
function firstNonEmptyOptionsArray(...candidates) {
|
|
23226
|
+
for (const c of candidates) {
|
|
23227
|
+
if (Array.isArray(c) && c.length > 0) return c;
|
|
23228
|
+
}
|
|
23229
|
+
const fallback = candidates[0];
|
|
23230
|
+
return Array.isArray(fallback) ? fallback : [];
|
|
23231
|
+
}
|
|
23232
|
+
function extractAcpPermissionRequestOptionArray(params) {
|
|
23233
|
+
const toolCall = params.toolCall;
|
|
23234
|
+
const fromToolCall = toolCall != null && typeof toolCall === "object" && !Array.isArray(toolCall) ? toolCall : null;
|
|
23235
|
+
return firstNonEmptyOptionsArray(
|
|
23236
|
+
params.options,
|
|
23237
|
+
params.permissionOptions,
|
|
23238
|
+
fromToolCall?.options,
|
|
23239
|
+
fromToolCall?.permissionOptions
|
|
23240
|
+
);
|
|
23241
|
+
}
|
|
23242
|
+
function buildCliAutoApprovedPermissionRpcResult(requestParams) {
|
|
23243
|
+
const opt = pickAllowOption(normalizeOptions(extractAcpPermissionRequestOptionArray(requestParams)));
|
|
23244
|
+
if (!opt) return null;
|
|
23245
|
+
const kind = opt.kind?.trim();
|
|
23246
|
+
return {
|
|
23247
|
+
outcome: {
|
|
23248
|
+
outcome: "selected",
|
|
23249
|
+
optionId: opt.optionId,
|
|
23250
|
+
...kind ? { _meta: { permissionOptionKind: kind } } : {}
|
|
23251
|
+
}
|
|
23252
|
+
};
|
|
23253
|
+
}
|
|
23254
|
+
|
|
23255
|
+
// ../types/src/agent-config.ts
|
|
23256
|
+
var AGENT_CONFIG_CLAUDE_PERMISSION_MODE_KEY = "claude_permission_mode";
|
|
23257
|
+
var AGENT_CONFIG_CLI_PERMISSION_MODE_KEY = "cli_permission_mode";
|
|
23258
|
+
var AGENT_CONFIG_CODEX_PERMISSION_MODE_KEY = "codex_permission_mode";
|
|
23259
|
+
var AGENT_CONFIG_AGENT_MODEL_KEY = "agent_model";
|
|
23260
|
+
function getClaudePermissionModeFromAgentConfig(config2) {
|
|
23261
|
+
if (!config2) return null;
|
|
23262
|
+
const raw = config2[AGENT_CONFIG_CLAUDE_PERMISSION_MODE_KEY];
|
|
23263
|
+
if (typeof raw !== "string") return null;
|
|
23264
|
+
const t = raw.trim();
|
|
23265
|
+
return isClaudeCodePermissionMode(t) ? t : null;
|
|
23266
|
+
}
|
|
23267
|
+
function getCliPermissionModeFromAgentConfig(config2) {
|
|
23268
|
+
if (!config2) return CLI_PERMISSION_MODE_DEFAULT;
|
|
23269
|
+
return normalizeCliPermissionModeInput(config2[AGENT_CONFIG_CLI_PERMISSION_MODE_KEY]);
|
|
23270
|
+
}
|
|
23271
|
+
function getCodexPermissionModeFromAgentConfig(config2) {
|
|
23272
|
+
if (!config2) return null;
|
|
23273
|
+
return normalizeCodexPermissionModeInput(config2[AGENT_CONFIG_CODEX_PERMISSION_MODE_KEY]);
|
|
23274
|
+
}
|
|
23275
|
+
function getAgentModelFromAgentConfig(config2) {
|
|
23276
|
+
if (!config2) return null;
|
|
23277
|
+
const cur = config2[AGENT_CONFIG_AGENT_MODEL_KEY];
|
|
23278
|
+
if (typeof cur !== "string") return null;
|
|
23279
|
+
const t = cur.trim();
|
|
23280
|
+
return t !== "" ? t : null;
|
|
23281
|
+
}
|
|
23282
|
+
|
|
23283
|
+
// src/agents/acp/safe-fs-path.ts
|
|
23284
|
+
import * as path2 from "node:path";
|
|
23285
|
+
function resolveSafePathUnderCwd(cwd, filePath) {
|
|
23286
|
+
const trimmed2 = filePath.trim();
|
|
23287
|
+
if (!trimmed2) return null;
|
|
23288
|
+
const normalizedCwd = path2.resolve(cwd);
|
|
23289
|
+
const resolved = path2.isAbsolute(trimmed2) ? path2.normalize(trimmed2) : path2.resolve(normalizedCwd, trimmed2);
|
|
23290
|
+
const rel = path2.relative(normalizedCwd, resolved);
|
|
23291
|
+
if (rel.startsWith("..") || path2.isAbsolute(rel)) return null;
|
|
23292
|
+
return resolved;
|
|
23293
|
+
}
|
|
23294
|
+
function toDisplayPathRelativeToCwd(cwd, absolutePath) {
|
|
23295
|
+
const normalizedCwd = path2.resolve(cwd);
|
|
23296
|
+
const rel = path2.relative(normalizedCwd, path2.resolve(absolutePath));
|
|
23297
|
+
if (!rel || rel === "") return path2.basename(absolutePath);
|
|
23298
|
+
return rel.split(path2.sep).join("/");
|
|
23299
|
+
}
|
|
23300
|
+
|
|
23301
|
+
// src/agents/acp/clients/shared/acp-fs-read-write.ts
|
|
23302
|
+
function sliceFileContentForAcp(content, line, limit) {
|
|
23303
|
+
if (line == null && limit == null) return content;
|
|
23304
|
+
const lines = content.split("\n");
|
|
23305
|
+
const start = line != null && line > 0 ? line - 1 : 0;
|
|
23306
|
+
const end = limit != null && limit > 0 ? start + limit : lines.length;
|
|
23307
|
+
return lines.slice(start, end).join("\n");
|
|
23308
|
+
}
|
|
23309
|
+
function acpReadTextFileInProcess(ctx, filePath, line, limit) {
|
|
23310
|
+
const resolvedPath = resolveSafePathUnderCwd(ctx.cwd, filePath);
|
|
23311
|
+
if (!resolvedPath) throw new Error("Invalid or disallowed path");
|
|
23312
|
+
try {
|
|
23313
|
+
let content = readFileSync(resolvedPath, "utf8");
|
|
23314
|
+
content = sliceFileContentForAcp(content, line, limit);
|
|
23315
|
+
return { content };
|
|
23316
|
+
} catch (e) {
|
|
23317
|
+
if (e.code === "ENOENT") return { content: "" };
|
|
23318
|
+
throw e;
|
|
23319
|
+
}
|
|
23320
|
+
}
|
|
23321
|
+
function acpWriteTextFileInProcess(ctx, filePath, newText) {
|
|
23322
|
+
const resolvedPath = resolveSafePathUnderCwd(ctx.cwd, filePath);
|
|
23323
|
+
if (!resolvedPath) throw new Error("Invalid or disallowed path");
|
|
23324
|
+
let oldText = "";
|
|
23325
|
+
try {
|
|
23326
|
+
oldText = readFileSync(resolvedPath, "utf8");
|
|
23327
|
+
} catch (e) {
|
|
23328
|
+
if (e.code !== "ENOENT") throw e;
|
|
23329
|
+
}
|
|
23330
|
+
mkdirSync(dirname(resolvedPath), { recursive: true });
|
|
23331
|
+
writeFileSync(resolvedPath, newText, "utf8");
|
|
23332
|
+
const displayPath = toDisplayPathRelativeToCwd(ctx.cwd, resolvedPath);
|
|
23333
|
+
const patchContent = editSnippetToUnifiedDiff(displayPath, oldText, newText);
|
|
23334
|
+
ctx.onFileChange?.({ path: displayPath, oldText, newText, patchContent });
|
|
23335
|
+
return {};
|
|
23336
|
+
}
|
|
23337
|
+
|
|
23338
|
+
// src/agents/acp/clients/shared/dispatch-session-update.ts
|
|
23339
|
+
function dispatchAcpSessionUpdate(opts) {
|
|
23340
|
+
const { flatPayload, onAcpConfigOptionsUpdated, onSessionUpdate, suppressLoadReplay } = opts;
|
|
23341
|
+
const su = flatPayload.sessionUpdate ?? flatPayload.session_update;
|
|
23342
|
+
if (su === "config_option_update") {
|
|
23343
|
+
const co = flatPayload.configOptions;
|
|
23344
|
+
if (Array.isArray(co)) onAcpConfigOptionsUpdated?.(co);
|
|
23345
|
+
return;
|
|
23346
|
+
}
|
|
23347
|
+
if (suppressLoadReplay()) return;
|
|
23348
|
+
onSessionUpdate?.(flatPayload);
|
|
23349
|
+
}
|
|
23350
|
+
|
|
23351
|
+
// src/agents/acp/clients/shared/flatten-sdk-session-notification.ts
|
|
23352
|
+
function flattenSdkSessionNotificationParams(params) {
|
|
23353
|
+
return { sessionId: params.sessionId, ...params.update };
|
|
23354
|
+
}
|
|
23355
|
+
|
|
23356
|
+
// src/agents/acp/clients/kiro-sdk-ext-notifications.ts
|
|
23357
|
+
function createKiroSdkExtNotificationHandler(options) {
|
|
23358
|
+
const { onSessionUpdate } = options;
|
|
23359
|
+
return async (method, params) => {
|
|
23360
|
+
if (method === "_kiro.dev/metadata") {
|
|
23361
|
+
const p = params && typeof params === "object" ? params : {};
|
|
23362
|
+
const pct = p.contextUsagePercentage;
|
|
23363
|
+
if (typeof pct !== "number" || !Number.isFinite(pct) || !onSessionUpdate) return;
|
|
23364
|
+
onSessionUpdate({
|
|
23365
|
+
sessionUpdate: "context_usage",
|
|
23366
|
+
contextUsagePercentage: pct
|
|
23367
|
+
});
|
|
23368
|
+
return;
|
|
23369
|
+
}
|
|
23370
|
+
};
|
|
23371
|
+
}
|
|
23372
|
+
|
|
23373
|
+
// src/agents/acp/clients/sdk/sdk-stdio-ext-notifications.ts
|
|
23374
|
+
var noopExtNotification = async () => {
|
|
23375
|
+
};
|
|
23376
|
+
function createSdkStdioExtNotificationHandler(options) {
|
|
23377
|
+
const { backendAgentType, onSessionUpdate } = options;
|
|
23378
|
+
switch (backendAgentType) {
|
|
23379
|
+
case "kiro-acp":
|
|
23380
|
+
return createKiroSdkExtNotificationHandler({ onSessionUpdate });
|
|
23381
|
+
default:
|
|
23382
|
+
return noopExtNotification;
|
|
23383
|
+
}
|
|
23384
|
+
}
|
|
23385
|
+
|
|
23386
|
+
// src/agents/acp/clients/sdk/sdk-stdio-permission-request-handshake.ts
|
|
23387
|
+
function awaitSdkStdioPermissionRequestHandshake(params) {
|
|
23388
|
+
const { requestId, paramsRecord, pending, onRequest } = params;
|
|
23389
|
+
return new Promise((resolve20) => {
|
|
23390
|
+
pending.set(requestId, { resolve: resolve20, params: paramsRecord });
|
|
23391
|
+
if (onRequest == null) {
|
|
23392
|
+
pending.delete(requestId);
|
|
23393
|
+
resolve20({ outcome: { outcome: "denied" } });
|
|
23394
|
+
return;
|
|
23395
|
+
}
|
|
23396
|
+
try {
|
|
23397
|
+
onRequest({
|
|
23398
|
+
requestId,
|
|
23399
|
+
method: "session/request_permission",
|
|
23400
|
+
params: paramsRecord
|
|
23401
|
+
});
|
|
23402
|
+
} catch {
|
|
23403
|
+
}
|
|
23404
|
+
});
|
|
23405
|
+
}
|
|
23406
|
+
|
|
23407
|
+
// src/agents/acp/clients/sdk/sdk-stdio-permission-pending.ts
|
|
23408
|
+
function resolvePendingSdkStdioPermissionCancellations(pending) {
|
|
23409
|
+
for (const [id, entry] of [...pending.entries()]) {
|
|
23410
|
+
pending.delete(id);
|
|
23411
|
+
entry.resolve({ outcome: { outcome: "cancelled" } });
|
|
23412
|
+
}
|
|
23439
23413
|
}
|
|
23440
23414
|
|
|
23441
|
-
//
|
|
23442
|
-
function
|
|
23443
|
-
|
|
23444
|
-
|
|
23445
|
-
|
|
23446
|
-
|
|
23447
|
-
|
|
23448
|
-
|
|
23449
|
-
|
|
23450
|
-
|
|
23451
|
-
|
|
23452
|
-
|
|
23453
|
-
|
|
23454
|
-
|
|
23455
|
-
|
|
23456
|
-
|
|
23457
|
-
|
|
23415
|
+
// src/agents/acp/clients/sdk/sdk-stdio-connection-client.ts
|
|
23416
|
+
function createSdkStdioConnectionClient(deps) {
|
|
23417
|
+
const { backendAgentType, onSessionUpdate, onRequest, sessionCtx, pendingPermissionReplies } = deps;
|
|
23418
|
+
const extNotification = createSdkStdioExtNotificationHandler({
|
|
23419
|
+
backendAgentType,
|
|
23420
|
+
onSessionUpdate
|
|
23421
|
+
});
|
|
23422
|
+
let permissionSeq = 0;
|
|
23423
|
+
return (_agent) => ({
|
|
23424
|
+
async requestPermission(params) {
|
|
23425
|
+
const requestId = `perm-${++permissionSeq}`;
|
|
23426
|
+
const paramsRecord = params != null && typeof params === "object" ? params : {};
|
|
23427
|
+
return await awaitSdkStdioPermissionRequestHandshake({
|
|
23428
|
+
requestId,
|
|
23429
|
+
paramsRecord,
|
|
23430
|
+
pending: pendingPermissionReplies,
|
|
23431
|
+
onRequest
|
|
23432
|
+
});
|
|
23433
|
+
},
|
|
23434
|
+
async readTextFile(params) {
|
|
23435
|
+
return acpReadTextFileInProcess(sessionCtx, params.path, params.line, params.limit);
|
|
23436
|
+
},
|
|
23437
|
+
async writeTextFile(params) {
|
|
23438
|
+
return acpWriteTextFileInProcess(sessionCtx, params.path, params.content);
|
|
23439
|
+
},
|
|
23440
|
+
async sessionUpdate(params) {
|
|
23441
|
+
const bridged = flattenSdkSessionNotificationParams(params);
|
|
23442
|
+
dispatchAcpSessionUpdate({
|
|
23443
|
+
flatPayload: bridged,
|
|
23444
|
+
onAcpConfigOptionsUpdated: sessionCtx.onAcpConfigOptionsUpdated,
|
|
23445
|
+
onSessionUpdate,
|
|
23446
|
+
suppressLoadReplay: () => sessionCtx.suppressLoadReplay.value
|
|
23447
|
+
});
|
|
23448
|
+
},
|
|
23449
|
+
async extNotification(method, params) {
|
|
23450
|
+
await extNotification(method, params);
|
|
23451
|
+
}
|
|
23452
|
+
});
|
|
23458
23453
|
}
|
|
23459
|
-
function
|
|
23460
|
-
const
|
|
23461
|
-
if (
|
|
23462
|
-
|
|
23463
|
-
|
|
23464
|
-
|
|
23465
|
-
if (notAlways.length > 0) return notAlways[0] ?? null;
|
|
23466
|
-
return nonReject.find((o) => o.kind === "allow_always") ?? nonReject[0] ?? null;
|
|
23454
|
+
function resolveSdkStdioPermissionRequest(pendingPermissionReplies, requestId, result) {
|
|
23455
|
+
const entry = pendingPermissionReplies.get(requestId);
|
|
23456
|
+
if (!entry) return;
|
|
23457
|
+
pendingPermissionReplies.delete(requestId);
|
|
23458
|
+
const enriched = enrichAcpPermissionRpcResultFromRequestParams(result, entry.params);
|
|
23459
|
+
entry.resolve(enriched);
|
|
23467
23460
|
}
|
|
23468
|
-
|
|
23469
|
-
|
|
23470
|
-
|
|
23461
|
+
|
|
23462
|
+
// src/agents/acp/clients/sdk/create-sdk-stdio-handle.ts
|
|
23463
|
+
function createSdkStdioHandle(options) {
|
|
23464
|
+
let teardownStarted = false;
|
|
23465
|
+
async function disconnectGracefully() {
|
|
23466
|
+
if (teardownStarted) return;
|
|
23467
|
+
teardownStarted = true;
|
|
23468
|
+
await gracefulAcpSubprocessDisconnect({
|
|
23469
|
+
child: options.child,
|
|
23470
|
+
sessionId: options.sessionId,
|
|
23471
|
+
transport: options.transport,
|
|
23472
|
+
resolvePendingPermissionCancellations: () => resolvePendingSdkStdioPermissionCancellations(options.pendingPermissionReplies)
|
|
23473
|
+
});
|
|
23471
23474
|
}
|
|
23472
|
-
const fallback = candidates[0];
|
|
23473
|
-
return Array.isArray(fallback) ? fallback : [];
|
|
23474
|
-
}
|
|
23475
|
-
function extractAcpPermissionRequestOptionArray(params) {
|
|
23476
|
-
const toolCall = params.toolCall;
|
|
23477
|
-
const fromToolCall = toolCall != null && typeof toolCall === "object" && !Array.isArray(toolCall) ? toolCall : null;
|
|
23478
|
-
return firstNonEmptyOptionsArray(
|
|
23479
|
-
params.options,
|
|
23480
|
-
params.permissionOptions,
|
|
23481
|
-
fromToolCall?.options,
|
|
23482
|
-
fromToolCall?.permissionOptions
|
|
23483
|
-
);
|
|
23484
|
-
}
|
|
23485
|
-
function buildCliAutoApprovedPermissionRpcResult(requestParams) {
|
|
23486
|
-
const opt = pickAllowOption(normalizeOptions(extractAcpPermissionRequestOptionArray(requestParams)));
|
|
23487
|
-
if (!opt) return null;
|
|
23488
|
-
const kind = opt.kind?.trim();
|
|
23489
23475
|
return {
|
|
23490
|
-
|
|
23491
|
-
|
|
23492
|
-
|
|
23493
|
-
|
|
23476
|
+
sessionId: options.sessionId,
|
|
23477
|
+
async sendPrompt(prompt, sendOptions) {
|
|
23478
|
+
const imgs = sendOptions?.images?.map((im) => ({
|
|
23479
|
+
type: "image",
|
|
23480
|
+
mimeType: im.mimeType,
|
|
23481
|
+
data: im.dataBase64
|
|
23482
|
+
}));
|
|
23483
|
+
return sendAcpPromptViaTransport(
|
|
23484
|
+
options.transport,
|
|
23485
|
+
options.sessionCtx,
|
|
23486
|
+
options.sessionId,
|
|
23487
|
+
prompt,
|
|
23488
|
+
imgs
|
|
23489
|
+
);
|
|
23490
|
+
},
|
|
23491
|
+
async cancel() {
|
|
23492
|
+
resolvePendingSdkStdioPermissionCancellations(options.pendingPermissionReplies);
|
|
23493
|
+
try {
|
|
23494
|
+
await options.transport.cancelSession(options.sessionId);
|
|
23495
|
+
} catch {
|
|
23496
|
+
}
|
|
23497
|
+
if (options.killSubprocessAfterCancelMs != null && options.killSubprocessAfterCancelMs >= 0) {
|
|
23498
|
+
const t = setTimeout(() => {
|
|
23499
|
+
if (options.child.exitCode == null && options.child.signalCode == null) {
|
|
23500
|
+
void disconnectGracefully();
|
|
23501
|
+
}
|
|
23502
|
+
}, options.killSubprocessAfterCancelMs);
|
|
23503
|
+
t.unref?.();
|
|
23504
|
+
}
|
|
23505
|
+
},
|
|
23506
|
+
resolveRequest(requestId, result) {
|
|
23507
|
+
resolveSdkStdioPermissionRequest(options.pendingPermissionReplies, requestId, result);
|
|
23508
|
+
},
|
|
23509
|
+
disconnectGracefully,
|
|
23510
|
+
disconnect() {
|
|
23511
|
+
void disconnectGracefully();
|
|
23494
23512
|
}
|
|
23495
23513
|
};
|
|
23496
23514
|
}
|
|
23497
23515
|
|
|
23498
|
-
//
|
|
23499
|
-
var
|
|
23500
|
-
|
|
23501
|
-
|
|
23502
|
-
var AGENT_CONFIG_AGENT_MODEL_KEY = "agent_model";
|
|
23503
|
-
function getClaudePermissionModeFromAgentConfig(config2) {
|
|
23504
|
-
if (!config2) return null;
|
|
23505
|
-
const raw = config2[AGENT_CONFIG_CLAUDE_PERMISSION_MODE_KEY];
|
|
23506
|
-
if (typeof raw !== "string") return null;
|
|
23507
|
-
const t = raw.trim();
|
|
23508
|
-
return isClaudeCodePermissionMode(t) ? t : null;
|
|
23516
|
+
// src/cli-log-level.ts
|
|
23517
|
+
var verbosity = "info";
|
|
23518
|
+
function setCliLogVerbosity(level) {
|
|
23519
|
+
verbosity = level;
|
|
23509
23520
|
}
|
|
23510
|
-
function
|
|
23511
|
-
|
|
23512
|
-
return normalizeCliPermissionModeInput(config2[AGENT_CONFIG_CLI_PERMISSION_MODE_KEY]);
|
|
23521
|
+
function getCliLogVerbosity() {
|
|
23522
|
+
return verbosity;
|
|
23513
23523
|
}
|
|
23514
|
-
function
|
|
23515
|
-
|
|
23516
|
-
return normalizeCodexPermissionModeInput(config2[AGENT_CONFIG_CODEX_PERMISSION_MODE_KEY]);
|
|
23524
|
+
function isCliTrace() {
|
|
23525
|
+
return verbosity === "trace";
|
|
23517
23526
|
}
|
|
23518
|
-
|
|
23519
|
-
|
|
23520
|
-
|
|
23521
|
-
|
|
23522
|
-
|
|
23523
|
-
|
|
23527
|
+
|
|
23528
|
+
// src/log.ts
|
|
23529
|
+
function timestampPrefix() {
|
|
23530
|
+
const time3 = (/* @__PURE__ */ new Date()).toISOString().slice(11, 19);
|
|
23531
|
+
return `[${time3}]`;
|
|
23532
|
+
}
|
|
23533
|
+
function log(line) {
|
|
23534
|
+
console.log(`${timestampPrefix()} ${line}`);
|
|
23535
|
+
}
|
|
23536
|
+
function logImmediate(line) {
|
|
23537
|
+
process.stdout.write(`${timestampPrefix()} ${line}
|
|
23538
|
+
`);
|
|
23539
|
+
}
|
|
23540
|
+
function logDebug(line) {
|
|
23541
|
+
const v = getCliLogVerbosity();
|
|
23542
|
+
if (v !== "debug" && v !== "trace") return;
|
|
23543
|
+
console.log(`${timestampPrefix()} [debug] ${line}`);
|
|
23544
|
+
}
|
|
23545
|
+
function logTrace(line) {
|
|
23546
|
+
if (getCliLogVerbosity() !== "trace") return;
|
|
23547
|
+
console.log(`${timestampPrefix()} [trace] ${line}`);
|
|
23548
|
+
}
|
|
23549
|
+
|
|
23550
|
+
// src/agents/acp/clients/sdk/create-sdk-stdio-session-context.ts
|
|
23551
|
+
function createSdkStdioSessionContext(options) {
|
|
23552
|
+
const suppressLoadReplayRef = { value: false };
|
|
23553
|
+
return {
|
|
23554
|
+
cwd: options.cwd,
|
|
23555
|
+
onFileChange: options.onFileChange,
|
|
23556
|
+
mcpServers: [],
|
|
23557
|
+
persistedAcpSessionId: options.persistedAcpSessionId,
|
|
23558
|
+
agentLabel: "ACP",
|
|
23559
|
+
suppressLoadReplay: suppressLoadReplayRef,
|
|
23560
|
+
backendAgentType: options.backendAgentType ?? null,
|
|
23561
|
+
agentConfig: options.agentConfig,
|
|
23562
|
+
getActiveConfigOptions: options.getActiveConfigOptions,
|
|
23563
|
+
onAcpSessionEstablished: options.onAcpSessionEstablished,
|
|
23564
|
+
onAcpConfigOptionsUpdated: options.onAcpConfigOptionsUpdated,
|
|
23565
|
+
logDebug,
|
|
23566
|
+
getStderrText: () => options.stderrCapture.getText()
|
|
23567
|
+
};
|
|
23524
23568
|
}
|
|
23525
23569
|
|
|
23570
|
+
// src/agents/acp/clients/sdk/sdk-stdio-bootstrap-connection.ts
|
|
23571
|
+
import { Readable, Writable } from "node:stream";
|
|
23572
|
+
|
|
23526
23573
|
// src/agents/acp/claude-acp-permission-from-session.ts
|
|
23527
23574
|
function flattenSelectOptions(options) {
|
|
23528
23575
|
if (options == null || options.length === 0) return [];
|
|
@@ -24421,7 +24468,7 @@ function installBridgeProcessResilience() {
|
|
|
24421
24468
|
}
|
|
24422
24469
|
|
|
24423
24470
|
// src/cli-version.ts
|
|
24424
|
-
var CLI_VERSION = "0.1.
|
|
24471
|
+
var CLI_VERSION = "0.1.43".length > 0 ? "0.1.43" : "0.0.0-dev";
|
|
24425
24472
|
|
|
24426
24473
|
// src/connection/heartbeat/constants.ts
|
|
24427
24474
|
var BRIDGE_APP_HEARTBEAT_INTERVAL_MS = 1e4;
|
|
@@ -26066,18 +26113,6 @@ async function closeBridgeConnection(state, acpManager, devServerManager, log2)
|
|
|
26066
26113
|
say("Shutdown complete.");
|
|
26067
26114
|
}
|
|
26068
26115
|
|
|
26069
|
-
// src/agents/acp/acp-idle-disconnect-ms.ts
|
|
26070
|
-
var DEFAULT_ACP_IDLE_DISCONNECT_MS = 10 * 60 * 1e3;
|
|
26071
|
-
function resolveAcpIdleDisconnectMs() {
|
|
26072
|
-
const raw = process.env.BUILDAUTOMATON_ACP_IDLE_DISCONNECT_MS;
|
|
26073
|
-
if (raw === "0") return 0;
|
|
26074
|
-
if (raw != null && raw.trim() !== "") {
|
|
26075
|
-
const parsed = Number(raw);
|
|
26076
|
-
if (Number.isFinite(parsed) && parsed >= 0) return parsed;
|
|
26077
|
-
}
|
|
26078
|
-
return DEFAULT_ACP_IDLE_DISCONNECT_MS;
|
|
26079
|
-
}
|
|
26080
|
-
|
|
26081
26116
|
// src/agents/acp/acp-prompt-routing-registry.ts
|
|
26082
26117
|
var AcpPromptRoutingRegistry = class {
|
|
26083
26118
|
runs = /* @__PURE__ */ new Map();
|
|
@@ -26127,9 +26162,7 @@ function createAcpManagerContext(options) {
|
|
|
26127
26162
|
acpAgents: /* @__PURE__ */ new Map(),
|
|
26128
26163
|
promptRouting: new AcpPromptRoutingRegistry(),
|
|
26129
26164
|
runDispatch: /* @__PURE__ */ new Map(),
|
|
26130
|
-
pendingCancelRunIds: /* @__PURE__ */ new Set()
|
|
26131
|
-
idleDisconnectTimers: /* @__PURE__ */ new Map(),
|
|
26132
|
-
idleDisconnectMs: options.idleDisconnectMs
|
|
26165
|
+
pendingCancelRunIds: /* @__PURE__ */ new Set()
|
|
26133
26166
|
};
|
|
26134
26167
|
}
|
|
26135
26168
|
|
|
@@ -27860,55 +27893,8 @@ async function ensureAcpClient(options) {
|
|
|
27860
27893
|
return state.acpStartPromise;
|
|
27861
27894
|
}
|
|
27862
27895
|
|
|
27863
|
-
// src/agents/acp/manager/idle-disconnect.ts
|
|
27864
|
-
function hasActiveWorkForAcpAgent(ctx, acpAgentKey) {
|
|
27865
|
-
if (ctx.promptRouting.getStreamingRunId(acpAgentKey)) return true;
|
|
27866
|
-
for (const meta of ctx.runDispatch.values()) {
|
|
27867
|
-
if (meta.acpAgentKey === acpAgentKey) return true;
|
|
27868
|
-
}
|
|
27869
|
-
return false;
|
|
27870
|
-
}
|
|
27871
|
-
function clearIdleDisconnectTimer(ctx, acpAgentKey) {
|
|
27872
|
-
const timer = ctx.idleDisconnectTimers.get(acpAgentKey);
|
|
27873
|
-
if (timer == null) return;
|
|
27874
|
-
clearTimeout(timer);
|
|
27875
|
-
ctx.idleDisconnectTimers.delete(acpAgentKey);
|
|
27876
|
-
}
|
|
27877
|
-
function disconnectIdleAcpAgent(ctx, acpAgentKey) {
|
|
27878
|
-
clearIdleDisconnectTimer(ctx, acpAgentKey);
|
|
27879
|
-
if (hasActiveWorkForAcpAgent(ctx, acpAgentKey)) return;
|
|
27880
|
-
const state = ctx.acpAgents.get(acpAgentKey);
|
|
27881
|
-
if (!state?.acpHandle && !state?.acpStartPromise) {
|
|
27882
|
-
ctx.acpAgents.delete(acpAgentKey);
|
|
27883
|
-
return;
|
|
27884
|
-
}
|
|
27885
|
-
const handle = state.acpHandle;
|
|
27886
|
-
void (async () => {
|
|
27887
|
-
try {
|
|
27888
|
-
await handle?.disconnectGracefully();
|
|
27889
|
-
} catch {
|
|
27890
|
-
}
|
|
27891
|
-
invalidateAcpClientState(state);
|
|
27892
|
-
ctx.acpAgents.delete(acpAgentKey);
|
|
27893
|
-
logDebug(`[Agent] Idle disconnect (${acpAgentKey.split("::")[0] ?? acpAgentKey})`);
|
|
27894
|
-
})();
|
|
27895
|
-
}
|
|
27896
|
-
function scheduleIdleDisconnect(ctx, acpAgentKey) {
|
|
27897
|
-
if (ctx.idleDisconnectMs <= 0) return;
|
|
27898
|
-
clearIdleDisconnectTimer(ctx, acpAgentKey);
|
|
27899
|
-
const timer = setTimeout(() => {
|
|
27900
|
-
ctx.idleDisconnectTimers.delete(acpAgentKey);
|
|
27901
|
-
disconnectIdleAcpAgent(ctx, acpAgentKey);
|
|
27902
|
-
}, ctx.idleDisconnectMs);
|
|
27903
|
-
timer.unref?.();
|
|
27904
|
-
ctx.idleDisconnectTimers.set(acpAgentKey, timer);
|
|
27905
|
-
}
|
|
27906
|
-
|
|
27907
27896
|
// src/agents/acp/manager/disconnect-all.ts
|
|
27908
27897
|
async function disconnectAll(ctx) {
|
|
27909
|
-
for (const acpAgentKey of ctx.idleDisconnectTimers.keys()) {
|
|
27910
|
-
clearIdleDisconnectTimer(ctx, acpAgentKey);
|
|
27911
|
-
}
|
|
27912
27898
|
await Promise.all(
|
|
27913
27899
|
[...ctx.acpAgents.values()].map(async (state) => {
|
|
27914
27900
|
try {
|
|
@@ -33245,7 +33231,6 @@ function handlePrompt(ctx, opts) {
|
|
|
33245
33231
|
}
|
|
33246
33232
|
const activeAcpAgentKey = acpAgentKey;
|
|
33247
33233
|
ctx.pendingCancelRunIds.delete(activeRunId);
|
|
33248
|
-
clearIdleDisconnectTimer(ctx, activeAcpAgentKey);
|
|
33249
33234
|
ctx.promptRouting.registerRun({ sessionId, runId: activeRunId });
|
|
33250
33235
|
ctx.runDispatch.set(activeRunId, { acpAgentKey: activeAcpAgentKey });
|
|
33251
33236
|
async function run() {
|
|
@@ -33328,7 +33313,6 @@ function handlePrompt(ctx, opts) {
|
|
|
33328
33313
|
ctx.promptRouting.unregisterRun(activeRunId);
|
|
33329
33314
|
ctx.runDispatch.delete(activeRunId);
|
|
33330
33315
|
ctx.pendingCancelRunIds.delete(activeRunId);
|
|
33331
|
-
scheduleIdleDisconnect(ctx, activeAcpAgentKey);
|
|
33332
33316
|
});
|
|
33333
33317
|
}
|
|
33334
33318
|
|
|
@@ -33346,8 +33330,7 @@ function logPromptReceivedFromBridge(ctx, opts) {
|
|
|
33346
33330
|
async function createAcpManager(options) {
|
|
33347
33331
|
const ctx = createAcpManagerContext({
|
|
33348
33332
|
log: options.log,
|
|
33349
|
-
reportAgentCapabilities: options.reportAgentCapabilities
|
|
33350
|
-
idleDisconnectMs: resolveAcpIdleDisconnectMs()
|
|
33333
|
+
reportAgentCapabilities: options.reportAgentCapabilities
|
|
33351
33334
|
});
|
|
33352
33335
|
return {
|
|
33353
33336
|
setPreferredAgentType(agentType) {
|
|
@@ -33854,12 +33837,16 @@ async function hydrateUnifiedPatchWithFileContext(patch, filePath, repoGitCwd, p
|
|
|
33854
33837
|
}
|
|
33855
33838
|
|
|
33856
33839
|
// src/git/changes/unified-diff-for-file.ts
|
|
33840
|
+
function patchTextFromGitDiffOutput(raw) {
|
|
33841
|
+
if (raw.trim() === "") return void 0;
|
|
33842
|
+
return normalizePatchContent(raw);
|
|
33843
|
+
}
|
|
33857
33844
|
async function unifiedDiffForFile(repoCwd, pathInRepo, change) {
|
|
33858
33845
|
const g = cliSimpleGit(repoCwd);
|
|
33859
33846
|
const args = change === "added" ? ["diff", "--no-color", "HEAD", "--", pathInRepo] : change === "removed" ? ["diff", "--no-color", "HEAD", "--", pathInRepo] : ["diff", "--no-color", "HEAD", "--", pathInRepo];
|
|
33860
33847
|
const raw = await g.raw([...args]).catch(() => "");
|
|
33861
|
-
const
|
|
33862
|
-
return
|
|
33848
|
+
const patch = patchTextFromGitDiffOutput(String(raw));
|
|
33849
|
+
return patch ? truncatePatch(patch) : void 0;
|
|
33863
33850
|
}
|
|
33864
33851
|
|
|
33865
33852
|
// src/git/changes/list-changed-files-for-repo.ts
|