open-agents-ai 0.187.149 → 0.187.150

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 +354 -132
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -256448,7 +256448,7 @@ ${output}`, durationMs: performance.now() - start2 };
256448
256448
  import { execSync as execSync36, spawnSync as spawnSync2 } from "node:child_process";
256449
256449
  import { existsSync as existsSync34, readFileSync as readFileSync25, writeFileSync as writeFileSync13, mkdirSync as mkdirSync14 } from "node:fs";
256450
256450
  import { join as join48 } from "node:path";
256451
- import { tmpdir as tmpdir12 } from "node:os";
256451
+ import { tmpdir as tmpdir12, homedir as homedir13 } from "node:os";
256452
256452
  var GPS_USB_IDS, GpsLocationTool;
256453
256453
  var init_gps_location = __esm({
256454
256454
  "packages/execution/dist/tools/gps-location.js"() {
@@ -256549,13 +256549,63 @@ var init_gps_location = __esm({
256549
256549
  },
256550
256550
  required: ["action"]
256551
256551
  };
256552
+ /** Venv for pyserial + pynmea2 (same stack as proven gps_service) */
256553
+ GPS_VENV = join48(homedir13(), ".open-agents", "gps-venv");
256554
+ GPS_PYTHON = join48(this.GPS_VENV, "bin", "python3");
256555
+ GPS_PIP = join48(this.GPS_VENV, "bin", "pip");
256556
+ /** Ensure pyserial + pynmea2 venv exists */
256557
+ async ensureGpsVenv() {
256558
+ if (existsSync34(this.GPS_PYTHON)) {
256559
+ try {
256560
+ execSync36(`${this.GPS_PYTHON} -c "import serial, pynmea2"`, { timeout: 5e3, stdio: "pipe" });
256561
+ return true;
256562
+ } catch {
256563
+ }
256564
+ }
256565
+ try {
256566
+ execSync36(`python3 -m venv ${this.GPS_VENV}`, { timeout: 3e4, stdio: "pipe" });
256567
+ execSync36(`${this.GPS_PIP} install pyserial pynmea2`, { timeout: 6e4, stdio: "pipe" });
256568
+ return true;
256569
+ } catch {
256570
+ return false;
256571
+ }
256572
+ }
256573
+ /** Run a Python GPS script using pyserial+pynmea2 and return JSON result */
256574
+ async runGpsPython(script, timeoutMs = 3e4) {
256575
+ await this.ensureGpsVenv();
256576
+ const scriptFile = join48(tmpdir12(), `oa-gps-${Date.now()}.py`);
256577
+ writeFileSync13(scriptFile, script);
256578
+ try {
256579
+ const output = execSync36(`${this.GPS_PYTHON} ${scriptFile}`, {
256580
+ encoding: "utf8",
256581
+ timeout: timeoutMs,
256582
+ stdio: ["pipe", "pipe", "pipe"]
256583
+ });
256584
+ const lastLine = output.trim().split("\n").pop() || "{}";
256585
+ return JSON.parse(lastLine);
256586
+ } catch (err) {
256587
+ const stderr = err.stderr?.toString() || "";
256588
+ const stdout = err.stdout?.toString() || "";
256589
+ for (const src2 of [stdout, stderr]) {
256590
+ const lines = src2.trim().split("\n");
256591
+ for (let i2 = lines.length - 1; i2 >= 0; i2--) {
256592
+ try {
256593
+ return JSON.parse(lines[i2]);
256594
+ } catch {
256595
+ continue;
256596
+ }
256597
+ }
256598
+ }
256599
+ throw new Error(stderr.slice(0, 300) || stdout.slice(0, 300) || "GPS Python script failed");
256600
+ }
256601
+ }
256552
256602
  async execute(args) {
256553
256603
  const action = args["action"];
256554
256604
  const start2 = performance.now();
256555
256605
  try {
256556
256606
  switch (action) {
256557
256607
  case "detect":
256558
- return await this.detectGps(start2);
256608
+ return await this.detectGps(args, start2);
256559
256609
  case "fix":
256560
256610
  return await this.getFix(args, start2);
256561
256611
  case "nmea":
@@ -256576,64 +256626,128 @@ var init_gps_location = __esm({
256576
256626
  // =========================================================================
256577
256627
  // Detect GPS hardware
256578
256628
  // =========================================================================
256579
- async detectGps(start2) {
256629
+ async detectGps(args, start2) {
256630
+ try {
256631
+ const result = await this.runGpsPython(`
256632
+ import json, sys
256633
+ try:
256634
+ from serial.tools import list_ports
256635
+ import serial
256636
+
256637
+ candidates = []
256638
+ for p in list_ports.comports():
256639
+ dev = p.device or ""
256640
+ desc = (p.description or "").lower()
256641
+ hwid = (p.hwid or "").lower()
256642
+ vid = getattr(p, 'vid', None)
256643
+ pid = getattr(p, 'pid', None)
256644
+ manufacturer = getattr(p, 'manufacturer', '') or ''
256645
+ product = getattr(p, 'product', '') or ''
256646
+
256647
+ score = 0
256648
+ label = f"{dev}: {p.description or 'unknown'}"
256649
+ if vid: label += f" [VID:PID={vid:04x}:{pid:04x}]"
256650
+
256651
+ # GPS-specific keywords
256652
+ if "gps" in desc or "gnss" in desc or "gps" in manufacturer.lower():
256653
+ score += 10
256654
+ # Known GPS vendors (u-blox=0x1546, Garmin=0x091e, GlobalSat/Prolific=0x067b)
256655
+ if vid in (0x1546, 0x091e, 0x2c7c, 0x152a, 0x0df7, 0x16d0):
256656
+ score += 8
256657
+ # UART bridges commonly used for GPS (Prolific, FTDI, CP210x, CH340)
256658
+ if vid in (0x067b, 0x0403, 0x10c4, 0x1a86):
256659
+ score += 4
256660
+ # ttyUSB devices are very often GPS
256661
+ if "ttyUSB" in dev:
256662
+ score += 3
256663
+ # USB serial in general
256664
+ if "usb" in hwid:
256665
+ score += 2
256666
+ if any(k in dev for k in ("ttyUSB", "ttyACM", "cu.usb", "COM")):
256667
+ score += 1
256668
+
256669
+ if score > 0:
256670
+ candidates.append({"device": dev, "label": label, "score": score,
256671
+ "vid": f"{vid:04x}" if vid else None,
256672
+ "pid": f"{pid:04x}" if pid else None,
256673
+ "manufacturer": manufacturer, "product": product})
256674
+
256675
+ candidates.sort(key=lambda x: -x["score"])
256676
+
256677
+ # Also try to read NMEA from top candidate to confirm it's GPS
256678
+ gps_confirmed = None
256679
+ for c in candidates[:3]:
256680
+ try:
256681
+ with serial.Serial(c["device"], 4800, timeout=2) as ser:
256682
+ ser.reset_input_buffer()
256683
+ for _ in range(20):
256684
+ line = ser.readline().decode(errors="ignore").strip()
256685
+ if line.startswith("$G"):
256686
+ c["nmea_confirmed"] = True
256687
+ gps_confirmed = c["device"]
256688
+ break
256689
+ except: pass
256690
+ if not gps_confirmed:
256691
+ try:
256692
+ with serial.Serial(c["device"], 9600, timeout=2) as ser:
256693
+ ser.reset_input_buffer()
256694
+ for _ in range(20):
256695
+ line = ser.readline().decode(errors="ignore").strip()
256696
+ if line.startswith("$G"):
256697
+ c["nmea_confirmed"] = True
256698
+ gps_confirmed = c["device"]
256699
+ break
256700
+ except: pass
256701
+
256702
+ print(json.dumps({"success": True, "candidates": candidates, "gps_confirmed": gps_confirmed}))
256703
+ except Exception as e:
256704
+ print(json.dumps({"success": False, "error": str(e)}))
256705
+ `, 15e3);
256706
+ if (!result.success) {
256707
+ return { success: false, output: "", error: `GPS detect failed: ${result.error}`, durationMs: performance.now() - start2 };
256708
+ }
256709
+ const candidates = result.candidates || [];
256710
+ if (candidates.length === 0) {
256711
+ return { success: true, output: "No GPS devices detected. Connect a USB GPS receiver (BU-353N, BU-363, U-blox 7, etc.).", durationMs: performance.now() - start2 };
256712
+ }
256713
+ const lines = candidates.map((c7) => ` ${c7.device}: ${c7.label}${c7.nmea_confirmed ? " \u2713 NMEA confirmed" : ""} (score: ${c7.score})`);
256714
+ return {
256715
+ success: true,
256716
+ output: `GPS device(s) found:
256717
+ ${lines.join("\n")}` + (result.gps_confirmed ? `
256718
+
256719
+ Confirmed GPS on: ${result.gps_confirmed} (NMEA sentences detected)` : "\n\nNo NMEA confirmed yet \u2014 device may need time to initialize."),
256720
+ durationMs: performance.now() - start2
256721
+ };
256722
+ } catch (err) {
256723
+ return this.detectGpsFallback(start2);
256724
+ }
256725
+ }
256726
+ /** Fallback detection using lsusb + udevadm (no Python) */
256727
+ detectGpsFallback(start2) {
256580
256728
  const devices = [];
256581
256729
  try {
256582
256730
  const lsusb = execSync36("lsusb 2>/dev/null", { encoding: "utf8", timeout: 5e3 });
256583
256731
  for (const known of GPS_USB_IDS) {
256584
256732
  if (lsusb.toLowerCase().includes(`${known.vid}:${known.pid}`)) {
256585
- const line = lsusb.split("\n").find((l2) => l2.toLowerCase().includes(`${known.vid}:${known.pid}`));
256586
- devices.push(` USB: ${known.name} \u2014 ${line?.trim() || `${known.vid}:${known.pid}`}`);
256587
- }
256588
- }
256589
- for (const line of lsusb.split("\n")) {
256590
- if (/gps|gnss|navsat/i.test(line) && !devices.some((d2) => d2.includes(line.trim()))) {
256591
- devices.push(` USB: ${line.trim()}`);
256733
+ devices.push(` ${known.name}`);
256592
256734
  }
256593
256735
  }
256594
256736
  } catch {
256595
256737
  }
256596
- const serialDevs = [];
256597
- for (const pattern of ["/dev/ttyUSB*", "/dev/ttyACM*"]) {
256598
- try {
256599
- const devs = execSync36(`ls ${pattern} 2>/dev/null`, { encoding: "utf8", timeout: 3e3 }).trim().split("\n").filter(Boolean);
256600
- serialDevs.push(...devs);
256601
- } catch {
256602
- }
256603
- }
256604
- for (const dev of serialDevs) {
256605
- try {
256606
- const udev = execSync36(`udevadm info --query=all --name=${dev} 2>/dev/null`, { encoding: "utf8", timeout: 3e3 });
256607
- const vendor = udev.match(/ID_VENDOR=(.+)/)?.[1] || "";
256608
- const model = udev.match(/ID_MODEL=(.+)/)?.[1] || "";
256609
- const serial = udev.match(/ID_SERIAL_SHORT=(.+)/)?.[1] || "";
256610
- const isGps = GPS_USB_IDS.some((g) => udev.toLowerCase().includes(g.vid)) || /gps|gnss|prolific|cp210x|u-blox|ublox|sirf/i.test(udev);
256611
- if (isGps) {
256612
- devices.push(` Serial: ${dev} \u2014 ${model || vendor} ${serial ? `(SN: ${serial})` : ""}`);
256738
+ try {
256739
+ const serialDevs = execSync36("ls /dev/ttyUSB* /dev/ttyACM* 2>/dev/null", { encoding: "utf8", timeout: 3e3 }).trim().split("\n").filter(Boolean);
256740
+ for (const dev of serialDevs) {
256741
+ if (!devices.some((d2) => d2.includes(dev))) {
256742
+ devices.push(` Serial: ${dev} (unidentified \u2014 may be GPS)`);
256613
256743
  }
256614
- } catch {
256615
256744
  }
256616
- }
256617
- let gpsdRunning = false;
256618
- try {
256619
- execSync36("pgrep gpsd", { timeout: 3e3, stdio: "pipe" });
256620
- gpsdRunning = true;
256621
- devices.push(" Service: gpsd is running");
256622
256745
  } catch {
256623
256746
  }
256624
- if (devices.length === 0) {
256625
- return {
256626
- success: true,
256627
- output: "No GPS devices detected. Connect a USB GPS receiver (BU-353N, U-blox 7, etc.)." + (serialDevs.length > 0 ? `
256628
-
256629
- Serial devices found but not identified as GPS: ${serialDevs.join(", ")}` : ""),
256630
- durationMs: performance.now() - start2
256631
- };
256632
- }
256633
256747
  return {
256634
256748
  success: true,
256635
- output: `GPS devices found:
256636
- ${devices.join("\n")}` + (!gpsdRunning ? "\n\nTip: Start gpsd for best results: gps_location will auto-install and start it." : ""),
256749
+ output: devices.length > 0 ? `Potential GPS devices:
256750
+ ${devices.join("\n")}` : "No GPS devices found. Connect a USB GPS receiver.",
256637
256751
  durationMs: performance.now() - start2
256638
256752
  };
256639
256753
  }
@@ -256679,42 +256793,150 @@ Raw: ${JSON.stringify(fix)}`,
256679
256793
  } catch {
256680
256794
  }
