open-agents-ai 0.187.137 → 0.187.138

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 +686 -189
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -247838,9 +247838,9 @@ var init_vision = __esm({
247838
247838
  if (ollamaResult)
247839
247839
  return ollamaResult;
247840
247840
  try {
247841
- const { execSync: execSync46 } = await import("node:child_process");
247841
+ const { execSync: execSync48 } = await import("node:child_process");
247842
247842
  try {
247843
- execSync46("pip3 install --user moondream 2>/dev/null || pip install --user moondream 2>/dev/null", {
247843
+ execSync48("pip3 install --user moondream 2>/dev/null || pip install --user moondream 2>/dev/null", {
247844
247844
  timeout: 12e4,
247845
247845
  stdio: "pipe"
247846
247846
  });
@@ -247853,7 +247853,7 @@ var init_vision = __esm({
247853
247853
  } catch {
247854
247854
  }
247855
247855
  try {
247856
- execSync46("ollama pull moondream", { timeout: 3e5, stdio: "pipe" });
247856
+ execSync48("ollama pull moondream", { timeout: 3e5, stdio: "pipe" });
247857
247857
  const retryOllama = await this.tryOllamaVision(buffer2, filename, action, prompt, length4, start2);
247858
247858
  if (retryOllama)
247859
247859
  return retryOllama;
@@ -247961,8 +247961,8 @@ Coordinates are normalized (0-1). Multiply by image width/height for pixel value
247961
247961
  const errText = await res.text().catch(() => "");
247962
247962
  if (res.status === 404 || /not found|does not exist/i.test(errText)) {
247963
247963
  try {
247964
- const { execSync: execSync46 } = await import("node:child_process");
247965
- execSync46("ollama pull moondream", { timeout: 3e5, stdio: "pipe" });
247964
+ const { execSync: execSync48 } = await import("node:child_process");
247965
+ execSync48("ollama pull moondream", { timeout: 3e5, stdio: "pipe" });
247966
247966
  res = await fetch(`${ollamaHost}/api/generate`, {
247967
247967
  method: "POST",
247968
247968
  headers: { "Content-Type": "application/json" },
@@ -254888,6 +254888,497 @@ ${devices.join("\n")}`,
254888
254888
  }
254889
254889
  });
254890
254890
 
254891
+ // packages/execution/dist/tools/wifi-control.js
254892
+ import { execSync as execSync30 } from "node:child_process";
254893
+ var WifiControlTool;
254894
+ var init_wifi_control = __esm({
254895
+ "packages/execution/dist/tools/wifi-control.js"() {
254896
+ "use strict";
254897
+ WifiControlTool = class {
254898
+ name = "wifi_control";
254899
+ description = "Scan, connect, and manage WiFi networks. Actions: 'scan' to discover nearby networks, 'interfaces' to list WiFi adapters, 'connect' to join a network, 'disconnect' to leave, 'status' for current connection info, 'monitor' to toggle monitor mode on an adapter. Use this to explore the wireless environment, find networks, check signal strength, connect to specific networks, or manage multiple WiFi adapters.";
254900
+ parameters = {
254901
+ type: "object",
254902
+ properties: {
254903
+ action: {
254904
+ type: "string",
254905
+ enum: ["scan", "interfaces", "connect", "disconnect", "status", "monitor"],
254906
+ description: "Action to perform"
254907
+ },
254908
+ ssid: {
254909
+ type: "string",
254910
+ description: "WiFi network name (for 'connect' action)"
254911
+ },
254912
+ password: {
254913
+ type: "string",
254914
+ description: "WiFi password (for 'connect' action)"
254915
+ },
254916
+ interface: {
254917
+ type: "string",
254918
+ description: "WiFi interface name (e.g. wlp69s0, wlan1). Default: auto-detect."
254919
+ },
254920
+ enable: {
254921
+ type: "boolean",
254922
+ description: "true to enable, false to disable (for 'monitor' action)"
254923
+ }
254924
+ },
254925
+ required: ["action"]
254926
+ };
254927
+ async execute(args) {
254928
+ const action = args["action"];
254929
+ const start2 = performance.now();
254930
+ try {
254931
+ switch (action) {
254932
+ case "scan":
254933
+ return this.scanNetworks(args, start2);
254934
+ case "interfaces":
254935
+ return this.listInterfaces(start2);
254936
+ case "connect":
254937
+ return this.connectNetwork(args, start2);
254938
+ case "disconnect":
254939
+ return this.disconnectNetwork(args, start2);
254940
+ case "status":
254941
+ return this.connectionStatus(args, start2);
254942
+ case "monitor":
254943
+ return this.monitorMode(args, start2);
254944
+ default:
254945
+ return { success: false, output: "", error: `Unknown action: ${action}`, durationMs: performance.now() - start2 };
254946
+ }
254947
+ } catch (err) {
254948
+ return { success: false, output: "", error: `wifi_control error: ${err instanceof Error ? err.message : String(err)}`, durationMs: performance.now() - start2 };
254949
+ }
254950
+ }
254951
+ // =========================================================================
254952
+ // Scan nearby WiFi networks
254953
+ // =========================================================================
254954
+ scanNetworks(args, start2) {
254955
+ const iface = args["interface"] || this.findWifiInterface();
254956
+ if (!iface) {
254957
+ return { success: false, output: "", error: "No WiFi interface found. Connect a WiFi adapter.", durationMs: performance.now() - start2 };
254958
+ }
254959
+ try {
254960
+ execSync30(`nmcli device wifi rescan ifname ${iface} 2>/dev/null`, { timeout: 1e4, stdio: "pipe" });
254961
+ execSync30("sleep 1", { timeout: 5e3 });
254962
+ } catch {
254963
+ }
254964
+ try {
254965
+ const raw = execSync30(`nmcli -t -f BSSID,SSID,MODE,CHAN,FREQ,RATE,SIGNAL,BARS,SECURITY,IN-USE device wifi list ifname ${iface} 2>/dev/null`, { encoding: "utf8", timeout: 15e3 });
254966
+ const networks = [];
254967
+ for (const line of raw.trim().split("\n").filter(Boolean)) {
254968
+ const parts = line.split(":");
254969
+ if (parts.length < 9)
254970
+ continue;
254971
+ const bssid = parts.slice(0, 6).join(":");
254972
+ const rest = parts.slice(6);
254973
+ if (rest.length < 9)
254974
+ continue;
254975
+ const ssid = rest[0] || "(hidden)";
254976
+ const channel = parseInt(rest[2] || "0");
254977
+ const frequency = rest[3] || "";
254978
+ const rate = rest[4] || "";
254979
+ const signal = parseInt(rest[5] || "0");
254980
+ const bars = rest[6] || "";
254981
+ const security = rest[7] || "Open";
254982
+ const active = rest[8] === "*";
254983
+ networks.push({ ssid, bssid, channel, frequency, signal, bars, security, rate, active });
254984
+ }
254985
+ if (networks.length === 0) {
254986
+ return { success: true, output: `No WiFi networks found on ${iface}. The adapter may be disabled or out of range.`, durationMs: performance.now() - start2 };
254987
+ }
254988
+ networks.sort((a2, b) => b.signal - a2.signal);
254989
+ const lines = networks.map((n2) => {
254990
+ const marker = n2.active ? " *" : " ";
254991
+ return `${marker}${n2.signal}% ${n2.bars} ${n2.ssid.padEnd(25)} Ch${String(n2.channel).padEnd(3)} ${n2.security.padEnd(12)} ${n2.rate} (${n2.bssid})`;
254992
+ });
254993
+ return {
254994
+ success: true,
254995
+ output: `WiFi networks on ${iface} (${networks.length} found, sorted by signal):
254996
+ ${" Sig".padEnd(5)} ${"".padEnd(5)} ${"SSID".padEnd(25)} ${"Ch".padEnd(4)} ${"Security".padEnd(12)} Rate
254997
+ ${"-".repeat(90)}
254998
+ ` + lines.join("\n") + (networks.some((n2) => n2.active) ? "\n\n * = currently connected" : ""),
254999
+ durationMs: performance.now() - start2
255000
+ };
255001
+ } catch (err) {
255002
+ try {
255003
+ const iwScan = execSync30(`iw dev ${iface} scan 2>/dev/null | grep -E "SSID:|signal:|freq:" | head -60`, { encoding: "utf8", timeout: 15e3 });
255004
+ return { success: true, output: `WiFi scan (iw fallback) on ${iface}:
255005
+ ${iwScan}`, durationMs: performance.now() - start2 };
255006
+ } catch {
255007
+ return { success: false, output: "", error: `WiFi scan failed on ${iface}: ${err instanceof Error ? err.message : String(err)}`, durationMs: performance.now() - start2 };
255008
+ }
255009
+ }
255010
+ }
255011
+ // =========================================================================
255012
+ // List WiFi interfaces
255013
+ // =========================================================================
255014
+ listInterfaces(start2) {
255015
+ const interfaces = [];
255016
+ try {
255017
+ const ifaces = execSync30("ls /sys/class/net/", { encoding: "utf8", timeout: 5e3 }).trim().split("\n");
255018
+ for (const iface of ifaces) {
255019
+ try {
255020
+ execSync30(`test -d /sys/class/net/${iface}/wireless`, { timeout: 2e3, stdio: "pipe" });
255021
+ let info = ` ${iface}:`;
255022
+ try {
255023
+ const driver = execSync30(`readlink /sys/class/net/${iface}/device/driver 2>/dev/null`, { encoding: "utf8", timeout: 2e3 }).trim().split("/").pop();
255024
+ info += ` driver=${driver}`;
255025
+ } catch {
255026
+ }
255027
+ try {
255028
+ const mac = execSync30(`cat /sys/class/net/${iface}/address 2>/dev/null`, { encoding: "utf8", timeout: 2e3 }).trim();
255029
+ info += ` mac=${mac}`;
255030
+ } catch {
255031
+ }
255032
+ try {
255033
+ const state = execSync30(`cat /sys/class/net/${iface}/operstate 2>/dev/null`, { encoding: "utf8", timeout: 2e3 }).trim();
255034
+ info += ` state=${state}`;
255035
+ } catch {
255036
+ }
255037
+ try {
255038
+ const uevent = execSync30(`cat /sys/class/net/${iface}/device/uevent 2>/dev/null`, { encoding: "utf8", timeout: 2e3 });
255039
+ const prodMatch = uevent.match(/PRODUCT=([^\n]+)/);
255040
+ if (prodMatch)
255041
+ info += ` usb=${prodMatch[1]}`;
255042
+ } catch {
255043
+ }
255044
+ try {
255045
+ const conn = execSync30(`nmcli -t -f NAME connection show --active 2>/dev/null | head -1`, { encoding: "utf8", timeout: 3e3 }).trim();
255046
+ const devConn = execSync30(`nmcli -t -f DEVICE connection show --active 2>/dev/null | head -1`, { encoding: "utf8", timeout: 3e3 }).trim();
255047
+ if (devConn === iface && conn)
255048
+ info += ` connected="${conn}"`;
255049
+ } catch {
255050
+ }
255051
+ interfaces.push(info);
255052
+ } catch {
255053
+ }
255054
+ }
255055
+ } catch {
255056
+ }
255057
+ try {
255058
+ const lsusb = execSync30("lsusb 2>/dev/null", { encoding: "utf8", timeout: 5e3 });
255059
+ const usbWifi = lsusb.split("\n").filter((l2) => /wireless|wifi|802\.11|rtl88|mt76|ath9k|ac600|archer/i.test(l2) && !l2.includes("Bluetooth"));
255060
+ for (const dev of usbWifi) {
255061
+ const already = interfaces.some((i2) => {
255062
+ const match = dev.match(/ID\s+([0-9a-f:]+)/i);
255063
+ return match && i2.includes(match[1].replace(":", "/"));
255064
+ });
255065
+ if (!already) {
255066
+ interfaces.push(` [no-interface] ${dev.trim()} (driver may not be loaded)`);
255067
+ }
255068
+ }
255069
+ } catch {
255070
+ }
255071
+ if (interfaces.length === 0) {
255072
+ return { success: true, output: "No WiFi interfaces found. Connect a WiFi adapter.", durationMs: performance.now() - start2 };
255073
+ }
255074
+ return {
255075
+ success: true,
255076
+ output: `WiFi interfaces:
255077
+ ${interfaces.join("\n")}`,
255078
+ durationMs: performance.now() - start2
255079
+ };
255080
+ }
255081
+ // =========================================================================
255082
+ // Connect to a network
255083
+ // =========================================================================
255084
+ connectNetwork(args, start2) {
255085
+ const ssid = args["ssid"];
255086
+ if (!ssid) {
255087
+ return { success: false, output: "", error: "Missing 'ssid'. Specify the WiFi network name to connect to.", durationMs: performance.now() - start2 };
255088
+ }
255089
+ const password = args["password"];
255090
+ const iface = args["interface"] || this.findWifiInterface();
255091
+ if (!iface) {
255092
+ return { success: false, output: "", error: "No WiFi interface available.", durationMs: performance.now() - start2 };
255093
+ }
255094
+ const cmd = password ? `nmcli device wifi connect "${ssid}" password "${password}" ifname ${iface}` : `nmcli device wifi connect "${ssid}" ifname ${iface}`;
255095
+ try {
255096
+ execSync30(cmd, { encoding: "utf8", timeout: 3e4, stdio: "pipe" });
255097
+ } catch (err) {
255098
+ const msg = err instanceof Error ? err.message : String(err);
255099
+ if (msg.includes("No network with SSID")) {
255100
+ return { success: false, output: "", error: `Network "${ssid}" not found. Run wifi_control action='scan' to see available networks.`, durationMs: performance.now() - start2 };
255101
+ }
255102
+ if (msg.includes("Secrets were required")) {
255103
+ return { success: false, output: "", error: `Password required for "${ssid}". Provide the password parameter.`, durationMs: performance.now() - start2 };
255104
+ }
255105
+ return { success: false, output: "", error: `Failed to connect to "${ssid}": ${msg.slice(0, 300)}`, durationMs: performance.now() - start2 };
255106
+ }
255107
+ try {
255108
+ execSync30("sleep 2", { timeout: 5e3 });
255109
+ const ip = execSync30(`ip addr show ${iface} | grep "inet " | awk '{print $2}'`, { encoding: "utf8", timeout: 5e3 }).trim();
255110
+ return { success: true, output: `Connected to "${ssid}" on ${iface}.
255111
+ IP address: ${ip}`, durationMs: performance.now() - start2 };
255112
+ } catch {
255113
+ return { success: true, output: `Connected to "${ssid}" on ${iface}. (IP assignment pending)`, durationMs: performance.now() - start2 };
255114
+ }
255115
+ }
255116
+ // =========================================================================
255117
+ // Disconnect
255118
+ // =========================================================================
255119
+ disconnectNetwork(args, start2) {
255120
+ const iface = args["interface"] || this.findWifiInterface();
255121
+ if (!iface) {
255122
+ return { success: false, output: "", error: "No WiFi interface found.", durationMs: performance.now() - start2 };
255123
+ }
255124
+ try {
255125
+ execSync30(`nmcli device disconnect ${iface}`, { timeout: 1e4, stdio: "pipe" });
255126
+ return { success: true, output: `Disconnected ${iface} from WiFi.`, durationMs: performance.now() - start2 };
255127
+ } catch (err) {
255128
+ return { success: false, output: "", error: `Disconnect failed: ${err instanceof Error ? err.message : String(err)}`, durationMs: performance.now() - start2 };
255129
+ }
255130
+ }
255131
+ // =========================================================================
255132
+ // Connection status
255133
+ // =========================================================================
255134
+ connectionStatus(args, start2) {
255135
+ const iface = args["interface"] || this.findWifiInterface();
255136
+ if (!iface) {
255137
+ return { success: false, output: "", error: "No WiFi interface found.", durationMs: performance.now() - start2 };
255138
+ }
255139
+ const info = [`WiFi status for ${iface}:`];
255140
+ try {
255141
+ const state = execSync30(`nmcli -t -f GENERAL.STATE device show ${iface} 2>/dev/null`, { encoding: "utf8", timeout: 5e3 });
255142
+ const stateMatch = state.match(/GENERAL\.STATE:(.+)/);
255143
+ info.push(` State: ${stateMatch ? stateMatch[1].trim() : "unknown"}`);
255144
+ } catch {
255145
+ }
255146
+ try {
255147
+ const conn = execSync30(`nmcli -t -f GENERAL.CONNECTION device show ${iface} 2>/dev/null`, { encoding: "utf8", timeout: 5e3 });
255148
+ const connMatch = conn.match(/GENERAL\.CONNECTION:(.+)/);
255149
+ info.push(` Network: ${connMatch ? connMatch[1].trim() || "(not connected)" : "(not connected)"}`);
255150
+ } catch {
255151
+ }
255152
+ try {
255153
+ const ip = execSync30(`ip addr show ${iface} 2>/dev/null | grep "inet " | awk '{print $2}'`, { encoding: "utf8", timeout: 5e3 }).trim();
255154
+ info.push(` IP: ${ip || "(no IP)"}`);
255155
+ } catch {
255156
+ }
255157
+ try {
255158
+ const iwconfig = execSync30(`iwconfig ${iface} 2>/dev/null`, { encoding: "utf8", timeout: 5e3 });
255159
+ const signalMatch = iwconfig.match(/Signal level[=:](-?\d+)\s*dBm/);
255160
+ const linkMatch = iwconfig.match(/Link Quality[=:](\d+\/\d+)/);
255161
+ const bitRateMatch = iwconfig.match(/Bit Rate[=:]([^\s]+)/);
255162
+ const freqMatch = iwconfig.match(/Frequency[=:]([^\s]+\s*GHz)/);
255163
+ if (signalMatch)
255164
+ info.push(` Signal: ${signalMatch[1]} dBm`);
255165
+ if (linkMatch)
255166
+ info.push(` Link Quality: ${linkMatch[1]}`);
255167
+ if (bitRateMatch)
255168
+ info.push(` Bit Rate: ${bitRateMatch[1]}`);
255169
+ if (freqMatch)
255170
+ info.push(` Frequency: ${freqMatch[1]}`);
255171
+ } catch {
255172
+ }
255173
+ try {
255174
+ const gw = execSync30(`ip route show dev ${iface} 2>/dev/null | grep default | awk '{print $3}'`, { encoding: "utf8", timeout: 5e3 }).trim();
255175
+ if (gw)
255176
+ info.push(` Gateway: ${gw}`);
255177
+ } catch {
255178
+ }
255179
+ try {
255180
+ const dns2 = execSync30(`nmcli -t -f IP4.DNS device show ${iface} 2>/dev/null`, { encoding: "utf8", timeout: 5e3 });
255181
+ const dnsServers = dns2.match(/IP4\.DNS\[?\d*\]?:(.+)/g);
255182
+ if (dnsServers)
255183
+ info.push(` DNS: ${dnsServers.map((d2) => d2.split(":")[1]).join(", ")}`);
255184
+ } catch {
255185
+ }
255186
+ return { success: true, output: info.join("\n"), durationMs: performance.now() - start2 };
255187
+ }
255188
+ // =========================================================================
255189
+ // Monitor mode
255190
+ // =========================================================================
255191
+ monitorMode(args, start2) {
255192
+ const iface = args["interface"] || this.findWifiInterface();
255193
+ if (!iface) {
255194
+ return { success: false, output: "", error: "No WiFi interface found.", durationMs: performance.now() - start2 };
255195
+ }
255196
+ const enable = args["enable"] !== false;
255197
+ if (enable) {
255198
+ try {
255199
+ execSync30(`ip link set ${iface} down && iw dev ${iface} set type monitor && ip link set ${iface} up`, { timeout: 1e4, stdio: "pipe" });
255200
+ return { success: true, output: `Monitor mode ENABLED on ${iface}. Use 'monitor enable=false' to restore managed mode.`, durationMs: performance.now() - start2 };
255201
+ } catch (err) {
255202
+ const msg = err instanceof Error ? err.message : String(err);
255203
+ if (msg.includes("Operation not permitted")) {
255204
+ return { success: false, output: "", error: `Monitor mode requires root. Run with sudo or use shell: sudo ip link set ${iface} down && sudo iw dev ${iface} set type monitor && sudo ip link set ${iface} up`, durationMs: performance.now() - start2 };
255205
+ }
255206
+ return { success: false, output: "", error: `Failed to enable monitor mode: ${msg.slice(0, 300)}`, durationMs: performance.now() - start2 };
255207
+ }
255208
+ } else {
255209
+ try {
255210
+ execSync30(`ip link set ${iface} down && iw dev ${iface} set type managed && ip link set ${iface} up`, { timeout: 1e4, stdio: "pipe" });
255211
+ return { success: true, output: `Monitor mode DISABLED on ${iface}. Restored to managed mode.`, durationMs: performance.now() - start2 };
255212
+ } catch (err) {
255213
+ return { success: false, output: "", error: `Failed to disable monitor mode: ${err instanceof Error ? err.message : String(err)}`, durationMs: performance.now() - start2 };
255214
+ }
255215
+ }
255216
+ }
255217
+ // =========================================================================
255218
+ // Helpers
255219
+ // =========================================================================
255220
+ findWifiInterface() {
255221
+ try {
255222
+ const ifaces = execSync30("ls /sys/class/net/", { encoding: "utf8", timeout: 3e3 }).trim().split("\n");
255223
+ for (const iface of ifaces) {
255224
+ try {
255225
+ execSync30(`test -d /sys/class/net/${iface}/wireless`, { timeout: 2e3, stdio: "pipe" });
255226
+ return iface;
255227
+ } catch {
255228
+ }
255229
+ }
255230
+ } catch {
255231
+ }
255232
+ return null;
255233
+ }
255234
+ };
255235
+ }
255236
+ });
255237
+
255238
+ // packages/execution/dist/tools/bluetooth-scan.js
255239
+ import { execSync as execSync31 } from "node:child_process";
255240
+ var BluetoothScanTool;
255241
+ var init_bluetooth_scan = __esm({
255242
+ "packages/execution/dist/tools/bluetooth-scan.js"() {
255243
+ "use strict";
255244
+ BluetoothScanTool = class {
255245
+ name = "bluetooth_scan";
255246
+ description = "Discover nearby Bluetooth devices. Actions: 'scan' to find Classic and BLE devices, 'interfaces' to list Bluetooth adapters, 'info' to get device details. Use this to discover Bluetooth peripherals, check for nearby devices, or identify what Bluetooth hardware is connected to this system.";
255247
+ parameters = {
255248
+ type: "object",
255249
+ properties: {
255250
+ action: {
255251
+ type: "string",
255252
+ enum: ["scan", "interfaces", "info"],
255253
+ description: "Action: scan for devices, list adapters, or get device info"
255254
+ },
255255
+ device: {
255256
+ type: "string",
255257
+ description: "HCI device (e.g. hci0). Default: first available."
255258
+ },
255259
+ address: {
255260
+ type: "string",
255261
+ description: "Bluetooth MAC address for 'info' action"
255262
+ },
255263
+ timeout: {
255264
+ type: "number",
255265
+ description: "Scan timeout in seconds (default: 8)"
255266
+ }
255267
+ },
255268
+ required: ["action"]
255269
+ };
255270
+ async execute(args) {
255271
+ const action = args["action"];
255272
+ const start2 = performance.now();
255273
+ try {
255274
+ switch (action) {
255275
+ case "scan":
255276
+ return this.scanDevices(args, start2);
255277
+ case "interfaces":
255278
+ return this.listInterfaces(start2);
255279
+ case "info":
255280
+ return this.deviceInfo(args, start2);
255281
+ default:
255282
+ return { success: false, output: "", error: `Unknown action: ${action}`, durationMs: performance.now() - start2 };
255283
+ }
255284
+ } catch (err) {
255285
+ return { success: false, output: "", error: `bluetooth_scan error: ${err instanceof Error ? err.message : String(err)}`, durationMs: performance.now() - start2 };
255286
+ }
255287
+ }
255288
+ scanDevices(args, start2) {
255289
+ const hci = args["device"] || "hci0";
255290
+ const timeout2 = args["timeout"] || 8;
255291
+ const devices = [];
255292
+ try {
255293
+ const classic = execSync31(`hcitool -i ${hci} scan --length=${timeout2} 2>/dev/null`, { encoding: "utf8", timeout: (timeout2 + 5) * 1e3 });
255294
+ for (const line of classic.split("\n")) {
255295
+ const match = line.trim().match(/^([0-9A-F:]{17})\s+(.+)$/i);
255296
+ if (match)
255297
+ devices.push({ mac: match[1], name: match[2].trim(), type: "classic" });
255298
+ }
255299
+ } catch {
255300
+ }
255301
+ try {
255302
+ const ble = execSync31(`timeout ${Math.min(timeout2, 5)} hcitool -i ${hci} lescan --duplicates 2>/dev/null || true`, { encoding: "utf8", timeout: (timeout2 + 5) * 1e3 });
255303
+ const seen = /* @__PURE__ */ new Set();
255304
+ for (const line of ble.split("\n")) {
255305
+ const match = line.trim().match(/^([0-9A-F:]{17})\s+(.*)$/i);
255306
+ if (match && !seen.has(match[1])) {
255307
+ seen.add(match[1]);
255308
+ devices.push({ mac: match[1], name: match[2].trim() || "(unnamed)", type: "ble" });
255309
+ }
255310
+ }
255311
+ } catch {
255312
+ }
255313
+ if (devices.length === 0) {
255314
+ try {
255315
+ const btctl = execSync31(`echo -e "scan on\\n" | timeout ${timeout2} bluetoothctl 2>/dev/null | grep "Device "`, { encoding: "utf8", timeout: (timeout2 + 5) * 1e3 });
255316
+ for (const line of btctl.split("\n")) {
255317
+ const match = line.match(/Device\s+([0-9A-F:]{17})\s+(.+)/i);
255318
+ if (match)
255319
+ devices.push({ mac: match[1], name: match[2].trim(), type: "unknown" });
255320
+ }
255321
+ } catch {
255322
+ }
255323
+ }
255324
+ if (devices.length === 0) {
255325
+ return { success: true, output: `No Bluetooth devices found within ${timeout2}s scan on ${hci}.
255326
+ Tip: Make sure target devices are in discoverable/pairing mode.`, durationMs: performance.now() - start2 };
255327
+ }
255328
+ const lines = devices.map((d2) => ` ${d2.mac} ${d2.name.padEnd(30)} [${d2.type}]`);
255329
+ return {
255330
+ success: true,
255331
+ output: `Found ${devices.length} Bluetooth device(s) on ${hci}:
255332
+ ${lines.join("\n")}`,
255333
+ durationMs: performance.now() - start2
255334
+ };
255335
+ }
255336
+ listInterfaces(start2) {
255337
+ const adapters = [];
255338
+ try {
255339
+ const hciconfig = execSync31("hciconfig -a 2>/dev/null", { encoding: "utf8", timeout: 5e3 });
255340
+ const blocks = hciconfig.split(/^(hci\d+)/m);
255341
+ for (let i2 = 1; i2 < blocks.length; i2 += 2) {
255342
+ const name10 = blocks[i2];
255343
+ const info = blocks[i2 + 1] || "";
255344
+ const bdAddr = info.match(/BD Address:\s*([0-9A-F:]{17})/i)?.[1] || "unknown";
255345
+ const state = info.includes("UP RUNNING") ? "up" : info.includes("DOWN") ? "down" : "unknown";
255346
+ const type = info.match(/Type:\s*(\w+)/)?.[1] || "";
255347
+ adapters.push(` ${name10}: ${bdAddr} state=${state} ${type}`);
255348
+ }
255349
+ } catch {
255350
+ try {
255351
+ const devs = execSync31("ls /sys/class/bluetooth/ 2>/dev/null", { encoding: "utf8", timeout: 3e3 }).trim().split("\n").filter(Boolean);
255352
+ for (const dev of devs) {
255353
+ const addr = execSync31(`cat /sys/class/bluetooth/${dev}/address 2>/dev/null`, { encoding: "utf8", timeout: 2e3 }).trim();
255354
+ adapters.push(` ${dev}: ${addr}`);
255355
+ }
255356
+ } catch {
255357
+ }
255358
+ }
255359
+ if (adapters.length === 0) {
255360
+ return { success: true, output: "No Bluetooth adapters found.", durationMs: performance.now() - start2 };
255361
+ }
255362
+ return { success: true, output: `Bluetooth adapters:
255363
+ ${adapters.join("\n")}`, durationMs: performance.now() - start2 };
255364
+ }
255365
+ deviceInfo(args, start2) {
255366
+ const address = args["address"];
255367
+ if (!address) {
255368
+ return { success: false, output: "", error: "Missing 'address'. Provide a Bluetooth MAC address.", durationMs: performance.now() - start2 };
255369
+ }
255370
+ try {
255371
+ const info = execSync31(`hcitool info ${address} 2>/dev/null`, { encoding: "utf8", timeout: 1e4 });
255372
+ return { success: true, output: `Bluetooth device ${address}:
255373
+ ${info}`, durationMs: performance.now() - start2 };
255374
+ } catch {
255375
+ return { success: true, output: `Could not query ${address}. Device may be out of range or not in discoverable mode.`, durationMs: performance.now() - start2 };
255376
+ }
255377
+ }
255378
+ };
255379
+ }
255380
+ });
255381
+
254891
255382
  // packages/execution/dist/tools/full-sub-agent.js
254892
255383
  import { spawn as spawn13, ChildProcess } from "node:child_process";
254893
255384
  import { randomBytes as randomBytes13 } from "node:crypto";
@@ -255332,7 +255823,7 @@ var init_agent_tool = __esm({
255332
255823
  });
255333
255824
 
255334
255825
  // packages/execution/dist/tools/worktree.js
255335
- import { execSync as execSync30 } from "node:child_process";
255826
+ import { execSync as execSync32 } from "node:child_process";
255336
255827
  import { existsSync as existsSync31, mkdirSync as mkdirSync12, rmSync } from "node:fs";
255337
255828
  import { join as join46, resolve as resolve30 } from "node:path";
255338
255829
  function validateSlug(slug) {
@@ -255351,7 +255842,7 @@ function flattenSlug(slug) {
255351
255842
  }
255352
255843
  function isGitRepo(cwd4) {
255353
255844
  try {
255354
- execSync30("git rev-parse --is-inside-work-tree", { cwd: cwd4, stdio: "pipe" });
255845
+ execSync32("git rev-parse --is-inside-work-tree", { cwd: cwd4, stdio: "pipe" });
255355
255846
  return true;
255356
255847
  } catch {
255357
255848
  return false;
@@ -255359,14 +255850,14 @@ function isGitRepo(cwd4) {
255359
255850
  }
255360
255851
  function getCurrentBranch(cwd4) {
255361
255852
  try {
255362
- return execSync30("git rev-parse --abbrev-ref HEAD", { cwd: cwd4, stdio: "pipe" }).toString().trim();
255853
+ return execSync32("git rev-parse --abbrev-ref HEAD", { cwd: cwd4, stdio: "pipe" }).toString().trim();
255363
255854
  } catch {
255364
255855
  return void 0;
255365
255856
  }
255366
255857
  }
255367
255858
  function getCurrentCommit(cwd4) {
255368
255859
  try {
255369
- return execSync30("git rev-parse --short HEAD", { cwd: cwd4, stdio: "pipe" }).toString().trim();
255860
+ return execSync32("git rev-parse --short HEAD", { cwd: cwd4, stdio: "pipe" }).toString().trim();
255370
255861
  } catch {
255371
255862
  return void 0;
255372
255863
  }
@@ -255397,13 +255888,13 @@ function createWorktree(repoRoot, slug) {
255397
255888
  }
255398
255889
  mkdirSync12(worktreeBase, { recursive: true });
255399
255890
  try {
255400
- execSync30(`git worktree add "${worktreePath}" -b "${branchName}"`, {
255891
+ execSync32(`git worktree add "${worktreePath}" -b "${branchName}"`, {
255401
255892
  cwd: repoRoot,
255402
255893
  stdio: "pipe"
255403
255894
  });
255404
255895
  } catch (err) {
255405
255896
  try {
255406
- execSync30(`git worktree add "${worktreePath}" "${branchName}"`, {
255897
+ execSync32(`git worktree add "${worktreePath}" "${branchName}"`, {
255407
255898
  cwd: repoRoot,
255408
255899
  stdio: "pipe"
255409
255900
  });
@@ -255425,7 +255916,7 @@ function createWorktree(repoRoot, slug) {
255425
255916
  }
255426
255917
  function worktreeHasChanges(worktreePath) {
255427
255918
  try {
255428
- const status = execSync30("git status --porcelain", {
255919
+ const status = execSync32("git status --porcelain", {
255429
255920
  cwd: worktreePath,
255430
255921
  stdio: "pipe"
255431
255922
  }).toString().trim();
@@ -255446,20 +255937,20 @@ function removeWorktree(repoRoot, slug, force = false) {
255446
255937
  return "Worktree has uncommitted changes. Use force=true to discard, or commit/stash first.";
255447
255938
  }
255448
255939
  try {
255449
- execSync30(`git worktree remove "${worktreePath}" ${force ? "--force" : ""}`, {
255940
+ execSync32(`git worktree remove "${worktreePath}" ${force ? "--force" : ""}`, {
255450
255941
  cwd: repoRoot,
255451
255942
  stdio: "pipe"
255452
255943
  });
255453
255944
  } catch (err) {
255454
255945
  try {
255455
255946
  rmSync(worktreePath, { recursive: true, force: true });
255456
- execSync30("git worktree prune", { cwd: repoRoot, stdio: "pipe" });
255947
+ execSync32("git worktree prune", { cwd: repoRoot, stdio: "pipe" });
255457
255948
  } catch {
255458
255949
  return `Failed to remove worktree: ${err}`;
255459
255950
  }
255460
255951
  }
255461
255952
  try {
255462
- execSync30(`git branch -D "${branchName}"`, { cwd: repoRoot, stdio: "pipe" });
255953
+ execSync32(`git branch -D "${branchName}"`, { cwd: repoRoot, stdio: "pipe" });
255463
255954
  } catch {
255464
255955
  }
255465
255956
  _sessions.delete(slug);
@@ -256736,7 +257227,7 @@ var init_notebook_edit = __esm({
256736
257227
  });
256737
257228
 
256738
257229
  // packages/execution/dist/tools/environment-snapshot.js
256739
- import { execSync as execSync31 } from "node:child_process";
257230
+ import { execSync as execSync33 } from "node:child_process";
256740
257231
  import { cpus, totalmem, freemem, hostname as hostname2, platform, arch, uptime } from "node:os";
256741
257232
  import { statfsSync } from "node:fs";
256742
257233
  function collectSnapshot(workingDir) {
@@ -256754,7 +257245,7 @@ function collectSnapshot(workingDir) {
256754
257245
  }
256755
257246
  let gpu = void 0;
256756
257247
  try {
256757
- const nvOut = execSync31("nvidia-smi --query-gpu=name,memory.total,memory.used,temperature.gpu --format=csv,noheader,nounits", { encoding: "utf-8", timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] }).trim().split(",").map((s2) => s2.trim());
257248
+ const nvOut = execSync33("nvidia-smi --query-gpu=name,memory.total,memory.used,temperature.gpu --format=csv,noheader,nounits", { encoding: "utf-8", timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] }).trim().split(",").map((s2) => s2.trim());
256758
257249
  if (nvOut.length >= 3) {
256759
257250
  gpu = {
256760
257251
  name: nvOut[0],
@@ -256769,12 +257260,12 @@ function collectSnapshot(workingDir) {
256769
257260
  let battery = void 0;
256770
257261
  try {
256771
257262
  if (platform() === "linux") {
256772
- const cap = execSync31("cat /sys/class/power_supply/BAT0/capacity 2>/dev/null", { encoding: "utf-8", timeout: 1e3 }).trim();
256773
- const status = execSync31("cat /sys/class/power_supply/BAT0/status 2>/dev/null", { encoding: "utf-8", timeout: 1e3 }).trim();
257263
+ const cap = execSync33("cat /sys/class/power_supply/BAT0/capacity 2>/dev/null", { encoding: "utf-8", timeout: 1e3 }).trim();
257264
+ const status = execSync33("cat /sys/class/power_supply/BAT0/status 2>/dev/null", { encoding: "utf-8", timeout: 1e3 }).trim();
256774
257265
  if (cap)
256775
257266
  battery = { percent: parseInt(cap, 10), charging: status === "Charging" || status === "Full" };
256776
257267
  } else if (platform() === "darwin") {
256777
- const pmOut = execSync31("pmset -g batt", { encoding: "utf-8", timeout: 2e3 });
257268
+ const pmOut = execSync33("pmset -g batt", { encoding: "utf-8", timeout: 2e3 });
256778
257269
  const match = pmOut.match(/(\d+)%;\s*(charging|discharging|charged)/i);
256779
257270
  if (match)
256780
257271
  battery = { percent: parseInt(match[1], 10), charging: match[2].toLowerCase() !== "discharging" };
@@ -256795,8 +257286,8 @@ function collectSnapshot(workingDir) {
256795
257286
  }
256796
257287
  let processInfo = { total: 0, nodeCount: 0, oaSpawned: 0, topCpu: [] };
256797
257288
  try {
256798
- const psLines = execSync31("ps -eo pid,%cpu,args --sort=-%cpu --no-headers 2>/dev/null | head -50", { encoding: "utf-8", timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] }).trim().split("\n");
256799
- const total = parseInt(execSync31("ps aux | wc -l", { encoding: "utf-8", timeout: 2e3 }).trim(), 10);
257289
+ const psLines = execSync33("ps -eo pid,%cpu,args --sort=-%cpu --no-headers 2>/dev/null | head -50", { encoding: "utf-8", timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] }).trim().split("\n");
257290
+ const total = parseInt(execSync33("ps aux | wc -l", { encoding: "utf-8", timeout: 2e3 }).trim(), 10);
256800
257291
  let nodeCount = 0;
256801
257292
  let oaSpawned = 0;
256802
257293
  const topCpu = [];
@@ -256877,7 +257368,7 @@ var init_environment_snapshot = __esm({
256877
257368
  });
256878
257369
 
256879
257370
  // packages/execution/dist/tools/video-understand.js
256880
- import { execSync as execSync32 } from "node:child_process";
257371
+ import { execSync as execSync34 } from "node:child_process";
256881
257372
  import { existsSync as existsSync35, mkdirSync as mkdirSync13, writeFileSync as writeFileSync13, readFileSync as readFileSync26, readdirSync as readdirSync8, unlinkSync as unlinkSync7 } from "node:fs";
256882
257373
  import { join as join49, basename as basename11 } from "node:path";
256883
257374
  import { createHash as createHash2 } from "node:crypto";
@@ -256886,11 +257377,11 @@ function isYouTubeUrl2(url) {
256886
257377
  }
256887
257378
  function ensureYtDlp2() {
256888
257379
  try {
256889
- execSync32("yt-dlp --version", { timeout: 5e3, stdio: "pipe" });
257380
+ execSync34("yt-dlp --version", { timeout: 5e3, stdio: "pipe" });
256890
257381
  return true;
256891
257382
  } catch {
256892
257383
  try {
256893
- execSync32("pip3 install --break-system-packages yt-dlp 2>/dev/null || pip3 install --user yt-dlp 2>/dev/null", { timeout: 6e4, stdio: "pipe" });
257384
+ execSync34("pip3 install --break-system-packages yt-dlp 2>/dev/null || pip3 install --user yt-dlp 2>/dev/null", { timeout: 6e4, stdio: "pipe" });
256894
257385
  return true;
256895
257386
  } catch {
256896
257387
  return false;
@@ -256899,7 +257390,7 @@ function ensureYtDlp2() {
256899
257390
  }
256900
257391
  function ensureFfmpeg() {
256901
257392
  try {
256902
- execSync32("ffmpeg -version", { timeout: 3e3, stdio: "pipe" });
257393
+ execSync34("ffmpeg -version", { timeout: 3e3, stdio: "pipe" });
256903
257394
  return true;
256904
257395
  } catch {
256905
257396
  return false;
@@ -256979,32 +257470,32 @@ var init_video_understand = __esm({
256979
257470
  return { success: false, output: "", error: "yt-dlp required but not available. Install: pip3 install yt-dlp", durationMs: performance.now() - start2 };
256980
257471
  }
256981
257472
  try {
256982
- execSync32(`yt-dlp -f "worst[ext=mp4]" -o "${join49(tmpDir, "video.%(ext)s")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
257473
+ execSync34(`yt-dlp -f "worst[ext=mp4]" -o "${join49(tmpDir, "video.%(ext)s")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
256983
257474
  } catch {
256984
- execSync32(`yt-dlp -f worst -o "${join49(tmpDir, "video.%(ext)s")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
257475
+ execSync34(`yt-dlp -f worst -o "${join49(tmpDir, "video.%(ext)s")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
256985
257476
  }
256986
- execSync32(`yt-dlp -x --audio-format mp3 --audio-quality 5 -o "${join49(tmpDir, "audio.%(ext)s")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
257477
+ execSync34(`yt-dlp -x --audio-format mp3 --audio-quality 5 -o "${join49(tmpDir, "audio.%(ext)s")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
256987
257478
  try {
256988
- title = execSync32(`yt-dlp --get-title "${url}"`, { encoding: "utf-8", timeout: 15e3, stdio: ["pipe", "pipe", "pipe"] }).trim();
257479
+ title = execSync34(`yt-dlp --get-title "${url}"`, { encoding: "utf-8", timeout: 15e3, stdio: ["pipe", "pipe", "pipe"] }).trim();
256989
257480
  } catch {
256990
257481
  }
256991
257482
  } else {
256992
- execSync32(`curl -sL -o "${join49(tmpDir, "video.mp4")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
256993
- execSync32(`ffmpeg -i "${join49(tmpDir, "video.mp4")}" -vn -acodec libmp3lame -q:a 5 "${join49(tmpDir, "audio.mp3")}" -y`, { timeout: 12e4, stdio: "pipe" });
257483
+ execSync34(`curl -sL -o "${join49(tmpDir, "video.mp4")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
257484
+ execSync34(`ffmpeg -i "${join49(tmpDir, "video.mp4")}" -vn -acodec libmp3lame -q:a 5 "${join49(tmpDir, "audio.mp3")}" -y`, { timeout: 12e4, stdio: "pipe" });
256994
257485
  }
256995
257486
  videoPath = readdirSync8(tmpDir).find((f2) => f2.startsWith("video")) ? join49(tmpDir, readdirSync8(tmpDir).find((f2) => f2.startsWith("video"))) : join49(tmpDir, "video.mp4");
256996
257487
  audioPath = readdirSync8(tmpDir).find((f2) => f2.startsWith("audio")) ? join49(tmpDir, readdirSync8(tmpDir).find((f2) => f2.startsWith("audio"))) : join49(tmpDir, "audio.mp3");
256997
257488
  } else {
256998
257489
  videoPath = localPath;
256999
257490
  audioPath = join49(tmpDir, "audio.mp3");
257000
- execSync32(`ffmpeg -i "${videoPath}" -vn -acodec libmp3lame -q:a 5 "${audioPath}" -y`, { timeout: 12e4, stdio: "pipe" });
257491
+ execSync34(`ffmpeg -i "${videoPath}" -vn -acodec libmp3lame -q:a 5 "${audioPath}" -y`, { timeout: 12e4, stdio: "pipe" });
257001
257492
  }
257002
257493
  let segments = [];
257003
257494
  let language = "en";
257004
257495
  let duration = 0;
257005
257496
  try {
257006
257497
  const jsonOut = join49(tmpDir, "transcript.json");
257007
- execSync32(`transcribe-cli transcribe "${audioPath}" --model ${whisperModel} --format json -o "${tmpDir}"`, { timeout: 6e5, stdio: "pipe" });
257498
+ execSync34(`transcribe-cli transcribe "${audioPath}" --model ${whisperModel} --format json -o "${tmpDir}"`, { timeout: 6e5, stdio: "pipe" });
257008
257499
  const jsonFile = readdirSync8(tmpDir).find((f2) => f2.endsWith(".json") && f2 !== "result.json");
257009
257500
  if (jsonFile) {
257010
257501
  const data = JSON.parse(readFileSync26(join49(tmpDir, jsonFile), "utf-8"));
@@ -257027,7 +257518,7 @@ var init_video_understand = __esm({
257027
257518
  const fps = 25;
257028
257519
  const intervalFrames = Math.max(1, frameInterval * fps);
257029
257520
  try {
257030
- execSync32(`ffmpeg -i "${videoPath}" -vf "select='gt(scene\\,${sceneThreshold})+not(mod(n\\,${intervalFrames}))',showinfo" -vsync vfr "${join49(framesDir, "frame_%04d.jpg")}" -y`, { timeout: 3e5, stdio: "pipe" });
257521
+ execSync34(`ffmpeg -i "${videoPath}" -vf "select='gt(scene\\,${sceneThreshold})+not(mod(n\\,${intervalFrames}))',showinfo" -vsync vfr "${join49(framesDir, "frame_%04d.jpg")}" -y`, { timeout: 3e5, stdio: "pipe" });
257031
257522
  } catch {
257032
257523
  }
257033
257524
  const frameFiles = readdirSync8(framesDir).filter((f2) => f2.endsWith(".jpg")).sort();
@@ -257160,7 +257651,7 @@ Topic: ${segments.slice(0, 5).map((s2) => s2.text).join(" ").slice(0, 300)}`,
257160
257651
  }
257161
257652
  }
257162
257653
  try {
257163
- execSync32(`rm -rf "${tmpDir}"`, { timeout: 1e4, stdio: "pipe" });
257654
+ execSync34(`rm -rf "${tmpDir}"`, { timeout: 1e4, stdio: "pipe" });
257164
257655
  } catch {
257165
257656
  }
257166
257657
  return {
@@ -258054,6 +258545,7 @@ __export(dist_exports, {
258054
258545
  BackgroundRunTool: () => BackgroundRunTool,
258055
258546
  BackgroundTaskManager: () => BackgroundTaskManager,
258056
258547
  BatchEditTool: () => BatchEditTool,
258548
+ BluetoothScanTool: () => BluetoothScanTool,
258057
258549
  BrowserActionTool: () => BrowserActionTool,
258058
258550
  CameraCaptureTool: () => CameraCaptureTool,
258059
258551
  CodeSandboxTool: () => CodeSandboxTool,
@@ -258129,6 +258621,7 @@ __export(dist_exports, {
258129
258621
  WebCrawlTool: () => WebCrawlTool,
258130
258622
  WebFetchTool: () => WebFetchTool,
258131
258623
  WebSearchTool: () => WebSearchTool,
258624
+ WifiControlTool: () => WifiControlTool,
258132
258625
  WorkingNotesTool: () => WorkingNotesTool,
258133
258626
  YouTubeDownloadTool: () => YouTubeDownloadTool,
258134
258627
  addProjectConstraint: () => addProjectConstraint,
@@ -258290,6 +258783,8 @@ var init_dist4 = __esm({
258290
258783
  init_camera_capture();
258291
258784
  init_audio_capture();
258292
258785
  init_audio_playback();
258786
+ init_wifi_control();
258787
+ init_bluetooth_scan();
258293
258788
  init_system_auth();
258294
258789
  init_full_sub_agent();
258295
258790
  init_agent_tool();
@@ -261194,12 +261689,12 @@ var init_tool_batching = __esm({
261194
261689
  });
261195
261690
 
261196
261691
  // packages/orchestrator/dist/hooks.js
261197
- import { execSync as execSync33 } from "node:child_process";
261692
+ import { execSync as execSync35 } from "node:child_process";
261198
261693
  function executeHook(hook, env2 = {}) {
261199
261694
  const start2 = performance.now();
261200
261695
  const timeout2 = hook.timeoutMs ?? DEFAULT_HOOK_TIMEOUT;
261201
261696
  try {
261202
- const output = execSync33(hook.command, {
261697
+ const output = execSync35(hook.command, {
261203
261698
  timeout: timeout2,
261204
261699
  env: { ...process.env, ...env2 },
261205
261700
  encoding: "utf8",
@@ -265423,7 +265918,7 @@ ${result}`
265423
265918
  const buffer2 = Buffer.from(rawBase64, "base64");
265424
265919
  let resizedBase64 = null;
265425
265920
  try {
265426
- const { execSync: execSync46 } = await import("node:child_process");
265921
+ const { execSync: execSync48 } = await import("node:child_process");
265427
265922
  const { writeFileSync: writeFileSync38, readFileSync: readFileSync56, unlinkSync: unlinkSync17 } = await import("node:fs");
265428
265923
  const { join: join91 } = await import("node:path");
265429
265924
  const { tmpdir: tmpdir14 } = await import("node:os");
@@ -265433,7 +265928,7 @@ ${result}`
265433
265928
  const pyBin = process.platform === "win32" ? "python" : "python3";
265434
265929
  const escapedIn = tmpIn.replace(/\\/g, "\\\\");
265435
265930
  const escapedOut = tmpOut.replace(/\\/g, "\\\\");
265436
- execSync46(`${pyBin} -c "from PIL import Image; img = Image.open('${escapedIn}'); img.thumbnail((512, 512), Image.LANCZOS); img = img.convert('RGB'); img.save('${escapedOut}', 'JPEG', quality=75)"`, { timeout: 1e4, stdio: "pipe" });
265931
+ execSync48(`${pyBin} -c "from PIL import Image; img = Image.open('${escapedIn}'); img.thumbnail((512, 512), Image.LANCZOS); img = img.convert('RGB'); img.save('${escapedOut}', 'JPEG', quality=75)"`, { timeout: 1e4, stdio: "pipe" });
265437
265932
  const resizedBuf = readFileSync56(tmpOut);
265438
265933
  resizedBase64 = `data:image/jpeg;base64,${resizedBuf.toString("base64")}`;
265439
265934
  try {
@@ -265487,8 +265982,8 @@ ${result}`
265487
265982
  if (!res.ok && model === "moondream" && res.status === 404) {
265488
265983
  this.emit({ type: "status", content: `Pulling moondream vision model...`, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
265489
265984
  try {
265490
- const { execSync: execSync46 } = await import("node:child_process");
265491
- execSync46("ollama pull moondream", { timeout: 3e5, stdio: "pipe" });
265985
+ const { execSync: execSync48 } = await import("node:child_process");
265986
+ execSync48("ollama pull moondream", { timeout: 3e5, stdio: "pipe" });
265492
265987
  res = await fetch(`${ollamaHost}/api/generate`, {
265493
265988
  method: "POST",
265494
265989
  headers: { "Content-Type": "application/json" },
@@ -267852,7 +268347,7 @@ __export(listen_exports, {
267852
268347
  isVideoPath: () => isVideoPath,
267853
268348
  waitForTranscribeCli: () => waitForTranscribeCli
267854
268349
  });
267855
- import { spawn as spawn17, execSync as execSync34 } from "node:child_process";
268350
+ import { spawn as spawn17, execSync as execSync36 } from "node:child_process";
267856
268351
  import { existsSync as existsSync41, mkdirSync as mkdirSync16, writeFileSync as writeFileSync17, readdirSync as readdirSync9 } from "node:fs";
267857
268352
  import { join as join57, dirname as dirname16 } from "node:path";
267858
268353
  import { homedir as homedir15 } from "node:os";
@@ -267874,7 +268369,7 @@ function findMicCaptureCommand() {
267874
268369
  const platform6 = process.platform;
267875
268370
  if (platform6 === "linux") {
267876
268371
  try {
267877
- execSync34("which arecord", { stdio: "pipe" });
268372
+ execSync36("which arecord", { stdio: "pipe" });
267878
268373
  return {
267879
268374
  cmd: "arecord",
267880
268375
  args: ["-f", "S16_LE", "-r", "16000", "-c", "1", "-t", "raw", "-q", "-"]
@@ -267884,7 +268379,7 @@ function findMicCaptureCommand() {
267884
268379
  }
267885
268380
  if (platform6 === "darwin") {
267886
268381
  try {
267887
- execSync34("which sox", { stdio: "pipe" });
268382
+ execSync36("which sox", { stdio: "pipe" });
267888
268383
  return {
267889
268384
  cmd: "sox",
267890
268385
  args: ["-d", "-t", "raw", "-r", "16000", "-c", "1", "-b", "16", "-e", "signed-integer", "-"]
@@ -267893,7 +268388,7 @@ function findMicCaptureCommand() {
267893
268388
  }
267894
268389
  }
267895
268390
  try {
267896
- execSync34("which ffmpeg", { stdio: "pipe" });
268391
+ execSync36("which ffmpeg", { stdio: "pipe" });
267897
268392
  if (platform6 === "linux") {
267898
268393
  return {
267899
268394
  cmd: "ffmpeg",
@@ -267951,7 +268446,7 @@ function findLiveWhisperScript() {
267951
268446
  if (existsSync41(p2)) return p2;
267952
268447
  }
267953
268448
  try {
267954
- const globalRoot = execSync34("npm root -g", {
268449
+ const globalRoot = execSync36("npm root -g", {
267955
268450
  encoding: "utf-8",
267956
268451
  timeout: 5e3,
267957
268452
  stdio: ["pipe", "pipe", "pipe"]
@@ -267981,7 +268476,7 @@ function ensureTranscribeCliBackground() {
267981
268476
  if (_bgInstallPromise) return;
267982
268477
  _bgInstallPromise = (async () => {
267983
268478
  try {
267984
- const globalRoot = execSync34("npm root -g", {
268479
+ const globalRoot = execSync36("npm root -g", {
267985
268480
  encoding: "utf-8",
267986
268481
  timeout: 5e3,
267987
268482
  stdio: ["pipe", "pipe", "pipe"]
@@ -268183,7 +268678,7 @@ var init_listen = __esm({
268183
268678
  }
268184
268679
  if (!this.transcribeCliAvailable) {
268185
268680
  try {
268186
- execSync34("which transcribe-cli", { stdio: "pipe" });
268681
+ execSync36("which transcribe-cli", { stdio: "pipe" });
268187
268682
  this.transcribeCliAvailable = true;
268188
268683
  } catch {
268189
268684
  this.transcribeCliAvailable = false;
@@ -268200,7 +268695,7 @@ var init_listen = __esm({
268200
268695
  } catch {
268201
268696
  }
268202
268697
  try {
268203
- const globalRoot = execSync34("npm root -g", {
268698
+ const globalRoot = execSync36("npm root -g", {
268204
268699
  encoding: "utf-8",
268205
268700
  timeout: 5e3,
268206
268701
  stdio: ["pipe", "pipe", "pipe"]
@@ -268249,7 +268744,7 @@ var init_listen = __esm({
268249
268744
  }
268250
268745
  if (!tc) {
268251
268746
  try {
268252
- execSync34("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
268747
+ execSync36("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
268253
268748
  this.transcribeCliAvailable = null;
268254
268749
  tc = await this.loadTranscribeCli();
268255
268750
  } catch {
@@ -268427,7 +268922,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
268427
268922
  }
268428
268923
  if (!tc) {
268429
268924
  try {
268430
- execSync34("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
268925
+ execSync36("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
268431
268926
  this.transcribeCliAvailable = null;
268432
268927
  tc = await this.loadTranscribeCli();
268433
268928
  } catch {
@@ -268480,7 +268975,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
268480
268975
  }
268481
268976
  if (!tc) {
268482
268977
  try {
268483
- execSync34("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
268978
+ execSync36("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
268484
268979
  this.transcribeCliAvailable = null;
268485
268980
  tc = await this.loadTranscribeCli();
268486
268981
  } catch {
@@ -273402,7 +273897,7 @@ var init_render = __esm({
273402
273897
 
273403
273898
  // packages/cli/src/tui/voice-session.ts
273404
273899
  import { createServer as createServer3 } from "node:http";
273405
- import { spawn as spawn18, execSync as execSync35 } from "node:child_process";
273900
+ import { spawn as spawn18, execSync as execSync37 } from "node:child_process";
273406
273901
  import { EventEmitter as EventEmitter4 } from "node:events";
273407
273902
  function generateFrontendHTML() {
273408
273903
  return `<!DOCTYPE html>
@@ -279271,7 +279766,7 @@ __export(text_selection_exports, {
279271
279766
  stripAnsi: () => stripAnsi,
279272
279767
  visibleLength: () => visibleLength
279273
279768
  });
279274
- import { execSync as execSync36 } from "node:child_process";
279769
+ import { execSync as execSync38 } from "node:child_process";
279275
279770
  function stripAnsi(s2) {
279276
279771
  return s2.replace(/\x1B\[[0-9;]*[A-Za-z]|\x1B\].*?(?:\x07|\x1B\\)/g, "");
279277
279772
  }
@@ -279282,16 +279777,16 @@ function copyText(text) {
279282
279777
  try {
279283
279778
  const platform6 = process.platform;
279284
279779
  if (platform6 === "darwin") {
279285
- execSync36("pbcopy", { input: text, timeout: 3e3 });
279780
+ execSync38("pbcopy", { input: text, timeout: 3e3 });
279286
279781
  return true;
279287
279782
  }
279288
279783
  if (platform6 === "win32") {
279289
- execSync36("clip", { input: text, timeout: 3e3 });
279784
+ execSync38("clip", { input: text, timeout: 3e3 });
279290
279785
  return true;
279291
279786
  }
279292
279787
  for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
279293
279788
  try {
279294
- execSync36(tool, { input: text, timeout: 3e3 });
279789
+ execSync38(tool, { input: text, timeout: 3e3 });
279295
279790
  return true;
279296
279791
  } catch {
279297
279792
  continue;
@@ -279300,10 +279795,10 @@ function copyText(text) {
279300
279795
  if (!_clipboardAutoInstallAttempted) {
279301
279796
  _clipboardAutoInstallAttempted = true;
279302
279797
  try {
279303
- execSync36("which apt-get", { timeout: 2e3, stdio: "pipe" });
279798
+ execSync38("which apt-get", { timeout: 2e3, stdio: "pipe" });
279304
279799
  try {
279305
- execSync36("sudo -n apt-get install -y xclip 2>/dev/null", { timeout: 15e3, stdio: "pipe" });
279306
- execSync36("xclip -selection clipboard", { input: text, timeout: 3e3 });
279800
+ execSync38("sudo -n apt-get install -y xclip 2>/dev/null", { timeout: 15e3, stdio: "pipe" });
279801
+ execSync38("xclip -selection clipboard", { input: text, timeout: 3e3 });
279307
279802
  return true;
279308
279803
  } catch {
279309
279804
  }
@@ -283181,7 +283676,7 @@ __export(personaplex_exports, {
283181
283676
  import { existsSync as existsSync46, writeFileSync as writeFileSync21, readFileSync as readFileSync36, mkdirSync as mkdirSync20, copyFileSync as copyFileSync2, readdirSync as readdirSync12, statSync as statSync16 } from "node:fs";
283182
283677
  import { join as join63, dirname as dirname20 } from "node:path";
283183
283678
  import { homedir as homedir17 } from "node:os";
283184
- import { execSync as execSync37, spawn as spawn20 } from "node:child_process";
283679
+ import { execSync as execSync39, spawn as spawn20 } from "node:child_process";
283185
283680
  import { fileURLToPath as fileURLToPath12 } from "node:url";
283186
283681
  function execAsync(cmd, opts = {}) {
283187
283682
  return new Promise((resolve39, reject) => {
@@ -283214,7 +283709,7 @@ function detectJetson() {
283214
283709
  try {
283215
283710
  const model = readFileSync36("/proc/device-tree/model", "utf8").replace(/\0/g, "").trim();
283216
283711
  if (/jetson|orin|tegra/i.test(model)) {
283217
- const memInfo = execSync37("grep MemTotal /proc/meminfo", { encoding: "utf8", timeout: 3e3, stdio: "pipe" });
283712
+ const memInfo = execSync39("grep MemTotal /proc/meminfo", { encoding: "utf8", timeout: 3e3, stdio: "pipe" });
283218
283713
  const memKB = parseInt(memInfo.match(/(\d+)/)?.[1] ?? "0", 10);
283219
283714
  return { isJetson: true, model, totalMemGB: memKB / 1024 / 1024 };
283220
283715
  }
@@ -283248,7 +283743,7 @@ function detectPersonaPlexCapability() {
283248
283743
  };
283249
283744
  }
283250
283745
  try {
283251
- const nvsmi = execSync37("nvidia-smi --query-gpu=name,memory.total --format=csv,noheader,nounits", {
283746
+ const nvsmi = execSync39("nvidia-smi --query-gpu=name,memory.total --format=csv,noheader,nounits", {
283252
283747
  encoding: "utf8",
283253
283748
  timeout: 5e3,
283254
283749
  stdio: "pipe"
@@ -283260,7 +283755,7 @@ function detectPersonaPlexCapability() {
283260
283755
  return { ...fail2(`GPU has ${vramGB.toFixed(1)}GB VRAM (need \u22658GB)`), gpuName: gpuName ?? "", vramGB };
283261
283756
  }
283262
283757
  try {
283263
- execSync37('python3 -c "import torch; assert torch.cuda.is_available()"', {
283758
+ execSync39('python3 -c "import torch; assert torch.cuda.is_available()"', {
283264
283759
  timeout: 1e4,
283265
283760
  stdio: "pipe"
283266
283761
  });
@@ -283333,7 +283828,7 @@ async function installPersonaPlex(onInfo, weightTier) {
283333
283828
  mkdirSync20(PERSONAPLEX_DIR, { recursive: true });
283334
283829
  let arch2 = "";
283335
283830
  try {
283336
- arch2 = execSync37("uname -m", { encoding: "utf8", timeout: 3e3, stdio: "pipe" }).trim();
283831
+ arch2 = execSync39("uname -m", { encoding: "utf8", timeout: 3e3, stdio: "pipe" }).trim();
283337
283832
  } catch {
283338
283833
  }
283339
283834
  const isAarch64 = arch2 === "aarch64" || arch2 === "arm64";
@@ -283354,16 +283849,16 @@ async function installPersonaPlex(onInfo, weightTier) {
283354
283849
  log22("Checking system dependencies (libopus)...");
283355
283850
  try {
283356
283851
  if (process.platform === "linux") {
283357
- execSync37("dpkg -l libopus-dev 2>/dev/null || sudo apt-get install -y libopus-dev", { timeout: 3e4, stdio: "pipe" });
283852
+ execSync39("dpkg -l libopus-dev 2>/dev/null || sudo apt-get install -y libopus-dev", { timeout: 3e4, stdio: "pipe" });
283358
283853
  } else if (process.platform === "darwin") {
283359
- execSync37("brew list opus 2>/dev/null || brew install opus", { timeout: 6e4, stdio: "pipe" });
283854
+ execSync39("brew list opus 2>/dev/null || brew install opus", { timeout: 6e4, stdio: "pipe" });
283360
283855
  }
283361
283856
  } catch {
283362
283857
  }
283363
283858
  if (isAarch64) {
283364
283859
  log22("ARM64: Checking Rust toolchain for sphn build...");
283365
283860
  try {
283366
- execSync37("rustc --version", { timeout: 5e3, stdio: "pipe" });
283861
+ execSync39("rustc --version", { timeout: 5e3, stdio: "pipe" });
283367
283862
  } catch {
283368
283863
  log22("ARM64: Installing Rust toolchain (needed for sphn audio codec)...");
283369
283864
  try {
@@ -283436,7 +283931,7 @@ async function installPersonaPlex(onInfo, weightTier) {
283436
283931
  }
283437
283932
  const serverPy = join63(venvDir, "lib", `python3.${process.versions.node ? "12" : "10"}`, "site-packages", "moshi", "server.py");
283438
283933
  try {
283439
- const sitePackages = execSync37(`"${python}" -c "import moshi, os; print(os.path.dirname(moshi.__file__))"`, {
283934
+ const sitePackages = execSync39(`"${python}" -c "import moshi, os; print(os.path.dirname(moshi.__file__))"`, {
283440
283935
  encoding: "utf8",
283441
283936
  timeout: 5e3,
283442
283937
  stdio: "pipe"
@@ -283453,7 +283948,7 @@ async function installPersonaPlex(onInfo, weightTier) {
283453
283948
  } catch {
283454
283949
  }
283455
283950
  try {
283456
- const sitePackages = execSync37(`"${python}" -c "import moshi, os; print(os.path.dirname(moshi.__file__))"`, {
283951
+ const sitePackages = execSync39(`"${python}" -c "import moshi, os; print(os.path.dirname(moshi.__file__))"`, {
283457
283952
  encoding: "utf8",
283458
283953
  timeout: 5e3,
283459
283954
  stdio: "pipe"
@@ -283557,7 +284052,7 @@ $2if filename.endswith(".safetensors"):`
283557
284052
  } catch {
283558
284053
  }
283559
284054
  try {
283560
- const sitePackages2 = execSync37(`"${python}" -c "import moshi, os; print(os.path.dirname(moshi.__file__))"`, {
284055
+ const sitePackages2 = execSync39(`"${python}" -c "import moshi, os; print(os.path.dirname(moshi.__file__))"`, {
283561
284056
  encoding: "utf8",
283562
284057
  timeout: 5e3,
283563
284058
  stdio: "pipe"
@@ -283692,14 +284187,14 @@ async function startPersonaPlexDaemon(onInfo) {
283692
284187
  if (tier === "nf4-distilled") {
283693
284188
  log22(`Weight tier: ${tier} \u2014 distilled NF4 (90% token match, ${repoInfo.sizeGB}GB)...`);
283694
284189
  try {
283695
- const weightPath = execSync37(
284190
+ const weightPath = execSync39(
283696
284191
  `"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', '${repoInfo.file}', token=False))"`,
283697
284192
  { encoding: "utf8", timeout: 6e4, stdio: "pipe" }
283698
284193
  ).trim();
283699
284194
  if (existsSync46(weightPath)) {
283700
284195
  if (!existsSync46(cachedBf16)) {
283701
284196
  log22("Converting .pt checkpoint to safetensors (one-time)...");
283702
- execSync37(
284197
+ execSync39(
283703
284198
  `"${venvPython2}" -c "
283704
284199
  import torch; from safetensors.torch import save_file
283705
284200
  state = torch.load('${weightPath}', map_location='cpu', weights_only=True)
@@ -283731,13 +284226,13 @@ print('Converted')
283731
284226
  }
283732
284227
  }
283733
284228
  try {
283734
- const weightPath = execSync37(
284229
+ const weightPath = execSync39(
283735
284230
  `"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', '${repoInfo.file}'${repoInfo.needsToken ? "" : ", token=False"}))"`,
283736
284231
  { encoding: "utf8", timeout: 3e4, stdio: "pipe" }
283737
284232
  ).trim();
283738
284233
  if (existsSync46(dequantScript) && existsSync46(weightPath)) {
283739
284234
  try {
283740
- execSync37(
284235
+ execSync39(
283741
284236
  `"${venvPython2}" "${dequantScript}" --input "${weightPath}" --output "${cachedBf16}"`,
283742
284237
  { timeout: 3e5, stdio: "pipe" }
283743
284238
  );
@@ -283750,7 +284245,7 @@ print('Converted')
283750
284245
  }
283751
284246
  }
283752
284247
  try {
283753
- const mimiPath = execSync37(
284248
+ const mimiPath = execSync39(
283754
284249
  `"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', 'tokenizer-e351c8d8-checkpoint125.safetensors', token=False))"`,
283755
284250
  { encoding: "utf8", timeout: 3e4, stdio: "pipe" }
283756
284251
  ).trim();
@@ -283758,7 +284253,7 @@ print('Converted')
283758
284253
  } catch {
283759
284254
  }
283760
284255
  try {
283761
- const tokPath = execSync37(
284256
+ const tokPath = execSync39(
283762
284257
  `"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', 'tokenizer_spm_32k_3.model', token=False))"`,
283763
284258
  { encoding: "utf8", timeout: 3e4, stdio: "pipe" }
283764
284259
  ).trim();
@@ -283782,7 +284277,7 @@ print('Converted')
283782
284277
  }
283783
284278
  if (!ollamaModel) ollamaModel = "qwen3.5:4b";
283784
284279
  try {
283785
- const ollamaCheck = execSync37("curl -s http://localhost:11434/api/tags", {
284280
+ const ollamaCheck = execSync39("curl -s http://localhost:11434/api/tags", {
283786
284281
  timeout: 3e3,
283787
284282
  stdio: "pipe",
283788
284283
  encoding: "utf8"
@@ -283856,7 +284351,7 @@ print('Converted')
283856
284351
  return null;
283857
284352
  }
283858
284353
  try {
283859
- execSync37(`curl -sk -o /dev/null -w "%{http_code}" https://127.0.0.1:${PORT}/`, {
284354
+ execSync39(`curl -sk -o /dev/null -w "%{http_code}" https://127.0.0.1:${PORT}/`, {
283860
284355
  timeout: 3e3,
283861
284356
  stdio: "pipe",
283862
284357
  encoding: "utf8"
@@ -283879,7 +284374,7 @@ function stopPersonaPlex() {
283879
284374
  if (isNaN(pid) || pid <= 0) return;
283880
284375
  try {
283881
284376
  if (process.platform === "win32") {
283882
- execSync37(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
284377
+ execSync39(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
283883
284378
  } else {
283884
284379
  process.kill(pid, "SIGTERM");
283885
284380
  }
@@ -284183,7 +284678,7 @@ __export(setup_exports, {
284183
284678
  updateOllama: () => updateOllama
284184
284679
  });
284185
284680
  import * as readline from "node:readline";
284186
- import { execSync as execSync38, spawn as spawn21, exec as exec4 } from "node:child_process";
284681
+ import { execSync as execSync40, spawn as spawn21, exec as exec4 } from "node:child_process";
284187
284682
  import { promisify as promisify7 } from "node:util";
284188
284683
  import { existsSync as existsSync47, writeFileSync as writeFileSync22, readFileSync as readFileSync37, appendFileSync as appendFileSync2, mkdirSync as mkdirSync21 } from "node:fs";
284189
284684
  import { join as join64 } from "node:path";
@@ -284221,7 +284716,7 @@ function detectSystemSpecs() {
284221
284716
  let gpuVramGB = 0;
284222
284717
  let gpuName = "";
284223
284718
  try {
284224
- const memInfo = execSync38("free -b 2>/dev/null || sysctl -n hw.memsize 2>/dev/null", {
284719
+ const memInfo = execSync40("free -b 2>/dev/null || sysctl -n hw.memsize 2>/dev/null", {
284225
284720
  encoding: "utf8",
284226
284721
  timeout: 5e3
284227
284722
  });
@@ -284241,7 +284736,7 @@ function detectSystemSpecs() {
284241
284736
  } catch {
284242
284737
  }
284243
284738
  try {
284244
- const nvidiaSmi = execSync38(
284739
+ const nvidiaSmi = execSync40(
284245
284740
  "nvidia-smi --query-gpu=memory.total,name --format=csv,noheader,nounits 2>/dev/null",
284246
284741
  { encoding: "utf8", timeout: 5e3 }
284247
284742
  );
@@ -284415,7 +284910,7 @@ function ensureCurl() {
284415
284910
  for (const s2 of strategies) {
284416
284911
  if (hasCmd(s2.check)) {
284417
284912
  try {
284418
- execSync38(s2.install, { stdio: "inherit", timeout: 12e4 });
284913
+ execSync40(s2.install, { stdio: "inherit", timeout: 12e4 });
284419
284914
  if (hasCmd("curl")) {
284420
284915
  process.stdout.write(` ${c3.green("\u2714")} curl installed via ${s2.label}.
284421
284916
  `);
@@ -284429,7 +284924,7 @@ function ensureCurl() {
284429
284924
  }
284430
284925
  if (plat === "darwin") {
284431
284926
  try {
284432
- execSync38("xcode-select --install", { stdio: "inherit", timeout: 3e5 });
284927
+ execSync40("xcode-select --install", { stdio: "inherit", timeout: 3e5 });
284433
284928
  if (hasCmd("curl")) return true;
284434
284929
  } catch {
284435
284930
  }
@@ -284463,7 +284958,7 @@ function installOllamaLinux() {
284463
284958
 
284464
284959
  `);
284465
284960
  try {
284466
- execSync38("curl -fsSL https://ollama.com/install.sh | sh", {
284961
+ execSync40("curl -fsSL https://ollama.com/install.sh | sh", {
284467
284962
  stdio: "inherit",
284468
284963
  timeout: 3e5
284469
284964
  });
@@ -284491,7 +284986,7 @@ async function installOllamaMac(_rl) {
284491
284986
 
284492
284987
  `);
284493
284988
  try {
284494
- execSync38(
284989
+ execSync40(
284495
284990
  '/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"',
284496
284991
  { stdio: "inherit", timeout: 6e5 }
284497
284992
  );
@@ -284527,7 +285022,7 @@ async function installOllamaMac(_rl) {
284527
285022
 
284528
285023
  `);
284529
285024
  try {
284530
- execSync38("brew install ollama", {
285025
+ execSync40("brew install ollama", {
284531
285026
  stdio: "inherit",
284532
285027
  timeout: 3e5
284533
285028
  });
@@ -284554,7 +285049,7 @@ function installOllamaWindows() {
284554
285049
 
284555
285050
  `);
284556
285051
  try {
284557
- execSync38('powershell -Command "irm https://ollama.com/install.ps1 | iex"', {
285052
+ execSync40('powershell -Command "irm https://ollama.com/install.ps1 | iex"', {
284558
285053
  stdio: "inherit",
284559
285054
  timeout: 3e5
284560
285055
  });
@@ -284634,7 +285129,7 @@ async function ensureOllamaRunning(backendUrl, rl) {
284634
285129
  }
284635
285130
  function getOllamaVersion() {
284636
285131
  try {
284637
- const out = execSync38("ollama --version", { encoding: "utf8", timeout: 5e3 });
285132
+ const out = execSync40("ollama --version", { encoding: "utf8", timeout: 5e3 });
284638
285133
  const match = out.match(/(\d+\.\d+\.\d+)/);
284639
285134
  return match ? match[1] : null;
284640
285135
  } catch {
@@ -284680,7 +285175,7 @@ function updateOllama() {
284680
285175
  return false;
284681
285176
  }
284682
285177
  try {
284683
- execSync38("curl -fsSL https://ollama.com/install.sh | sh", {
285178
+ execSync40("curl -fsSL https://ollama.com/install.sh | sh", {
284684
285179
  stdio: "inherit",
284685
285180
  timeout: 3e5
284686
285181
  });
@@ -284691,7 +285186,7 @@ function updateOllama() {
284691
285186
  }
284692
285187
  function pullModelWithAutoUpdate(tag) {
284693
285188
  try {
284694
- execSync38(`ollama pull ${tag}`, {
285189
+ execSync40(`ollama pull ${tag}`, {
284695
285190
  stdio: "inherit",
284696
285191
  timeout: 36e5
284697
285192
  // 1 hour max
@@ -284711,7 +285206,7 @@ function pullModelWithAutoUpdate(tag) {
284711
285206
 
284712
285207
  `);
284713
285208
  try {
284714
- execSync38("curl -fsSL https://ollama.com/install.sh | sh", {
285209
+ execSync40("curl -fsSL https://ollama.com/install.sh | sh", {
284715
285210
  stdio: "inherit",
284716
285211
  timeout: 3e5
284717
285212
  // 5 min max for install
@@ -284722,7 +285217,7 @@ function pullModelWithAutoUpdate(tag) {
284722
285217
  process.stdout.write(` ${c3.cyan("\u25CF")} Retrying pull of ${c3.bold(tag)}...
284723
285218
 
284724
285219
  `);
284725
- execSync38(`ollama pull ${tag}`, {
285220
+ execSync40(`ollama pull ${tag}`, {
284726
285221
  stdio: "inherit",
284727
285222
  timeout: 36e5
284728
285223
  });
@@ -284811,7 +285306,7 @@ function ensurePython3() {
284811
285306
  if (plat === "darwin") {
284812
285307
  if (hasCmd("brew")) {
284813
285308
  try {
284814
- execSync38("brew install python3", { stdio: "inherit", timeout: 3e5 });
285309
+ execSync40("brew install python3", { stdio: "inherit", timeout: 3e5 });
284815
285310
  if (hasCmd("python3")) {
284816
285311
  process.stdout.write(` ${c3.green("\u2714")} Python3 installed via Homebrew.
284817
285312
  `);
@@ -284824,7 +285319,7 @@ function ensurePython3() {
284824
285319
  for (const s2 of strategies) {
284825
285320
  if (hasCmd(s2.check)) {
284826
285321
  try {
284827
- execSync38(s2.install, { stdio: "inherit", timeout: 12e4 });
285322
+ execSync40(s2.install, { stdio: "inherit", timeout: 12e4 });
284828
285323
  if (hasCmd("python3") || hasCmd("python")) {
284829
285324
  process.stdout.write(` ${c3.green("\u2714")} Python3 installed via ${s2.label}.
284830
285325
  `);
@@ -284840,11 +285335,11 @@ function ensurePython3() {
284840
285335
  }
284841
285336
  function checkPythonVenv() {
284842
285337
  try {
284843
- execSync38("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
285338
+ execSync40("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
284844
285339
  return true;
284845
285340
  } catch {
284846
285341
  try {
284847
- execSync38("python -m venv --help", { stdio: "pipe", timeout: 5e3 });
285342
+ execSync40("python -m venv --help", { stdio: "pipe", timeout: 5e3 });
284848
285343
  return true;
284849
285344
  } catch {
284850
285345
  return false;
@@ -284863,7 +285358,7 @@ function ensurePythonVenv() {
284863
285358
  for (const s2 of strategies) {
284864
285359
  if (hasCmd(s2.check)) {
284865
285360
  try {
284866
- execSync38(s2.install, { stdio: "inherit", timeout: 12e4 });
285361
+ execSync40(s2.install, { stdio: "inherit", timeout: 12e4 });
284867
285362
  if (checkPythonVenv()) {
284868
285363
  process.stdout.write(` ${c3.green("\u2714")} python3-venv installed via ${s2.label}.
284869
285364
  `);
@@ -285291,7 +285786,7 @@ async function doSetup(config, rl) {
285291
285786
  const modelfilePath = join64(modelDir2, `Modelfile.${customName}`);
285292
285787
  writeFileSync22(modelfilePath, modelfileContent + "\n", "utf8");
285293
285788
  process.stdout.write(` ${c3.dim("Creating model...")} `);
285294
- execSync38(`ollama create ${customName} -f ${modelfilePath}`, {
285789
+ execSync40(`ollama create ${customName} -f ${modelfilePath}`, {
285295
285790
  stdio: "pipe",
285296
285791
  timeout: 12e4
285297
285792
  });
@@ -285342,7 +285837,7 @@ function isFirstRun() {
285342
285837
  function hasCmd(cmd) {
285343
285838
  try {
285344
285839
  const whichCmd = process.platform === "win32" ? `where ${cmd}` : `which ${cmd}`;
285345
- execSync38(whichCmd, { stdio: "pipe", timeout: 3e3 });
285840
+ execSync40(whichCmd, { stdio: "pipe", timeout: 3e3 });
285346
285841
  return true;
285347
285842
  } catch {
285348
285843
  return false;
@@ -285354,7 +285849,7 @@ function detectPkgManager() {
285354
285849
  if (hasCmd("choco")) return "choco";
285355
285850
  if (hasCmd("winget")) return "winget";
285356
285851
  try {
285357
- execSync38(
285852
+ execSync40(
285358
285853
  `powershell -NoProfile -Command "Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))"`,
285359
285854
  { stdio: "pipe", timeout: 12e4 }
285360
285855
  );
@@ -285366,7 +285861,7 @@ function detectPkgManager() {
285366
285861
  if (plat === "darwin") {
285367
285862
  if (hasCmd("brew")) return "brew";
285368
285863
  try {
285369
- execSync38(
285864
+ execSync40(
285370
285865
  '/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"',
285371
285866
  { stdio: "pipe", timeout: 3e5, env: { ...process.env, NONINTERACTIVE: "1" } }
285372
285867
  );
@@ -285386,7 +285881,7 @@ function getVenvDir() {
285386
285881
  }
285387
285882
  function hasVenvModule() {
285388
285883
  try {
285389
- execSync38("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
285884
+ execSync40("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
285390
285885
  return true;
285391
285886
  } catch {
285392
285887
  return false;
@@ -285410,8 +285905,8 @@ function ensureVenv(log22) {
285410
285905
  try {
285411
285906
  mkdirSync21(join64(homedir18(), ".open-agents"), { recursive: true });
285412
285907
  const pyCmd = hasCmd(pythonCmd) ? pythonCmd : "python3";
285413
- execSync38(`${pyCmd} -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
285414
- execSync38(`"${pipPath}" install --upgrade pip`, {
285908
+ execSync40(`${pyCmd} -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
285909
+ execSync40(`"${pipPath}" install --upgrade pip`, {
285415
285910
  stdio: "pipe",
285416
285911
  timeout: 6e4
285417
285912
  });
@@ -285424,7 +285919,7 @@ function ensureVenv(log22) {
285424
285919
  }
285425
285920
  function trySudoPasswordless(cmd, timeoutMs = 12e4) {
285426
285921
  try {
285427
- execSync38(`sudo -n ${cmd}`, {
285922
+ execSync40(`sudo -n ${cmd}`, {
285428
285923
  stdio: "pipe",
285429
285924
  timeout: timeoutMs,
285430
285925
  env: { ...process.env, DEBIAN_FRONTEND: "noninteractive" }
@@ -285437,7 +285932,7 @@ function trySudoPasswordless(cmd, timeoutMs = 12e4) {
285437
285932
  function runWithSudo(cmd, password, timeoutMs = 12e4) {
285438
285933
  try {
285439
285934
  const escaped = cmd.replace(/'/g, "'\\''");
285440
- execSync38(`sudo -S bash -c '${escaped}'`, {
285935
+ execSync40(`sudo -S bash -c '${escaped}'`, {
285441
285936
  input: password + "\n",
285442
285937
  stdio: ["pipe", "pipe", "pipe"],
285443
285938
  timeout: timeoutMs,
@@ -285531,7 +286026,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
285531
286026
  let winNeedsElevation = false;
285532
286027
  if (process.platform === "win32") {
285533
286028
  try {
285534
- execSync38("net session", { stdio: "pipe", timeout: 3e3 });
286029
+ execSync40("net session", { stdio: "pipe", timeout: 3e3 });
285535
286030
  } catch {
285536
286031
  winNeedsElevation = true;
285537
286032
  log22(`Installing ${labels} via ${pm2} (requires admin \u2014 UAC prompt will appear)...`);
@@ -285578,12 +286073,12 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
285578
286073
  if (needsSudo) {
285579
286074
  await sudoInstall(installCmd, getPassword, log22, cachedPasswordRef, 18e4);
285580
286075
  } else if (winNeedsElevation) {
285581
- execSync38(
286076
+ execSync40(
285582
286077
  `powershell -NoProfile -Command "Start-Process -FilePath 'cmd.exe' -ArgumentList '/c ${installCmd.replace(/'/g, "''")}' -Verb RunAs -Wait"`,
285583
286078
  { stdio: "pipe", timeout: 18e4 }
285584
286079
  );
285585
286080
  } else {
285586
- execSync38(installCmd, { stdio: "pipe", timeout: 18e4 });
286081
+ execSync40(installCmd, { stdio: "pipe", timeout: 18e4 });
285587
286082
  }
285588
286083
  } catch (e2) {
285589
286084
  const stderr = e2.stderr?.toString?.()?.trim?.() ?? "";
@@ -285596,7 +286091,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
285596
286091
  if (!hasCmd(d2.binary) && pipPkg) {
285597
286092
  try {
285598
286093
  const pipCmd = process.platform === "win32" ? `pip install ${pipPkg}` : `pip3 install ${pipPkg}`;
285599
- execSync38(pipCmd, { stdio: "pipe", timeout: 12e4 });
286094
+ execSync40(pipCmd, { stdio: "pipe", timeout: 12e4 });
285600
286095
  lastError = "";
285601
286096
  } catch (e2) {
285602
286097
  const stderr = e2.stderr?.toString?.()?.trim?.() ?? "";
@@ -285608,7 +286103,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
285608
286103
  }
285609
286104
  if (process.platform === "win32" && !hasCmd(d2.binary)) {
285610
286105
  try {
285611
- const freshPath = execSync38(
286106
+ const freshPath = execSync40(
285612
286107
  `powershell -NoProfile -Command "[System.Environment]::GetEnvironmentVariable('Path','Machine') + ';' + [System.Environment]::GetEnvironmentVariable('Path','User')"`,
285613
286108
  { encoding: "utf8", timeout: 5e3, stdio: "pipe" }
285614
286109
  ).trim();
@@ -285654,7 +286149,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
285654
286149
  const venvCmds = {
285655
286150
  apt: () => {
285656
286151
  try {
285657
- const pyVer = execSync38(
286152
+ const pyVer = execSync40(
285658
286153
  `python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"`,
285659
286154
  { encoding: "utf8", stdio: "pipe", timeout: 5e3 }
285660
286155
  ).trim();
@@ -285686,12 +286181,12 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
285686
286181
  const venvPip2 = join64(venvBin, "pip");
285687
286182
  log22("Installing moondream-station in ~/.open-agents/venv...");
285688
286183
  try {
285689
- execSync38(`"${venvPip2}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
286184
+ execSync40(`"${venvPip2}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
285690
286185
  if (existsSync47(venvMoondream)) {
285691
286186
  log22("moondream-station installed successfully.");
285692
286187
  } else {
285693
286188
  try {
285694
- const check = execSync38(`"${venvPip2}" show moondream-station`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 });
286189
+ const check = execSync40(`"${venvPip2}" show moondream-station`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 });
285695
286190
  if (check.includes("moondream")) {
285696
286191
  log22("moondream-station package installed.");
285697
286192
  }
@@ -285708,7 +286203,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
285708
286203
  const venvPip2 = join64(venvBin, isWin2 ? "pip.exe" : "pip");
285709
286204
  let ocrStackInstalled = false;
285710
286205
  try {
285711
- execSync38(
286206
+ execSync40(
285712
286207
  `"${venvPython2}" -c "import cv2, pytesseract, numpy, PIL"`,
285713
286208
  { stdio: "pipe", timeout: 1e4 }
285714
286209
  );
@@ -285719,12 +286214,12 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
285719
286214
  const ocrPackages = "pytesseract Pillow opencv-python-headless numpy";
285720
286215
  log22("Installing OCR Python stack (pytesseract, OpenCV, Pillow, numpy)...");
285721
286216
  try {
285722
- execSync38(
286217
+ execSync40(
285723
286218
  `"${venvPip2}" install ${ocrPackages}`,
285724
286219
  { stdio: "pipe", timeout: 3e5 }
285725
286220
  );
285726
286221
  try {
285727
- execSync38(
286222
+ execSync40(
285728
286223
  `"${venvPython2}" -c "import cv2, pytesseract, numpy, PIL"`,
285729
286224
  { stdio: "pipe", timeout: 1e4 }
285730
286225
  );
@@ -285760,7 +286255,7 @@ function ensureCloudflaredBackground(onInfo) {
285760
286255
  const archMap = { x64: "amd64", arm64: "arm64", arm: "arm" };
285761
286256
  const cfArch = archMap[arch2] ?? "amd64";
285762
286257
  try {
285763
- execSync38(
286258
+ execSync40(
285764
286259
  `curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && mkdir -p "${homedir18()}/.local/bin" && mv /tmp/cloudflared "${homedir18()}/.local/bin/cloudflared"`,
285765
286260
  { stdio: "pipe", timeout: 6e4 }
285766
286261
  );
@@ -285774,7 +286269,7 @@ function ensureCloudflaredBackground(onInfo) {
285774
286269
  } catch {
285775
286270
  }
285776
286271
  try {
285777
- execSync38(
286272
+ execSync40(
285778
286273
  `curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && sudo mv /tmp/cloudflared /usr/local/bin/cloudflared 2>/dev/null`,
285779
286274
  { stdio: "pipe", timeout: 6e4 }
285780
286275
  );
@@ -285786,7 +286281,7 @@ function ensureCloudflaredBackground(onInfo) {
285786
286281
  }
285787
286282
  } else if (os8 === "darwin") {
285788
286283
  try {
285789
- execSync38("brew install cloudflared", { stdio: "pipe", timeout: 12e4 });
286284
+ execSync40("brew install cloudflared", { stdio: "pipe", timeout: 12e4 });
285790
286285
  if (hasCmd("cloudflared")) {
285791
286286
  log22("cloudflared installed via Homebrew.");
285792
286287
  return true;
@@ -285866,7 +286361,7 @@ function createExpandedVariant(baseModel, specs, sizeGB, kvBytesPerToken, archMa
285866
286361
  mkdirSync21(modelDir2, { recursive: true });
285867
286362
  const modelfilePath = join64(modelDir2, `Modelfile.${customName}`);
285868
286363
  writeFileSync22(modelfilePath, modelfileContent + "\n", "utf8");
285869
- execSync38(`ollama create ${customName} -f ${modelfilePath}`, {
286364
+ execSync40(`ollama create ${customName} -f ${modelfilePath}`, {
285870
286365
  stdio: "pipe",
285871
286366
  timeout: 12e4
285872
286367
  });
@@ -285952,7 +286447,7 @@ async function ensureExpandedContext(modelName, backendUrl) {
285952
286447
  }
285953
286448
  async function ensureNeovim() {
285954
286449
  try {
285955
- const nvimPath = execSync38("which nvim 2>/dev/null || where nvim 2>nul", {
286450
+ const nvimPath = execSync40("which nvim 2>/dev/null || where nvim 2>nul", {
285956
286451
  encoding: "utf8",
285957
286452
  stdio: "pipe",
285958
286453
  timeout: 5e3
@@ -285973,14 +286468,14 @@ async function ensureNeovim() {
285973
286468
  const url = `https://github.com/neovim/neovim/releases/latest/download/${appImageName}`;
285974
286469
  console.log(` Downloading Neovim (${appImageName})...`);
285975
286470
  try {
285976
- execSync38(`curl -fsSL "${url}" -o "${nvimDest}"`, { stdio: "pipe", timeout: 6e4 });
285977
- execSync38(`chmod +x "${nvimDest}"`, { stdio: "pipe", timeout: 3e3 });
286471
+ execSync40(`curl -fsSL "${url}" -o "${nvimDest}"`, { stdio: "pipe", timeout: 6e4 });
286472
+ execSync40(`chmod +x "${nvimDest}"`, { stdio: "pipe", timeout: 3e3 });
285978
286473
  } catch (err) {
285979
286474
  console.log(` Failed to download Neovim: ${err instanceof Error ? err.message : String(err)}`);
285980
286475
  return null;
285981
286476
  }
285982
286477
  try {
285983
- const ver = execSync38(`"${nvimDest}" --version`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).split("\n")[0];
286478
+ const ver = execSync40(`"${nvimDest}" --version`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).split("\n")[0];
285984
286479
  console.log(` Installed: ${ver}`);
285985
286480
  } catch {
285986
286481
  console.log(" Warning: nvim binary downloaded but may not work (missing FUSE? Try: nvim --appimage-extract)");
@@ -285995,8 +286490,8 @@ async function ensureNeovim() {
285995
286490
  if (hasCmd("brew")) {
285996
286491
  console.log(" Installing Neovim via Homebrew...");
285997
286492
  try {
285998
- execSync38("brew install neovim", { stdio: "inherit", timeout: 12e4 });
285999
- const nvimPath = execSync38("which nvim", { encoding: "utf8", stdio: "pipe", timeout: 3e3 }).trim();
286493
+ execSync40("brew install neovim", { stdio: "inherit", timeout: 12e4 });
286494
+ const nvimPath = execSync40("which nvim", { encoding: "utf8", stdio: "pipe", timeout: 3e3 }).trim();
286000
286495
  return nvimPath || null;
286001
286496
  } catch {
286002
286497
  console.log(" brew install neovim failed.");
@@ -286010,7 +286505,7 @@ async function ensureNeovim() {
286010
286505
  if (hasCmd("choco")) {
286011
286506
  console.log(" Installing Neovim via Chocolatey...");
286012
286507
  try {
286013
- execSync38("choco install neovim -y", { stdio: "inherit", timeout: 12e4 });
286508
+ execSync40("choco install neovim -y", { stdio: "inherit", timeout: 12e4 });
286014
286509
  return "nvim";
286015
286510
  } catch {
286016
286511
  console.log(" choco install neovim failed.");
@@ -286019,7 +286514,7 @@ async function ensureNeovim() {
286019
286514
  if (hasCmd("winget")) {
286020
286515
  console.log(" Installing Neovim via winget...");
286021
286516
  try {
286022
- execSync38("winget install Neovim.Neovim --accept-source-agreements --accept-package-agreements", {
286517
+ execSync40("winget install Neovim.Neovim --accept-source-agreements --accept-package-agreements", {
286023
286518
  stdio: "inherit",
286024
286519
  timeout: 12e4
286025
286520
  });
@@ -286270,7 +286765,7 @@ var init_drop_panel = __esm({
286270
286765
  import { existsSync as existsSync49, unlinkSync as unlinkSync11 } from "node:fs";
286271
286766
  import { tmpdir as tmpdir11 } from "node:os";
286272
286767
  import { join as join65 } from "node:path";
286273
- import { execSync as execSync39 } from "node:child_process";
286768
+ import { execSync as execSync41 } from "node:child_process";
286274
286769
  function isNeovimActive() {
286275
286770
  return _state !== null && !_state.cleanedUp;
286276
286771
  }
@@ -286287,7 +286782,7 @@ async function startNeovimMode(opts) {
286287
286782
  }
286288
286783
  let nvimPath;
286289
286784
  try {
286290
- nvimPath = execSync39("which nvim 2>/dev/null", { encoding: "utf8" }).trim();
286785
+ nvimPath = execSync41("which nvim 2>/dev/null", { encoding: "utf8" }).trim();
286291
286786
  if (!nvimPath) throw new Error();
286292
286787
  } catch {
286293
286788
  const installed = await ensureNeovim();
@@ -286822,8 +287317,8 @@ async function startDaemon() {
286822
287317
  let oaScript = process.argv[1];
286823
287318
  if (!oaScript) {
286824
287319
  try {
286825
- const { execSync: execSync46 } = await import("node:child_process");
286826
- const whichOa = execSync46("which oa 2>/dev/null || where oa 2>nul", { encoding: "utf8" }).trim();
287320
+ const { execSync: execSync48 } = await import("node:child_process");
287321
+ const whichOa = execSync48("which oa 2>/dev/null || where oa 2>nul", { encoding: "utf8" }).trim();
286827
287322
  if (whichOa) oaScript = whichOa;
286828
287323
  } catch {
286829
287324
  }
@@ -288230,7 +288725,7 @@ __export(voice_exports, {
288230
288725
  import { existsSync as existsSync52, mkdirSync as mkdirSync24, writeFileSync as writeFileSync25, readFileSync as readFileSync40, unlinkSync as unlinkSync13, readdirSync as readdirSync13, statSync as statSync17 } from "node:fs";
288231
288726
  import { join as join68, dirname as dirname22 } from "node:path";
288232
288727
  import { homedir as homedir20, tmpdir as tmpdir12, platform as platform4 } from "node:os";
288233
- import { execSync as execSync40, spawn as nodeSpawn } from "node:child_process";
288728
+ import { execSync as execSync42, spawn as nodeSpawn } from "node:child_process";
288234
288729
  import { createRequire as createRequire2 } from "node:module";
288235
288730
  function sanitizeForTTS(text) {
288236
288731
  return text.replace(/^#{1,6}\s+/gm, "").replace(/\*{1,3}([^*]+)\*{1,3}/g, "$1").replace(/_{1,3}([^_]+)_{1,3}/g, "$1").replace(/~~([^~]+)~~/g, "$1").replace(/`([^`]+)`/g, "$1").replace(/```[\s\S]*?```/g, "").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/!\[([^\]]*)\]\([^)]+\)/g, "$1").replace(/^[\s]*[-*+]\s+/gm, "").replace(/^[\s]*\d+\.\s+/gm, "").replace(/^>\s+/gm, "").replace(/^[-*_]{3,}$/gm, "").replace(/\[[ xX]\]\s*/g, "").replace(/[\u{1F600}-\u{1F64F}]/gu, "").replace(/[\u{1F300}-\u{1F5FF}]/gu, "").replace(/[\u{1F680}-\u{1F6FF}]/gu, "").replace(/[\u{1F1E0}-\u{1F1FF}]/gu, "").replace(/[\u{2600}-\u{26FF}]/gu, "").replace(/[\u{2700}-\u{27BF}]/gu, "").replace(/[\u{FE00}-\u{FE0F}]/gu, "").replace(/[\u{1F900}-\u{1F9FF}]/gu, "").replace(/[\u{1FA00}-\u{1FA6F}]/gu, "").replace(/[\u{1FA70}-\u{1FAFF}]/gu, "").replace(/[\u{200D}]/gu, "").replace(/[\u{20E3}]/gu, "").replace(/[✓✔✗✘✕✖⚠️⏸⏹⏵●○◆◇■□▪▫►▼▲◀⬆⬇⬅➡↑↓←→⇐⇒⇑⇓]/g, "").replace(/[─━│┃┌┐└┘├┤┬┴┼╔╗╚╝╠╣╦╩╬⎿⎾▕▏⏐░▒▓█⠀-⣿]/g, "").replace(/\s{2,}/g, " ").trim();
@@ -289918,7 +290413,7 @@ var init_voice = __esm({
289918
290413
  }
289919
290414
  for (const player of ["paplay", "pw-play", "aplay"]) {
289920
290415
  try {
289921
- execSync40(`which ${player}`, { stdio: "pipe" });
290416
+ execSync42(`which ${player}`, { stdio: "pipe" });
289922
290417
  return [player, path5];
289923
290418
  } catch {
289924
290419
  }
@@ -289946,7 +290441,7 @@ var init_voice = __esm({
289946
290441
  if (this.python3Path) return this.python3Path;
289947
290442
  for (const bin of ["python3", "python"]) {
289948
290443
  try {
289949
- const path5 = execSync40(`which ${bin}`, { stdio: "pipe", timeout: 5e3 }).toString().trim();
290444
+ const path5 = execSync42(`which ${bin}`, { stdio: "pipe", timeout: 5e3 }).toString().trim();
289950
290445
  if (path5) {
289951
290446
  this.python3Path = path5;
289952
290447
  return path5;
@@ -290008,7 +290503,7 @@ var init_voice = __esm({
290008
290503
  return false;
290009
290504
  }
290010
290505
  try {
290011
- execSync40(`${py} -c "import mlx_audio"`, { stdio: "pipe", timeout: 1e4 });
290506
+ execSync42(`${py} -c "import mlx_audio"`, { stdio: "pipe", timeout: 1e4 });
290012
290507
  this.mlxInstalled = true;
290013
290508
  return true;
290014
290509
  } catch {
@@ -290071,14 +290566,14 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
290071
290566
  `tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
290072
290567
  ].join("; ");
290073
290568
  try {
290074
- execSync40(
290569
+ execSync42(
290075
290570
  `${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`,
290076
290571
  { stdio: "pipe", timeout: 6e4, cwd: tmpdir12() }
290077
290572
  );
290078
290573
  } catch (err) {
290079
290574
  try {
290080
290575
  const safeText = cleaned.replace(/'/g, "'\\''");
290081
- execSync40(
290576
+ execSync42(
290082
290577
  `${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`,
290083
290578
  { stdio: "pipe", timeout: 6e4, cwd: tmpdir12() }
290084
290579
  );
@@ -290145,14 +290640,14 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
290145
290640
  `tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
290146
290641
  ].join("; ");
290147
290642
  try {
290148
- execSync40(
290643
+ execSync42(
290149
290644
  `${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`,
290150
290645
  { stdio: "pipe", timeout: 6e4, cwd: tmpdir12() }
290151
290646
  );
290152
290647
  } catch {
290153
290648
  try {
290154
290649
  const safeText = cleaned.replace(/'/g, "'\\''");
290155
- execSync40(
290650
+ execSync42(
290156
290651
  `${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`,
290157
290652
  { stdio: "pipe", timeout: 6e4, cwd: tmpdir12() }
290158
290653
  );
@@ -295667,7 +296162,7 @@ async function handlePeerEndpoint(peerId, authKey, ctx3, local) {
295667
296162
  }
295668
296163
  }
295669
296164
  async function handleParallel(arg, ctx3) {
295670
- const { execSync: execSync46 } = await import("node:child_process");
296165
+ const { execSync: execSync48 } = await import("node:child_process");
295671
296166
  const baseUrl = ctx3.config.backendUrl || "http://localhost:11434";
295672
296167
  const isRemote = ctx3.config.backendType === "nexus";
295673
296168
  if (isRemote) {
@@ -295691,7 +296186,7 @@ async function handleParallel(arg, ctx3) {
295691
296186
  }
295692
296187
  let systemdVal = "";
295693
296188
  try {
295694
- const out = execSync46("systemctl show ollama.service -p Environment 2>/dev/null || true", { encoding: "utf8" });
296189
+ const out = execSync48("systemctl show ollama.service -p Environment 2>/dev/null || true", { encoding: "utf8" });
295695
296190
  const match = out.match(/OLLAMA_NUM_PARALLEL=(\d+)/);
295696
296191
  if (match) systemdVal = match[1];
295697
296192
  } catch {
@@ -295719,7 +296214,7 @@ async function handleParallel(arg, ctx3) {
295719
296214
  }
295720
296215
  const isSystemd = (() => {
295721
296216
  try {
295722
- const out = execSync46("systemctl is-active ollama.service 2>/dev/null", { encoding: "utf8" }).trim();
296217
+ const out = execSync48("systemctl is-active ollama.service 2>/dev/null", { encoding: "utf8" }).trim();
295723
296218
  return out === "active" || out === "inactive";
295724
296219
  } catch {
295725
296220
  return false;
@@ -295733,10 +296228,10 @@ async function handleParallel(arg, ctx3) {
295733
296228
  const overrideContent = `[Service]
295734
296229
  Environment="OLLAMA_NUM_PARALLEL=${n2}"
295735
296230
  `;
295736
- execSync46(`sudo mkdir -p ${overrideDir}`, { stdio: "pipe" });
295737
- execSync46(`echo '${overrideContent}' | sudo tee ${overrideFile} > /dev/null`, { stdio: "pipe" });
295738
- execSync46("sudo systemctl daemon-reload", { stdio: "pipe" });
295739
- execSync46("sudo systemctl restart ollama.service", { stdio: "pipe" });
296231
+ execSync48(`sudo mkdir -p ${overrideDir}`, { stdio: "pipe" });
296232
+ execSync48(`echo '${overrideContent}' | sudo tee ${overrideFile} > /dev/null`, { stdio: "pipe" });
296233
+ execSync48("sudo systemctl daemon-reload", { stdio: "pipe" });
296234
+ execSync48("sudo systemctl restart ollama.service", { stdio: "pipe" });
295740
296235
  let ready = false;
295741
296236
  for (let i2 = 0; i2 < 30 && !ready; i2++) {
295742
296237
  await new Promise((r2) => setTimeout(r2, 500));
@@ -295762,7 +296257,7 @@ Environment="OLLAMA_NUM_PARALLEL=${n2}"
295762
296257
  renderInfo(`Setting OLLAMA_NUM_PARALLEL=${n2}...`);
295763
296258
  try {
295764
296259
  try {
295765
- execSync46("pkill -f 'ollama serve' 2>/dev/null || true", { stdio: "pipe" });
296260
+ execSync48("pkill -f 'ollama serve' 2>/dev/null || true", { stdio: "pipe" });
295766
296261
  } catch {
295767
296262
  }
295768
296263
  await new Promise((r2) => setTimeout(r2, 1e3));
@@ -296814,18 +297309,18 @@ async function showExposeDashboard(gateway, rl, ctx3) {
296814
297309
  const cmd = `/endpoint ${id} --auth ${gateway.authKey ?? ""}`;
296815
297310
  let copied = false;
296816
297311
  try {
296817
- const { execSync: execSync46 } = __require("node:child_process");
297312
+ const { execSync: execSync48 } = __require("node:child_process");
296818
297313
  const platform6 = process.platform;
296819
297314
  if (platform6 === "darwin") {
296820
- execSync46("pbcopy", { input: cmd, timeout: 3e3 });
297315
+ execSync48("pbcopy", { input: cmd, timeout: 3e3 });
296821
297316
  copied = true;
296822
297317
  } else if (platform6 === "win32") {
296823
- execSync46("clip", { input: cmd, timeout: 3e3 });
297318
+ execSync48("clip", { input: cmd, timeout: 3e3 });
296824
297319
  copied = true;
296825
297320
  } else {
296826
297321
  for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
296827
297322
  try {
296828
- execSync46(tool, { input: cmd, timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] });
297323
+ execSync48(tool, { input: cmd, timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] });
296829
297324
  copied = true;
296830
297325
  break;
296831
297326
  } catch {
@@ -296920,7 +297415,7 @@ var init_commands = __esm({
296920
297415
  // packages/cli/src/tui/project-context.ts
296921
297416
  import { existsSync as existsSync54, readFileSync as readFileSync42, readdirSync as readdirSync15 } from "node:fs";
296922
297417
  import { join as join70, basename as basename13 } from "node:path";
296923
- import { execSync as execSync41 } from "node:child_process";
297418
+ import { execSync as execSync43 } from "node:child_process";
296924
297419
  import { homedir as homedir22, platform as platform5, release } from "node:os";
296925
297420
  function getModelTier(modelName) {
296926
297421
  const m2 = modelName.toLowerCase();
@@ -296962,18 +297457,18 @@ function loadProjectMap(repoRoot) {
296962
297457
  }
296963
297458
  function getGitInfo(repoRoot) {
296964
297459
  try {
296965
- execSync41("git rev-parse --is-inside-work-tree", { cwd: repoRoot, stdio: "pipe" });
297460
+ execSync43("git rev-parse --is-inside-work-tree", { cwd: repoRoot, stdio: "pipe" });
296966
297461
  } catch {
296967
297462
  return "";
296968
297463
  }
296969
297464
  const lines = [];
296970
297465
  try {
296971
- const branch = execSync41("git branch --show-current", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
297466
+ const branch = execSync43("git branch --show-current", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
296972
297467
  if (branch) lines.push(`Branch: ${branch}`);
296973
297468
  } catch {
296974
297469
  }
296975
297470
  try {
296976
- const status = execSync41("git status --porcelain", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
297471
+ const status = execSync43("git status --porcelain", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
296977
297472
  if (status) {
296978
297473
  const changed = status.split("\n").length;
296979
297474
  lines.push(`Working tree: ${changed} changed file(s)`);
@@ -296983,7 +297478,7 @@ function getGitInfo(repoRoot) {
296983
297478
  } catch {
296984
297479
  }
296985
297480
  try {
296986
- const log22 = execSync41("git log --oneline -5 --no-decorate", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
297481
+ const log22 = execSync43("git log --oneline -5 --no-decorate", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
296987
297482
  if (log22) lines.push(`Recent commits:
296988
297483
  ${log22}`);
296989
297484
  } catch {
@@ -299647,7 +300142,7 @@ var init_promptLoader3 = __esm({
299647
300142
  // packages/cli/src/tui/dream-engine.ts
299648
300143
  import { mkdirSync as mkdirSync29, writeFileSync as writeFileSync29, readFileSync as readFileSync46, existsSync as existsSync58, readdirSync as readdirSync17 } from "node:fs";
299649
300144
  import { join as join75, basename as basename15 } from "node:path";
299650
- import { execSync as execSync42 } from "node:child_process";
300145
+ import { execSync as execSync44 } from "node:child_process";
299651
300146
  function setDreamWriteContent(fn) {
299652
300147
  _dreamWriteContent = fn;
299653
300148
  }
@@ -300021,7 +300516,7 @@ var init_dream_engine = __esm({
300021
300516
  }
300022
300517
  }
300023
300518
  try {
300024
- const output = execSync42(cmd, {
300519
+ const output = execSync44(cmd, {
300025
300520
  cwd: this.repoRoot,
300026
300521
  timeout: 3e4,
300027
300522
  encoding: "utf-8",
@@ -300880,17 +301375,17 @@ ${summaryResult}
300880
301375
  try {
300881
301376
  mkdirSync29(checkpointDir, { recursive: true });
300882
301377
  try {
300883
- const gitStatus = execSync42("git status --porcelain", {
301378
+ const gitStatus = execSync44("git status --porcelain", {
300884
301379
  cwd: this.repoRoot,
300885
301380
  encoding: "utf-8",
300886
301381
  timeout: 1e4
300887
301382
  });
300888
- const gitDiff = execSync42("git diff", {
301383
+ const gitDiff = execSync44("git diff", {
300889
301384
  cwd: this.repoRoot,
300890
301385
  encoding: "utf-8",
300891
301386
  timeout: 1e4
300892
301387
  });
300893
- const gitHash = execSync42("git rev-parse HEAD 2>/dev/null || echo 'no-git'", {
301388
+ const gitHash = execSync44("git rev-parse HEAD 2>/dev/null || echo 'no-git'", {
300894
301389
  cwd: this.repoRoot,
300895
301390
  encoding: "utf-8",
300896
301391
  timeout: 5e3
@@ -306483,7 +306978,7 @@ var init_profiles = __esm({
306483
306978
  });
306484
306979
 
306485
306980
  // packages/cli/src/docker.ts
306486
- import { execSync as execSync43, spawn as spawn23 } from "node:child_process";
306981
+ import { execSync as execSync45, spawn as spawn23 } from "node:child_process";
306487
306982
  import { existsSync as existsSync66, mkdirSync as mkdirSync35, writeFileSync as writeFileSync33 } from "node:fs";
306488
306983
  import { join as join83, resolve as resolve33, dirname as dirname24 } from "node:path";
306489
306984
  import { homedir as homedir24 } from "node:os";
@@ -306504,7 +306999,7 @@ function getDockerDir() {
306504
306999
  }
306505
307000
  function isDockerAvailable() {
306506
307001
  try {
306507
- execSync43("docker info", { stdio: "pipe", timeout: 1e4 });
307002
+ execSync45("docker info", { stdio: "pipe", timeout: 1e4 });
306508
307003
  return true;
306509
307004
  } catch {
306510
307005
  return false;
@@ -306512,7 +307007,7 @@ function isDockerAvailable() {
306512
307007
  }
306513
307008
  function isDockerInstalled() {
306514
307009
  try {
306515
- execSync43("docker --version", { stdio: "pipe", timeout: 5e3 });
307010
+ execSync45("docker --version", { stdio: "pipe", timeout: 5e3 });
306516
307011
  return true;
306517
307012
  } catch {
306518
307013
  return false;
@@ -306537,31 +307032,31 @@ async function ensureDocker() {
306537
307032
  }
306538
307033
  try {
306539
307034
  console.log("[oa-docker] Docker not found. Installing via get.docker.com...");
306540
- execSync43("curl -fsSL https://get.docker.com | sh", {
307035
+ execSync45("curl -fsSL https://get.docker.com | sh", {
306541
307036
  stdio: "inherit",
306542
307037
  timeout: 3e5
306543
307038
  });
306544
307039
  const user = process.env["USER"] || process.env["LOGNAME"];
306545
307040
  if (user) {
306546
307041
  try {
306547
- execSync43(`sudo usermod -aG docker ${user}`, { stdio: "pipe" });
307042
+ execSync45(`sudo usermod -aG docker ${user}`, { stdio: "pipe" });
306548
307043
  } catch {
306549
307044
  }
306550
307045
  }
306551
307046
  try {
306552
- execSync43("sudo systemctl start docker", { stdio: "pipe", timeout: 15e3 });
307047
+ execSync45("sudo systemctl start docker", { stdio: "pipe", timeout: 15e3 });
306553
307048
  } catch {
306554
307049
  }
306555
307050
  try {
306556
- execSync43("nvidia-smi", { stdio: "pipe", timeout: 5e3 });
306557
- const runtimes = execSync43("docker info --format '{{json .Runtimes}}'", {
307051
+ execSync45("nvidia-smi", { stdio: "pipe", timeout: 5e3 });
307052
+ const runtimes = execSync45("docker info --format '{{json .Runtimes}}'", {
306558
307053
  stdio: "pipe",
306559
307054
  timeout: 5e3
306560
307055
  }).toString();
306561
307056
  if (!runtimes.includes("nvidia")) {
306562
307057
  console.log("[oa-docker] NVIDIA GPU detected. Installing nvidia-container-toolkit...");
306563
307058
  try {
306564
- execSync43(`
307059
+ execSync45(`
306565
307060
  curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg 2>/dev/null
306566
307061
  curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list > /dev/null 2>&1
306567
307062
  sudo apt-get update -qq 2>/dev/null && sudo apt-get install -y -qq nvidia-container-toolkit 2>/dev/null || ( sudo dnf install -y nvidia-container-toolkit 2>/dev/null || sudo yum install -y nvidia-container-toolkit 2>/dev/null || true )
@@ -306591,7 +307086,7 @@ async function ensureDocker() {
306591
307086
  }
306592
307087
  async function ensureNvidiaToolkit() {
306593
307088
  try {
306594
- execSync43("nvidia-smi --query-gpu=name --format=csv,noheader", { stdio: "pipe", timeout: 5e3 });
307089
+ execSync45("nvidia-smi --query-gpu=name --format=csv,noheader", { stdio: "pipe", timeout: 5e3 });
306595
307090
  } catch {
306596
307091
  return { ok: false, message: "No NVIDIA GPU detected (nvidia-smi not found)" };
306597
307092
  }
@@ -306602,7 +307097,7 @@ async function ensureNvidiaToolkit() {
306602
307097
  return { ok: false, message: "Auto-install only supported on Linux. Install manually: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html" };
306603
307098
  }
306604
307099
  try {
306605
- execSync43(`
307100
+ execSync45(`
306606
307101
  curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg 2>/dev/null
306607
307102
  curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list > /dev/null 2>&1
306608
307103
  sudo apt-get update -qq 2>/dev/null && sudo apt-get install -y -qq nvidia-container-toolkit 2>/dev/null || ( sudo dnf install -y nvidia-container-toolkit 2>/dev/null || sudo yum install -y nvidia-container-toolkit 2>/dev/null || true )
@@ -306616,7 +307111,7 @@ async function ensureNvidiaToolkit() {
306616
307111
  }
306617
307112
  function isOaImageBuilt() {
306618
307113
  try {
306619
- const out = execSync43(`docker images -q ${OA_IMAGE}:${OA_IMAGE_TAG}`, {
307114
+ const out = execSync45(`docker images -q ${OA_IMAGE}:${OA_IMAGE_TAG}`, {
306620
307115
  stdio: "pipe",
306621
307116
  timeout: 5e3
306622
307117
  }).toString().trim();
@@ -306640,7 +307135,7 @@ async function ensureOaImage(force = false) {
306640
307135
  }
306641
307136
  try {
306642
307137
  console.log(`[oa-docker] Building image ${OA_IMAGE}:${OA_IMAGE_TAG}...`);
306643
- execSync43(`docker build -t ${OA_IMAGE}:${OA_IMAGE_TAG} ${buildContext}`, {
307138
+ execSync45(`docker build -t ${OA_IMAGE}:${OA_IMAGE_TAG} ${buildContext}`, {
306644
307139
  stdio: "inherit",
306645
307140
  timeout: 6e5
306646
307141
  // 10 min
@@ -306714,11 +307209,11 @@ exec "$@"
306714
307209
  }
306715
307210
  function hasNvidiaGpu() {
306716
307211
  try {
306717
- execSync43("nvidia-smi --query-gpu=name --format=csv,noheader", {
307212
+ execSync45("nvidia-smi --query-gpu=name --format=csv,noheader", {
306718
307213
  stdio: "pipe",
306719
307214
  timeout: 5e3
306720
307215
  });
306721
- const runtimes = execSync43("docker info --format '{{json .Runtimes}}'", {
307216
+ const runtimes = execSync45("docker info --format '{{json .Runtimes}}'", {
306722
307217
  stdio: "pipe",
306723
307218
  timeout: 5e3
306724
307219
  }).toString();
@@ -306788,7 +307283,7 @@ import * as https3 from "node:https";
306788
307283
  import { createRequire as createRequire4 } from "node:module";
306789
307284
  import { fileURLToPath as fileURLToPath16 } from "node:url";
306790
307285
  import { dirname as dirname25, join as join84, resolve as resolve34 } from "node:path";
306791
- import { spawn as spawn24, execSync as execSync44 } from "node:child_process";
307286
+ import { spawn as spawn24, execSync as execSync46 } from "node:child_process";
306792
307287
  import { mkdirSync as mkdirSync36, writeFileSync as writeFileSync34, readFileSync as readFileSync53, readdirSync as readdirSync23, existsSync as existsSync67 } from "node:fs";
306793
307288
  import { randomBytes as randomBytes19, randomUUID as randomUUID5 } from "node:crypto";
306794
307289
  function getVersion3() {
@@ -307796,7 +308291,7 @@ function handleV1RunsDelete(res, id) {
307796
308291
  const containerName = `oa-${id}`;
307797
308292
  if (job.sandbox === "container") {
307798
308293
  try {
307799
- execSync44(`docker stop ${containerName}`, { timeout: 5e3, stdio: "ignore" });
308294
+ execSync46(`docker stop ${containerName}`, { timeout: 5e3, stdio: "ignore" });
307800
308295
  } catch {
307801
308296
  }
307802
308297
  }
@@ -308706,7 +309201,7 @@ import { createRequire as createRequire5 } from "node:module";
308706
309201
  import { fileURLToPath as fileURLToPath17 } from "node:url";
308707
309202
  import { readFileSync as readFileSync54, writeFileSync as writeFileSync35, appendFileSync as appendFileSync6, rmSync as rmSync4, readdirSync as readdirSync24, mkdirSync as mkdirSync37 } from "node:fs";
308708
309203
  import { existsSync as existsSync68 } from "node:fs";
308709
- import { execSync as execSync45 } from "node:child_process";
309204
+ import { execSync as execSync47 } from "node:child_process";
308710
309205
  import { homedir as homedir25 } from "node:os";
308711
309206
  function formatTimeAgo(date) {
308712
309207
  const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
@@ -308873,6 +309368,8 @@ function buildTools(repoRoot, config, contextWindowSize, modelTier) {
308873
309368
  new CameraCaptureTool(),
308874
309369
  new AudioCaptureTool(),
308875
309370
  new AudioPlaybackTool(),
309371
+ new WifiControlTool(),
309372
+ new BluetoothScanTool(),
308876
309373
  // Full OA sub-process — callbacks wired after runner + statusBar created
308877
309374
  (() => {
308878
309375
  _fullSubAgentToolRef = new FullSubAgentTool(repoRoot, config.model, config.backendUrl);
@@ -313031,7 +313528,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
313031
313528
  try {
313032
313529
  if (process.platform === "win32") {
313033
313530
  try {
313034
- execSync45(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
313531
+ execSync47(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
313035
313532
  } catch {
313036
313533
  }
313037
313534
  } else {
@@ -313058,7 +313555,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
313058
313555
  if (pid > 0) {
313059
313556
  if (process.platform === "win32") {
313060
313557
  try {
313061
- execSync45(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
313558
+ execSync47(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
313062
313559
  } catch {
313063
313560
  }
313064
313561
  } else {
@@ -313075,7 +313572,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
313075
313572
  } catch {
313076
313573
  }
313077
313574
  try {
313078
- execSync45(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.5", { timeout: 3e3, stdio: "ignore" });
313575
+ execSync47(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.5", { timeout: 3e3, stdio: "ignore" });
313079
313576
  } catch {
313080
313577
  }
313081
313578
  const oaPath = join85(repoRoot, OA_DIR);
@@ -313089,14 +313586,14 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
313089
313586
  } catch (err) {
313090
313587
  if (attempt < 2) {
313091
313588
  try {
313092
- execSync45(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.3", { timeout: 3e3, stdio: "ignore" });
313589
+ execSync47(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.3", { timeout: 3e3, stdio: "ignore" });
313093
313590
  } catch {
313094
313591
  }
313095
313592
  } else {
313096
313593
  writeContent(() => renderWarning(`Could not fully remove ${OA_DIR}/: ${err instanceof Error ? err.message : String(err)}`));
313097
313594
  if (process.platform === "win32") {
313098
313595
  try {
313099
- execSync45(`rd /s /q "${oaPath}"`, { timeout: 1e4, stdio: "ignore" });
313596
+ execSync47(`rd /s /q "${oaPath}"`, { timeout: 1e4, stdio: "ignore" });
313100
313597
  deleted = true;
313101
313598
  } catch {
313102
313599
  }