@cortexkit/aft 0.60.0 → 0.61.0

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.
Files changed (2) hide show
  1. package/dist/index.js +309 -157
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -109,6 +109,29 @@ var ACTIVE_LOGGER_SYMBOL;
109
109
  var init_active_logger = __esm(() => {
110
110
  ACTIVE_LOGGER_SYMBOL = Symbol.for("aft-bridge-active-logger");
111
111
  });
112
+
113
+ // ../aft-bridge/dist/protocol.js
114
+ function isTerminalBashStatus(status, compatibilityAliases = false) {
115
+ return typeof status === "string" && (TERMINAL_BASH_STATUSES.has(status) || compatibilityAliases && (status === "cancelled" || status === "timeout"));
116
+ }
117
+ var TERMINAL_BG_TASK_STATUSES, TERMINAL_BASH_STATUSES;
118
+ var init_protocol = __esm(() => {
119
+ TERMINAL_BG_TASK_STATUSES = Object.freeze([
120
+ "completed",
121
+ "failed",
122
+ "killed",
123
+ "timed_out",
124
+ "fate_unknown"
125
+ ]);
126
+ TERMINAL_BASH_STATUSES = new Set(TERMINAL_BG_TASK_STATUSES);
127
+ });
128
+
129
+ // ../aft-bridge/dist/bash-format.js
130
+ var init_bash_format = __esm(() => {
131
+ init_protocol();
132
+ init_protocol();
133
+ });
134
+
112
135
  // ../aft-bridge/dist/path-display.js
113
136
  import { homedir } from "node:os";
114
137
  import { posix, win32 } from "node:path";
@@ -129,6 +152,7 @@ var init_path_display = () => {};
129
152
 
130
153
  // ../aft-bridge/dist/bash-hints.js
131
154
  var init_bash_hints = __esm(() => {
155
+ init_bash_format();
132
156
  init_path_display();
133
157
  });
134
158
 
@@ -615,9 +639,6 @@ var WORKER_SESSION_FIELD = "worker_session", HOST_TOOL_NAMES_FIELD = "host_tool_
615
639
  import { homedir as homedir4 } from "node:os";
616
640
  import { join as join3 } from "node:path";
617
641
  import { StringDecoder } from "node:string_decoder";
