@buildautomaton/cli 0.1.19 → 0.1.20

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 CHANGED
@@ -974,7 +974,7 @@ var require_command = __commonJS({
974
974
  var EventEmitter2 = __require("node:events").EventEmitter;
975
975
  var childProcess2 = __require("node:child_process");
976
976
  var path36 = __require("node:path");
977
- var fs32 = __require("node:fs");
977
+ var fs34 = __require("node:fs");
978
978
  var process8 = __require("node:process");
979
979
  var { Argument: Argument2, humanReadableArgName } = require_argument();
980
980
  var { CommanderError: CommanderError2 } = require_error();
@@ -1907,10 +1907,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
1907
1907
  const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
1908
1908
  function findFile(baseDir, baseName) {
1909
1909
  const localBin = path36.resolve(baseDir, baseName);
1910
- if (fs32.existsSync(localBin)) return localBin;
1910
+ if (fs34.existsSync(localBin)) return localBin;
1911
1911
  if (sourceExt.includes(path36.extname(baseName))) return void 0;
1912
1912
  const foundExt = sourceExt.find(
1913
- (ext) => fs32.existsSync(`${localBin}${ext}`)
1913
+ (ext) => fs34.existsSync(`${localBin}${ext}`)
1914
1914
  );
1915
1915
  if (foundExt) return `${localBin}${foundExt}`;
1916
1916
  return void 0;
@@ -1922,7 +1922,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1922
1922
  if (this._scriptPath) {
1923
1923
  let resolvedScriptPath;
1924
1924
  try {
1925
- resolvedScriptPath = fs32.realpathSync(this._scriptPath);
1925
+ resolvedScriptPath = fs34.realpathSync(this._scriptPath);
1926
1926
  } catch (err) {
1927
1927
  resolvedScriptPath = this._scriptPath;
1928
1928
  }
@@ -5236,7 +5236,7 @@ var require_websocket = __commonJS({
5236
5236
  var http = __require("http");
5237
5237
  var net = __require("net");
5238
5238
  var tls = __require("tls");
5239
- var { randomBytes: randomBytes3, createHash: createHash3 } = __require("crypto");
5239
+ var { randomBytes: randomBytes3, createHash: createHash2 } = __require("crypto");
5240
5240
  var { Duplex, Readable: Readable2 } = __require("stream");
5241
5241
  var { URL: URL2 } = __require("url");
5242
5242
  var PerMessageDeflate = require_permessage_deflate();
@@ -5896,7 +5896,7 @@ var require_websocket = __commonJS({
5896
5896
  abortHandshake(websocket, socket, "Invalid Upgrade header");
5897
5897
  return;
5898
5898
  }
5899
- const digest = createHash3("sha1").update(key + GUID).digest("base64");
5899
+ const digest = createHash2("sha1").update(key + GUID).digest("base64");
5900
5900
  if (res.headers["sec-websocket-accept"] !== digest) {
5901
5901
  abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
5902
5902
  return;
@@ -6263,7 +6263,7 @@ var require_websocket_server = __commonJS({
6263
6263
  var EventEmitter2 = __require("events");
6264
6264
  var http = __require("http");
6265
6265
  var { Duplex } = __require("stream");
6266
- var { createHash: createHash3 } = __require("crypto");
6266
+ var { createHash: createHash2 } = __require("crypto");
6267
6267
  var extension = require_extension();
6268
6268
  var PerMessageDeflate = require_permessage_deflate();
6269
6269
  var subprotocol = require_subprotocol();
@@ -6564,7 +6564,7 @@ var require_websocket_server = __commonJS({
6564
6564
  );
6565
6565
  }
6566
6566
  if (this._state > RUNNING) return abortHandshake(socket, 503);
6567
- const digest = createHash3("sha1").update(key + GUID).digest("base64");
6567
+ const digest = createHash2("sha1").update(key + GUID).digest("base64");
6568
6568
  const headers = [
6569
6569
  "HTTP/1.1 101 Switching Protocols",
6570
6570
  "Upgrade: websocket",
@@ -7129,7 +7129,7 @@ var require_has_flag = __commonJS({
7129
7129
  var require_supports_color = __commonJS({
7130
7130
  "../../node_modules/.pnpm/supports-color@7.2.0/node_modules/supports-color/index.js"(exports, module) {
7131
7131
  "use strict";
7132
- var os6 = __require("os");
7132
+ var os7 = __require("os");
7133
7133
  var tty = __require("tty");
7134
7134
  var hasFlag = require_has_flag();
7135
7135
  var { env } = process;
@@ -7177,7 +7177,7 @@ var require_supports_color = __commonJS({
7177
7177
  return min;
7178
7178
  }
7179
7179
  if (process.platform === "win32") {
7180
- const osRelease = os6.release().split(".");
7180
+ const osRelease = os7.release().split(".");
7181
7181
  if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
7182
7182
  return Number(osRelease[2]) >= 14931 ? 3 : 2;
7183
7183
  }
@@ -24800,8 +24800,8 @@ var init_acp = __esm({
24800
24800
  this.#requestHandler = requestHandler;
24801
24801
  this.#notificationHandler = notificationHandler;
24802
24802
  this.#stream = stream;
24803
- this.#closedPromise = new Promise((resolve19) => {
24804
- this.#abortController.signal.addEventListener("abort", () => resolve19());
24803
+ this.#closedPromise = new Promise((resolve18) => {
24804
+ this.#abortController.signal.addEventListener("abort", () => resolve18());
24805
24805
  });
24806
24806
  this.#receive();
24807
24807
  }
@@ -24950,8 +24950,8 @@ var init_acp = __esm({
24950
24950
  }
24951
24951
  async sendRequest(method, params) {
24952
24952
  const id = this.#nextRequestId++;
24953
- const responsePromise = new Promise((resolve19, reject) => {
24954
- this.#pendingResponses.set(id, { resolve: resolve19, reject });
24953
+ const responsePromise = new Promise((resolve18, reject) => {
24954
+ this.#pendingResponses.set(id, { resolve: resolve18, reject });
24955
24955
  });
24956
24956
  await this.#sendMessage({ jsonrpc: "2.0", id, method, params });
24957
24957
  return responsePromise;
@@ -25064,14 +25064,14 @@ var {
25064
25064
  } = import_index.default;
25065
25065
 
25066
25066
  // src/cli-version.ts
25067
- var CLI_VERSION = "0.1.19".length > 0 ? "0.1.19" : "0.0.0-dev";
25067
+ var CLI_VERSION = "0.1.20".length > 0 ? "0.1.20" : "0.0.0-dev";
25068
25068
 
25069
25069
  // src/cli/defaults.ts
25070
25070
  var DEFAULT_API_URL = process.env.BUILDAUTOMATON_API_URL ?? "https://api.buildautomaton.com";
25071
25071
  var DEFAULT_FIREHOSE_URL = "https://buildautomaton-firehose.fly.dev";
25072
25072
 
25073
25073
  // src/cli/run-cli-action.ts
25074
- import * as fs31 from "node:fs";
25074
+ import * as fs33 from "node:fs";
25075
25075
  import * as path35 from "node:path";
25076
25076
 
25077
25077
  // src/config.ts
@@ -26037,14 +26037,14 @@ var baseOpen = async (options) => {
26037
26037
  }
26038
26038
  const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions);
26039
26039
  if (options.wait) {
26040
- return new Promise((resolve19, reject) => {
26040
+ return new Promise((resolve18, reject) => {
26041
26041
  subprocess.once("error", reject);
26042
26042
  subprocess.once("close", (exitCode) => {
26043
26043
  if (!options.allowNonzeroExitCode && exitCode > 0) {
26044
26044
  reject(new Error(`Exited with code ${exitCode}`));
26045
26045
  return;
26046
26046
  }
26047
- resolve19(subprocess);
26047
+ resolve18(subprocess);
26048
26048
  });
26049
26049
  });
26050
26050
  }
@@ -26340,8 +26340,8 @@ function runPendingAuth(options) {
26340
26340
  let hasOpenedBrowser = false;
26341
26341
  let resolved = false;
26342
26342
  let resolveAuth;
26343
- const authPromise = new Promise((resolve19) => {
26344
- resolveAuth = resolve19;
26343
+ const authPromise = new Promise((resolve18) => {
26344
+ resolveAuth = resolve18;
26345
26345
  });
26346
26346
  let reconnectAttempt = 0;
26347
26347
  const signInQuiet = createEmptyReconnectQuietSlot();
@@ -26463,7 +26463,7 @@ function runPendingAuth(options) {
26463
26463
  async function closeBridgeConnection(state, acpManager, devServerManager, log2) {
26464
26464
  const say = log2 ?? logImmediate;
26465
26465
  say("Cleaning up connections\u2026");
26466
- await new Promise((resolve19) => setImmediate(resolve19));
26466
+ await new Promise((resolve18) => setImmediate(resolve18));
26467
26467
  state.closedByUser = true;
26468
26468
  clearReconnectQuietTimer(state.mainQuiet);
26469
26469
  clearReconnectQuietTimer(state.firehoseQuiet);
@@ -31367,18 +31367,7 @@ async function collectTurnGitDiffFromPreTurnSnapshot(options) {
31367
31367
  }
31368
31368
  }
31369
31369
 
31370
- // ../types/dist/index.js
31371
- init_zod();
31372
- init_zod();
31373
- init_zod();
31374
- init_zod();
31375
- init_zod();
31376
- init_zod();
31377
- init_zod();
31378
- init_zod();
31379
- init_zod();
31380
- init_zod();
31381
- init_zod();
31370
+ // ../types/src/work-items.ts
31382
31371
  init_zod();
31383
31372
  var WorkItemStatusSchema = external_exports.enum(["backlog", "in-progress", "completed"]);
31384
31373
  var WorkItemProgressSchema = external_exports.object({
@@ -31419,6 +31408,9 @@ var WorkItemSchema = external_exports.object({
31419
31408
  dependencies: external_exports.array(WorkItemDependencySchema).default([]),
31420
31409
  assignedToUserId: external_exports.string().optional()
31421
31410
  });
31411
+
31412
+ // ../types/src/user-profiles.ts
31413
+ init_zod();
31422
31414
  var UserWorkspaceProfileSchema = external_exports.object({
31423
31415
  id: external_exports.string(),
31424
31416
  workspaceId: external_exports.string(),
@@ -31428,6 +31420,9 @@ var UserWorkspaceProfileSchema = external_exports.object({
31428
31420
  preferences: external_exports.record(external_exports.unknown()).optional(),
31429
31421
  learnings: external_exports.array(external_exports.string())
31430
31422
  });
31423
+
31424
+ // ../types/src/runtime.ts
31425
+ init_zod();
31431
31426
  var WorkspaceOwnerInfoSchema = external_exports.object({
31432
31427
  ownerId: external_exports.string(),
31433
31428
  ownerName: external_exports.string().optional(),
@@ -31441,6 +31436,9 @@ var WorkspaceRuntimeEntrySchema = external_exports.object({
31441
31436
  owner: WorkspaceOwnerInfoSchema.optional(),
31442
31437
  isOwner: external_exports.boolean().optional()
31443
31438
  });
31439
+
31440
+ // ../types/src/agent.ts
31441
+ init_zod();
31444
31442
  var ProjectContextSchema = external_exports.object({
31445
31443
  projectId: external_exports.string(),
31446
31444
  context: external_exports.record(external_exports.unknown()).default({}),
@@ -31465,6 +31463,9 @@ var WebSocketMessageSchema = external_exports.object({
31465
31463
  data: external_exports.any().optional(),
31466
31464
  error: external_exports.string().optional()
31467
31465
  });
31466
+
31467
+ // ../types/src/checkpoints.ts
31468
+ init_zod();
31468
31469
  var CheckpointKindSchema = external_exports.enum(["daily", "weekly", "overall"]);
31469
31470
  var CheckpointSummarySchema = external_exports.object({
31470
31471
  id: external_exports.string(),
@@ -31475,6 +31476,9 @@ var CheckpointSummarySchema = external_exports.object({
31475
31476
  createdAt: external_exports.string(),
31476
31477
  updatedAt: external_exports.string()
31477
31478
  });
31479
+
31480
+ // ../types/src/threads.ts
31481
+ init_zod();
31478
31482
  var ThreadMetaSchema = external_exports.object({
31479
31483
  threadId: external_exports.string(),
31480
31484
  workspaceId: external_exports.string(),
@@ -31502,6 +31506,9 @@ var ThreadMessageSchema = external_exports.object({
31502
31506
  var ThreadCheckpointSummarySchema = CheckpointSummarySchema.extend({
31503
31507
  threadId: external_exports.string()
31504
31508
  });
31509
+
31510
+ // ../types/src/content-items.ts
31511
+ init_zod();
31505
31512
  var ContentSourceSchema = external_exports.enum(["notion", "doc", "slack_thread", "other"]);
31506
31513
  var ContentItemMetaSchema = external_exports.object({
31507
31514
  contentId: external_exports.string(),
@@ -31523,6 +31530,9 @@ var ContentStorageRefSchema = external_exports.object({
31523
31530
  var ContentCheckpointSummarySchema = CheckpointSummarySchema.extend({
31524
31531
  contentId: external_exports.string()
31525
31532
  });
31533
+
31534
+ // ../types/src/stories.ts
31535
+ init_zod();
31526
31536
  var StoryMetaSchema = external_exports.object({
31527
31537
  storyId: external_exports.string(),
31528
31538
  workspaceId: external_exports.string(),
@@ -31545,6 +31555,9 @@ var StoryContentItemRefSchema = external_exports.object({
31545
31555
  var StoryCheckpointSummarySchema = CheckpointSummarySchema.extend({
31546
31556
  storyId: external_exports.string()
31547
31557
  });
31558
+
31559
+ // ../types/src/sessions.ts
31560
+ init_zod();
31548
31561
  var BUILTIN_SESSION_CHANGE_SUMMARY_FOLLOW_UP_CATALOG_PROMPT_ID = "__builtin_change_summary__";
31549
31562
  var SessionMetaSchema = external_exports.object({
31550
31563
  sessionId: external_exports.string(),
@@ -31587,6 +31600,8 @@ var SessionThreadRefSchema = external_exports.object({
31587
31600
  threadId: external_exports.string(),
31588
31601
  addedAt: external_exports.string()
31589
31602
  });
31603
+
31604
+ // ../types/src/change-summary-path.ts
31590
31605
  function normalizeRepoRelativePath(p) {
31591
31606
  let t = p.trim().replace(/\\/g, "/");
31592
31607
  while (t.startsWith("./")) t = t.slice(2);
@@ -31603,6 +31618,8 @@ function resolveChangeSummaryPathAgainstAllowed(rawPath, allowed) {
31603
31618
  }
31604
31619
  return null;
31605
31620
  }
31621
+
31622
+ // ../types/src/parse-change-summary-json.ts
31606
31623
  function clampSummaryToAtMostTwoLines(summary) {
31607
31624
  const lines = summary.split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0);
31608
31625
  return lines.slice(0, 2).join("\n");
@@ -31645,6 +31662,8 @@ function parseChangeSummaryJson(raw, allowedPaths, options) {
31645
31662
  }
31646
31663
  return rows;
31647
31664
  }
31665
+
31666
+ // ../types/src/build-change-summary-prompt.ts
31648
31667
  var PATCH_PREVIEW_MAX = 12e3;
31649
31668
  function clip(s, max) {
31650
31669
  if (s.length <= max) return s;
@@ -31702,6 +31721,8 @@ function buildSessionChangeSummaryPrompt(files) {
31702
31721
  }
31703
31722
  return lines.join("\n");
31704
31723
  }
31724
+
31725
+ // ../types/src/dedupe-session-file-changes-by-path.ts
31705
31726
  function defaultRichness(c) {
31706
31727
  const patch = typeof c.patchContent === "string" ? c.patchContent.length : 0;
31707
31728
  const nt = typeof c.newText === "string" ? c.newText.length : 0;
@@ -31719,6 +31740,9 @@ function dedupeSessionFileChangesByPath(items, richness = (item) => defaultRichn
31719
31740
  }
31720
31741
  return Array.from(byPath.entries()).sort(([a], [b]) => a.localeCompare(b)).map(([, v]) => v);
31721
31742
  }
31743
+
31744
+ // ../types/src/artifacts.ts
31745
+ init_zod();
31722
31746
  var ArtifactMetaSchema = external_exports.object({
31723
31747
  artifactId: external_exports.string(),
31724
31748
  workspaceId: external_exports.string(),
@@ -31732,6 +31756,9 @@ var ArtifactMetaSchema = external_exports.object({
31732
31756
  createdAt: external_exports.string(),
31733
31757
  updatedAt: external_exports.string()
31734
31758
  });
31759
+
31760
+ // ../types/src/templates.ts
31761
+ init_zod();
31735
31762
  var TemplateMetaSchema = external_exports.object({
31736
31763
  templateId: external_exports.string(),
31737
31764
  workspaceId: external_exports.string(),
@@ -31741,6 +31768,9 @@ var TemplateMetaSchema = external_exports.object({
31741
31768
  createdAt: external_exports.string(),
31742
31769
  updatedAt: external_exports.string()
31743
31770
  });
31771
+
31772
+ // ../types/src/git-repos.ts
31773
+ init_zod();
31744
31774
  var GitRepoMetaSchema = external_exports.object({
31745
31775
  /** Stable id for the repo (e.g. hash of normalized canonical URL). Used for DO idFromName. */
31746
31776
  repoId: external_exports.string(),
@@ -32157,7 +32187,7 @@ async function createSdkStdioAcpClient(options) {
32157
32187
  child.once("close", (code, signal) => {
32158
32188
  onAgentSubprocessExit?.({ code, signal });
32159
32189
  });
32160
- return new Promise((resolve19, reject) => {
32190
+ return new Promise((resolve18, reject) => {
32161
32191
  let initSettled = false;
32162
32192
  const settleReject = (err) => {
32163
32193
  if (initSettled) return;
@@ -32171,7 +32201,7 @@ async function createSdkStdioAcpClient(options) {
32171
32201
  const settleResolve = (handle) => {
32172
32202
  if (initSettled) return;
32173
32203
  initSettled = true;
32174
- resolve19(handle);
32204
+ resolve18(handle);
32175
32205
  };
32176
32206
  child.on("error", (err) => {
32177
32207
  settleReject(new Error(formatSpawnError(err, command[0])));
@@ -32207,8 +32237,8 @@ async function createSdkStdioAcpClient(options) {
32207
32237
  });
32208
32238
  } catch {
32209
32239
  }
32210
- return await new Promise((resolve20) => {
32211
- pendingPermissionResolvers.set(requestId, resolve20);
32240
+ return await new Promise((resolve19) => {
32241
+ pendingPermissionResolvers.set(requestId, resolve19);
32212
32242
  });
32213
32243
  },
32214
32244
  async readTextFile(params) {
@@ -32316,9 +32346,9 @@ async function createSdkStdioAcpClient(options) {
32316
32346
  }
32317
32347
  },
32318
32348
  async cancel() {
32319
- for (const [id, resolve20] of [...pendingPermissionResolvers.entries()]) {
32349
+ for (const [id, resolve19] of [...pendingPermissionResolvers.entries()]) {
32320
32350
  pendingPermissionResolvers.delete(id);
32321
- resolve20({ outcome: { outcome: "cancelled" } });
32351
+ resolve19({ outcome: { outcome: "cancelled" } });
32322
32352
  }
32323
32353
  try {
32324
32354
  await connection.cancel({ sessionId });
@@ -32334,10 +32364,10 @@ async function createSdkStdioAcpClient(options) {
32334
32364
  }
32335
32365
  },
32336
32366
  resolveRequest(requestId, result) {
32337
- const resolve20 = pendingPermissionResolvers.get(requestId);
32338
- if (!resolve20) return;
32367
+ const resolve19 = pendingPermissionResolvers.get(requestId);
32368
+ if (!resolve19) return;
32339
32369
  pendingPermissionResolvers.delete(requestId);
32340
- resolve20(result);
32370
+ resolve19(result);
32341
32371
  },
32342
32372
  disconnect() {
32343
32373
  child.kill();
@@ -32488,7 +32518,7 @@ async function createCursorAcpClient(options) {
32488
32518
  });
32489
32519
  const stderrCapture = createStderrCapture(child);
32490
32520
  child.stderr?.on("data", (chunk) => stderrCapture.append(chunk));
32491
- return new Promise((resolve19, reject) => {
32521
+ return new Promise((resolve18, reject) => {
32492
32522
  child.on("error", (err) => {
32493
32523
  child.kill();
32494
32524
  reject(new Error(formatSpawnError2(err, command[0])));
@@ -32675,7 +32705,7 @@ async function createCursorAcpClient(options) {
32675
32705
  const newResult = await send("session/new", { cwd, mcpServers: [] });
32676
32706
  const sessionId = newResult?.sessionId ?? "";
32677
32707
  if (!sessionId) throw new Error("Cursor ACP session/new did not return sessionId");
32678
- resolve19({
32708
+ resolve18({
32679
32709
  sessionId,
32680
32710
  async sendPrompt(prompt, _options) {
32681
32711
  promptOutputBuffer = "";
@@ -34827,7 +34857,7 @@ import path22 from "node:path";
34827
34857
 
34828
34858
  // src/runtime/yield-to-event-loop.ts
34829
34859
  function yieldToEventLoop() {
34830
- return new Promise((resolve19) => setImmediate(resolve19));
34860
+ return new Promise((resolve18) => setImmediate(resolve18));
34831
34861
  }
34832
34862
 
34833
34863
  // src/files/index/walk-workspace-tree.ts
@@ -35189,15 +35219,15 @@ function sendDevServerStatus(getWs, serverId, status, options) {
35189
35219
 
35190
35220
  // src/dev-servers/process/terminate-child-process.ts
35191
35221
  async function sigtermAndWaitForExit(proc, graceMs, log2, shortId) {
35192
- const exited = new Promise((resolve19) => {
35193
- proc.once("exit", () => resolve19());
35222
+ const exited = new Promise((resolve18) => {
35223
+ proc.once("exit", () => resolve18());
35194
35224
  });
35195
35225
  log2(`[dev-server] Sending SIGTERM to ${shortId} (pid=${proc.pid ?? "?"}).`);
35196
35226
  try {
35197
35227
  proc.kill("SIGTERM");
35198
35228
  } catch {
35199
35229
  }
35200
- await Promise.race([exited, new Promise((resolve19) => setTimeout(resolve19, graceMs))]);
35230
+ await Promise.race([exited, new Promise((resolve18) => setTimeout(resolve18, graceMs))]);
35201
35231
  }
35202
35232
  function forceKillChild(proc, log2, shortId, graceMs) {
35203
35233
  log2(
@@ -36080,7 +36110,7 @@ async function proxyToLocal(request) {
36080
36110
  };
36081
36111
  const maxAttempts = isIdempotentProxyMethod(request.method) ? LOCAL_PREVIEW_FETCH_RETRY_DELAYS_MS.length + 1 : 1;
36082
36112
  for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
36083
- const once = await new Promise((resolve19) => {
36113
+ const once = await new Promise((resolve18) => {
36084
36114
  const req = mod.request(opts, (res) => {
36085
36115
  const chunks = [];
36086
36116
  res.on("data", (c) => chunks.push(c));
@@ -36091,7 +36121,7 @@ async function proxyToLocal(request) {
36091
36121
  if (typeof v === "string") headers[k] = v;
36092
36122
  else if (Array.isArray(v) && v[0]) headers[k] = v[0];
36093
36123
  }
36094
- resolve19({
36124
+ resolve18({
36095
36125
  id: request.id,
36096
36126
  statusCode: res.statusCode ?? 0,
36097
36127
  headers,
@@ -36100,7 +36130,7 @@ async function proxyToLocal(request) {
36100
36130
  });
36101
36131
  });
36102
36132
  req.on("error", (err) => {
36103
- resolve19({
36133
+ resolve18({
36104
36134
  id: request.id,
36105
36135
  statusCode: 0,
36106
36136
  headers: {},
@@ -36616,6 +36646,7 @@ var API_TO_BRIDGE_MESSAGE_TYPES = [
36616
36646
  "dev_servers_config",
36617
36647
  "server_control",
36618
36648
  "agent_config",
36649
+ "prompt_queue_state",
36619
36650
  "prompt",
36620
36651
  "session_git_request",
36621
36652
  "rename_session_branch",
@@ -36695,6 +36726,173 @@ var handleAgentConfigMessage = (msg, deps) => {
36695
36726
  // src/agents/acp/from-bridge/handle-bridge-prompt.ts
36696
36727
  import * as path30 from "node:path";
36697
36728
 
36729
+ // src/prompt-turn-queue/client-report.ts
36730
+ function sendPromptQueueClientReport(ws, queues) {
36731
+ if (!ws) return false;
36732
+ sendWsMessage(ws, { type: "prompt_queue_client_report", queues });
36733
+ return true;
36734
+ }
36735
+
36736
+ // src/prompt-turn-queue/disk-store.ts
36737
+ import fs28 from "node:fs";
36738
+
36739
+ // src/prompt-turn-queue/paths.ts
36740
+ import crypto3 from "node:crypto";
36741
+ import fs27 from "node:fs";
36742
+ import path29 from "node:path";
36743
+ import os6 from "node:os";
36744
+ var QUEUE_KEY_HEX_64 = /^[a-f0-9]{64}$/i;
36745
+ function queueStateFileSlug(queueKey) {
36746
+ if (QUEUE_KEY_HEX_64.test(queueKey)) return queueKey.toLowerCase();
36747
+ return crypto3.createHash("sha256").update(queueKey, "utf8").digest("hex");
36748
+ }
36749
+ function getPromptQueuesDirectory() {
36750
+ const override = process.env.BUILDAMATON_PROMPT_QUEUES_DIR?.trim();
36751
+ if (override) return path29.resolve(override);
36752
+ return path29.join(os6.homedir(), ".buildautomaton", "queues");
36753
+ }
36754
+ function ensurePromptQueuesDirectory() {
36755
+ const dir = getPromptQueuesDirectory();
36756
+ if (!fs27.existsSync(dir)) fs27.mkdirSync(dir, { recursive: true });
36757
+ }
36758
+ function queueStateFilePath(queueKey) {
36759
+ return path29.join(getPromptQueuesDirectory(), `${queueStateFileSlug(queueKey)}.json`);
36760
+ }
36761
+
36762
+ // src/prompt-turn-queue/disk-store.ts
36763
+ function parsePersistedQueueFile(raw) {
36764
+ try {
36765
+ const o = JSON.parse(raw);
36766
+ const queueKey = typeof o.queueKey === "string" ? o.queueKey : typeof o.queueKeyHash === "string" ? o.queueKeyHash : null;
36767
+ if (!queueKey || typeof o.updatedAt !== "string" || !Array.isArray(o.turns)) return null;
36768
+ return { queueKey, updatedAt: o.updatedAt, turns: o.turns };
36769
+ } catch {
36770
+ return null;
36771
+ }
36772
+ }
36773
+ function readPersistedQueue(queueKey) {
36774
+ const p = queueStateFilePath(queueKey);
36775
+ try {
36776
+ return parsePersistedQueueFile(fs28.readFileSync(p, "utf8"));
36777
+ } catch {
36778
+ return null;
36779
+ }
36780
+ }
36781
+ function writePersistedQueue(file2) {
36782
+ ensurePromptQueuesDirectory();
36783
+ const p = queueStateFilePath(file2.queueKey);
36784
+ fs28.writeFileSync(p, JSON.stringify(file2, null, 2), "utf8");
36785
+ }
36786
+ function mergeServerQueueSnapshot(queueKey, serverTurns) {
36787
+ const prev = readPersistedQueue(queueKey);
36788
+ const turns = [];
36789
+ for (const raw of serverTurns) {
36790
+ if (!raw || typeof raw !== "object") continue;
36791
+ const o = raw;
36792
+ const turnId = typeof o.turnId === "string" ? o.turnId : "";
36793
+ const sessionId = typeof o.sessionId === "string" ? o.sessionId : "";
36794
+ const turnOrd = typeof o.turnOrd === "number" ? o.turnOrd : Number(o.turnOrd) || 0;
36795
+ const serverState = o.serverState;
36796
+ const lastClientState = o.lastClientState ?? null;
36797
+ const payload = o.payload && typeof o.payload === "object" ? o.payload : {};
36798
+ if (!turnId || !sessionId) continue;
36799
+ if (serverState !== "queued" && serverState !== "stopping" && serverState !== "discarded") continue;
36800
+ const old = prev?.turns.find((t) => t.turnId === turnId);
36801
+ const mergedClient = old?.lastClientState === "running" && lastClientState == null ? "running" : lastClientState;
36802
+ turns.push({
36803
+ turnId,
36804
+ sessionId,
36805
+ turnOrd,
36806
+ serverState,
36807
+ lastClientState: mergedClient,
36808
+ payload
36809
+ });
36810
+ }
36811
+ turns.sort((a, b) => a.turnOrd - b.turnOrd);
36812
+ return { queueKey, updatedAt: (/* @__PURE__ */ new Date()).toISOString(), turns };
36813
+ }
36814
+
36815
+ // src/prompt-turn-queue/runner.ts
36816
+ var runIdToQueueKey = /* @__PURE__ */ new Map();
36817
+ function pickNextRunnableTurn(turns) {
36818
+ for (const t of turns) {
36819
+ if (t.serverState === "discarded" || t.serverState === "stopping") continue;
36820
+ if (t.serverState !== "queued") continue;
36821
+ if (t.lastClientState === "running" || t.lastClientState === "stopped" || t.lastClientState === "failed") continue;
36822
+ return t;
36823
+ }
36824
+ return null;
36825
+ }
36826
+ function hasRunningTurn(turns) {
36827
+ return turns.some((t) => t.lastClientState === "running");
36828
+ }
36829
+ function dispatchLocalPrompt(next, deps) {
36830
+ const pl = next.payload;
36831
+ const msg = {
36832
+ type: "prompt",
36833
+ sessionId: next.sessionId,
36834
+ runId: next.turnId,
36835
+ prompt: pl.prompt,
36836
+ mode: typeof pl.mode === "string" ? pl.mode : "agent",
36837
+ isNewSession: pl.isNewSession === true,
36838
+ ...typeof pl.followUpCatalogPromptId === "string" ? { followUpCatalogPromptId: pl.followUpCatalogPromptId } : {},
36839
+ ...Array.isArray(pl.sessionChangeSummaryFilePaths) ? { sessionChangeSummaryFilePaths: pl.sessionChangeSummaryFilePaths } : {},
36840
+ ...Array.isArray(pl.sessionChangeSummaryFileSnapshots) ? { sessionChangeSummaryFileSnapshots: pl.sessionChangeSummaryFileSnapshots } : {},
36841
+ ...typeof pl.agentType === "string" && pl.agentType.trim() ? { agentType: pl.agentType.trim() } : {}
36842
+ };
36843
+ handleBridgePrompt(msg, deps);
36844
+ }
36845
+ function applyPromptQueueStateFromServer(msg, deps) {
36846
+ const raw = msg.queues;
36847
+ if (!raw || typeof raw !== "object") return;
36848
+ const getWs = deps.getWs;
36849
+ for (const [queueKey, serverTurns] of Object.entries(raw)) {
36850
+ if (!Array.isArray(serverTurns)) continue;
36851
+ const file2 = mergeServerQueueSnapshot(queueKey, serverTurns);
36852
+ writePersistedQueue(file2);
36853
+ }
36854
+ const report = {};
36855
+ const startedThisTick = /* @__PURE__ */ new Set();
36856
+ for (const [queueKey, serverTurns] of Object.entries(raw)) {
36857
+ if (!Array.isArray(serverTurns)) continue;
36858
+ const file2 = readPersistedQueue(queueKey);
36859
+ if (!file2) continue;
36860
+ if (hasRunningTurn(file2.turns)) continue;
36861
+ const next = pickNextRunnableTurn(file2.turns);
36862
+ if (!next) continue;
36863
+ next.lastClientState = "running";
36864
+ writePersistedQueue(file2);
36865
+ runIdToQueueKey.set(next.turnId, queueKey);
36866
+ startedThisTick.add(next.turnId);
36867
+ report[queueKey] = [{ turnId: next.turnId, clientState: "running" }];
36868
+ }
36869
+ if (Object.keys(report).length > 0) {
36870
+ sendPromptQueueClientReport(getWs(), report);
36871
+ }
36872
+ for (const [queueKey, serverTurns] of Object.entries(raw)) {
36873
+ if (!Array.isArray(serverTurns)) continue;
36874
+ const file2 = readPersistedQueue(queueKey);
36875
+ if (!file2) continue;
36876
+ const running = file2.turns.find((t) => t.lastClientState === "running");
36877
+ if (!running || !startedThisTick.has(running.turnId)) continue;
36878
+ if (runIdToQueueKey.get(running.turnId) !== queueKey) continue;
36879
+ dispatchLocalPrompt(running, deps);
36880
+ }
36881
+ }
36882
+ function finalizePromptTurnOnBridge(getWs, runId, success2) {
36883
+ if (!runId) return;
36884
+ const queueKey = runIdToQueueKey.get(runId);
36885
+ runIdToQueueKey.delete(runId);
36886
+ if (!queueKey) return;
36887
+ const f = readPersistedQueue(queueKey);
36888
+ if (!f) return;
36889
+ const t = f.turns.find((x) => x.turnId === runId);
36890
+ if (!t) return;
36891
+ t.lastClientState = success2 ? "stopped" : "failed";
36892
+ writePersistedQueue(f);
36893
+ sendPromptQueueClientReport(getWs(), { [queueKey]: [{ turnId: runId, clientState: t.lastClientState }] });
36894
+ }
36895
+
36698
36896
  // src/agents/acp/from-bridge/bridge-prompt-wiring.ts
36699
36897
  function createBridgePromptSenders(deps, getWs) {
36700
36898
  const sendBridgeMessage = (message, encryptedFields = []) => {
@@ -36708,6 +36906,9 @@ function createBridgePromptSenders(deps, getWs) {
36708
36906
  const skipEncryptForChangeSummaryFollowUp = result.type === "prompt_result" && result.followUpCatalogPromptId === BUILTIN_SESSION_CHANGE_SUMMARY_FOLLOW_UP_CATALOG_PROMPT_ID;
36709
36907
  const encryptedFields = result.type === "prompt_result" && !skipEncryptForChangeSummaryFollowUp ? ["output", "error"] : [];
36710
36908
  sendBridgeMessage(result, encryptedFields);
36909
+ if (result.type === "prompt_result") {
36910
+ finalizePromptTurnOnBridge(getWs, typeof result.runId === "string" ? result.runId : void 0, result.success === true);
36911
+ }
36711
36912
  };
36712
36913
  const sendSessionUpdate = (payload) => {
36713
36914
  const s = getWs();
@@ -36732,63 +36933,6 @@ function createBridgePromptSenders(deps, getWs) {
36732
36933
  // src/agents/acp/from-bridge/bridge-prompt-preamble.ts
36733
36934
  import { execFile as execFile10 } from "node:child_process";
36734
36935
  import { promisify as promisify10 } from "node:util";
36735
-
36736
- // src/git/bridge-queue-key.ts
36737
- import * as path29 from "node:path";
36738
- import { createHash as createHash2 } from "node:crypto";
36739
- function normalizeCanonicalGitUrl(url2) {
36740
- let s = url2.trim();
36741
- if (!s) return s;
36742
- if (s.toLowerCase().endsWith(".git")) {
36743
- s = s.slice(0, -4);
36744
- }
36745
- s = s.replace(/\/+$/, "");
36746
- const httpsMatch = /^(https?):\/\/([^/]+)(\/.*)?$/i.exec(s);
36747
- if (httpsMatch) {
36748
- const host = httpsMatch[2].toLowerCase();
36749
- const p = httpsMatch[3] ?? "";
36750
- s = `${httpsMatch[1].toLowerCase()}://${host}${p}`;
36751
- } else {
36752
- const sshMatch = /^git@([^:]+):(.+)$/i.exec(s);
36753
- if (sshMatch) {
36754
- const host = sshMatch[1].toLowerCase();
36755
- s = `git@${host}:${sshMatch[2]}`;
36756
- }
36757
- }
36758
- return s;
36759
- }
36760
- function canonicalUrlToRepoIdSync(url2) {
36761
- const normalized = normalizeCanonicalGitUrl(url2);
36762
- return createHash2("sha256").update(normalized).digest("hex").slice(0, 32);
36763
- }
36764
- function fallbackRepoIdFromPath(absPath) {
36765
- return createHash2("sha256").update(path29.resolve(absPath)).digest("hex").slice(0, 32);
36766
- }
36767
- async function resolveBridgeQueueBindFields(options) {
36768
- const { effectiveCwd, worktreePaths, primaryRepoRoots, log: log2 } = options;
36769
- const cwdAbs = worktreePaths.length > 0 ? path29.resolve(worktreePaths[0]) : path29.resolve(effectiveCwd);
36770
- if (!primaryRepoRoots.length) {
36771
- log2("[Bridge service] Prompt queue bind skipped: no Git repository roots under the working directory.");
36772
- return null;
36773
- }
36774
- let primaryRoot = primaryRepoRoots[0];
36775
- let remote = await getRemoteOriginUrl(primaryRoot);
36776
- if (!remote) {
36777
- for (const r of primaryRepoRoots.slice(1)) {
36778
- const u = await getRemoteOriginUrl(r);
36779
- if (u) {
36780
- primaryRoot = r;
36781
- remote = u;
36782
- break;
36783
- }
36784
- }
36785
- }
36786
- const repoId = remote ? canonicalUrlToRepoIdSync(remote) : fallbackRepoIdFromPath(primaryRoot);
36787
- const canonicalQueueKey = `repo:${repoId}::cwd:${cwdAbs}`;
36788
- return { canonicalQueueKey, repoId, cwdAbs };
36789
- }
36790
-
36791
- // src/agents/acp/from-bridge/bridge-prompt-preamble.ts
36792
36936
  var execFileAsync9 = promisify10(execFile10);
36793
36937
  async function readGitBranch(cwd) {
36794
36938
  try {
@@ -36808,23 +36952,6 @@ async function runBridgePromptPreamble(params) {
36808
36952
  fallbackCwd: effectiveCwd,
36809
36953
  log: log2
36810
36954
  });
36811
- if (s && sessionId) {
36812
- const bind = await resolveBridgeQueueBindFields({
36813
- effectiveCwd,
36814
- worktreePaths,
36815
- primaryRepoRoots: repoRoots,
36816
- log: log2
36817
- });
36818
- if (bind) {
36819
- sendWsMessage(s, {
36820
- type: "bridge_queue_bind",
36821
- sessionId,
36822
- canonicalQueueKey: bind.canonicalQueueKey,
36823
- repoId: bind.repoId,
36824
- cwdAbs: bind.cwdAbs
36825
- });
36826
- }
36827
- }
36828
36955
  if (s && sessionId) {
36829
36956
  const cliGitBranch = await readGitBranch(effectiveCwd);
36830
36957
  const usesWt = sessionWorktreeManager.usesWorktreeSession(sessionId);
@@ -37016,6 +37143,11 @@ var handlePromptMessage = (msg, deps) => {
37016
37143
  handleBridgePrompt(msg, deps);
37017
37144
  };
37018
37145
 
37146
+ // src/bridge/routing/handlers/prompt-queue-state.ts
37147
+ var handlePromptQueueStateMessage = (msg, deps) => {
37148
+ applyPromptQueueStateFromServer(msg, deps);
37149
+ };
37150
+
37019
37151
  // src/agents/acp/from-bridge/handle-bridge-cancel-run.ts
37020
37152
  async function handleBridgeCancelRun(msg, { log: log2, acpManager, getWs }) {
37021
37153
  const runId = msg.runId;
@@ -37035,6 +37167,7 @@ async function handleBridgeCancelRun(msg, { log: log2, acpManager, getWs }) {
37035
37167
  error: "Stopped by user",
37036
37168
  stopReason: "no_local_run"
37037
37169
  });
37170
+ finalizePromptTurnOnBridge(getWs, runId, false);
37038
37171
  }
37039
37172
 
37040
37173
  // src/bridge/routing/handlers/cancel-run.ts
@@ -37252,7 +37385,7 @@ var handleSkillCallMessage = (msg, { getWs, log: log2 }) => {
37252
37385
  };
37253
37386
 
37254
37387
  // src/files/list-dir.ts
37255
- import fs27 from "node:fs";
37388
+ import fs29 from "node:fs";
37256
37389
  import path32 from "node:path";
37257
37390
 
37258
37391
  // src/files/ensure-under-cwd.ts
@@ -37274,7 +37407,7 @@ async function listDirAsync(relativePath) {
37274
37407
  return { error: "Path is outside working directory" };
37275
37408
  }
37276
37409
  try {
37277
- const names = await fs27.promises.readdir(resolved, { withFileTypes: true });
37410
+ const names = await fs29.promises.readdir(resolved, { withFileTypes: true });
37278
37411
  const visible = names.filter((d) => !d.name.startsWith("."));
37279
37412
  const entries = [];
37280
37413
  for (let i = 0; i < visible.length; i++) {
@@ -37287,7 +37420,7 @@ async function listDirAsync(relativePath) {
37287
37420
  let isDir = d.isDirectory();
37288
37421
  if (d.isSymbolicLink()) {
37289
37422
  try {
37290
- const targetStat = await fs27.promises.stat(fullPath);
37423
+ const targetStat = await fs29.promises.stat(fullPath);
37291
37424
  isDir = targetStat.isDirectory();
37292
37425
  } catch {
37293
37426
  isDir = false;
@@ -37312,25 +37445,25 @@ async function listDirAsync(relativePath) {
37312
37445
  }
37313
37446
 
37314
37447
  // src/files/read-file.ts
37315
- import fs28 from "node:fs";
37448
+ import fs30 from "node:fs";
37316
37449
  import { StringDecoder } from "node:string_decoder";
37317
37450
  function resolveFilePath(relativePath) {
37318
37451
  const resolved = ensureUnderCwd(relativePath, getBridgeWorkspaceDirectory());
37319
37452
  if (!resolved) return { error: "Path is outside working directory" };
37320
37453
  let real;
37321
37454
  try {
37322
- real = fs28.realpathSync(resolved);
37455
+ real = fs30.realpathSync(resolved);
37323
37456
  } catch {
37324
37457
  real = resolved;
37325
37458
  }
37326
- const stat3 = fs28.statSync(real);
37459
+ const stat3 = fs30.statSync(real);
37327
37460
  if (!stat3.isFile()) return { error: "Not a file" };
37328
37461
  return real;
37329
37462
  }
37330
37463
  var LINE_CHUNK_SIZE = 64 * 1024;
37331
37464
  function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize = LINE_CHUNK_SIZE) {
37332
- const fileSize = fs28.statSync(filePath).size;
37333
- const fd = fs28.openSync(filePath, "r");
37465
+ const fileSize = fs30.statSync(filePath).size;
37466
+ const fd = fs30.openSync(filePath, "r");
37334
37467
  const bufSize = 64 * 1024;
37335
37468
  const buf = Buffer.alloc(bufSize);
37336
37469
  const decoder = new StringDecoder("utf8");
@@ -37343,7 +37476,7 @@ function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize
37343
37476
  let line0Accum = "";
37344
37477
  try {
37345
37478
  let bytesRead;
37346
- while (!done && (bytesRead = fs28.readSync(fd, buf, 0, bufSize, null)) > 0) {
37479
+ while (!done && (bytesRead = fs30.readSync(fd, buf, 0, bufSize, null)) > 0) {
37347
37480
  const text = partial2 + decoder.write(buf.subarray(0, bytesRead));
37348
37481
  partial2 = "";
37349
37482
  let lineStart = 0;
@@ -37478,7 +37611,7 @@ function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize
37478
37611
  }
37479
37612
  return { content: resultLines.join("\n"), size: fileSize };
37480
37613
  } finally {
37481
- fs28.closeSync(fd);
37614
+ fs30.closeSync(fd);
37482
37615
  }
37483
37616
  }
37484
37617
  function readFile3(relativePath, startLine, endLine, lineOffset, lineChunkSize = LINE_CHUNK_SIZE) {
@@ -37489,8 +37622,8 @@ function readFile3(relativePath, startLine, endLine, lineOffset, lineChunkSize =
37489
37622
  if (hasRange) {
37490
37623
  return readFileRange(result, startLine, endLine, lineOffset, lineChunkSize);
37491
37624
  }
37492
- const stat3 = fs28.statSync(result);
37493
- const raw = fs28.readFileSync(result, "utf8");
37625
+ const stat3 = fs30.statSync(result);
37626
+ const raw = fs30.readFileSync(result, "utf8");
37494
37627
  const lines = raw.split(/\r?\n/);
37495
37628
  return { content: raw, totalLines: lines.length, size: stat3.size };
37496
37629
  } catch (err) {
@@ -37608,7 +37741,7 @@ function handleSkillLayoutRequest(msg, deps) {
37608
37741
  }
37609
37742
 
37610
37743
  // src/skills/install-remote-skills.ts
37611
- import fs29 from "node:fs";
37744
+ import fs31 from "node:fs";
37612
37745
  import path33 from "node:path";
37613
37746
  function installRemoteSkills(cwd, targetDir, items) {
37614
37747
  const installed2 = [];
@@ -37624,11 +37757,11 @@ function installRemoteSkills(cwd, targetDir, items) {
37624
37757
  for (const f of item.files) {
37625
37758
  if (typeof f.path !== "string" || !f.text && !f.base64) continue;
37626
37759
  const dest = path33.join(skillDir, f.path);
37627
- fs29.mkdirSync(path33.dirname(dest), { recursive: true });
37760
+ fs31.mkdirSync(path33.dirname(dest), { recursive: true });
37628
37761
  if (f.text !== void 0) {
37629
- fs29.writeFileSync(dest, f.text, "utf8");
37762
+ fs31.writeFileSync(dest, f.text, "utf8");
37630
37763
  } else if (f.base64) {
37631
- fs29.writeFileSync(dest, Buffer.from(f.base64, "base64"));
37764
+ fs31.writeFileSync(dest, Buffer.from(f.base64, "base64"));
37632
37765
  }
37633
37766
  }
37634
37767
  installed2.push({
@@ -37778,7 +37911,7 @@ var handleSessionDiscardedMessage = (msg, deps) => {
37778
37911
  };
37779
37912
 
37780
37913
  // src/bridge/routing/handlers/revert-turn-snapshot.ts
37781
- import * as fs30 from "node:fs";
37914
+ import * as fs32 from "node:fs";
37782
37915
  var handleRevertTurnSnapshotMessage = (msg, deps) => {
37783
37916
  const id = typeof msg.id === "string" ? msg.id : "";
37784
37917
  const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
@@ -37790,7 +37923,7 @@ var handleRevertTurnSnapshotMessage = (msg, deps) => {
37790
37923
  if (!s) return;
37791
37924
  const agentBase = sessionWorktreeManager.getAgentCwdForSession(sessionId) ?? getBridgeWorkspaceDirectory();
37792
37925
  const file2 = snapshotFilePath(agentBase, turnId);
37793
- if (!fs30.existsSync(file2)) {
37926
+ if (!fs32.existsSync(file2)) {
37794
37927
  sendWsMessage(s, {
37795
37928
  type: "revert_turn_snapshot_result",
37796
37929
  id,
@@ -37848,6 +37981,9 @@ function dispatchBridgeMessage(msg, deps) {
37848
37981
  case "agent_config":
37849
37982
  handleAgentConfigMessage(msg, deps);
37850
37983
  break;
37984
+ case "prompt_queue_state":
37985
+ handlePromptQueueStateMessage(msg, deps);
37986
+ break;
37851
37987
  case "prompt":
37852
37988
  handlePromptMessage(msg, deps);
37853
37989
  break;
@@ -38347,7 +38483,7 @@ async function runCliAction(program2, opts) {
38347
38483
  if (opts.cwd && typeof opts.cwd === "string" && opts.cwd.trim()) {
38348
38484
  const resolvedCwd = path35.resolve(process.cwd(), opts.cwd.trim());
38349
38485
  try {
38350
- const st = fs31.statSync(resolvedCwd);
38486
+ const st = fs33.statSync(resolvedCwd);
38351
38487
  if (!st.isDirectory()) {
38352
38488
  console.error(`--cwd is not a directory: ${resolvedCwd}`);
38353
38489
  process.exit(1);