@buildautomaton/cli 0.1.42 → 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/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"]);
@@ -23361,6 +23025,99 @@ function dedupeSessionFileChangesByPath(items, richness = (item) => defaultRichn
23361
23025
  return Array.from(byPath.entries()).sort(([a], [b]) => a.localeCompare(b)).map(([, v]) => v);
23362
23026
  }
23363
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--;
23091
+ }
23092
+ }
23093
+ const eofNewlineChange = detectEofNewlineChange(oldText, newText, oldLines, newLines);
23094
+ if (eofNewlineChange) result.push(createEofNewlineDiffLine(eofNewlineChange));
23095
+ return result;
23096
+ }
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}`);
23117
+ }
23118
+ return out.join("\n");
23119
+ }
23120
+
23364
23121
  // ../types/src/artifacts.ts
23365
23122
  init_zod();
23366
23123
  var ArtifactMetaSchema = external_exports.object({
@@ -23438,91 +23195,381 @@ function normalizeCliPermissionModeInput(raw) {
23438
23195
  return CLI_PERMISSION_MODE_DEFAULT;
23439
23196
  }
23440
23197
 
23441
- // ../types/src/acp-permission-auto-approve.ts
23442
- function isRejectKind(kind) {
23443
- return kind === "reject_once" || kind === "reject_always";
23444
- }
23445
- function normalizeOptions(raw) {
23446
- if (!Array.isArray(raw)) return [];
23447
- const out = [];
23448
- for (const item of raw) {
23449
- if (item == null || typeof item !== "object" || Array.isArray(item)) continue;
23450
- const o = item;
23451
- const rawId = o.optionId ?? o.id;
23452
- const optionId = typeof rawId === "string" && rawId.trim() !== "" ? rawId.trim() : typeof rawId === "number" && Number.isFinite(rawId) ? String(rawId) : "";
23453
- if (!optionId) continue;
23454
- const kind = typeof o.kind === "string" ? o.kind : void 0;
23455
- out.push({ optionId, ...kind ? { kind } : {} });
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;
23456
23383
  }
23457
- return out;
23458
23384
  }
23459
- function pickAllowOption(options) {
23460
- const nonReject = options.filter((o) => !isRejectKind(o.kind));
23461
- if (nonReject.length === 0) return null;
23462
- const allowOnce = nonReject.find((o) => o.kind === "allow_once");
23463
- if (allowOnce) return allowOnce;
23464
- const notAlways = nonReject.filter((o) => o.kind !== "allow_always");
23465
- if (notAlways.length > 0) return notAlways[0] ?? null;
23466
- return nonReject.find((o) => o.kind === "allow_always") ?? nonReject[0] ?? null;
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
+ });
23467
23405
  }
23468
- function firstNonEmptyOptionsArray(...candidates) {
23469
- for (const c of candidates) {
23470
- if (Array.isArray(c) && c.length > 0) return c;
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" } });
23471
23412
  }
23472
- const fallback = candidates[0];
23473
- return Array.isArray(fallback) ? fallback : [];
23474
23413
  }
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
- );
23414
+
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
+ });
23484
23453
  }
23485
- function buildCliAutoApprovedPermissionRpcResult(requestParams) {
23486
- const opt = pickAllowOption(normalizeOptions(extractAcpPermissionRequestOptionArray(requestParams)));
23487
- if (!opt) return null;
23488
- const kind = opt.kind?.trim();
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);
23460
+ }
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
+ });
23474
+ }
23489
23475
  return {
23490
- outcome: {
23491
- outcome: "selected",
23492
- optionId: opt.optionId,
23493
- ...kind ? { _meta: { permissionOptionKind: kind } } : {}
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
- // ../types/src/agent-config.ts
23499
- var AGENT_CONFIG_CLAUDE_PERMISSION_MODE_KEY = "claude_permission_mode";
23500
- var AGENT_CONFIG_CLI_PERMISSION_MODE_KEY = "cli_permission_mode";
23501
- var AGENT_CONFIG_CODEX_PERMISSION_MODE_KEY = "codex_permission_mode";
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 getCliPermissionModeFromAgentConfig(config2) {
23511
- if (!config2) return CLI_PERMISSION_MODE_DEFAULT;
23512
- return normalizeCliPermissionModeInput(config2[AGENT_CONFIG_CLI_PERMISSION_MODE_KEY]);
23521
+ function getCliLogVerbosity() {
23522
+ return verbosity;
23513
23523
  }
23514
- function getCodexPermissionModeFromAgentConfig(config2) {
23515
- if (!config2) return null;
23516
- return normalizeCodexPermissionModeInput(config2[AGENT_CONFIG_CODEX_PERMISSION_MODE_KEY]);
23524
+ function isCliTrace() {
23525
+ return verbosity === "trace";
23517
23526
  }
23518
- function getAgentModelFromAgentConfig(config2) {
23519
- if (!config2) return null;
23520
- const cur = config2[AGENT_CONFIG_AGENT_MODEL_KEY];
23521
- if (typeof cur !== "string") return null;
23522
- const t = cur.trim();
23523
- return t !== "" ? t : null;
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.42".length > 0 ? "0.1.42" : "0.0.0-dev";
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;
@@ -33790,12 +33837,16 @@ async function hydrateUnifiedPatchWithFileContext(patch, filePath, repoGitCwd, p
33790
33837
  }
33791
33838
 
33792
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
+ }
33793
33844
  async function unifiedDiffForFile(repoCwd, pathInRepo, change) {
33794
33845
  const g = cliSimpleGit(repoCwd);
33795
33846
  const args = change === "added" ? ["diff", "--no-color", "HEAD", "--", pathInRepo] : change === "removed" ? ["diff", "--no-color", "HEAD", "--", pathInRepo] : ["diff", "--no-color", "HEAD", "--", pathInRepo];
33796
33847
  const raw = await g.raw([...args]).catch(() => "");
33797
- const t = String(raw).trim();
33798
- return t ? truncatePatch(t) : void 0;
33848
+ const patch = patchTextFromGitDiffOutput(String(raw));
33849
+ return patch ? truncatePatch(patch) : void 0;
33799
33850
  }
33800
33851
 
33801
33852
  // src/git/changes/list-changed-files-for-repo.ts