618
- function isTerminalBashStatus(status) {
619
- return typeof status === "string" && TERMINAL_BASH_STATUSES.has(status);
620
- }
621
642
  function bashTaskIdFrom(response) {
622
643
  const snakeCase = response.task_id;
623
644
  if (typeof snakeCase === "string" && snakeCase.length > 0)
@@ -646,44 +667,37 @@ function shouldSurfaceStderrLine(line) {
646
667
  return !(normalized === `Error in cpuinfo: ${BENIGN_CPUINFO_PROC_CPUINFO_PARSE_FAILURE}` || normalized === BENIGN_CPUINFO_PROC_CPUINFO_PARSE_FAILURE);
647
668
  }
648
669
  function compareSemver(a, b) {
649
- const [aMain, aPre] = a.split("-", 2);
650
- const [bMain, bPre] = b.split("-", 2);
651
- const aParts = aMain.split(".").map(Number);
652
- const bParts = bMain.split(".").map(Number);
670
+ const parse = (version) => {
671
+ const match = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/.exec(version);
672
+ const pre = match?.[4]?.split(".") ?? [];
673
+ if (!match || pre.some((id) => /^\d+$/.test(id) && id.length > 1 && id[0] === "0")) {
674
+ throw new Error(`Invalid semantic version: ${version}`);
675
+ }
676
+ return { core: match.slice(1, 4), pre };
677
+ };
678
+ const numeric = (a, b) => a.length !== b.length ? a.length - b.length : a === b ? 0 : a < b ? -1 : 1;
679
+ const left = parse(a);
680
+ const right = parse(b);
653
681
  for (let i = 0;i < 3; i++) {
654
- if (aParts[i] !== bParts[i])
655
- return (aParts[i] ?? 0) - (bParts[i] ?? 0);
682
+ const diff = numeric(left.core[i], right.core[i]);
683
+ if (diff !== 0)
684
+ return diff;
656
685
  }
657
- if (!aPre && !bPre)
658
- return 0;
659
- if (!aPre)
660
- return 1;
661
- if (!bPre)
662
- return -1;
663
- const aIds = aPre.split(".");
664
- const bIds = bPre.split(".");
665
- for (let i = 0;i < Math.max(aIds.length, bIds.length); i++) {
666
- const ai = aIds[i];
667
- const bi = bIds[i];
686
+ if (left.pre.length === 0 || right.pre.length === 0) {
687
+ return left.pre.length === right.pre.length ? 0 : left.pre.length === 0 ? 1 : -1;
688
+ }
689
+ for (let i = 0;i < Math.max(left.pre.length, right.pre.length); i++) {
690
+ const ai = left.pre[i];
691
+ const bi = right.pre[i];
668
692
  if (ai === undefined)
669
693
  return -1;
670
694
  if (bi === undefined)
671
695
  return 1;
672
696
  const aNum = /^\d+$/.test(ai);
673
697
  const bNum = /^\d+$/.test(bi);
674
- if (aNum && bNum) {
675
- const diff = Number.parseInt(ai, 10) - Number.parseInt(bi, 10);
676
- if (diff !== 0)
677
- return diff;
678
- } else if (aNum) {
679
- return -1;
680
- } else if (bNum) {
681
- return 1;
682
- } else {
683
- const cmp = ai.localeCompare(bi);
684
- if (cmp !== 0)
685
- return cmp;
686
- }
698
+ const diff = aNum && bNum ? numeric(ai, bi) : aNum !== bNum ? aNum ? -1 : 1 : ai === bi ? 0 : ai < bi ? -1 : 1;
699
+ if (diff !== 0)
700
+ return diff;
687
701
  }
688
702
  return 0;
689
703
  }
@@ -701,22 +715,27 @@ function coerceConfigureDroppedKeys(value) {
701
715
  }
702
716
  return dropped;
703
717
  }
704
- var DEFAULT_BRIDGE_TIMEOUT_MS = 30000, BRIDGE_HANG_TIMEOUT_THRESHOLD = 2, MAX_STDOUT_BUFFER, MALFORMED_STDOUT_LOG_CHARS = 512, HASHLINE_REGISTRATION_LOG_INTERVAL_MS = 60000, HASHLINE_REGISTRATION_LOG_STATE_LIMIT = 256, TERMINAL_BASH_STATUSES, binaryFingerprintReader, binaryFingerprintAsyncReader, BENIGN_CPUINFO_PROC_CPUINFO_PARSE_FAILURE = "failed to parse processor information from /proc/cpuinfo", BridgeReplacedDuringVersionCheck, BridgeTransportTimeoutError, BridgeTransportUnavailableError, BridgeTransportUnknownOutcomeError, BinaryBridge;
718
+ function shellOutcomeFromLateReply(response) {
719
+ const taskId = bashTaskIdFrom(response);
720
+ if (taskId)
721
+ return { kind: "task_started", taskId };
722
+ if (response.success === false) {
723
+ return {
724
+ kind: "not_started",
725
+ ...typeof response.code === "string" ? { code: response.code } : {},
726
+ ...typeof response.message === "string" ? { message: response.message } : {}
727
+ };
728
+ }
729
+ return { kind: "unknown" };
730
+ }
731
+ var DEFAULT_BRIDGE_TIMEOUT_MS = 30000, BRIDGE_HANG_TIMEOUT_THRESHOLD = 2, MAX_STDOUT_BUFFER, MALFORMED_STDOUT_LOG_CHARS = 512, HASHLINE_REGISTRATION_LOG_INTERVAL_MS = 60000, HASHLINE_REGISTRATION_LOG_STATE_LIMIT = 256, binaryFingerprintReader, binaryFingerprintAsyncReader, BENIGN_CPUINFO_PROC_CPUINFO_PARSE_FAILURE = "failed to parse processor information from /proc/cpuinfo", BridgeReplacedDuringVersionCheck, BridgeTransportTimeoutError, SHELL_TASK_COMMANDS, DEFAULT_LATE_SHELL_REPLY_GRACE_MS = 1e4, BridgeTransportUnavailableError, BridgeTransportUnknownOutcomeError, BinaryBridge;
705
732
  var init_bridge = __esm(() => {
706
733
  init_active_logger();
707
734
  init_binary_identity();
708
735
  init_child_process();
709
736
  init_command_timeouts();
737
+ init_protocol();
710
738
  MAX_STDOUT_BUFFER = 64 * 1024 * 1024;
711
- TERMINAL_BASH_STATUSES = new Set([
712
- "completed",
713
- "failed",
714
- "killed",
715
- "timed_out",
716
- "fate_unknown",
717
- "cancelled",
718
- "timeout"
719
- ]);
720
739
  binaryFingerprintReader = peekBinaryFingerprint;
721
740
  binaryFingerprintAsyncReader = binaryContentHash;
722
741
  BridgeReplacedDuringVersionCheck = class BridgeReplacedDuringVersionCheck extends Error {
@@ -731,13 +750,16 @@ var init_bridge = __esm(() => {
731
750
  command;
732
751
  timeoutMs;
733
752
  code = "transport_timeout";
734
- constructor(command, timeoutMs, message) {
753
+ shellOutcome;
754
+ constructor(command, timeoutMs, message, shellOutcome) {
735
755
  super(message);
736
756
  this.command = command;
737
757
  this.timeoutMs = timeoutMs;
738
758
  this.name = "BridgeTransportTimeoutError";
759
+ this.shellOutcome = shellOutcome;
739
760
  }
740
761
  };
762
+ SHELL_TASK_COMMANDS = new Set(["bash", "powershell"]);
741
763
  BridgeTransportUnavailableError = class BridgeTransportUnavailableError extends Error {
742
764
  code = "bridge_transport_unavailable";
743
765
  constructor(message, options) {
@@ -778,6 +800,7 @@ var init_bridge = __esm(() => {
778
800
  _shuttingDown = false;
779
801
  timeoutMs;
780
802
  hangThreshold;
803
+ lateShellReplyGraceMs;
781
804
  maxRestarts;
782
805
  configured = false;
783
806
  _configurePromise = null;
@@ -794,6 +817,7 @@ var init_bridge = __esm(() => {
794
817
  cachedStatus = null;
795
818
  statusListeners = new Set;
796
819
  configureWarningClients = new Map;
820
+ restartTimer = null;
797
821
  restartResetTimer = null;
798
822
  lastChildActivityAt = 0;
799
823
  consecutiveRequestTimeouts = 0;
@@ -807,6 +831,7 @@ var init_bridge = __esm(() => {
807
831
  this.cwd = cwd;
808
832
  this.timeoutMs = options?.timeoutMs ?? DEFAULT_BRIDGE_TIMEOUT_MS;
809
833
  this.hangThreshold = options?.hangThreshold ?? BRIDGE_HANG_TIMEOUT_THRESHOLD;
834
+ this.lateShellReplyGraceMs = options?.lateShellReplyGraceMs ?? DEFAULT_LATE_SHELL_REPLY_GRACE_MS;
810
835
  this.maxRestarts = options?.maxRestarts ?? 3;
811
836
  this.errorPrefix = options?.errorPrefix ?? "[aft-bridge]";
812
837
  this.configOverrides = { ...configOverrides ?? {} };
@@ -1079,9 +1104,6 @@ var init_bridge = __esm(() => {
1079
1104
  }
1080
1105
  const requestSessionId = typeof params.session_id === "string" && params.session_id.length > 0 ? params.session_id : undefined;
1081
1106
  this.ensureSpawned(requestSessionId);
1082
- if (requestSessionId && options?.configureWarningClient !== undefined) {
1083
- this.configureWarningClients.set(requestSessionId, options.configureWarningClient);
1084
- }
1085
1107
  const passive = isPassiveCommand(command);
1086
1108
  const resolvedTimeoutMs = options?.transportTimeoutMs ?? options?.timeoutMs ?? this.timeoutMs;
1087
1109
  const effectiveTimeoutMs = passive ? Math.min(resolvedTimeoutMs, PASSIVE_COMMAND_TIMEOUT_MS) : resolvedTimeoutMs;
@@ -1092,6 +1114,9 @@ var init_bridge = __esm(() => {
1092
1114
  if (!this.configured) {
1093
1115
  if (command !== "configure" && command !== "version") {
1094
1116
  if (!this._configurePromise) {
1117
+ if (this.onConfigureWarnings && requestSessionId && options?.configureWarningClient !== undefined) {
1118
+ this.configureWarningClients.set(requestSessionId, options.configureWarningClient);
1119
+ }
1095
1120
  const configuringChild = this.process;
1096
1121
  const requireConfiguringChild = () => {
1097
1122
  if (this.process !== configuringChild) {
@@ -1118,6 +1143,10 @@ var init_bridge = __esm(() => {
1118
1143
  throw new BridgeTransportUnavailableError(`${this.errorPrefix} Bridge died during version check. Check logs: ${this.getLogFilePathVia()}`);
1119
1144
  }
1120
1145
  this.configured = true;
1146
+ } catch (error) {
1147
+ if (sessionIdForConfigure)
1148
+ this.configureWarningClients.delete(sessionIdForConfigure);
1149
+ throw error;
1121
1150
  } finally {
1122
1151
  this._configurePromise = null;
1123
1152
  }
@@ -1157,6 +1186,9 @@ var init_bridge = __esm(() => {
1157
1186
  const entry = this.pending.get(id);
1158
1187
  if (!entry)
1159
1188
  return;
1189
+ if (keepBridgeOnTimeout && this.holdForLateShellReply(id, entry, effectiveTimeoutMs, requestSessionId)) {
1190
+ return;
1191
+ }
1160
1192
  this.pending.delete(id);
1161
1193
  clearTimeout(entry.timer);
1162
1194
  entry.onSettled?.();
@@ -1251,52 +1283,48 @@ var init_bridge = __esm(() => {
1251
1283
  }
1252
1284
  }
1253
1285
  async deliverConfigureWarnings(configResult, params, options) {
1286
+ const sessionId = typeof params.session_id === "string" ? params.session_id : undefined;
1287
+ const client = options?.configureWarningClient ?? (sessionId ? this.configureWarningClients.get(sessionId) : undefined);
1288
+ if (sessionId && configResult.warnings_pending !== true)
1289
+ this.configureWarningClients.delete(sessionId);
1254
1290
  if (!this.onConfigureWarnings)
1255
1291
  return;
1256
1292
  const warnings = Array.isArray(configResult.warnings) ? configResult.warnings : [];
1257
1293
  const configDroppedKeys = coerceConfigureDroppedKeys(configResult.config_dropped_keys);
1258
1294
  if (warnings.length === 0 && configDroppedKeys.length === 0)
1259
1295
  return;
1260
- const sessionId = typeof params.session_id === "string" ? params.session_id : undefined;
1261
1296
  const context = {
1262
1297
  projectRoot: this.cwd,
1263
1298
  sessionId,
1264
- client: options?.configureWarningClient ?? (sessionId ? this.configureWarningClients.get(sessionId) : undefined),
1299
+ client,
1265
1300
  warnings
1266
1301
  };
1267
- if (configDroppedKeys.length > 0) {
1302
+ if (configDroppedKeys.length > 0)
1268
1303
  context.configDroppedKeys = configDroppedKeys;
1269
- }
1270
- try {
1271
- await this.onConfigureWarnings(context);
1272
- } catch (err) {
1273
- this.warnVia(`configure warning delivery failed: ${err instanceof Error ? err.message : String(err)}`);
1274
- } finally {
1275
- if (sessionId) {
1276
- this.configureWarningClients.delete(sessionId);
1277
- }
1278
- }
1304
+ this.dispatchHostCallback("configure warning", () => this.onConfigureWarnings?.(context));
1279
1305
  }
1280
1306
  async handleConfigureWarningsFrame(frame) {
1281
- if (!this.onConfigureWarnings)
1282
- return;
1283
- const warnings = frame.warnings;
1284
- if (!Array.isArray(warnings) || warnings.length === 0)
1307
+ const sessionId = typeof frame.session_id === "string" && frame.session_id.length > 0 ? frame.session_id : null;
1308
+ const client = sessionId ? this.configureWarningClients.get(sessionId) : undefined;
1309
+ if (sessionId)
1310
+ this.configureWarningClients.delete(sessionId);
1311
+ if (!this.onConfigureWarnings || !Array.isArray(frame.warnings) || frame.warnings.length === 0)
1285
1312
  return;
1286
- const projectRoot = typeof frame.project_root === "string" ? frame.project_root : this.cwd;
1287
- const rawSessionId = frame.session_id;
1288
- const sessionId = typeof rawSessionId === "string" && rawSessionId.length > 0 ? rawSessionId : null;
1313
+ this.dispatchHostCallback("configure warning", () => this.onConfigureWarnings?.({
1314
+ projectRoot: typeof frame.project_root === "string" ? frame.project_root : this.cwd,
1315
+ sessionId,
1316
+ client,
1317
+ warnings: frame.warnings
1318
+ }));
1319
+ }
1320
+ dispatchHostCallback(label, callback) {
1321
+ const failed = (error) => {
1322
+ this.warnVia(`${label} delivery failed: ${error instanceof Error ? error.message : String(error)}`);
1323
+ };
1289
1324
  try {
1290
- await this.onConfigureWarnings({
1291
- projectRoot,
1292
- sessionId,
1293
- client: sessionId ? this.configureWarningClients.get(sessionId) : undefined,
1294
- warnings
1295
- });
1296
- } finally {
1297
- if (sessionId) {
1298
- this.configureWarningClients.delete(sessionId);
1299
- }
1325
+ Promise.resolve(callback()).catch(failed);
1326
+ } catch (error) {
1327
+ failed(error);
1300
1328
  }
1301
1329
  }
1302
1330
  handleStatusChangedFrame(frame) {
@@ -1319,6 +1347,7 @@ var init_bridge = __esm(() => {
1319
1347
  this._shuttingDown = true;
1320
1348
  this.spawnedBinaryFingerprint = null;
1321
1349
  this.clearRestartResetTimer();
1350
+ this.clearRestartTimer();
1322
1351
  this.configureWarningClients.clear();
1323
1352
  this.rejectAllPending(new BridgeTransportUnknownOutcomeError(`${this.errorPrefix} Bridge shutting down`));
1324
1353
  if (this.process) {
@@ -1402,6 +1431,7 @@ var init_bridge = __esm(() => {
1402
1431
  this.spawnProcess(triggeringSessionId);
1403
1432
  }
1404
1433
  spawnProcess(triggeringSessionId) {
1434
+ this.clearRestartTimer();
1405
1435
  this._retiringDueToBinaryChange = false;
1406
1436
  if (triggeringSessionId) {
1407
1437
  this.sessionLogVia(triggeringSessionId, `Spawning binary: ${this.binaryPath} (cwd: ${this.cwd})`);
@@ -1452,6 +1482,11 @@ var init_bridge = __esm(() => {
1452
1482
  env: spawnEnv
1453
1483
  });
1454
1484
  const currentChild = child;
1485
+ child.stdin?.on("error", (cause) => {
1486
+ if (this.process !== currentChild)
1487
+ return;
1488
+ this.invalidateTransportProcess(new BridgeTransportUnknownOutcomeError(`${this.errorPrefix} Failed to write to stdin: ${cause.message}`, { cause }));
1489
+ });
1455
1490
  const stdoutDecoder = new StringDecoder("utf8");
1456
1491
  child.stdout?.on("data", (chunk) => {
1457
1492
  if (this.process !== currentChild)
@@ -1567,10 +1602,12 @@ var init_bridge = __esm(() => {
1567
1602
  ${tail}`;
1568
1603
  }
1569
1604
  onStdoutData(data) {
1570
- if (this.stdoutPendingLength + data.length > MAX_STDOUT_BUFFER) {
1605
+ const exceedsLimit = (fragment) => {
1606
+ if (this.stdoutPendingLength + Buffer.byteLength(fragment, "utf8") <= MAX_STDOUT_BUFFER)
1607
+ return false;
1571
1608
  this.handleCrash(new Error(`aft bridge stdout buffer exceeded ${MAX_STDOUT_BUFFER} bytes — killing bridge`));
1572
- return;
1573
- }
1609
+ return true;
1610
+ };
1574
1611
  this.stdoutScannedChars += data.length;
1575
1612
  const generation = this.processGeneration;
1576
1613
  let start = 0;
@@ -1578,6 +1615,8 @@ var init_bridge = __esm(() => {
1578
1615
  `);
1579
1616
  while (newlineIdx !== -1) {
1580
1617
  let line = data.slice(start, newlineIdx);
1618
+ if (exceedsLimit(line))
1619
+ return;
1581
1620
  if (this.stdoutPending.length > 0) {
1582
1621
  this.stdoutPending.push(line);
1583
1622
  line = this.stdoutPending.join("");
@@ -1596,8 +1635,10 @@ var init_bridge = __esm(() => {
1596
1635
  }
1597
1636
  if (start < data.length) {
1598
1637
  const rest = start === 0 ? data : data.slice(start);
1638
+ if (exceedsLimit(rest))
1639
+ return;
1599
1640
  this.stdoutPending.push(rest);
1600
- this.stdoutPendingLength += rest.length;
1641
+ this.stdoutPendingLength += Buffer.byteLength(rest, "utf8");
1601
1642
  }
1602
1643
  }
1603
1644
  flushStdoutBuffer() {
@@ -1641,15 +1682,15 @@ var init_bridge = __esm(() => {
1641
1682
  if (taskId)
1642
1683
  this.outstandingBackgroundTaskIds.delete(taskId);
1643
1684
  this.syncEventLoopHold();
1644
- this.onBashCompletion?.(response, this);
1685
+ this.dispatchHostCallback("bash completion", () => this.onBashCompletion?.(response, this));
1645
1686
  return;
1646
1687
  }
1647
1688
  if (response.type === "bash_long_running") {
1648
- this.onBashLongRunning?.(response, this);
1689
+ this.dispatchHostCallback("bash long-running", () => this.onBashLongRunning?.(response, this));
1649
1690
  return;
1650
1691
  }
1651
1692
  if (response.type === "bash_pattern_match") {
1652
- this.onBashPatternMatch?.(response, this);
1693
+ this.dispatchHostCallback("bash pattern-match", () => this.onBashPatternMatch?.(response, this));
1653
1694
  return;
1654
1695
  }
1655
1696
  if (response.type === "configure_warnings") {
@@ -1685,6 +1726,13 @@ var init_bridge = __esm(() => {
1685
1726
  this.scheduleRestartCountReset();
1686
1727
  this.accountForBashTaskResponse(entry.command, response);
1687
1728
  entry.resolve(response);
1729
+ } else if (id && typeof response.type !== "string") {
1730
+ const taskId = bashTaskIdFrom(response);
1731
+ if (taskId) {
1732
+ this.warnVia(`Dropped late reply for settled request id=${id} task_id=${taskId}`);
1733
+ } else {
1734
+ this.logVia(`Dropped late reply for settled request id=${id}`);
1735
+ }
1688
1736
  } else if (typeof response.type === "string") {
1689
1737
  this.logVia(`Ignoring unknown stdout push frame type: ${response.type}`);
1690
1738
  }
@@ -1693,11 +1741,38 @@ var init_bridge = __esm(() => {
1693
1741
  this.warnVia(`Failed to parse stdout line: ${quoted}`);
1694
1742
  }
1695
1743
  }
1744
+ holdForLateShellReply(id, entry, effectiveTimeoutMs, requestSessionId) {
1745
+ const graceMs = this.lateShellReplyGraceMs;
1746
+ if (!SHELL_TASK_COMMANDS.has(entry.command) || graceMs <= 0)
1747
+ return false;
1748
+ const timeoutMsg = `Request "${entry.command}" (id=${id}) timed out after ${effectiveTimeoutMs}ms; waiting up to ${graceMs}ms for a late reply naming its task`;
1749
+ if (requestSessionId) {
1750
+ this.sessionWarnVia(requestSessionId, timeoutMsg);
1751
+ } else {
1752
+ this.warnVia(timeoutMsg);
1753
+ }
1754
+ const message = `${this.errorPrefix} Request "${entry.command}" (id=${id}) timed out after ${effectiveTimeoutMs}ms`;
1755
+ const rejectWith = entry.reject;
1756
+ const settle = (outcome) => {
1757
+ rejectWith(new BridgeTransportTimeoutError(entry.command, effectiveTimeoutMs, message, outcome));
1758
+ };
1759
+ entry.resolve = (response) => settle(shellOutcomeFromLateReply(response));
1760
+ clearTimeout(entry.timer);
1761
+ entry.timer = setTimeout(() => {
1762
+ if (this.pending.get(id) !== entry)
1763
+ return;
1764
+ this.pending.delete(id);
1765
+ entry.onSettled?.();
1766
+ this.warnVia(`Request "${entry.command}" (id=${id}) got no reply within ${graceMs}ms after its deadline`);
1767
+ settle({ kind: "unknown" });
1768
+ }, graceMs);
1769
+ return true;
1770
+ }
1696
1771
  accountForBashTaskResponse(command, response) {
1697
1772
  const taskId = bashTaskIdFrom(response);
1698
1773
  if (!taskId)
1699
1774
  return;
1700
- if (isTerminalBashStatus(response.status)) {
1775
+ if (isTerminalBashStatus(response.status, true)) {
1701
1776
  this.outstandingBackgroundTaskIds.delete(taskId);
1702
1777
  return;
1703
1778
  }
@@ -1732,6 +1807,7 @@ var init_bridge = __esm(() => {
1732
1807
  }
1733
1808
  }
1734
1809
  handleCrash(cause) {
1810
+ this.clearRestartTimer();
1735
1811
  const proc = this.process;
1736
1812
  this.process = null;
1737
1813
  this.spawnedBinaryFingerprint = null;
@@ -1754,7 +1830,8 @@ var init_bridge = __esm(() => {
1754
1830
  const delay = 100 * 2 ** this._restartCount;
1755
1831
  this._restartCount++;
1756
1832
  this.logVia(`Auto-restart #${this._restartCount} in ${delay}ms`);
1757
- const restartTimer = setTimeout(() => {
1833
+ this.restartTimer = setTimeout(() => {
1834
+ this.restartTimer = null;
1758
1835
  if (!this._shuttingDown && !this.isAlive()) {
1759
1836
  try {
1760
1837
  this.spawnProcess();
@@ -1763,7 +1840,7 @@ var init_bridge = __esm(() => {
1763
1840
  }
1764
1841
  }
1765
1842
  }, delay);
1766
- restartTimer.unref?.();
1843
+ this.restartTimer.unref?.();
1767
1844
  this.scheduleRestartCountReset();
1768
1845
  } else {
1769
1846
  this.errorVia(`Max restarts (${this.maxRestarts}) reached, giving up. Logs: ${this.getLogFilePathVia()}${tail}`);
@@ -1771,6 +1848,7 @@ var init_bridge = __esm(() => {
1771
1848
  }
1772
1849
  }
1773
1850
  rejectAllPending(error) {
1851
+ this.configureWarningClients.clear();
1774
1852
  for (const [_id, entry] of this.pending) {
1775
1853
  clearTimeout(entry.timer);
1776
1854
  entry.onSettled?.();
@@ -1779,6 +1857,8 @@ var init_bridge = __esm(() => {
1779
1857
  this.pending.clear();
1780
1858
  }
1781
1859
  scheduleRestartCountReset() {
1860
+ if (this._restartCount === 0)
1861
+ return;
1782
1862
  this.clearRestartResetTimer();
1783
1863
  this.restartResetTimer = setTimeout(() => {
1784
1864
  this._restartCount = 0;
@@ -1786,6 +1866,11 @@ var init_bridge = __esm(() => {
1786
1866
  }, BinaryBridge.RESTART_RESET_MS);
1787
1867
  this.restartResetTimer.unref?.();
1788
1868
  }
1869
+ clearRestartTimer() {
1870
+ if (this.restartTimer)
1871
+ clearTimeout(this.restartTimer);
1872
+ this.restartTimer = null;
1873
+ }
1789
1874
  clearRestartResetTimer() {
1790
1875
  if (this.restartResetTimer) {
1791
1876
  clearTimeout(this.restartResetTimer);
@@ -2061,7 +2146,8 @@ async function downloadBinary(version) {
2061
2146
  const handleSigint = () => {
2062
2147
  cleanUpInterruptedDownload();
2063
2148
  process.off("SIGINT", handleSigint);
2064
- process.kill(process.pid, "SIGINT");
2149
+ if (process.listenerCount("SIGINT") === 0)
2150
+ process.kill(process.pid, "SIGINT");
2065
2151
  };
2066
2152
  const handleExit = () => cleanUpInterruptedDownload();
2067
2153
  process.once("SIGINT", handleSigint);
@@ -2987,6 +3073,7 @@ var CALL_DEADLINE_EXPIRED, LOCALLY_SATISFIED_COMMANDS, dispatchProbes;
2987
3073
  var init_subc_transport = __esm(() => {
2988
3074
  init_dist();
2989
3075
  init_active_logger();
3076
+ init_bash_format();
2990
3077
  init_error_contract();
2991
3078
  init_lifecycle_registry();
2992
3079
  init_project_identity();
@@ -3189,6 +3276,30 @@ function translateBlock(map, userBase, blockLabel, out) {
3189
3276
  translateGithubAliases(map, prefix, out);
3190
3277
  translateInspectLspPaths(map, prefix, out);
3191
3278
  translateExperimentalPaths(map, prefix, out);
3279
+ if (isRecord(map.sandbox) && Object.hasOwn(map.sandbox, "enabled")) {
3280
+ const sandbox = map.sandbox;
3281
+ const enabled = sandbox.enabled;
3282
+ delete sandbox.enabled;
3283
+ recordRetired(out, prefix, "sandbox.enabled");
3284
+ if (typeof enabled === "boolean") {
3285
+ if (sandbox.profile === undefined)
3286
+ sandbox.profile = {};
3287
+ if (isRecord(sandbox.profile)) {
3288
+ const modes = { worker: enabled ? "strict" : "relaxed", head: enabled ? "strict" : "off" };
3289
+ for (const role of ["worker", "head"]) {
3290
+ if (sandbox.profile[role] !== undefined && sandbox.profile[role] !== modes[role]) {
3291
+ superseded(out, `${prefix}sandbox.enabled`, `sandbox.profile.${role} takes precedence over sandbox.enabled`);
3292
+ }
3293
+ sandbox.profile[role] ??= modes[role];
3294
+ }
3295
+ }
3296
+ } else
3297
+ out.warnings.push({
3298
+ code: "invalid_legacy_config",
3299
+ key: `${prefix}sandbox.enabled`,
3300
+ message: "Ignoring non-boolean sandbox.enabled; use sandbox.profile"
3301
+ });
3302
+ }
3192
3303
  let explicitList;
3193
3304
  const rawList = map.disabled_tools;
3194
3305
  if (Array.isArray(rawList) && rawList.every((entry) => typeof entry === "string")) {
@@ -3418,6 +3529,7 @@ var init_feature_config = __esm(() => {
3418
3529
  aft_bash: "bash"
3419
3530
  };
3420
3531
  RETIRED_PATHS = [
3532
+ ["sandbox.enabled", "sandbox.profile"],
3421
3533
  ["tool_surface", "disabled_tools"],
3422
3534
  ["hoist_builtin_tools", "disabled_tools"],
3423
3535
  ["enabled", "disabled_tools"],
@@ -3477,6 +3589,73 @@ var init_location_lifecycle = __esm(() => {
3477
3589
  RELEASE_LOCATION = Symbol.for("@cortexkit/aft-bridge/location-release/v1");
3478
3590
  });
3479
3591
 
3592
+ // ../aft-bridge/dist/lsp-github-probe.js
3593
+ var init_lsp_github_probe = __esm(() => {
3594
+ init_active_logger();
3595
+ });
3596
+
3597
+ // ../aft-bridge/dist/lsp-github-table.js
3598
+ var init_lsp_github_table = () => {};
3599
+
3600
+ // ../aft-bridge/dist/tar-executable.js
3601
+ import { existsSync as existsSync3 } from "node:fs";
3602
+ import { join as join8 } from "node:path";
3603
+ function windowsTarExecutable(options = {}) {
3604
+ const platform = options.platform ?? process.platform;
3605
+ if (platform !== "win32")
3606
+ return "tar";
3607
+ const env = options.env ?? process.env;
3608
+ const systemTar = join8(env.SystemRoot ?? "C:\\Windows", "System32", "tar.exe");
3609
+ return (options.exists ?? existsSync3)(systemTar) ? systemTar : "tar";
3610
+ }
3611
+ function extractionCommand(args, privateStorage) {
3612
+ const executable = windowsTarExecutable();
3613
+ if (privateStorage && process.platform !== "win32") {
3614
+ return {
3615
+ executable,
3616
+ file: "/bin/sh",
3617
+ args: [
3618
+ "-c",
3619
+ 'umask 077; exec "$@"',
3620
+ "aft-extract",
3621
+ executable,
3622
+ "--no-same-permissions",
3623
+ ...args.map((arg, index) => index === 0 && !arg.startsWith("-") ? `-${arg}` : arg)
3624
+ ]
3625
+ };
3626
+ }
3627
+ return { executable, file: executable, args };
3628
+ }
3629
+ function extractionError(executable, cause) {
3630
+ const detail = cause instanceof Error ? cause.message : String(cause);
3631
+ return new Error(`tar extraction failed using ${executable}: ${detail}`, { cause });
3632
+ }
3633
+ function execTarExtraction(args, timeout, privateStorage = false) {
3634
+ const command = extractionCommand(args, privateStorage);
3635
+ return new Promise((resolve, reject) => {
3636
+ execFile(command.file, command.args, { timeout }, (error) => {
3637
+ if (error)
3638
+ reject(extractionError(command.executable, error));
3639
+ else
3640
+ resolve();
3641
+ });
3642
+ });
3643
+ }
3644
+ var init_tar_executable = __esm(() => {
3645
+ init_child_process();
3646
+ });
3647
+
3648
+ // ../aft-bridge/dist/lsp-github-install.js
3649
+ var init_lsp_github_install = __esm(() => {
3650
+ init_binary_identity();
3651
+ init_cache_paths();
3652
+ init_child_process();
3653
+ init_lsp_github_probe();
3654
+ init_lsp_github_table();
3655
+ init_path_display();
3656
+ init_tar_executable();
3657
+ });
3658
+
3480
3659
  // ../aft-bridge/dist/message-detach.js
3481
3660
  var BASH_WAIT_DETACH_MAGIC_KEYWORD = "&detach", STANDALONE_DETACH_KEYWORD_SOURCE, STANDALONE_DETACH_KEYWORD_PATTERN, STANDALONE_DETACH_KEYWORDS_PATTERN;
3482
3661
  var init_message_detach = __esm(() => {
@@ -3487,7 +3666,7 @@ var init_message_detach = __esm(() => {
3487
3666
 
3488
3667
  // ../aft-bridge/dist/paths.js
3489
3668
  import { homedir as homedir7 } from "node:os";
3490
- import { dirname as dirname2, isAbsolute as isAbsolute4, join as join8, resolve as resolve5 } from "node:path";
3669
+ import { dirname as dirname2, isAbsolute as isAbsolute4, join as join9, resolve as resolve5 } from "node:path";
3491
3670
  function homeDir3() {
3492
3671
  if (process.platform === "win32")
3493
3672
  return process.env.USERPROFILE || process.env.HOME || homedir7();
@@ -3497,20 +3676,20 @@ function configHome() {
3497
3676
  const xdg = process.env.XDG_CONFIG_HOME;
3498
3677
  if (xdg && isAbsolute4(xdg))
3499
3678
  return xdg;
3500
- return join8(homeDir3(), ".config");
3679
+ return join9(homeDir3(), ".config");
3501
3680
  }
3502
3681
  function resolveCortexKitUserConfigPath() {
3503
- return join8(configHome(), "cortexkit", "aft.jsonc");
3682
+ return join9(configHome(), "cortexkit", "aft.jsonc");
3504
3683
  }
3505
3684
  function resolveCortexKitProjectConfigPath(projectDirectory) {
3506
- return join8(projectDirectory, ".cortexkit", "aft.jsonc");
3685
+ return join9(projectDirectory, ".cortexkit", "aft.jsonc");
3507
3686
  }
3508
3687
  var init_paths = __esm(() => {
3509
3688
  init_private_storage();
3510
3689
  });
3511
3690
 
3512
3691
  // ../aft-bridge/dist/resolver.js
3513
- import { closeSync as closeSync4, existsSync as existsSync3, promises as fsPromises, openSync as openSync4, readFileSync as readFileSync4, readSync as readSync3 } from "node:fs";
3692
+ import { closeSync as closeSync4, existsSync as existsSync4, promises as fsPromises, openSync as openSync4, readFileSync as readFileSync4, readSync as readSync3 } from "node:fs";
3514
3693
  function isNativeExecutable(binaryPath) {
3515
3694
  let fd = null;
3516
3695
  try {
@@ -3567,10 +3746,10 @@ var init_migration = __esm(() => {
3567
3746
  // ../aft-bridge/dist/migration-notices.js
3568
3747
  import { readFileSync as readFileSync5, renameSync as renameSync3, rmdirSync, statSync as statSync3, writeFileSync as writeFileSync2 } from "node:fs";
3569
3748
  import { homedir as homedir8 } from "node:os";
3570
- import { dirname as dirname3, join as join9, resolve as resolve6 } from "node:path";
3749
+ import { dirname as dirname3, join as join10, resolve as resolve6 } from "node:path";
3571
3750
  function migrationNoticeStorePath(env = process.env) {
3572
- const stateHome = env.XDG_STATE_HOME && env.XDG_STATE_HOME.length > 0 ? env.XDG_STATE_HOME : join9(homedir8(), ".local", "state");
3573
- return join9(stateHome, "cortexkit", "aft", "migration-notices.json");
3751
+ const stateHome = env.XDG_STATE_HOME && env.XDG_STATE_HOME.length > 0 ? env.XDG_STATE_HOME : join10(homedir8(), ".local", "state");
3752
+ return join10(stateHome, "cortexkit", "aft", "migration-notices.json");
3574
3753
  }
3575
3754
  function readRecords(storePath) {
3576
3755
  try {
@@ -3631,7 +3810,7 @@ var init_migration_notices = __esm(() => {
3631
3810
  // ../aft-bridge/dist/npm-resolver.js
3632
3811
  import { readdirSync as readdirSync2, statSync as statSync4 } from "node:fs";
3633
3812
  import { homedir as homedir9 } from "node:os";
3634
- import { dirname as dirname4, isAbsolute as isAbsolute5, join as join10 } from "node:path";
3813
+ import { dirname as dirname4, isAbsolute as isAbsolute5, join as join11 } from "node:path";
3635
3814
  function defaultDeps() {
3636
3815
  return {
3637
3816
  platform: process.platform,
@@ -3660,14 +3839,14 @@ function npmFromPath(deps) {
3660
3839
  const dir = entry.trim().replace(/^"|"$/g, "");
3661
3840
  if (!dir || !isAbsolute5(dir))
3662
3841
  continue;
3663
- if (isFile(join10(dir, name)))
3842
+ if (isFile(join11(dir, name)))
3664
3843
  return dir;
3665
3844
  }
3666
3845
  return null;
3667
3846
  }
3668
3847
  function npmAdjacentToNode(deps) {
3669
3848
  const dir = dirname4(deps.execPath);
3670
- return isFile(join10(dir, npmBinaryName(deps.platform))) ? dir : null;
3849
+ return isFile(join11(dir, npmBinaryName(deps.platform))) ? dir : null;
3671
3850
  }
3672
3851
  function highestVersionedNodeBin(installsDir, name) {
3673
3852
  let entries;
@@ -3676,8 +3855,8 @@ function highestVersionedNodeBin(installsDir, name) {
3676
3855
  } catch {
3677
3856
  return null;
3678
3857
  }
3679
- const candidates = entries.filter((v) => isFile(join10(installsDir, v, "bin", name))).sort((a, b) => compareVersionsDesc(a, b));
3680
- return candidates.length > 0 ? join10(installsDir, candidates[0], "bin") : null;
3858
+ const candidates = entries.filter((v) => isFile(join11(installsDir, v, "bin", name))).sort((a, b) => compareVersionsDesc(a, b));
3859
+ return candidates.length > 0 ? join11(installsDir, candidates[0], "bin") : null;
3681
3860
  }
3682
3861
  function compareVersionsDesc(a, b) {
3683
3862
  const pa = a.replace(/^v/, "").split(".").map((n) => Number.parseInt(n, 10));
@@ -3702,22 +3881,22 @@ function wellKnownNpmDirs(deps) {
3702
3881
  const programFiles = env.ProgramFiles || "C:\\Program Files";
3703
3882
  const appData = env.APPDATA;
3704
3883
  const localAppData = env.LOCALAPPDATA;
3705
- push(join10(programFiles, "nodejs"));
3884
+ push(join11(programFiles, "nodejs"));
3706
3885
  if (appData)
3707
- push(join10(appData, "npm"));
3886
+ push(join11(appData, "npm"));
3708
3887
  if (localAppData)
3709
- push(join10(localAppData, "Volta", "bin"));
3888
+ push(join11(localAppData, "Volta", "bin"));
3710
3889
  if (env.NVM_SYMLINK)
3711
3890
  push(env.NVM_SYMLINK);
3712
3891
  } else {
3713
3892
  if (env.NVM_BIN)
3714
3893
  push(env.NVM_BIN);
3715
- push(highestVersionedNodeBin(join10(home, ".nvm", "versions", "node"), name));
3716
- push(highestVersionedNodeBin(join10(home, ".local", "share", "mise", "installs", "node"), name));
3717
- push(highestVersionedNodeBin(join10(home, ".asdf", "installs", "nodejs"), name));
3718
- push(join10(home, ".volta", "bin"));
3719
- push(join10(home, ".asdf", "shims"));
3720
- const systemDirs = deps.systemNpmDirs ?? (platform === "darwin" ? ["/opt/homebrew/bin", "/usr/local/bin"] : ["/usr/local/bin", "/usr/bin", join10(home, ".local", "bin")]);
3894
+ push(highestVersionedNodeBin(join11(home, ".nvm", "versions", "node"), name));
3895
+ push(highestVersionedNodeBin(join11(home, ".local", "share", "mise", "installs", "node"), name));
3896
+ push(highestVersionedNodeBin(join11(home, ".asdf", "installs", "nodejs"), name));
3897
+ push(join11(home, ".volta", "bin"));
3898
+ push(join11(home, ".asdf", "shims"));
3899
+ const systemDirs = deps.systemNpmDirs ?? (platform === "darwin" ? ["/opt/homebrew/bin", "/usr/local/bin"] : ["/usr/local/bin", "/usr/bin", join11(home, ".local", "bin")]);
3721
3900
  for (const dir of systemDirs)
3722
3901
  push(dir);
3723
3902
  }
@@ -3727,12 +3906,12 @@ function resolveNpm(deps = defaultDeps()) {
3727
3906
  const name = npmBinaryName(deps.platform);
3728
3907
  const onPath = npmFromPath(deps);
3729
3908
  if (onPath)
3730
- return { command: join10(onPath, name), binDir: onPath };
3909
+ return { command: join11(onPath, name), binDir: onPath };
3731
3910
  const adjacent = npmAdjacentToNode(deps);
3732
3911
  if (adjacent)
3733
- return { command: join10(adjacent, name), binDir: adjacent };
3912
+ return { command: join11(adjacent, name), binDir: adjacent };
3734
3913
  for (const dir of wellKnownNpmDirs(deps)) {
3735
- const candidate = join10(dir, name);
3914
+ const candidate = join11(dir, name);
3736
3915
  if (isFile(candidate))
3737
3916
  return { command: candidate, binDir: dir };
3738
3917
  }
@@ -3893,7 +4072,7 @@ function terminateNpmProcessTree(child, invocation, env = process.env, gracePeri
3893
4072
  };
3894
4073
  child.once("exit", onChildExit);
3895
4074
  const systemRoot = env.SystemRoot ?? env.SYSTEMROOT;
3896
- const taskkill = systemRoot ? join10(systemRoot, "System32", "taskkill.exe") : "taskkill.exe";
4075
+ const taskkill = systemRoot ? join11(systemRoot, "System32", "taskkill.exe") : "taskkill.exe";
3897
4076
  try {
3898
4077
  killer = spawn(taskkill, ["/pid", String(child.pid), "/t", "/f"], {
3899
4078
  stdio: "ignore",
@@ -3929,7 +4108,7 @@ var init_npm_resolver = __esm(() => {
3929
4108
  });
3930
4109
 
3931
4110
  // ../aft-bridge/dist/onnx-probe.js
3932
- import { closeSync as closeSync5, existsSync as existsSync4, openSync as openSync5, readSync as readSync4, realpathSync as realpathSync2 } from "node:fs";
4111
+ import { closeSync as closeSync5, existsSync as existsSync5, openSync as openSync5, readSync as readSync4, realpathSync as realpathSync2 } from "node:fs";
3933
4112
  function readAt(fd, offset, length) {
3934
4113
  const buffer = Buffer.alloc(length);
3935
4114
  const read = readSync4(fd, buffer, 0, length, offset);
@@ -4032,7 +4211,7 @@ function probeOnnxRuntimeLoadable(libPath, arch = process.arch) {
4032
4211
  for (const dependency of dylibs) {
4033
4212
  if (isUncheckableDependency(dependency))
4034
4213
  continue;
4035
- if (!existsSync4(dependency)) {
4214
+ if (!existsSync5(dependency)) {
4036
4215
  return { loadable: false, reason: `missing dependency ${dependency}` };
4037
4216
  }
4038
4217
  }
@@ -4049,41 +4228,6 @@ var init_onnx_probe = __esm(() => {
4049
4228
  UNCHECKED = { loadable: true, checked: false };
4050
4229
  });
4051
4230
 
4052
- // ../aft-bridge/dist/tar-executable.js
4053
- import { existsSync as existsSync5 } from "node:fs";
4054
- import { join as join11 } from "node:path";
4055
- function windowsTarExecutable(options = {}) {
4056
- const platform = options.platform ?? process.platform;
4057
- if (platform !== "win32")
4058
- return "tar";
4059
- const env = options.env ?? process.env;
4060
- const systemTar = join11(env.SystemRoot ?? "C:\\Windows", "System32", "tar.exe");
4061
- return (options.exists ?? existsSync5)(systemTar) ? systemTar : "tar";
4062
- }
4063
- function execTarExtractionSync(args, timeout, privateStorage = false) {
4064
- const executable = windowsTarExecutable();
4065
- try {
4066
- if (privateStorage && process.platform !== "win32") {
4067
- execFileSync("/bin/sh", [
4068
- "-c",
4069
- 'umask 077; exec "$@"',
4070
- "aft-extract",
4071
- executable,
4072
- "--no-same-permissions",
4073
- ...args.map((arg, index) => index === 0 && !arg.startsWith("-") ? `-${arg}` : arg)
4074
- ], { stdio: "pipe", timeout });
4075
- } else {
4076
- execFileSync(executable, args, { stdio: "pipe", timeout });
4077
- }
4078
- } catch (cause) {
4079
- const detail = cause instanceof Error ? cause.message : String(cause);
4080
- throw new Error(`tar extraction failed using ${executable}: ${detail}`, { cause });
4081
- }
4082
- }
4083
- var init_tar_executable = __esm(() => {
4084
- init_child_process();
4085
- });
4086
-
4087
4231
  // ../aft-bridge/dist/onnx-runtime.js
4088
4232
  import { randomBytes } from "node:crypto";
4089
4233
  import { chmodSync as chmodSync2, closeSync as closeSync6, copyFileSync as copyFileSync3, createWriteStream as createWriteStream2, existsSync as existsSync6, lstatSync as lstatSync2, openSync as openSync6, readdirSync as readdirSync3, readFileSync as readFileSync6, readlinkSync, realpathSync as realpathSync3, renameSync as renameSync4, rmSync as rmSync2, statSync as statSync5, symlinkSync, unlinkSync as unlinkSync3, writeFileSync as writeFileSync3 } from "node:fs";
@@ -4541,7 +4685,7 @@ async function downloadOnnxRuntime(info, targetDir) {
4541
4685
  const archiveSha256 = await sha256File(archivePath);
4542
4686
  log(`ONNX Runtime archive sha256=${archiveSha256}`);
4543
4687
  if (info.archiveType === "tgz") {
4544
- execTarExtractionSync(["xzf", archivePath, "-C", extractionRoot], 120000, true);
4688
+ await execTarExtraction(["xzf", archivePath, "-C", extractionRoot], 120000, true);
4545
4689
  } else {
4546
4690
  await extractZipArchive(archivePath, extractionRoot);
4547
4691
  }
@@ -4674,12 +4818,16 @@ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, c
4674
4818
  }
4675
4819
  async function extractZipArchive(archivePath, destinationDir) {
4676
4820
  if (process.platform === "win32") {
4677
- execTarExtractionSync(["-xf", archivePath, "-C", destinationDir], 120000);
4821
+ await execTarExtraction(["-xf", archivePath, "-C", destinationDir], 120000);
4678
4822
  return;
4679
4823
  }
4680
- execFileSync("unzip", ["-q", archivePath, "-d", destinationDir], {
4681
- stdio: "pipe",
4682
- timeout: 120000
4824
+ await new Promise((resolve, reject) => {
4825
+ execFile("unzip", ["-q", archivePath, "-d", destinationDir], { timeout: 120000 }, (error) => {
4826
+ if (error)
4827
+ reject(error);
4828
+ else
4829
+ resolve();
4830
+ });
4683
4831
  });
4684
4832
  }
4685
4833
  function writeOnnxInstalledMeta(installDir, version, sha256, archiveSha256) {
@@ -4954,6 +5102,7 @@ var init_semantic_status = __esm(() => {
4954
5102
  // ../aft-bridge/dist/index.js
4955
5103
  var init_dist2 = __esm(() => {
4956
5104
  init_active_logger();
5105
+ init_bash_format();
4957
5106
  init_bash_hints();
4958
5107
  init_bash_host_fallback();
4959
5108
  init_binary_identity();
@@ -4971,6 +5120,9 @@ var init_dist2 = __esm(() => {
4971
5120
  init_error_contract();
4972
5121
  init_lifecycle_registry();
4973
5122
  init_location_lifecycle();
5123
+ init_lsp_github_install();
5124
+ init_lsp_github_probe();
5125
+ init_lsp_github_table();
4974
5126
  init_message_detach();
4975
5127
  init_migration();
4976
5128
  init_migration_notices();
@@ -13651,7 +13803,7 @@ function getSelfVersion() {
13651
13803
  var init_self_version = () => {};
13652
13804
 
13653
13805
  // ../../.github/opencode-version.txt
13654
- var opencode_version_default = `1.18.30
13806
+ var opencode_version_default = `1.19.3
13655
13807
  `;
13656
13808
  var init_opencode_version = () => {};
13657
13809
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/aft",
3
- "version": "0.60.0",
3
+ "version": "0.61.0",
4
4
  "type": "module",
5
5
  "description": "Unified CLI for Agent File Tools (AFT) — setup, one-shot index snapshots, doctor, and diagnostics across supported agent harnesses (OpenCode, Pi)",
6
6
  "license": "MIT",
@@ -25,7 +25,7 @@
25
25
  "dependencies": {
26
26
  "@clack/core": "^1.4.2",
27
27
  "@clack/prompts": "^1.6.0",
28
- "@cortexkit/aft-bridge": "0.60.0",
28
+ "@cortexkit/aft-bridge": "0.61.0",
29
29
  "comment-json": "^4.6.2"
30
30
  },
31
31
  "devDependencies": {