256681
256795
  }
256682
- return this.getFixFromNmea(args, start2);
256796
+ return this.getFixPyserial(args, start2);
256683
256797
  }
256684
- /** Parse GPS fix directly from NMEA on serial port */
256685
- getFixFromNmea(args, start2) {
256686
- const device = args["device"] || this.findGpsSerial();
256687
- if (!device) {
256688
- return { success: false, output: "", error: "No GPS device found. Connect a USB GPS receiver.", durationMs: performance.now() - start2 };
256689
- }
256798
+ /** Get GPS fix using pyserial+pynmea2 proven stack from gps_service/server.py */
256799
+ async getFixPyserial(args, start2) {
256800
+ const device = args["device"] || "";
256690
256801
  const timeout2 = args["timeout"] || 30;
256691
- const baud = this.detectBaud(device);
256692
256802
  try {
256693
- execSync36(`stty -F ${device} ${baud} raw -echo -echoe -echok 2>/dev/null`, { timeout: 5e3, stdio: "pipe" });
256694
- const raw = execSync36(`timeout ${timeout2} cat ${device}`, { encoding: "utf8", timeout: (timeout2 + 5) * 1e3 });
256695
- const gga = raw.split("\n").find((l2) => l2.includes("$GPGGA") || l2.includes("$GNGGA"));
256696
- const rmc = raw.split("\n").find((l2) => l2.includes("$GPRMC") || l2.includes("$GNRMC"));
256697
- if (!gga && !rmc) {
256698
- return { success: true, output: `GPS device responding on ${device} but no fix yet (${timeout2}s timeout). Try again \u2014 cold start can take 30-60s.`, durationMs: performance.now() - start2 };
256699
- }
256700
- const fix = this.parseGGA(gga) || {};
256701
- const rmcData = this.parseRMC(rmc) || {};
256803
+ const result = await this.runGpsPython(`
256804
+ import json, sys, time
256805
+ import serial
256806
+ import pynmea2
256807
+
256808
+ def guess_port():
256809
+ try:
256810
+ from serial.tools import list_ports
256811
+ for p in list_ports.comports():
256812
+ dev = p.device or ""
256813
+ desc = (p.description or "").lower()
256814
+ vid = getattr(p, 'vid', None)
256815
+ if vid in (0x1546, 0x091e, 0x067b, 0x0403, 0x10c4, 0x1a86, 0x2c7c, 0x152a, 0x0df7):
256816
+ return dev, vid
256817
+ if "gps" in desc or "gnss" in desc:
256818
+ return dev, vid
256819
+ if "ttyUSB" in dev:
256820
+ return dev, vid
256821
+ return None, None
256822
+ except:
256823
+ import os
256824
+ for p in ("/dev/ttyUSB0", "/dev/ttyUSB1", "/dev/ttyACM0"):
256825
+ if os.path.exists(p):
256826
+ return p, None
256827
+ return None, None
256828
+
256829
+ port = "${device}" if "${device}" else None
256830
+ vid = None
256831
+ if not port:
256832
+ port, vid = guess_port()
256833
+ if not port:
256834
+ print(json.dumps({"success": False, "error": "No GPS serial device found. Connect a USB GPS receiver."}))
256835
+ sys.exit(0)
256836
+
256837
+ # Try common baud rates \u2014 BU-353/363 use 4800, U-blox uses 9600
256838
+ last_lat = last_lon = last_alt = last_sats = last_hdop = last_speed = last_track = None
256839
+ fix_valid = False
256840
+ raw_sentences = []
256841
+ found_nmea = False
256842
+
256843
+ for baud in [4800, 9600, 38400, 115200]:
256844
+ try:
256845
+ with serial.Serial(port, baud, timeout=2) as ser:
256846
+ ser.reset_input_buffer()
256847
+ deadline = time.time() + min(${timeout2}, 15)
256848
+ while time.time() < deadline:
256849
+ try:
256850
+ line = ser.readline().decode(errors="ignore").strip()
256851
+ except: continue
256852
+ if not line.startswith("$"):
256853
+ continue
256854
+ found_nmea = True
256855
+ raw_sentences.append(line)
256856
+
256857
+ try:
256858
+ msg = pynmea2.parse(line, check=True)
256859
+ except: continue
256860
+
256861
+ if msg.sentence_type == "GGA":
256862
+ try:
256863
+ fix_valid = int(getattr(msg, 'gps_qual', 0) or 0) > 0
256864
+ if msg.latitude is not None: last_lat = float(msg.latitude)
256865
+ if msg.longitude is not None: last_lon = float(msg.longitude)
256866
+ if msg.altitude not in (None, ""): last_alt = float(msg.altitude)
256867
+ if msg.num_sats not in (None, ""): last_sats = int(msg.num_sats)
256868
+ if msg.horizontal_dil not in (None, ""): last_hdop = float(msg.horizontal_dil)
256869
+ except: pass
256870
+
256871
+ elif msg.sentence_type == "RMC":
256872
+ try:
256873
+ rmc_valid = getattr(msg, 'status', '') == 'A'
256874
+ if rmc_valid: fix_valid = True
256875
+ if msg.latitude is not None: last_lat = float(msg.latitude)
256876
+ if msg.longitude is not None: last_lon = float(msg.longitude)
256877
+ if msg.spd_over_grnd not in (None, ""): last_speed = float(msg.spd_over_grnd)
256878
+ if msg.true_course not in (None, ""): last_track = float(msg.true_course)
256879
+ except: pass
256880
+
256881
+ # If we have a valid fix with lat/lon, we're done
256882
+ if fix_valid and last_lat is not None and last_lon is not None:
256883
+ break
256884
+
256885
+ if found_nmea:
256886
+ break # found NMEA at this baud rate, stop trying others
256887
+ except Exception as e:
256888
+ continue
256889
+
256890
+ if not found_nmea:
256891
+ print(json.dumps({"success": False, "error": f"No NMEA data from {port}. Device may not be a GPS or needs different permissions."}))
256892
+ elif last_lat is None or last_lon is None:
256893
+ print(json.dumps({
256894
+ "success": True,
256895
+ "fix": False,
256896
+ "port": port,
256897
+ "baud": baud,
256898
+ "message": f"GPS on {port} responding but no fix yet. Sentences seen: {len(raw_sentences)}. Try again \u2014 cold start takes 30-60s.",
256899
+ "sample_nmea": raw_sentences[:3],
256900
+ }))
256901
+ else:
256902
+ print(json.dumps({
256903
+ "success": True,
256904
+ "fix": True,
256905
+ "port": port,
256906
+ "baud": baud,
256907
+ "lat": last_lat,
256908
+ "lon": last_lon,
256909
+ "alt_m": last_alt,
256910
+ "speed_knots": last_speed,
256911
+ "track_deg": last_track,
256912
+ "sats": last_sats,
256913
+ "hdop": last_hdop,
256914
+ "fix_valid": fix_valid,
256915
+ "sentences_read": len(raw_sentences),
256916
+ }))
256917
+ `, (timeout2 + 20) * 1e3);
256918
+ if (!result.success) {
256919
+ return { success: false, output: "", error: result.error || "GPS fix failed", durationMs: performance.now() - start2 };
256920
+ }
256921
+ if (!result.fix) {
256922
+ return { success: true, output: result.message + (result.sample_nmea ? `
256923
+
256924
+ Sample: ${result.sample_nmea.join("\n")}` : ""), durationMs: performance.now() - start2 };
256925
+ }
256702
256926
  return {
256703
256927
  success: true,
256704
- output: `GPS Fix (NMEA from ${device} @ ${baud} baud):
256705
- Position: ${fix.lat ?? "no fix"}, ${fix.lon ?? "no fix"}
256706
- Altitude: ${fix.alt ?? "unknown"}m
256707
- Satellites: ${fix.sats ?? "unknown"}
256708
- Fix quality: ${fix.quality ?? "unknown"}
256709
- Speed: ${rmcData.speed ?? "unknown"} knots
256710
- Time (UTC): ${fix.time ?? rmcData.time ?? "unknown"}
256711
-
256712
- Raw GGA: ${gga || "none"}
256713
- Raw RMC: ${rmc || "none"}`,
256928
+ output: `GPS Fix (${result.port} @ ${result.baud} baud):
256929
+ Position: ${result.lat}, ${result.lon}
256930
+ Altitude: ${result.alt_m != null ? result.alt_m + "m" : "unknown"}
256931
+ Speed: ${result.speed_knots != null ? (result.speed_knots * 1.852).toFixed(1) + " km/h" : "unknown"}
256932
+ Heading: ${result.track_deg != null ? result.track_deg + "\xB0" : "unknown"}
256933
+ Satellites: ${result.sats ?? "unknown"}${result.hdop ? ` (HDOP: ${result.hdop})` : ""}
256934
+ Fix valid: ${result.fix_valid ? "yes" : "no"}
256935
+ Sentences read: ${result.sentences_read}`,
256714
256936
  durationMs: performance.now() - start2
256715
256937
  };
256716
256938
  } catch (err) {
256717
- return { success: false, output: "", error: `NMEA read failed on ${device}: ${err instanceof Error ? err.message : String(err)}`, durationMs: performance.now() - start2 };
256939
+ return { success: false, output: "", error: `GPS fix error: ${err instanceof Error ? err.message : String(err)}`, durationMs: performance.now() - start2 };
256718
256940
  }
256719
256941
  }
256720
256942
  // =========================================================================
@@ -258250,10 +258472,10 @@ var init_client3 = __esm({
258250
258472
  // packages/execution/dist/mcp/manager.js
258251
258473
  import { existsSync as existsSync36, readFileSync as readFileSync26 } from "node:fs";
258252
258474
  import { join as join50 } from "node:path";
258253
- import { homedir as homedir13 } from "node:os";
258475
+ import { homedir as homedir14 } from "node:os";
258254
258476
  function loadMcpConfig(repoRoot) {
258255
258477
  const servers = {};
258256
- const globalPath = join50(homedir13(), ".open-agents", "mcp.json");
258478
+ const globalPath = join50(homedir14(), ".open-agents", "mcp.json");
258257
258479
  if (existsSync36(globalPath)) {
258258
258480
  try {
258259
258481
  const global2 = JSON.parse(readFileSync26(globalPath, "utf8"));
@@ -258557,10 +258779,10 @@ var init_mcp = __esm({
258557
258779
  // packages/execution/dist/plugins/plugin-system.js
258558
258780
  import { existsSync as existsSync37, readdirSync as readdirSync7, readFileSync as readFileSync27 } from "node:fs";
258559
258781
  import { join as join51 } from "node:path";
258560
- import { homedir as homedir14 } from "node:os";
258782
+ import { homedir as homedir15 } from "node:os";
258561
258783
  function discoverPlugins(repoRoot) {
258562
258784
  const plugins = [];
258563
- const globalDir = join51(homedir14(), ".open-agents", "plugins");
258785
+ const globalDir = join51(homedir15(), ".open-agents", "plugins");
258564
258786
  if (existsSync37(globalDir)) {
258565
258787
  plugins.push(...loadPluginsFromDir(globalDir));
258566
258788
  }
@@ -259987,10 +260209,10 @@ var init_buildRunner = __esm({
259987
260209
  // packages/execution/dist/constraints.js
259988
260210
  import { existsSync as existsSync42, readFileSync as readFileSync32, writeFileSync as writeFileSync17, mkdirSync as mkdirSync18 } from "node:fs";
259989
260211
  import { join as join55 } from "node:path";
259990
- import { homedir as homedir15 } from "node:os";
260212
+ import { homedir as homedir16 } from "node:os";
259991
260213
  function loadConstraints(projectRoot) {
259992
260214
  projectConstraints = loadFile(join55(projectRoot, ".oa", "constraints.json"));
259993
- globalConstraints = loadFile(join55(homedir15(), ".open-agents", "constraints.json"));
260215
+ globalConstraints = loadFile(join55(homedir16(), ".open-agents", "constraints.json"));
259994
260216
  }
259995
260217
  function loadFile(path5) {
259996
260218
  try {
@@ -270007,7 +270229,7 @@ __export(listen_exports, {
270007
270229
  import { spawn as spawn17, execSync as execSync41 } from "node:child_process";
270008
270230
  import { existsSync as existsSync45, mkdirSync as mkdirSync19, writeFileSync as writeFileSync19, readdirSync as readdirSync9 } from "node:fs";
270009
270231
  import { join as join60, dirname as dirname16 } from "node:path";
270010
- import { homedir as homedir16 } from "node:os";
270232
+ import { homedir as homedir17 } from "node:os";
270011
270233
  import { fileURLToPath as fileURLToPath9 } from "node:url";
270012
270234
  import { EventEmitter as EventEmitter3 } from "node:events";
270013
270235
  import { createInterface as createInterface2 } from "node:readline";
@@ -270117,7 +270339,7 @@ function findLiveWhisperScript() {
270117
270339
  }
270118
270340
  } catch {
270119
270341
  }
270120
- const nvmBase = join60(homedir16(), ".nvm", "versions", "node");
270342
+ const nvmBase = join60(homedir17(), ".nvm", "versions", "node");
270121
270343
  if (existsSync45(nvmBase)) {
270122
270344
  try {
270123
270345
  for (const ver of readdirSync9(nvmBase)) {
@@ -270365,7 +270587,7 @@ var init_listen = __esm({
270365
270587
  }
270366
270588
  } catch {
270367
270589
  }
270368
- const nvmBase = join60(homedir16(), ".nvm", "versions", "node");
270590
+ const nvmBase = join60(homedir17(), ".nvm", "versions", "node");
270369
270591
  if (existsSync45(nvmBase)) {
270370
270592
  try {
270371
270593
  const { readdirSync: readdirSync26 } = await import("node:fs");
@@ -280191,7 +280413,7 @@ __export(oa_directory_exports, {
280191
280413
  });
280192
280414
  import { existsSync as existsSync49, mkdirSync as mkdirSync22, readFileSync as readFileSync37, writeFileSync as writeFileSync22, readdirSync as readdirSync11, statSync as statSync16, unlinkSync as unlinkSync11 } from "node:fs";
280193
280415
  import { join as join65, relative as relative4, basename as basename12 } from "node:path";
280194
- import { homedir as homedir17 } from "node:os";
280416
+ import { homedir as homedir18 } from "node:os";
280195
280417
  function initOaDirectory(repoRoot) {
280196
280418
  const oaPath = join65(repoRoot, OA_DIR);
280197
280419
  for (const sub of SUBDIRS) {
@@ -280231,7 +280453,7 @@ function saveProjectSettings(repoRoot, settings) {
280231
280453
  writeFileSync22(join65(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
280232
280454
  }
280233
280455
  function loadGlobalSettings() {
280234
- const settingsPath = join65(homedir17(), ".open-agents", "settings.json");
280456
+ const settingsPath = join65(homedir18(), ".open-agents", "settings.json");
280235
280457
  try {
280236
280458
  if (existsSync49(settingsPath)) {
280237
280459
  return JSON.parse(readFileSync37(settingsPath, "utf-8"));
@@ -280241,7 +280463,7 @@ function loadGlobalSettings() {
280241
280463
  return {};
280242
280464
  }
280243
280465
  function saveGlobalSettings(settings) {
280244
- const dir = join65(homedir17(), ".open-agents");
280466
+ const dir = join65(homedir18(), ".open-agents");
280245
280467
  mkdirSync22(dir, { recursive: true });
280246
280468
  const existing = loadGlobalSettings();
280247
280469
  const merged = { ...existing, ...settings };
@@ -280739,13 +280961,13 @@ function recordUsage(kind, value2, opts) {
280739
280961
  }
280740
280962
  saveUsageFile(filePath, data);
280741
280963
  };
280742
- update2(join65(homedir17(), ".open-agents", USAGE_HISTORY_FILE));
280964
+ update2(join65(homedir18(), ".open-agents", USAGE_HISTORY_FILE));
280743
280965
  if (opts?.repoRoot) {
280744
280966
  update2(join65(opts.repoRoot, OA_DIR, USAGE_HISTORY_FILE));
280745
280967
  }
280746
280968
  }
280747
280969
  function loadUsageHistory(kind, repoRoot) {
280748
- const globalPath = join65(homedir17(), ".open-agents", USAGE_HISTORY_FILE);
280970
+ const globalPath = join65(homedir18(), ".open-agents", USAGE_HISTORY_FILE);
280749
280971
  const globalData = loadUsageFile(globalPath);
280750
280972
  const localData = repoRoot ? loadUsageFile(join65(repoRoot, OA_DIR, USAGE_HISTORY_FILE)) : { records: [] };
280751
280973
  const map2 = /* @__PURE__ */ new Map();
@@ -280776,7 +280998,7 @@ function deleteUsageRecord(kind, value2, repoRoot) {
280776
280998
  saveUsageFile(filePath, data);
280777
280999
  }
280778
281000
  };
280779
- remove(join65(homedir17(), ".open-agents", USAGE_HISTORY_FILE));
281001
+ remove(join65(homedir18(), ".open-agents", USAGE_HISTORY_FILE));
280780
281002
  if (repoRoot) {
280781
281003
  remove(join65(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
280782
281004
  }
@@ -285332,7 +285554,7 @@ __export(personaplex_exports, {
285332
285554
  });
285333
285555
  import { existsSync as existsSync50, writeFileSync as writeFileSync23, readFileSync as readFileSync39, mkdirSync as mkdirSync23, copyFileSync as copyFileSync2, readdirSync as readdirSync12, statSync as statSync17 } from "node:fs";
285334
285556
  import { join as join66, dirname as dirname20 } from "node:path";
285335
- import { homedir as homedir18 } from "node:os";
285557
+ import { homedir as homedir19 } from "node:os";
285336
285558
  import { execSync as execSync44, spawn as spawn20 } from "node:child_process";
285337
285559
  import { fileURLToPath as fileURLToPath12 } from "node:url";
285338
285560
  function execAsync(cmd, opts = {}) {
@@ -285927,7 +286149,7 @@ print('Converted')
285927
286149
  let ollamaModel = process.env["HYBRID_LLM_MODEL"] || "";
285928
286150
  if (!ollamaModel) {
285929
286151
  try {
285930
- const oaConfig = JSON.parse(readFileSync39(join66(homedir18(), ".open-agents", "config.json"), "utf8"));
286152
+ const oaConfig = JSON.parse(readFileSync39(join66(homedir19(), ".open-agents", "config.json"), "utf8"));
285931
286153
  if (oaConfig.model) ollamaModel = oaConfig.model;
285932
286154
  } catch {
285933
286155
  }
@@ -286198,7 +286420,7 @@ function provisionShippedVoices(onInfo) {
286198
286420
  return deployed;
286199
286421
  }
286200
286422
  function getHFVoicesDir() {
286201
- const hfBase = join66(homedir18(), ".cache", "huggingface", "hub", "models--nvidia--personaplex-7b-v1");
286423
+ const hfBase = join66(homedir19(), ".cache", "huggingface", "hub", "models--nvidia--personaplex-7b-v1");
286202
286424
  if (!existsSync50(hfBase)) return null;
286203
286425
  try {
286204
286426
  const snapshots = join66(hfBase, "snapshots");
@@ -286214,7 +286436,7 @@ function getHFVoicesDir() {
286214
286436
  function patchFrontendVoiceList(onInfo) {
286215
286437
  const log22 = onInfo ?? (() => {
286216
286438
  });
286217
- const hfBase = join66(homedir18(), ".cache", "huggingface", "hub", "models--nvidia--personaplex-7b-v1");
286439
+ const hfBase = join66(homedir19(), ".cache", "huggingface", "hub", "models--nvidia--personaplex-7b-v1");
286218
286440
  if (!existsSync50(hfBase)) return;
286219
286441
  try {
286220
286442
  const snapshots = join66(hfBase, "snapshots");
@@ -286292,7 +286514,7 @@ var init_personaplex = __esm({
286292
286514
  nf4: { repo: "cudabenchmarktest/personaplex-7b-nf4", file: "model-nf4.safetensors", sizeGB: 4.1, needsToken: false },
286293
286515
  "nf4-distilled": { repo: "cudabenchmarktest/personaplex-7b-nf4-distilled", file: "student_best.pt", sizeGB: 16.7, needsToken: false }
286294
286516
  };
286295
- PERSONAPLEX_DIR = join66(homedir18(), ".open-agents", "voice", "personaplex");
286517
+ PERSONAPLEX_DIR = join66(homedir19(), ".open-agents", "voice", "personaplex");
286296
286518
  PID_FILE = join66(PERSONAPLEX_DIR, "daemon.pid");
286297
286519
  PORT_FILE = join66(PERSONAPLEX_DIR, "daemon.port");
286298
286520
  LOG_FILE = join66(PERSONAPLEX_DIR, "daemon.log");
@@ -286339,7 +286561,7 @@ import { execSync as execSync45, spawn as spawn21, exec as exec4 } from "node:ch
286339
286561
  import { promisify as promisify7 } from "node:util";
286340
286562
  import { existsSync as existsSync51, writeFileSync as writeFileSync24, readFileSync as readFileSync40, appendFileSync as appendFileSync2, mkdirSync as mkdirSync24 } from "node:fs";
286341
286563
  import { join as join67 } from "node:path";
286342
- import { homedir as homedir19, platform as platform3 } from "node:os";
286564
+ import { homedir as homedir20, platform as platform3 } from "node:os";
286343
286565
  async function checkToolSupport(modelName, backendUrl = "http://localhost:11434") {
286344
286566
  if (_toolSupportCache.has(modelName)) return _toolSupportCache.get(modelName);
286345
286567
  try {
@@ -287438,7 +287660,7 @@ async function doSetup(config, rl) {
287438
287660
  `PARAMETER num_predict ${numPredict}`,
287439
287661
  `PARAMETER stop "<|endoftext|>"`
287440
287662
  ].join("\n");
287441
- const modelDir2 = join67(homedir19(), ".open-agents", "models");
287663
+ const modelDir2 = join67(homedir20(), ".open-agents", "models");
287442
287664
  mkdirSync24(modelDir2, { recursive: true });
287443
287665
  const modelfilePath = join67(modelDir2, `Modelfile.${customName}`);
287444
287666
  writeFileSync24(modelfilePath, modelfileContent + "\n", "utf8");
@@ -287486,7 +287708,7 @@ async function isModelAvailable(config) {
287486
287708
  }
287487
287709
  function isFirstRun() {
287488
287710
  try {
287489
- return !existsSync51(join67(homedir19(), ".open-agents", "config.json"));
287711
+ return !existsSync51(join67(homedir20(), ".open-agents", "config.json"));
287490
287712
  } catch {
287491
287713
  return true;
287492
287714
  }
@@ -287534,7 +287756,7 @@ function detectPkgManager() {
287534
287756
  return null;
287535
287757
  }
287536
287758
  function getVenvDir() {
287537
- return join67(homedir19(), ".open-agents", "venv");
287759
+ return join67(homedir20(), ".open-agents", "venv");
287538
287760
  }
287539
287761
  function hasVenvModule() {
287540
287762
  try {
@@ -287560,7 +287782,7 @@ function ensureVenv(log22) {
287560
287782
  return null;
287561
287783
  }
287562
287784
  try {
287563
- mkdirSync24(join67(homedir19(), ".open-agents"), { recursive: true });
287785
+ mkdirSync24(join67(homedir20(), ".open-agents"), { recursive: true });
287564
287786
  const pyCmd = hasCmd(pythonCmd) ? pythonCmd : "python3";
287565
287787
  execSync45(`${pyCmd} -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
287566
287788
  execSync45(`"${pipPath}" install --upgrade pip`, {
@@ -287660,7 +287882,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
287660
287882
  ];
287661
287883
  {
287662
287884
  const pm2 = detectPkgManager();
287663
- const _visionMarkerDir = join67(homedir19(), ".open-agents");
287885
+ const _visionMarkerDir = join67(homedir20(), ".open-agents");
287664
287886
  const _visionMarkerFile = join67(_visionMarkerDir, "vision-deps-installed.json");
287665
287887
  let _visionPreviouslyInstalled = /* @__PURE__ */ new Set();
287666
287888
  try {
@@ -287913,11 +288135,11 @@ function ensureCloudflaredBackground(onInfo) {
287913
288135
  const cfArch = archMap[arch2] ?? "amd64";
287914
288136
  try {
287915
288137
  execSync45(
287916
- `curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && mkdir -p "${homedir19()}/.local/bin" && mv /tmp/cloudflared "${homedir19()}/.local/bin/cloudflared"`,
288138
+ `curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && mkdir -p "${homedir20()}/.local/bin" && mv /tmp/cloudflared "${homedir20()}/.local/bin/cloudflared"`,
287917
288139
  { stdio: "pipe", timeout: 6e4 }
287918
288140
  );
287919
- if (!process.env.PATH?.includes(`${homedir19()}/.local/bin`)) {
287920
- process.env.PATH = `${homedir19()}/.local/bin:${process.env.PATH}`;
288141
+ if (!process.env.PATH?.includes(`${homedir20()}/.local/bin`)) {
288142
+ process.env.PATH = `${homedir20()}/.local/bin:${process.env.PATH}`;
287921
288143
  }
287922
288144
  if (hasCmd("cloudflared")) {
287923
288145
  log22("cloudflared installed.");
@@ -288014,7 +288236,7 @@ function createExpandedVariant(baseModel, specs, sizeGB, kvBytesPerToken, archMa
288014
288236
  `PARAMETER num_predict ${numPredict}`,
288015
288237
  `PARAMETER stop "<|endoftext|>"`
288016
288238
  ].join("\n");
288017
- const modelDir2 = join67(homedir19(), ".open-agents", "models");
288239
+ const modelDir2 = join67(homedir20(), ".open-agents", "models");
288018
288240
  mkdirSync24(modelDir2, { recursive: true });
288019
288241
  const modelfilePath = join67(modelDir2, `Modelfile.${customName}`);
288020
288242
  writeFileSync24(modelfilePath, modelfileContent + "\n", "utf8");
@@ -288039,7 +288261,7 @@ async function createExpandedVariantAsync(baseModel, specs, sizeGB, kvBytesPerTo
288039
288261
  `PARAMETER num_predict ${numPredict}`,
288040
288262
  `PARAMETER stop "<|endoftext|>"`
288041
288263
  ].join("\n");
288042
- const modelDir2 = join67(homedir19(), ".open-agents", "models");
288264
+ const modelDir2 = join67(homedir20(), ".open-agents", "models");
288043
288265
  mkdirSync24(modelDir2, { recursive: true });
288044
288266
  const modelfilePath = join67(modelDir2, `Modelfile.${customName}`);
288045
288267
  writeFileSync24(modelfilePath, modelfileContent + "\n", "utf8");
@@ -288115,7 +288337,7 @@ async function ensureNeovim() {
288115
288337
  const platform6 = process.platform;
288116
288338
  const arch2 = process.arch;
288117
288339
  if (platform6 === "linux") {
288118
- const binDir = join67(homedir19(), ".local", "bin");
288340
+ const binDir = join67(homedir20(), ".local", "bin");
288119
288341
  const nvimDest = join67(binDir, "nvim");
288120
288342
  try {
288121
288343
  mkdirSync24(binDir, { recursive: true });
@@ -288187,7 +288409,7 @@ async function ensureNeovim() {
288187
288409
  }
288188
288410
  function ensurePathInShellRc(binDir) {
288189
288411
  const shell = process.env.SHELL ?? "";
288190
- const rcFile = shell.includes("zsh") ? join67(homedir19(), ".zshrc") : join67(homedir19(), ".bashrc");
288412
+ const rcFile = shell.includes("zsh") ? join67(homedir20(), ".zshrc") : join67(homedir20(), ".bashrc");
288191
288413
  try {
288192
288414
  const rcContent = existsSync51(rcFile) ? readFileSync40(rcFile, "utf8") : "";
288193
288415
  if (rcContent.includes(binDir)) return;
@@ -288930,7 +289152,7 @@ __export(daemon_exports, {
288930
289152
  import { spawn as spawn22 } from "node:child_process";
288931
289153
  import { existsSync as existsSync54, readFileSync as readFileSync41, writeFileSync as writeFileSync25, mkdirSync as mkdirSync25, unlinkSync as unlinkSync13 } from "node:fs";
288932
289154
  import { join as join69 } from "node:path";
288933
- import { homedir as homedir20 } from "node:os";
289155
+ import { homedir as homedir21 } from "node:os";
288934
289156
  import { fileURLToPath as fileURLToPath13 } from "node:url";
288935
289157
  import { dirname as dirname21 } from "node:path";
288936
289158
  function getDaemonPort() {
@@ -289081,7 +289303,7 @@ var OA_DIR2, PID_FILE2, DEFAULT_PORT2;
289081
289303
  var init_daemon = __esm({
289082
289304
  "packages/cli/src/daemon.ts"() {
289083
289305
  "use strict";
289084
- OA_DIR2 = join69(homedir20(), ".open-agents");
289306
+ OA_DIR2 = join69(homedir21(), ".open-agents");
289085
289307
  PID_FILE2 = join69(OA_DIR2, "daemon.pid");
289086
289308
  DEFAULT_PORT2 = 11435;
289087
289309
  }
@@ -290381,7 +290603,7 @@ __export(voice_exports, {
290381
290603
  });
290382
290604
  import { existsSync as existsSync56, mkdirSync as mkdirSync27, writeFileSync as writeFileSync27, readFileSync as readFileSync43, unlinkSync as unlinkSync14, readdirSync as readdirSync13, statSync as statSync18 } from "node:fs";
290383
290605
  import { join as join71, dirname as dirname22 } from "node:path";
290384
- import { homedir as homedir21, tmpdir as tmpdir15, platform as platform4 } from "node:os";
290606
+ import { homedir as homedir22, tmpdir as tmpdir15, platform as platform4 } from "node:os";
290385
290607
  import { execSync as execSync47, spawn as nodeSpawn } from "node:child_process";
290386
290608
  import { createRequire as createRequire2 } from "node:module";
290387
290609
  function sanitizeForTTS(text) {
@@ -290405,7 +290627,7 @@ function listVoiceModels() {
290405
290627
  }));
290406
290628
  }
290407
290629
  function voiceDir() {
290408
- return join71(homedir21(), ".open-agents", "voice");
290630
+ return join71(homedir22(), ".open-agents", "voice");
290409
290631
  }
290410
290632
  function modelsDir() {
290411
290633
  return join71(voiceDir(), "models");
@@ -291337,7 +291559,7 @@ var init_voice = __esm({
291337
291559
  }
291338
291560
  p2 = p2.replace(/\\ /g, " ");
291339
291561
  if (p2.startsWith("~/") || p2 === "~") {
291340
- p2 = join71(homedir21(), p2.slice(1));
291562
+ p2 = join71(homedir22(), p2.slice(1));
291341
291563
  }
291342
291564
  if (!existsSync56(p2)) {
291343
291565
  return `File not found: ${p2}
@@ -293687,9 +293909,9 @@ async function handleSlashCommand(input, ctx3) {
293687
293909
  renderInfo("No wallet configured. Ask the agent to create one via the nexus tool.");
293688
293910
  }
293689
293911
  } else if (sub === "name") {
293690
- const { homedir: homedir28 } = __require("node:os");
293912
+ const { homedir: homedir29 } = __require("node:os");
293691
293913
  const { existsSync: ex, readFileSync: rf, writeFileSync: wf, mkdirSync: mkd } = __require("node:fs");
293692
- const namePath = __require("node:path").join(homedir28(), ".open-agents", "agent-name");
293914
+ const namePath = __require("node:path").join(homedir29(), ".open-agents", "agent-name");
293693
293915
  if (rest2) {
293694
293916
  const customName = rest2.replace(/[^a-zA-Z0-9_\-.\s]/g, "").trim().slice(0, 40);
293695
293917
  if (!customName) {
@@ -295388,8 +295610,8 @@ The session corrections MUST become hard rules in the SKILL.md Rules section.`;
295388
295610
  let sponsorName = (config.header.message || "").replace(/^\/+/, "").trim();
295389
295611
  if (!sponsorName || sponsorName.length < 2) {
295390
295612
  try {
295391
- const { homedir: homedir28 } = __require("os");
295392
- const namePath = __require("path").join(homedir28(), ".open-agents", "agent-name");
295613
+ const { homedir: homedir29 } = __require("os");
295614
+ const namePath = __require("path").join(homedir29(), ".open-agents", "agent-name");
295393
295615
  if (existsSync57(namePath)) sponsorName = readFileSync44(namePath, "utf8").trim();
295394
295616
  } catch {
295395
295617
  }
@@ -296849,9 +297071,9 @@ async function handleVoiceMenu(ctx3, save2, hasLocal) {
296849
297071
  }
296850
297072
  const { basename: basename19, join: pathJoin } = await import("node:path");
296851
297073
  const { copyFileSync: copyFileSync3, mkdirSync: mkdirSync43, existsSync: exists2 } = await import("node:fs");
296852
- const { homedir: homedir28 } = await import("node:os");
297074
+ const { homedir: homedir29 } = await import("node:os");
296853
297075
  const modelName = basename19(onnxDrop.path, ".onnx").replace(/[^a-zA-Z0-9_-]/g, "-");
296854
- const destDir = pathJoin(homedir28(), ".open-agents", "voice", "models", modelName);
297076
+ const destDir = pathJoin(homedir29(), ".open-agents", "voice", "models", modelName);
296855
297077
  if (!exists2(destDir)) mkdirSync43(destDir, { recursive: true });
296856
297078
  copyFileSync3(onnxDrop.path, pathJoin(destDir, "model.onnx"));
296857
297079
  copyFileSync3(jsonDrop.path, pathJoin(destDir, "config.json"));
@@ -299073,7 +299295,7 @@ var init_commands = __esm({
299073
299295
  import { existsSync as existsSync58, readFileSync as readFileSync45, readdirSync as readdirSync15 } from "node:fs";
299074
299296
  import { join as join73, basename as basename13 } from "node:path";
299075
299297
  import { execSync as execSync48 } from "node:child_process";
299076
- import { homedir as homedir23, platform as platform5, release } from "node:os";
299298
+ import { homedir as homedir24, platform as platform5, release } from "node:os";
299077
299299
  function getModelTier(modelName) {
299078
299300
  const m2 = modelName.toLowerCase();
299079
299301
  const sizeMatch = m2.match(/\b(\d+)b\b/);
@@ -299152,7 +299374,7 @@ function loadMemoryContext(repoRoot) {
299152
299374
  const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
299153
299375
  if (legacyEntries) sections.push(legacyEntries);
299154
299376
  }
299155
- const globalMemDir = join73(homedir23(), ".open-agents", "memory");
299377
+ const globalMemDir = join73(homedir24(), ".open-agents", "memory");
299156
299378
  const globalEntries = loadMemoryDir(globalMemDir, "global");
299157
299379
  if (globalEntries) sections.push(globalEntries);
299158
299380
  return sections.join("\n\n");
@@ -308443,10 +308665,10 @@ var init_usage_tracker = __esm({
308443
308665
  // packages/cli/src/api/profiles.ts
308444
308666
  import { existsSync as existsSync69, readFileSync as readFileSync55, writeFileSync as writeFileSync34, mkdirSync as mkdirSync37, readdirSync as readdirSync22, unlinkSync as unlinkSync17 } from "node:fs";
308445
308667
  import { join as join85 } from "node:path";
308446
- import { homedir as homedir24 } from "node:os";
308668
+ import { homedir as homedir25 } from "node:os";
308447
308669
  import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, randomBytes as randomBytes18, scryptSync as scryptSync3 } from "node:crypto";
308448
308670
  function globalProfileDir() {
308449
- return join85(homedir24(), ".open-agents", "profiles");
308671
+ return join85(homedir25(), ".open-agents", "profiles");
308450
308672
  }
308451
308673
  function projectProfileDir(projectDir) {
308452
308674
  return join85(projectDir || process.cwd(), ".oa", "profiles");
@@ -308638,7 +308860,7 @@ var init_profiles = __esm({
308638
308860
  import { execSync as execSync50, spawn as spawn23 } from "node:child_process";
308639
308861
  import { existsSync as existsSync70, mkdirSync as mkdirSync38, writeFileSync as writeFileSync35 } from "node:fs";
308640
308862
  import { join as join86, resolve as resolve33, dirname as dirname24 } from "node:path";
308641
- import { homedir as homedir25 } from "node:os";
308863
+ import { homedir as homedir26 } from "node:os";
308642
308864
  import { fileURLToPath as fileURLToPath15 } from "node:url";
308643
308865
  function getDockerDir() {
308644
308866
  try {
@@ -308786,7 +309008,7 @@ async function ensureOaImage(force = false) {
308786
309008
  if (existsSync70(join86(dockerDir, "Dockerfile"))) {
308787
309009
  buildContext = dockerDir;
308788
309010
  } else {
308789
- buildContext = join86(homedir25(), ".oa", "docker-build");
309011
+ buildContext = join86(homedir26(), ".oa", "docker-build");
308790
309012
  mkdirSync38(buildContext, { recursive: true });
308791
309013
  writeDockerfiles(buildContext);
308792
309014
  }
@@ -310859,7 +311081,7 @@ import { fileURLToPath as fileURLToPath17 } from "node:url";
310859
311081
  import { readFileSync as readFileSync57, writeFileSync as writeFileSync37, appendFileSync as appendFileSync6, rmSync as rmSync4, readdirSync as readdirSync24, mkdirSync as mkdirSync40 } from "node:fs";
310860
311082
  import { existsSync as existsSync72 } from "node:fs";
310861
311083
  import { execSync as execSync52 } from "node:child_process";
310862
- import { homedir as homedir26 } from "node:os";
311084
+ import { homedir as homedir27 } from "node:os";
310863
311085
  function formatTimeAgo(date) {
310864
311086
  const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
310865
311087
  if (seconds < 60) return "just now";
@@ -313421,7 +313643,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
313421
313643
  const hits = allCompletions.filter((c7) => c7.toLowerCase().startsWith(lower));
313422
313644
  return [hits, line];
313423
313645
  }
313424
- const HISTORY_DIR = join88(homedir26(), ".open-agents");
313646
+ const HISTORY_DIR = join88(homedir27(), ".open-agents");
313425
313647
  const HISTORY_FILE = join88(HISTORY_DIR, "repl-history");
313426
313648
  const MAX_HISTORY_LINES = 500;
313427
313649
  let savedHistory = [];
@@ -315207,7 +315429,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
315207
315429
  } catch {
315208
315430
  }
315209
315431
  try {
315210
- const voiceDir2 = join88(homedir26(), ".open-agents", "voice");
315432
+ const voiceDir2 = join88(homedir27(), ".open-agents", "voice");
315211
315433
  const voicePidFiles = ["luxtts-daemon.pid", "piper-daemon.pid"];
315212
315434
  for (const pf of voicePidFiles) {
315213
315435
  const pidPath = join88(voiceDir2, pf);
@@ -315320,8 +315542,8 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
315320
315542
  try {
315321
315543
  const { isPersonaPlexRunning: isPersonaPlexRunning2 } = await Promise.resolve().then(() => (init_personaplex(), personaplex_exports));
315322
315544
  if (isPersonaPlexRunning2()) {
315323
- const ppPidFile = join88(homedir26(), ".open-agents", "voice", "personaplex", "daemon.pid");
315324
- const ppPortFile = join88(homedir26(), ".open-agents", "voice", "personaplex", "daemon.port");
315545
+ const ppPidFile = join88(homedir27(), ".open-agents", "voice", "personaplex", "daemon.pid");
315546
+ const ppPortFile = join88(homedir27(), ".open-agents", "voice", "personaplex", "daemon.port");
315325
315547
  if (existsSync72(ppPidFile)) {
315326
315548
  const ppPid = parseInt(readFileSync57(ppPidFile, "utf8").trim(), 10);
315327
315549
  const ppPort = existsSync72(ppPortFile) ? parseInt(readFileSync57(ppPortFile, "utf8").trim(), 10) : void 0;
@@ -317241,7 +317463,7 @@ __export(config_exports2, {
317241
317463
  configCommand: () => configCommand
317242
317464
  });
317243
317465
  import { join as join91, resolve as resolve38 } from "node:path";
317244
- import { homedir as homedir27 } from "node:os";
317466
+ import { homedir as homedir28 } from "node:os";
317245
317467
  import { cwd as cwd3 } from "node:process";
317246
317468
  function redactIfSensitive(key, value2) {
317247
317469
  if (SENSITIVE_KEYS.has(key) && typeof value2 === "string" && value2.length > 0) {
@@ -317322,7 +317544,7 @@ function handleShow(opts, config) {
317322
317544
  }
317323
317545
  }
317324
317546
  printSection("Config File");
317325
- printInfo(`~/.open-agents/config.json (${join91(homedir27(), ".open-agents", "config.json")})`);
317547
+ printInfo(`~/.open-agents/config.json (${join91(homedir28(), ".open-agents", "config.json")})`);
317326
317548
  printSection("Priority Chain");
317327
317549
  printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
317328
317550
  printInfo(" 2. Project .oa/settings.json (--local)");
@@ -318127,8 +318349,8 @@ function crashLog(label, err) {
318127
318349
  try {
318128
318350
  const { appendFileSync: appendFileSync7, mkdirSync: mkdirSync43 } = __require("node:fs");
318129
318351
  const { join: join94 } = __require("node:path");
318130
- const { homedir: homedir28 } = __require("node:os");
318131
- const logDir = join94(homedir28(), ".open-agents");
318352
+ const { homedir: homedir29 } = __require("node:os");
318353
+ const logDir = join94(homedir29(), ".open-agents");
318132
318354
  mkdirSync43(logDir, { recursive: true });
318133
318355
  appendFileSync7(join94(logDir, "crash.log"), logLine);
318134
318356
  } catch {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.187.149",
3
+ "version": "0.187.150",
4
4
  "description": "AI coding agent powered by open-source models (Ollama/vLLM) — interactive TUI with agentic tool-calling loop",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",