open-agents-ai 0.105.7 → 0.107.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +864 -451
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -5639,8 +5639,8 @@ function deleteCustomToolDefinition(name, scope, repoRoot) {
5639
5639
  const dir = scope === "project" && repoRoot ? projectToolsDir(repoRoot) : globalToolsDir();
5640
5640
  const filePath = join13(dir, `${name}.json`);
5641
5641
  if (existsSync10(filePath)) {
5642
- const { unlinkSync: unlinkSync10 } = __require("node:fs");
5643
- unlinkSync10(filePath);
5642
+ const { unlinkSync: unlinkSync11 } = __require("node:fs");
5643
+ unlinkSync11(filePath);
5644
5644
  return true;
5645
5645
  }
5646
5646
  return false;
@@ -7511,6 +7511,353 @@ ${result.filesCreated.join("\n")}`);
7511
7511
  }
7512
7512
  });
7513
7513
 
7514
+ // packages/execution/dist/tools/repl.js
7515
+ import { spawn as spawn6 } from "node:child_process";
7516
+ import { createServer } from "node:net";
7517
+ import { join as join18 } from "node:path";
7518
+ import { tmpdir as tmpdir3 } from "node:os";
7519
+ import { randomBytes as randomBytes2 } from "node:crypto";
7520
+ import { unlinkSync as unlinkSync2 } from "node:fs";
7521
+ var ReplTool;
7522
+ var init_repl = __esm({
7523
+ "packages/execution/dist/tools/repl.js"() {
7524
+ "use strict";
7525
+ ReplTool = class {
7526
+ name = "repl_exec";
7527
+ description = "Execute Python code in a persistent REPL environment. Variables, imports, and functions persist between calls within the same task. Use for data processing, analysis, and building up results across multiple steps. A special function llm_query(prompt, context='') is available to invoke the language model from within Python code for semantic analysis of text chunks. Write results to files or print them to see output.";
7528
+ parameters = {
7529
+ type: "object",
7530
+ properties: {
7531
+ code: {
7532
+ type: "string",
7533
+ description: "Python code to execute in the persistent REPL"
7534
+ },
7535
+ reset: {
7536
+ type: "boolean",
7537
+ description: "Reset the REPL state (kill process, clear all variables). Default: false"
7538
+ }
7539
+ },
7540
+ required: ["code"]
7541
+ };
7542
+ proc = null;
7543
+ ipcServer = null;
7544
+ ipcPath = null;
7545
+ cwd;
7546
+ llmQueryHandler = null;
7547
+ subCallCount = 0;
7548
+ maxSubCalls;
7549
+ execTimeout;
7550
+ constructor(cwd4, options) {
7551
+ this.cwd = cwd4;
7552
+ this.llmQueryHandler = options?.llmQueryHandler ?? null;
7553
+ this.maxSubCalls = options?.maxSubCalls ?? 50;
7554
+ this.execTimeout = options?.execTimeout ?? 6e4;
7555
+ }
7556
+ /** Set the llm_query handler (called after construction when backend is available) */
7557
+ setLlmQueryHandler(handler) {
7558
+ this.llmQueryHandler = handler;
7559
+ }
7560
+ /** Get the number of sub-calls made this session */
7561
+ getSubCallCount() {
7562
+ return this.subCallCount;
7563
+ }
7564
+ /**
7565
+ * Pre-load a large context string into the REPL as the `context` variable.
7566
+ * Used by prompt externalization (RLM paper §2, Principle 1: symbolic handle).
7567
+ * The context is stored as a Python string variable — the model can then
7568
+ * slice, search, and process it via repl_exec without it entering the LLM context.
7569
+ */
7570
+ async loadContext(content) {
7571
+ if (!this.proc || this.proc.killed || this.proc.exitCode !== null) {
7572
+ await this.startProcess();
7573
+ }
7574
+ const tempFile = join18(tmpdir3(), `oa-repl-ctx-${randomBytes2(6).toString("hex")}.txt`);
7575
+ const { writeFileSync: writeFs, unlinkSync: unlinkFs } = await import("node:fs");
7576
+ writeFs(tempFile, content, "utf8");
7577
+ const result = await this.executeCode(`with open(${JSON.stringify(tempFile)}, "r") as _f:
7578
+ context = _f.read()
7579
+ import os; os.unlink(${JSON.stringify(tempFile)})
7580
+ print(f"Context loaded: {len(context)} chars")`);
7581
+ try {
7582
+ unlinkFs(tempFile);
7583
+ } catch {
7584
+ }
7585
+ return result.success;
7586
+ }
7587
+ /**
7588
+ * Read a variable's value from the REPL environment.
7589
+ * Used by FINAL_VAR to extract the task output (RLM paper §2, Principle 2).
7590
+ */
7591
+ async readVariable(varName) {
7592
+ if (!this.proc || this.proc.killed || this.proc.exitCode !== null)
7593
+ return null;
7594
+ const result = await this.executeCode(`try:
7595
+ print(str(${varName}))
7596
+ except NameError:
7597
+ print("__OA_VAR_NOT_FOUND__")`);
7598
+ if (!result.success || result.output.includes("__OA_VAR_NOT_FOUND__"))
7599
+ return null;
7600
+ return result.output.trim();
7601
+ }
7602
+ async execute(args) {
7603
+ const code = String(args.code ?? "");
7604
+ const reset = Boolean(args.reset);
7605
+ if (reset) {
7606
+ await this.dispose();
7607
+ return { success: true, output: "REPL state cleared.", durationMs: 0 };
7608
+ }
7609
+ if (!code.trim()) {
7610
+ return { success: false, output: "No code provided.", error: "Empty code", durationMs: 0 };
7611
+ }
7612
+ const start = performance.now();
7613
+ try {
7614
+ if (!this.proc || this.proc.killed || this.proc.exitCode !== null) {
7615
+ await this.startProcess();
7616
+ }
7617
+ const result = await this.executeCode(code);
7618
+ return { ...result, durationMs: performance.now() - start };
7619
+ } catch (err) {
7620
+ const msg = err instanceof Error ? err.message : String(err);
7621
+ return { success: false, output: `REPL error: ${msg}`, error: msg, durationMs: performance.now() - start };
7622
+ }
7623
+ }
7624
+ // ── Process lifecycle ────────────────────────────────────────────────────
7625
+ async startProcess() {
7626
+ await this.startIpcServer();
7627
+ this.proc = spawn6("python3", ["-u", "-i", "-q"], {
7628
+ cwd: this.cwd,
7629
+ stdio: ["pipe", "pipe", "pipe"],
7630
+ env: {
7631
+ ...process.env,
7632
+ PYTHONUNBUFFERED: "1",
7633
+ PYTHONDONTWRITEBYTECODE: "1",
7634
+ OA_LLM_QUERY_SOCKET: this.ipcPath ?? ""
7635
+ }
7636
+ });
7637
+ this.proc.on("error", () => {
7638
+ });
7639
+ const initCode = this.buildInitCode();
7640
+ await this.executeCode(initCode, true);
7641
+ }
7642
+ buildInitCode() {
7643
+ return `
7644
+ import sys, os, json, socket
7645
+
7646
+ def llm_query(prompt, context=""):
7647
+ """Invoke the language model on a sub-prompt. Returns the model's text response.
7648
+ Use for semantic analysis, summarization, or reasoning about text chunks.
7649
+ Args:
7650
+ prompt: The question/instruction for the model
7651
+ context: Additional text context (max ~500K chars)
7652
+ Returns: Model's text response as a string
7653
+ """
7654
+ sock_path = os.environ.get("OA_LLM_QUERY_SOCKET", "")
7655
+ if not sock_path:
7656
+ return "[llm_query unavailable: no IPC socket]"
7657
+ sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
7658
+ try:
7659
+ sock.connect(sock_path)
7660
+ request = json.dumps({"prompt": str(prompt), "context": str(context)[:500000]})
7661
+ # Send length-prefixed message
7662
+ data = request.encode("utf-8")
7663
+ sock.sendall(len(data).to_bytes(4, "big") + data)
7664
+ # Read length-prefixed response
7665
+ length_bytes = b""
7666
+ while len(length_bytes) < 4:
7667
+ chunk = sock.recv(4 - len(length_bytes))
7668
+ if not chunk:
7669
+ return "[llm_query: connection closed]"
7670
+ length_bytes += chunk
7671
+ resp_len = int.from_bytes(length_bytes, "big")
7672
+ resp_data = b""
7673
+ while len(resp_data) < resp_len:
7674
+ chunk = sock.recv(min(resp_len - len(resp_data), 65536))
7675
+ if not chunk:
7676
+ break
7677
+ resp_data += chunk
7678
+ result = json.loads(resp_data.decode("utf-8"))
7679
+ if "error" in result:
7680
+ return f"[llm_query error: {result['error']}]"
7681
+ return result.get("response", "")
7682
+ except Exception as e:
7683
+ return f"[llm_query error: {e}]"
7684
+ finally:
7685
+ sock.close()
7686
+
7687
+ # Signal REPL ready
7688
+ print("__OA_REPL_READY__")
7689
+ `.trim();
7690
+ }
7691
+ // ── IPC Server (for llm_query bridge) ──────────────────────────────────
7692
+ async startIpcServer() {
7693
+ if (this.ipcServer)
7694
+ return;
7695
+ const sockId = randomBytes2(8).toString("hex");
7696
+ this.ipcPath = join18(tmpdir3(), `oa-repl-ipc-${sockId}.sock`);
7697
+ return new Promise((resolve32, reject) => {
7698
+ this.ipcServer = createServer((conn) => {
7699
+ let buffer = new Uint8Array(0);
7700
+ conn.on("data", (chunk) => {
7701
+ const combined = new Uint8Array(buffer.length + chunk.length);
7702
+ combined.set(buffer, 0);
7703
+ combined.set(chunk, buffer.length);
7704
+ buffer = combined;
7705
+ this.processIpcBuffer(conn, buffer).then((remaining) => {
7706
+ buffer = remaining;
7707
+ });
7708
+ });
7709
+ conn.on("error", () => {
7710
+ });
7711
+ });
7712
+ this.ipcServer.on("error", reject);
7713
+ this.ipcServer.listen(this.ipcPath, () => resolve32());
7714
+ });
7715
+ }
7716
+ async processIpcBuffer(conn, input) {
7717
+ let buffer = input;
7718
+ while (buffer.length >= 4) {
7719
+ const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
7720
+ const msgLen = view.getUint32(0, false);
7721
+ if (buffer.length < 4 + msgLen)
7722
+ break;
7723
+ const msgData = new TextDecoder().decode(buffer.subarray(4, 4 + msgLen));
7724
+ buffer = buffer.subarray(4 + msgLen);
7725
+ let response;
7726
+ try {
7727
+ const req = JSON.parse(msgData);
7728
+ if (!this.llmQueryHandler) {
7729
+ response = { error: "llm_query handler not configured" };
7730
+ } else if (this.subCallCount >= this.maxSubCalls) {
7731
+ response = { error: `Sub-call limit reached (${this.maxSubCalls})` };
7732
+ } else {
7733
+ this.subCallCount++;
7734
+ const result = await this.llmQueryHandler(req.prompt, req.context);
7735
+ response = { response: result };
7736
+ }
7737
+ } catch (err) {
7738
+ response = { error: err instanceof Error ? err.message : String(err) };
7739
+ }
7740
+ const respBytes = new TextEncoder().encode(JSON.stringify(response));
7741
+ const header = new Uint8Array(4);
7742
+ new DataView(header.buffer).setUint32(0, respBytes.length, false);
7743
+ const packet = new Uint8Array(4 + respBytes.length);
7744
+ packet.set(header, 0);
7745
+ packet.set(respBytes, 4);
7746
+ try {
7747
+ conn.write(packet);
7748
+ } catch {
7749
+ }
7750
+ }
7751
+ return buffer;
7752
+ }
7753
+ // ── Code execution ─────────────────────────────────────────────────────
7754
+ executeCode(code, isInit = false) {
7755
+ return new Promise((resolve32) => {
7756
+ if (!this.proc?.stdin || !this.proc?.stdout || !this.proc?.stderr) {
7757
+ resolve32({ success: false, output: "REPL process not available", error: "No process", durationMs: 0 });
7758
+ return;
7759
+ }
7760
+ const sentinel = `__OA_SENTINEL_${randomBytes2(6).toString("hex")}__`;
7761
+ let stdout = "";
7762
+ let stderr = "";
7763
+ let resolved = false;
7764
+ const timeout = setTimeout(() => {
7765
+ if (!resolved) {
7766
+ resolved = true;
7767
+ resolve32({
7768
+ success: false,
7769
+ output: stdout || "Execution timed out",
7770
+ error: `Timeout after ${this.execTimeout / 1e3}s`,
7771
+ durationMs: this.execTimeout
7772
+ });
7773
+ }
7774
+ }, this.execTimeout);
7775
+ const onStdout = (data) => {
7776
+ const text = data.toString();
7777
+ stdout += text;
7778
+ if (stdout.includes(sentinel)) {
7779
+ cleanup();
7780
+ const cleanOutput = stdout.split(sentinel)[0].trim();
7781
+ if (isInit) {
7782
+ const ready = cleanOutput.includes("__OA_REPL_READY__");
7783
+ const displayOutput = cleanOutput.replace("__OA_REPL_READY__", "").trim();
7784
+ resolve32({
7785
+ success: ready,
7786
+ output: displayOutput || "REPL initialized",
7787
+ durationMs: 0
7788
+ });
7789
+ } else {
7790
+ resolve32({
7791
+ success: true,
7792
+ output: cleanOutput || "(no output)",
7793
+ durationMs: 0
7794
+ });
7795
+ }
7796
+ }
7797
+ if (stdout.length > 2e5) {
7798
+ cleanup();
7799
+ resolve32({
7800
+ success: true,
7801
+ output: stdout.slice(0, 2e5) + "\n[output truncated at 200KB]",
7802
+ durationMs: 0
7803
+ });
7804
+ }
7805
+ };
7806
+ const onStderr = (data) => {
7807
+ stderr += data.toString();
7808
+ if (stderr.length > 5e4) {
7809
+ stderr = stderr.slice(0, 5e4) + "\n[stderr truncated]";
7810
+ }
7811
+ };
7812
+ const cleanup = () => {
7813
+ if (resolved)
7814
+ return;
7815
+ resolved = true;
7816
+ clearTimeout(timeout);
7817
+ this.proc?.stdout?.removeListener("data", onStdout);
7818
+ this.proc?.stderr?.removeListener("data", onStderr);
7819
+ };
7820
+ this.proc.stdout.on("data", onStdout);
7821
+ this.proc.stderr.on("data", onStderr);
7822
+ const wrappedCode = `
7823
+ try:
7824
+ exec(${JSON.stringify(code)})
7825
+ except Exception as __oa_e:
7826
+ import traceback as __oa_tb
7827
+ print(f"Error: {__oa_e}")
7828
+ __oa_tb.print_exc()
7829
+ print("${sentinel}")
7830
+ `;
7831
+ this.proc.stdin.write(wrappedCode + "\n");
7832
+ });
7833
+ }
7834
+ // ── Cleanup ────────────────────────────────────────────────────────────
7835
+ async dispose() {
7836
+ if (this.proc && !this.proc.killed) {
7837
+ try {
7838
+ this.proc.stdin?.end();
7839
+ this.proc.kill("SIGTERM");
7840
+ } catch {
7841
+ }
7842
+ this.proc = null;
7843
+ }
7844
+ if (this.ipcServer) {
7845
+ this.ipcServer.close();
7846
+ this.ipcServer = null;
7847
+ }
7848
+ if (this.ipcPath) {
7849
+ try {
7850
+ unlinkSync2(this.ipcPath);
7851
+ } catch {
7852
+ }
7853
+ this.ipcPath = null;
7854
+ }
7855
+ this.subCallCount = 0;
7856
+ }
7857
+ };
7858
+ }
7859
+ });
7860
+
7514
7861
  // packages/execution/dist/tools/structured-read.js
7515
7862
  import { readFile as readFile8, stat as stat2 } from "node:fs/promises";
7516
7863
  import { resolve as resolve15, extname as extname5 } from "node:path";
@@ -7848,8 +8195,8 @@ ${parts.join("\n\n")}`,
7848
8195
 
7849
8196
  // packages/execution/dist/tools/vision.js
7850
8197
  import { readFileSync as readFileSync11, existsSync as existsSync14, statSync as statSync5 } from "node:fs";
7851
- import { execSync as execSync11, spawn as spawn6 } from "node:child_process";
7852
- import { resolve as resolve16, extname as extname6, basename as basename5, dirname as dirname6, join as join18 } from "node:path";
8198
+ import { execSync as execSync11, spawn as spawn7 } from "node:child_process";
8199
+ import { resolve as resolve16, extname as extname6, basename as basename5, dirname as dirname6, join as join19 } from "node:path";
7853
8200
  import { fileURLToPath as fileURLToPath2 } from "node:url";
7854
8201
  async function probeStation(endpoint) {
7855
8202
  try {
@@ -7864,7 +8211,7 @@ async function probeStation(endpoint) {
7864
8211
  }
7865
8212
  }
7866
8213
  function findStationBinary() {
7867
- const oaVenvPython = join18(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "python");
8214
+ const oaVenvPython = join19(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "python");
7868
8215
  if (existsSync14(oaVenvPython)) {
7869
8216
  try {
7870
8217
  execSync11(`${JSON.stringify(oaVenvPython)} -c "import moondream_station"`, { stdio: "pipe", timeout: 5e3 });
@@ -7872,7 +8219,7 @@ function findStationBinary() {
7872
8219
  } catch {
7873
8220
  }
7874
8221
  }
7875
- const oaVenvBin = join18(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "moondream-station");
8222
+ const oaVenvBin = join19(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "moondream-station");
7876
8223
  if (existsSync14(oaVenvBin))
7877
8224
  return oaVenvBin;
7878
8225
  const thisDir = dirname6(fileURLToPath2(import.meta.url));
@@ -7906,7 +8253,7 @@ async function autoLaunchStation(port = 2020) {
7906
8253
  if (!existsSync14(launcherScript))
7907
8254
  return false;
7908
8255
  return new Promise((resolvePromise) => {
7909
- const child = spawn6(pythonBin, [launcherScript, "--port", String(port)], {
8256
+ const child = spawn7(pythonBin, [launcherScript, "--port", String(port)], {
7910
8257
  stdio: ["ignore", "pipe", "pipe"],
7911
8258
  detached: true
7912
8259
  });
@@ -8223,8 +8570,8 @@ ${response}`, durationMs: performance.now() - start };
8223
8570
  // packages/execution/dist/tools/desktop-click.js
8224
8571
  import { readFileSync as readFileSync12, existsSync as existsSync15 } from "node:fs";
8225
8572
  import { execSync as execSync12 } from "node:child_process";
8226
- import { tmpdir as tmpdir3 } from "node:os";
8227
- import { join as join19, dirname as dirname7 } from "node:path";
8573
+ import { tmpdir as tmpdir4 } from "node:os";
8574
+ import { join as join20, dirname as dirname7 } from "node:path";
8228
8575
  import { fileURLToPath as fileURLToPath3 } from "node:url";
8229
8576
  function hasCommand2(cmd) {
8230
8577
  try {
@@ -8348,7 +8695,7 @@ for i in range(${clicks}):
8348
8695
  } catch {
8349
8696
  }
8350
8697
  try {
8351
- const venvPy = join19(__dirname2, "../../../../.moondream-venv/bin/python");
8698
+ const venvPy = join20(__dirname2, "../../../../.moondream-venv/bin/python");
8352
8699
  execSync12(`DISPLAY=:0 ${JSON.stringify(venvPy)} -c "${pyScript}"`, { stdio: "pipe", timeout: 5e3 });
8353
8700
  return;
8354
8701
  } catch {
@@ -8440,7 +8787,7 @@ var init_desktop_click = __esm({
8440
8787
  if (delayMs > 0) {
8441
8788
  await new Promise((r) => setTimeout(r, delayMs));
8442
8789
  }
8443
- const screenshotPath = join19(tmpdir3(), `oa-desktop-click-${Date.now()}.png`);
8790
+ const screenshotPath = join20(tmpdir4(), `oa-desktop-click-${Date.now()}.png`);
8444
8791
  captureScreenshot(screenshotPath);
8445
8792
  const dims = getImageDimensions2(screenshotPath);
8446
8793
  if (!dims) {
@@ -8615,7 +8962,7 @@ Screenshot: ${screenshotPath}`,
8615
8962
  if (delayMs > 0) {
8616
8963
  await new Promise((r) => setTimeout(r, delayMs));
8617
8964
  }
8618
- const screenshotPath = join19(tmpdir3(), `oa-desktop-describe-${Date.now()}.png`);
8965
+ const screenshotPath = join20(tmpdir4(), `oa-desktop-describe-${Date.now()}.png`);
8619
8966
  captureScreenshot(screenshotPath);
8620
8967
  const dims = getImageDimensions2(screenshotPath);
8621
8968
  const imageBuffer = readFileSync12(screenshotPath);
@@ -8853,10 +9200,10 @@ Language: ${language}
8853
9200
  });
8854
9201
 
8855
9202
  // packages/execution/dist/tools/pdf-to-text.js
8856
- import { existsSync as existsSync17, statSync as statSync7, readFileSync as readFileSync13, unlinkSync as unlinkSync2 } from "node:fs";
8857
- import { resolve as resolve18, basename as basename7, join as join20 } from "node:path";
9203
+ import { existsSync as existsSync17, statSync as statSync7, readFileSync as readFileSync13, unlinkSync as unlinkSync3 } from "node:fs";
9204
+ import { resolve as resolve18, basename as basename7, join as join21 } from "node:path";
8858
9205
  import { execSync as execSync14 } from "node:child_process";
8859
- import { tmpdir as tmpdir4 } from "node:os";
9206
+ import { tmpdir as tmpdir5 } from "node:os";
8860
9207
  var PdfToTextTool;
8861
9208
  var init_pdf_to_text = __esm({
8862
9209
  "packages/execution/dist/tools/pdf-to-text.js"() {
@@ -9008,7 +9355,7 @@ ${text}`,
9008
9355
  if (!ocrCheck.available || !tesCheck.available || !gsCheck.available) {
9009
9356
  return null;
9010
9357
  }
9011
- const tmpPdf = join20(tmpdir4(), `oa-ocr-${Date.now()}.pdf`);
9358
+ const tmpPdf = join21(tmpdir5(), `oa-ocr-${Date.now()}.pdf`);
9012
9359
  try {
9013
9360
  const ocrCmd = `ocrmypdf -l ${language} --skip-text ${JSON.stringify(inputPath)} ${JSON.stringify(tmpPdf)}`;
9014
9361
  execSync14(ocrCmd, { stdio: "pipe", timeout: 6e5 });
@@ -9028,7 +9375,7 @@ ${text}`,
9028
9375
  return null;
9029
9376
  } finally {
9030
9377
  try {
9031
- unlinkSync2(tmpPdf);
9378
+ unlinkSync3(tmpPdf);
9032
9379
  } catch {
9033
9380
  }
9034
9381
  }
@@ -9039,10 +9386,10 @@ ${text}`,
9039
9386
 
9040
9387
  // packages/execution/dist/tools/ocr-image-advanced.js
9041
9388
  import { existsSync as existsSync18, statSync as statSync8 } from "node:fs";
9042
- import { resolve as resolve19, basename as basename8, dirname as dirname8, join as join21 } from "node:path";
9389
+ import { resolve as resolve19, basename as basename8, dirname as dirname8, join as join22 } from "node:path";
9043
9390
  import { execSync as execSync15 } from "node:child_process";
9044
9391
  import { fileURLToPath as fileURLToPath4 } from "node:url";
9045
- import { homedir as homedir7, tmpdir as tmpdir5 } from "node:os";
9392
+ import { homedir as homedir7, tmpdir as tmpdir6 } from "node:os";
9046
9393
  function findOcrScript() {
9047
9394
  const thisDir = dirname8(fileURLToPath4(import.meta.url));
9048
9395
  const devPath3 = resolve19(thisDir, "../../scripts/ocr-advanced.py");
@@ -9057,7 +9404,7 @@ function findOcrScript() {
9057
9404
  return null;
9058
9405
  }
9059
9406
  function findPython() {
9060
- const venvPython = join21(homedir7(), ".open-agents", "venv", "bin", "python");
9407
+ const venvPython = join22(homedir7(), ".open-agents", "venv", "bin", "python");
9061
9408
  if (existsSync18(venvPython)) {
9062
9409
  try {
9063
9410
  execSync15(`${JSON.stringify(venvPython)} -c "import cv2, pytesseract, numpy, PIL"`, {
@@ -9203,7 +9550,7 @@ var init_ocr_image_advanced = __esm({
9203
9550
  cmdParts.push("--output-dir", JSON.stringify(resolve19(this.workingDir, outputDir)));
9204
9551
  let debugDir;
9205
9552
  if (debug) {
9206
- debugDir = join21(tmpdir5(), `oa-ocr-debug-${Date.now()}`);
9553
+ debugDir = join22(tmpdir6(), `oa-ocr-debug-${Date.now()}`);
9207
9554
  cmdParts.push("--debug-dir", debugDir);
9208
9555
  }
9209
9556
  try {
@@ -9302,7 +9649,7 @@ var init_ocr_image_advanced = __esm({
9302
9649
  if (region) {
9303
9650
  try {
9304
9651
  const [x, y, w, h] = region.split(",").map(Number);
9305
- const croppedPath = join21(tmpdir5(), `oa-ocr-crop-${Date.now()}.png`);
9652
+ const croppedPath = join22(tmpdir6(), `oa-ocr-crop-${Date.now()}.png`);
9306
9653
  execSync15(`convert ${JSON.stringify(imagePath)} -crop ${w}x${h}+${x}+${y} +repage ${JSON.stringify(croppedPath)}`, { stdio: "pipe", timeout: 1e4 });
9307
9654
  inputPath = croppedPath;
9308
9655
  } catch {
@@ -9341,20 +9688,20 @@ Note: Advanced Python pipeline not available \u2014 install pytesseract, opencv-
9341
9688
  });
9342
9689
 
9343
9690
  // packages/execution/dist/tools/browser-action.js
9344
- import { execSync as execSync16, spawn as spawn7 } from "node:child_process";
9691
+ import { execSync as execSync16, spawn as spawn8 } from "node:child_process";
9345
9692
  import { existsSync as existsSync19, readFileSync as readFileSync14 } from "node:fs";
9346
- import { join as join22, dirname as dirname9 } from "node:path";
9693
+ import { join as join23, dirname as dirname9 } from "node:path";
9347
9694
  import { fileURLToPath as fileURLToPath5 } from "node:url";
9348
9695
  function findScrapeScript() {
9349
9696
  const candidates = [
9350
9697
  // Published npm package: dist/scripts/web_scrape.py
9351
- join22(__dirname3, "scripts", "web_scrape.py"),
9698
+ join23(__dirname3, "scripts", "web_scrape.py"),
9352
9699
  // Published npm package (from node_modules): node_modules/open-agents-ai/dist/scripts/
9353
- join22(__dirname3, "..", "node_modules", "open-agents-ai", "dist", "scripts", "web_scrape.py"),
9700
+ join23(__dirname3, "..", "node_modules", "open-agents-ai", "dist", "scripts", "web_scrape.py"),
9354
9701
  // Dev monorepo: packages/execution/src/tools/../../scripts/
9355
- join22(__dirname3, "..", "..", "scripts", "web_scrape.py"),
9702
+ join23(__dirname3, "..", "..", "scripts", "web_scrape.py"),
9356
9703
  // Dev monorepo alt: packages/execution/scripts/
9357
- join22(__dirname3, "..", "scripts", "web_scrape.py")
9704
+ join23(__dirname3, "..", "scripts", "web_scrape.py")
9358
9705
  ];
9359
9706
  return candidates.find((p) => existsSync19(p)) || candidates[0];
9360
9707
  }
@@ -9389,7 +9736,7 @@ async function launchService() {
9389
9736
  if (!existsSync19(SCRAPE_SCRIPT)) {
9390
9737
  return `Scrape service script not found at ${SCRAPE_SCRIPT}`;
9391
9738
  }
9392
- serviceProcess = spawn7(python, [SCRAPE_SCRIPT], {
9739
+ serviceProcess = spawn8(python, [SCRAPE_SCRIPT], {
9393
9740
  stdio: "ignore",
9394
9741
  detached: true,
9395
9742
  env: {
@@ -9607,9 +9954,9 @@ var init_browser_action = __esm({
9607
9954
  });
9608
9955
 
9609
9956
  // packages/execution/dist/tools/autoresearch.js
9610
- import { execSync as execSync17, spawn as spawn8 } from "node:child_process";
9957
+ import { execSync as execSync17, spawn as spawn9 } from "node:child_process";
9611
9958
  import { existsSync as existsSync20, readFileSync as readFileSync15, writeFileSync as writeFileSync6, mkdirSync as mkdirSync6, appendFileSync, copyFileSync } from "node:fs";
9612
- import { join as join23, resolve as resolve20, dirname as dirname10 } from "node:path";
9959
+ import { join as join24, resolve as resolve20, dirname as dirname10 } from "node:path";
9613
9960
  import { fileURLToPath as fileURLToPath6 } from "node:url";
9614
9961
  function findAutoresearchScript(scriptName) {
9615
9962
  const thisDir = dirname10(fileURLToPath6(import.meta.url));
@@ -9711,7 +10058,7 @@ Requires: NVIDIA GPU, Python 3.10+, uv (astral.sh package manager).`;
9711
10058
  async execute(args) {
9712
10059
  const start = Date.now();
9713
10060
  const action = String(args["action"] ?? "status");
9714
- const workspacePath = String(args["workspace"] ?? join23(this.repoRoot, ".oa", "autoresearch"));
10061
+ const workspacePath = String(args["workspace"] ?? join24(this.repoRoot, ".oa", "autoresearch"));
9715
10062
  try {
9716
10063
  switch (action) {
9717
10064
  case "setup":
@@ -9752,13 +10099,13 @@ Requires: NVIDIA GPU, Python 3.10+, uv (astral.sh package manager).`;
9752
10099
  const prepareScript = findAutoresearchScript("autoresearch-prepare.py");
9753
10100
  const trainScript = findAutoresearchScript("autoresearch-train.py");
9754
10101
  if (prepareScript) {
9755
- copyFileSync(prepareScript, join23(workspace, "prepare.py"));
10102
+ copyFileSync(prepareScript, join24(workspace, "prepare.py"));
9756
10103
  output.push("Copied prepare.py template");
9757
10104
  } else {
9758
10105
  return { success: false, output: output.join("\n"), error: "autoresearch-prepare.py template not found in distribution", durationMs: Date.now() - start };
9759
10106
  }
9760
10107
  if (trainScript) {
9761
- copyFileSync(trainScript, join23(workspace, "train.py"));
10108
+ copyFileSync(trainScript, join24(workspace, "train.py"));
9762
10109
  output.push("Copied train.py template");
9763
10110
  } else {
9764
10111
  return { success: false, output: output.join("\n"), error: "autoresearch-train.py template not found in distribution", durationMs: Date.now() - start };
@@ -9790,7 +10137,7 @@ name = "pytorch-cu128"
9790
10137
  url = "https://download.pytorch.org/whl/cu128"
9791
10138
  explicit = true
9792
10139
  `;
9793
- writeFileSync6(join23(workspace, "pyproject.toml"), pyprojectContent, "utf-8");
10140
+ writeFileSync6(join24(workspace, "pyproject.toml"), pyprojectContent, "utf-8");
9794
10141
  output.push("Created pyproject.toml");
9795
10142
  try {
9796
10143
  execSync17("git rev-parse --git-dir", { cwd: workspace, encoding: "utf-8", timeout: 5e3 });
@@ -9832,7 +10179,7 @@ explicit = true
9832
10179
  const e = err;
9833
10180
  output.push(`Data prep warning: ${(e.stderr ?? e.stdout ?? "failed").slice(0, 500)}`);
9834
10181
  }
9835
- const tsvPath = join23(workspace, "results.tsv");
10182
+ const tsvPath = join24(workspace, "results.tsv");
9836
10183
  if (!existsSync20(tsvPath)) {
9837
10184
  writeFileSync6(tsvPath, "commit val_bpb memory_gb status description\n", "utf-8");
9838
10185
  output.push("Created results.tsv");
@@ -9854,10 +10201,10 @@ Next steps:
9854
10201
  }
9855
10202
  // ── Run experiment ─────────────────────────────────────────────────────
9856
10203
  async run(workspace, args, start) {
9857
- if (!existsSync20(join23(workspace, "train.py"))) {
10204
+ if (!existsSync20(join24(workspace, "train.py"))) {
9858
10205
  return { success: false, output: "", error: `No train.py found in ${workspace}. Run autoresearch(action="setup") first.`, durationMs: Date.now() - start };
9859
10206
  }
9860
- if (!existsSync20(join23(workspace, ".venv")) && existsSync20(join23(workspace, "pyproject.toml"))) {
10207
+ if (!existsSync20(join24(workspace, ".venv")) && existsSync20(join24(workspace, "pyproject.toml"))) {
9861
10208
  try {
9862
10209
  execSync17("uv sync 2>&1", { cwd: workspace, encoding: "utf-8", timeout: 3e5 });
9863
10210
  } catch {
@@ -9865,9 +10212,9 @@ Next steps:
9865
10212
  }
9866
10213
  const timeoutMin = Number(args["timeout_minutes"] ?? 10);
9867
10214
  const timeoutMs = timeoutMin * 60 * 1e3;
9868
- const logPath = join23(workspace, "run.log");
10215
+ const logPath = join24(workspace, "run.log");
9869
10216
  return new Promise((resolveResult) => {
9870
- const proc = spawn8("uv", ["run", "train.py"], {
10217
+ const proc = spawn9("uv", ["run", "train.py"], {
9871
10218
  cwd: workspace,
9872
10219
  timeout: timeoutMs,
9873
10220
  stdio: ["pipe", "pipe", "pipe"],
@@ -9936,7 +10283,7 @@ ${fullLog.slice(-2e3)}`,
9936
10283
  return;
9937
10284
  }
9938
10285
  try {
9939
- writeFileSync6(join23(workspace, ".last-result.json"), JSON.stringify(result, null, 2), "utf-8");
10286
+ writeFileSync6(join24(workspace, ".last-result.json"), JSON.stringify(result, null, 2), "utf-8");
9940
10287
  } catch {
9941
10288
  }
9942
10289
  const memGB = (result.peak_vram_mb / 1024).toFixed(1);
@@ -9972,7 +10319,7 @@ ${fullLog.slice(-2e3)}`,
9972
10319
  }
9973
10320
  // ── Results ────────────────────────────────────────────────────────────
9974
10321
  getResults(workspace, start) {
9975
- const tsvPath = join23(workspace, "results.tsv");
10322
+ const tsvPath = join24(workspace, "results.tsv");
9976
10323
  if (!existsSync20(tsvPath)) {
9977
10324
  return { success: false, output: "", error: `No results.tsv found. Run autoresearch(action="setup") first.`, durationMs: Date.now() - start };
9978
10325
  }
@@ -9999,7 +10346,7 @@ ${fullLog.slice(-2e3)}`,
9999
10346
  // ── Status ─────────────────────────────────────────────────────────────
10000
10347
  getStatus(workspace, start) {
10001
10348
  const output = [];
10002
- if (!existsSync20(join23(workspace, "train.py"))) {
10349
+ if (!existsSync20(join24(workspace, "train.py"))) {
10003
10350
  return {
10004
10351
  success: true,
10005
10352
  output: `Autoresearch workspace not initialized at ${workspace}.
@@ -10022,7 +10369,7 @@ Run autoresearch(action="setup") to begin.`,
10022
10369
  } catch {
10023
10370
  output.push("GPU: not detected");
10024
10371
  }
10025
- const lastResultPath = join23(workspace, ".last-result.json");
10372
+ const lastResultPath = join24(workspace, ".last-result.json");
10026
10373
  if (existsSync20(lastResultPath)) {
10027
10374
  try {
10028
10375
  const last = JSON.parse(readFileSync15(lastResultPath, "utf-8"));
@@ -10030,20 +10377,20 @@ Run autoresearch(action="setup") to begin.`,
10030
10377
  } catch {
10031
10378
  }
10032
10379
  }
10033
- const tsvPath = join23(workspace, "results.tsv");
10380
+ const tsvPath = join24(workspace, "results.tsv");
10034
10381
  if (existsSync20(tsvPath)) {
10035
10382
  const lines = readFileSync15(tsvPath, "utf-8").trim().split("\n");
10036
10383
  output.push(`Experiments recorded: ${lines.length - 1}`);
10037
10384
  }
10038
- const cacheDir = join23(process.env["HOME"] ?? "~", ".cache", "autoresearch");
10385
+ const cacheDir = join24(process.env["HOME"] ?? "~", ".cache", "autoresearch");
10039
10386
  output.push(`Data cache: ${existsSync20(cacheDir) ? "present" : "not found"} (${cacheDir})`);
10040
10387
  return { success: true, output: output.join("\n"), durationMs: Date.now() - start };
10041
10388
  }
10042
10389
  // ── Keep / Discard ─────────────────────────────────────────────────────
10043
10390
  keepExperiment(workspace, args, start) {
10044
10391
  const desc = String(args["description"] ?? "experiment");
10045
- const tsvPath = join23(workspace, "results.tsv");
10046
- const lastResultPath = join23(workspace, ".last-result.json");
10392
+ const tsvPath = join24(workspace, "results.tsv");
10393
+ const lastResultPath = join24(workspace, ".last-result.json");
10047
10394
  let valBpb = args["val_bpb"];
10048
10395
  let memGb = args["memory_gb"];
10049
10396
  if ((valBpb === void 0 || memGb === void 0) && existsSync20(lastResultPath)) {
@@ -10081,8 +10428,8 @@ Branch advanced. Ready for next experiment.`,
10081
10428
  }
10082
10429
  discardExperiment(workspace, args, start) {
10083
10430
  const desc = String(args["description"] ?? "experiment");
10084
- const tsvPath = join23(workspace, "results.tsv");
10085
- const lastResultPath = join23(workspace, ".last-result.json");
10431
+ const tsvPath = join24(workspace, "results.tsv");
10432
+ const lastResultPath = join24(workspace, ".last-result.json");
10086
10433
  let valBpb = args["val_bpb"];
10087
10434
  let memGb = args["memory_gb"];
10088
10435
  if ((valBpb === void 0 || memGb === void 0) && existsSync20(lastResultPath)) {
@@ -10129,8 +10476,8 @@ train.py reverted to last kept state. Ready for next experiment.`,
10129
10476
  // packages/execution/dist/tools/scheduler.js
10130
10477
  import { execSync as execSync18, exec as execCb } from "node:child_process";
10131
10478
  import { readFile as readFile9, writeFile as writeFile8, mkdir as mkdir4 } from "node:fs/promises";
10132
- import { resolve as resolve21, join as join24 } from "node:path";
10133
- import { randomBytes as randomBytes2 } from "node:crypto";
10479
+ import { resolve as resolve21, join as join25 } from "node:path";
10480
+ import { randomBytes as randomBytes3 } from "node:crypto";
10134
10481
  function isValidCron(expr) {
10135
10482
  const parts = expr.trim().split(/\s+/);
10136
10483
  if (parts.length !== 5)
@@ -10213,7 +10560,7 @@ function installCronJob(task, workingDir) {
10213
10560
  const lines = getCurrentCrontab();
10214
10561
  const oaBin = findOaBinary();
10215
10562
  const logDir = resolve21(workingDir, ".oa", "scheduled", "logs");
10216
- const logFile = join24(logDir, `${task.id}.log`);
10563
+ const logFile = join25(logDir, `${task.id}.log`);
10217
10564
  const storeFile = resolve21(workingDir, ".oa", "scheduled", "tasks.json");
10218
10565
  const taskEscaped = task.task.replace(/'/g, "'\\''");
10219
10566
  const taskId = task.id;
@@ -10255,9 +10602,9 @@ async function loadStore(workingDir) {
10255
10602
  async function saveStore(workingDir, store) {
10256
10603
  const dir = resolve21(workingDir, ".oa", "scheduled");
10257
10604
  await mkdir4(dir, { recursive: true });
10258
- await mkdir4(join24(dir, "logs"), { recursive: true });
10605
+ await mkdir4(join25(dir, "logs"), { recursive: true });
10259
10606
  store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
10260
- await writeFile8(join24(dir, "tasks.json"), JSON.stringify(store, null, 2), "utf-8");
10607
+ await writeFile8(join25(dir, "tasks.json"), JSON.stringify(store, null, 2), "utf-8");
10261
10608
  }
10262
10609
  var SCHEDULE_PRESETS, CRON_MARKER, SchedulerTool;
10263
10610
  var init_scheduler = __esm({
@@ -10368,7 +10715,7 @@ var init_scheduler = __esm({
10368
10715
  durationMs: performance.now() - start
10369
10716
  };
10370
10717
  }
10371
- const id = `sched-${randomBytes2(4).toString("hex")}`;
10718
+ const id = `sched-${randomBytes3(4).toString("hex")}`;
10372
10719
  const oneShot = Boolean(args["one_shot"]);
10373
10720
  const maxRuns = typeof args["max_runs"] === "number" ? args["max_runs"] : void 0;
10374
10721
  const newTask = {
@@ -10491,8 +10838,8 @@ ${truncated}`, durationMs: performance.now() - start };
10491
10838
 
10492
10839
  // packages/execution/dist/tools/reminder.js
10493
10840
  import { readFile as readFile10, writeFile as writeFile9, mkdir as mkdir5 } from "node:fs/promises";
10494
- import { resolve as resolve22, join as join25 } from "node:path";
10495
- import { randomBytes as randomBytes3 } from "node:crypto";
10841
+ import { resolve as resolve22, join as join26 } from "node:path";
10842
+ import { randomBytes as randomBytes4 } from "node:crypto";
10496
10843
  function parseDueTime(due) {
10497
10844
  const lower = due.toLowerCase().trim();
10498
10845
  const now = /* @__PURE__ */ new Date();
@@ -10543,7 +10890,7 @@ function parseDueTime(due) {
10543
10890
  async function getStorePath(workingDir) {
10544
10891
  const dir = resolve22(workingDir, ".oa", "scheduled");
10545
10892
  await mkdir5(dir, { recursive: true });
10546
- return join25(dir, STORE_FILE);
10893
+ return join26(dir, STORE_FILE);
10547
10894
  }
10548
10895
  async function loadReminderStore(workingDir) {
10549
10896
  const storePath = await getStorePath(workingDir);
@@ -10689,7 +11036,7 @@ var init_reminder = __esm({
10689
11036
  dueAt = parsed.isoDate;
10690
11037
  dueDescription = parsed.description;
10691
11038
  }
10692
- const id = `rem-${randomBytes3(4).toString("hex")}`;
11039
+ const id = `rem-${randomBytes4(4).toString("hex")}`;
10693
11040
  const entry = {
10694
11041
  id,
10695
11042
  message,
@@ -10804,8 +11151,8 @@ var init_reminder = __esm({
10804
11151
 
10805
11152
  // packages/execution/dist/tools/agenda.js
10806
11153
  import { readFile as readFile11, writeFile as writeFile10, mkdir as mkdir6 } from "node:fs/promises";
10807
- import { resolve as resolve23, join as join26 } from "node:path";
10808
- import { randomBytes as randomBytes4 } from "node:crypto";
11154
+ import { resolve as resolve23, join as join27 } from "node:path";
11155
+ import { randomBytes as randomBytes5 } from "node:crypto";
10809
11156
  async function loadAttentionStore(workingDir) {
10810
11157
  const storePath = resolve23(workingDir, ".oa", "scheduled", "attention.json");
10811
11158
  try {
@@ -10819,7 +11166,7 @@ async function saveAttentionStore(workingDir, store) {
10819
11166
  const dir = resolve23(workingDir, ".oa", "scheduled");
10820
11167
  await mkdir6(dir, { recursive: true });
10821
11168
  store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
10822
- await writeFile10(join26(dir, "attention.json"), JSON.stringify(store, null, 2), "utf-8");
11169
+ await writeFile10(join27(dir, "attention.json"), JSON.stringify(store, null, 2), "utf-8");
10823
11170
  }
10824
11171
  async function getActiveAttentionItems(workingDir) {
10825
11172
  const store = await loadAttentionStore(workingDir);
@@ -11008,7 +11355,7 @@ ${sections.join("\n")}`,
11008
11355
  expiresAt = target.toISOString();
11009
11356
  }
11010
11357
  }
11011
- const id = `attn-${randomBytes4(4).toString("hex")}`;
11358
+ const id = `attn-${randomBytes5(4).toString("hex")}`;
11012
11359
  const item = {
11013
11360
  id,
11014
11361
  title,
@@ -11127,9 +11474,9 @@ ${sections.join("\n")}`,
11127
11474
  });
11128
11475
 
11129
11476
  // packages/execution/dist/tools/opencode.js
11130
- import { execSync as execSync19, spawn as spawn9 } from "node:child_process";
11477
+ import { execSync as execSync19, spawn as spawn10 } from "node:child_process";
11131
11478
  import { existsSync as existsSync21 } from "node:fs";
11132
- import { join as join27, resolve as resolve24 } from "node:path";
11479
+ import { join as join28, resolve as resolve24 } from "node:path";
11133
11480
  function findOpencode() {
11134
11481
  for (const cmd of ["opencode"]) {
11135
11482
  try {
@@ -11141,8 +11488,8 @@ function findOpencode() {
11141
11488
  }
11142
11489
  const homeDir = process.env.HOME || process.env.USERPROFILE || "";
11143
11490
  const candidates = [
11144
- join27(homeDir, ".opencode", "bin", "opencode"),
11145
- join27(homeDir, "bin", "opencode"),
11491
+ join28(homeDir, ".opencode", "bin", "opencode"),
11492
+ join28(homeDir, "bin", "opencode"),
11146
11493
  "/usr/local/bin/opencode"
11147
11494
  ];
11148
11495
  for (const p of candidates) {
@@ -11315,7 +11662,7 @@ var init_opencode = __esm({
11315
11662
  let output = "";
11316
11663
  const maxOutput = 5e5;
11317
11664
  let timedOut = false;
11318
- const child = spawn9(binary, cmdArgs, {
11665
+ const child = spawn10(binary, cmdArgs, {
11319
11666
  cwd: dir,
11320
11667
  env: { ...process.env, CI: "true", NONINTERACTIVE: "1" },
11321
11668
  stdio: ["ignore", "pipe", "pipe"]
@@ -11401,9 +11748,9 @@ var init_opencode = __esm({
11401
11748
  });
11402
11749
 
11403
11750
  // packages/execution/dist/tools/factory.js
11404
- import { execSync as execSync20, spawn as spawn10 } from "node:child_process";
11751
+ import { execSync as execSync20, spawn as spawn11 } from "node:child_process";
11405
11752
  import { existsSync as existsSync22 } from "node:fs";
11406
- import { join as join28 } from "node:path";
11753
+ import { join as join29 } from "node:path";
11407
11754
  function findDroid() {
11408
11755
  for (const cmd of ["droid"]) {
11409
11756
  try {
@@ -11415,8 +11762,8 @@ function findDroid() {
11415
11762
  }
11416
11763
  const homeDir = process.env.HOME || process.env.USERPROFILE || "";
11417
11764
  const candidates = [
11418
- join28(homeDir, ".factory", "bin", "droid"),
11419
- join28(homeDir, "bin", "droid"),
11765
+ join29(homeDir, ".factory", "bin", "droid"),
11766
+ join29(homeDir, "bin", "droid"),
11420
11767
  "/usr/local/bin/droid"
11421
11768
  ];
11422
11769
  for (const p of candidates) {
@@ -11620,7 +11967,7 @@ var init_factory = __esm({
11620
11967
  let output = "";
11621
11968
  const maxOutput = 5e5;
11622
11969
  let timedOut = false;
11623
- const child = spawn10(binary, cmdArgs, {
11970
+ const child = spawn11(binary, cmdArgs, {
11624
11971
  cwd: dir,
11625
11972
  env: { ...process.env },
11626
11973
  stdio: ["ignore", "pipe", "pipe"]
@@ -11712,8 +12059,8 @@ var init_factory = __esm({
11712
12059
  // packages/execution/dist/tools/cron-agent.js
11713
12060
  import { execSync as execSync21 } from "node:child_process";
11714
12061
  import { readFile as readFile12, writeFile as writeFile11, mkdir as mkdir7 } from "node:fs/promises";
11715
- import { resolve as resolve25, join as join29 } from "node:path";
11716
- import { randomBytes as randomBytes5 } from "node:crypto";
12062
+ import { resolve as resolve25, join as join30 } from "node:path";
12063
+ import { randomBytes as randomBytes6 } from "node:crypto";
11717
12064
  function isValidCron2(expr) {
11718
12065
  const parts = expr.trim().split(/\s+/);
11719
12066
  if (parts.length !== 5)
@@ -11798,7 +12145,7 @@ function installCronAgentJob(job, workingDir) {
11798
12145
  const lines = getCurrentCrontab2();
11799
12146
  const oaBin = findOaBinary2();
11800
12147
  const logDir = resolve25(workingDir, ".oa", "cron-agents", "logs");
11801
- const logFile = join29(logDir, `${job.id}.log`);
12148
+ const logFile = join30(logDir, `${job.id}.log`);
11802
12149
  const storeFile = resolve25(workingDir, ".oa", "cron-agents", "store.json");
11803
12150
  const taskEscaped = job.task.replace(/'/g, "'\\''");
11804
12151
  const jobId = job.id;
@@ -11837,9 +12184,9 @@ async function loadStore2(workingDir) {
11837
12184
  async function saveStore2(workingDir, store) {
11838
12185
  const dir = resolve25(workingDir, ".oa", "cron-agents");
11839
12186
  await mkdir7(dir, { recursive: true });
11840
- await mkdir7(join29(dir, "logs"), { recursive: true });
12187
+ await mkdir7(join30(dir, "logs"), { recursive: true });
11841
12188
  store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
11842
- await writeFile11(join29(dir, "store.json"), JSON.stringify(store, null, 2), "utf-8");
12189
+ await writeFile11(join30(dir, "store.json"), JSON.stringify(store, null, 2), "utf-8");
11843
12190
  }
11844
12191
  var LONG_HORIZON_PRESETS, CRON_AGENT_MARKER, CronAgentTool;
11845
12192
  var init_cron_agent = __esm({
@@ -11973,7 +12320,7 @@ var init_cron_agent = __esm({
11973
12320
  durationMs: performance.now() - start
11974
12321
  };
11975
12322
  }
11976
- const id = `cron-${randomBytes5(4).toString("hex")}`;
12323
+ const id = `cron-${randomBytes6(4).toString("hex")}`;
11977
12324
  const verifyCommand = args["verify_command"] ? String(args["verify_command"]) : void 0;
11978
12325
  const maxRuns = typeof args["max_runs"] === "number" ? args["max_runs"] : 0;
11979
12326
  const tags = Array.isArray(args["tags"]) ? args["tags"] : [];
@@ -12177,9 +12524,9 @@ ${truncated}`, durationMs: performance.now() - start };
12177
12524
  // packages/execution/dist/tools/nexus.js
12178
12525
  import { readFile as readFile13, writeFile as writeFile12, mkdir as mkdir8, chmod, unlink, readdir as readdir3, open as fsOpen } from "node:fs/promises";
12179
12526
  import { existsSync as existsSync23, readFileSync as readFileSync16, watch as fsWatchLocal } from "node:fs";
12180
- import { resolve as resolve26, join as join30 } from "node:path";
12181
- import { randomBytes as randomBytes6, createCipheriv, createDecipheriv, scryptSync, createHash } from "node:crypto";
12182
- import { execSync as execSync22, spawn as spawn11 } from "node:child_process";
12527
+ import { resolve as resolve26, join as join31 } from "node:path";
12528
+ import { randomBytes as randomBytes7, createCipheriv, createDecipheriv, scryptSync, createHash } from "node:crypto";
12529
+ import { execSync as execSync22, spawn as spawn12 } from "node:child_process";
12183
12530
  import { hostname, userInfo } from "node:os";
12184
12531
  function containsKeyMaterial(input) {
12185
12532
  for (const pattern of KEY_PATTERNS) {
@@ -14270,7 +14617,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14270
14617
  // Daemon management
14271
14618
  // =========================================================================
14272
14619
  getDaemonPid() {
14273
- const pidFile = join30(this.nexusDir, "daemon.pid");
14620
+ const pidFile = join31(this.nexusDir, "daemon.pid");
14274
14621
  if (!existsSync23(pidFile))
14275
14622
  return null;
14276
14623
  try {
@@ -14295,9 +14642,9 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14295
14642
  if (!pid)
14296
14643
  throw new Error("Nexus daemon not running. Use action 'connect' first.");
14297
14644
  }
14298
- const cmdId = randomBytes6(8).toString("hex");
14299
- const cmdFile = join30(this.nexusDir, "cmd.json");
14300
- const respFile = join30(this.nexusDir, "resp.json");
14645
+ const cmdId = randomBytes7(8).toString("hex");
14646
+ const cmdFile = join31(this.nexusDir, "cmd.json");
14647
+ const respFile = join31(this.nexusDir, "resp.json");
14301
14648
  if (existsSync23(respFile))
14302
14649
  await unlink(respFile).catch(() => {
14303
14650
  });
@@ -14381,7 +14728,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14381
14728
  const currentScriptHash = createHash("sha256").update(DAEMON_SCRIPT).digest("hex").slice(0, 16);
14382
14729
  const existingPid = this.getDaemonPid();
14383
14730
  if (existingPid) {
14384
- const daemonPath2 = join30(this.nexusDir, "nexus-daemon.mjs");
14731
+ const daemonPath2 = join31(this.nexusDir, "nexus-daemon.mjs");
14385
14732
  let needsRestart = true;
14386
14733
  if (existsSync23(daemonPath2)) {
14387
14734
  try {
@@ -14405,13 +14752,13 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14405
14752
  } catch {
14406
14753
  }
14407
14754
  for (const f of ["daemon.pid", "status.json", "cmd.json", "resp.json"]) {
14408
- const p = join30(this.nexusDir, f);
14755
+ const p = join31(this.nexusDir, f);
14409
14756
  if (existsSync23(p))
14410
14757
  await unlink(p).catch(() => {
14411
14758
  });
14412
14759
  }
14413
14760
  } else {
14414
- const statusFile2 = join30(this.nexusDir, "status.json");
14761
+ const statusFile2 = join31(this.nexusDir, "status.json");
14415
14762
  if (existsSync23(statusFile2)) {
14416
14763
  try {
14417
14764
  const status = JSON.parse(await readFile13(statusFile2, "utf8"));
@@ -14430,7 +14777,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14430
14777
  }
14431
14778
  }
14432
14779
  for (const f of ["daemon.pid", "status.json", "cmd.json", "resp.json"]) {
14433
- const p = join30(this.nexusDir, f);
14780
+ const p = join31(this.nexusDir, f);
14434
14781
  if (existsSync23(p))
14435
14782
  await unlink(p).catch(() => {
14436
14783
  });
@@ -14448,7 +14795,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14448
14795
  });
14449
14796
  });
14450
14797
  try {
14451
- const nexusPkg = join30(nodeModulesDir, "open-agents-nexus", "package.json");
14798
+ const nexusPkg = join31(nodeModulesDir, "open-agents-nexus", "package.json");
14452
14799
  if (existsSync23(nexusPkg)) {
14453
14800
  nexusResolved = true;
14454
14801
  try {
@@ -14459,7 +14806,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14459
14806
  } else {
14460
14807
  try {
14461
14808
  const globalDir = await execAsync2("npm root -g", { timeout: 5e3 });
14462
- const globalPkg = join30(globalDir, "open-agents-nexus", "package.json");
14809
+ const globalPkg = join31(globalDir, "open-agents-nexus", "package.json");
14463
14810
  if (existsSync23(globalPkg)) {
14464
14811
  nexusResolved = true;
14465
14812
  try {
@@ -14504,7 +14851,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14504
14851
  }
14505
14852
  }
14506
14853
  await this.ensureWallet();
14507
- const daemonPath = join30(this.nexusDir, "nexus-daemon.mjs");
14854
+ const daemonPath = join31(this.nexusDir, "nexus-daemon.mjs");
14508
14855
  await writeFile12(daemonPath, DAEMON_SCRIPT);
14509
14856
  const agentName = args.agent_name || "open-agents-node";
14510
14857
  const agentType = args.agent_type || "general";
@@ -14515,11 +14862,11 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14515
14862
  } catch {
14516
14863
  }
14517
14864
  const { openSync: openSync2, closeSync: closeSync2 } = await import("node:fs");
14518
- const daemonLogPath = join30(this.nexusDir, "daemon.log");
14519
- const daemonErrPath = join30(this.nexusDir, "daemon.err");
14865
+ const daemonLogPath = join31(this.nexusDir, "daemon.log");
14866
+ const daemonErrPath = join31(this.nexusDir, "daemon.err");
14520
14867
  const outFd = openSync2(daemonLogPath, "w");
14521
14868
  const errFd = openSync2(daemonErrPath, "w");
14522
- const child = spawn11("node", [daemonPath, this.nexusDir, agentName, agentType], {
14869
+ const child = spawn12("node", [daemonPath, this.nexusDir, agentName, agentType], {
14523
14870
  detached: true,
14524
14871
  stdio: ["ignore", outFd, errFd],
14525
14872
  cwd: this.repoRoot,
@@ -14534,7 +14881,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14534
14881
  closeSync2(errFd);
14535
14882
  } catch {
14536
14883
  }
14537
- const statusFile = join30(this.nexusDir, "status.json");
14884
+ const statusFile = join31(this.nexusDir, "status.json");
14538
14885
  for (let i = 0; i < 40; i++) {
14539
14886
  await new Promise((r) => setTimeout(r, 500));
14540
14887
  if (existsSync23(statusFile)) {
@@ -14593,7 +14940,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14593
14940
  } catch {
14594
14941
  }
14595
14942
  for (const f of ["daemon.pid", "status.json", "cmd.json", "resp.json"]) {
14596
- const p = join30(this.nexusDir, f);
14943
+ const p = join31(this.nexusDir, f);
14597
14944
  if (existsSync23(p))
14598
14945
  await unlink(p).catch(() => {
14599
14946
  });
@@ -14604,7 +14951,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14604
14951
  const pid = this.getDaemonPid();
14605
14952
  if (!pid)
14606
14953
  return "Nexus daemon not running. Use action 'connect' to start.";
14607
- const statusFile = join30(this.nexusDir, "status.json");
14954
+ const statusFile = join31(this.nexusDir, "status.json");
14608
14955
  if (!existsSync23(statusFile))
14609
14956
  return `Daemon running (pid: ${pid}) but no status yet.`;
14610
14957
  try {
@@ -14619,7 +14966,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14619
14966
  ` Capabilities: ${(status.capabilities || []).length ? (status.capabilities || []).join(", ") : "none"}`,
14620
14967
  ` Blocked peers: ${(status.blockedPeers || []).length || 0}`
14621
14968
  ];
14622
- const walletPath = join30(this.nexusDir, "wallet.enc");
14969
+ const walletPath = join31(this.nexusDir, "wallet.enc");
14623
14970
  if (existsSync23(walletPath)) {
14624
14971
  try {
14625
14972
  const w = JSON.parse(await readFile13(walletPath, "utf8"));
@@ -14630,14 +14977,14 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14630
14977
  } else {
14631
14978
  lines.push(` Wallet: not configured`);
14632
14979
  }
14633
- const inboxDir = join30(this.nexusDir, "inbox");
14980
+ const inboxDir = join31(this.nexusDir, "inbox");
14634
14981
  if (existsSync23(inboxDir)) {
14635
14982
  try {
14636
14983
  const roomDirs = await readdir3(inboxDir);
14637
14984
  let totalMsgs = 0;
14638
14985
  for (const rd of roomDirs) {
14639
14986
  try {
14640
- totalMsgs += (await readdir3(join30(inboxDir, rd))).length;
14987
+ totalMsgs += (await readdir3(join31(inboxDir, rd))).length;
14641
14988
  } catch {
14642
14989
  }
14643
14990
  }
@@ -14684,9 +15031,9 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14684
15031
  }
14685
15032
  async doReadMessages(args) {
14686
15033
  const roomId = args.room_id;
14687
- const inboxDir = join30(this.nexusDir, "inbox");
15034
+ const inboxDir = join31(this.nexusDir, "inbox");
14688
15035
  if (roomId) {
14689
- const roomInbox = join30(inboxDir, roomId);
15036
+ const roomInbox = join31(inboxDir, roomId);
14690
15037
  if (!existsSync23(roomInbox))
14691
15038
  return `No messages in room: ${roomId}`;
14692
15039
  const files = (await readdir3(roomInbox)).sort().slice(-20);
@@ -14695,7 +15042,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14695
15042
  const messages = [`Messages in ${roomId} (last ${files.length}):`];
14696
15043
  for (const f of files) {
14697
15044
  try {
14698
- const msg = JSON.parse(await readFile13(join30(roomInbox, f), "utf8"));
15045
+ const msg = JSON.parse(await readFile13(join31(roomInbox, f), "utf8"));
14699
15046
  const sender = (msg.sender || "unknown").slice(0, 12);
14700
15047
  messages.push(` [${new Date(msg.timestamp).toLocaleTimeString()}] ${sender}...: ${msg.content}`);
14701
15048
  } catch {
@@ -14711,7 +15058,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14711
15058
  const lines = ["Inbox:"];
14712
15059
  for (const rd of roomDirs) {
14713
15060
  try {
14714
- const count = (await readdir3(join30(inboxDir, rd))).length;
15061
+ const count = (await readdir3(join31(inboxDir, rd))).length;
14715
15062
  lines.push(` ${rd}: ${count} message(s)`);
14716
15063
  } catch {
14717
15064
  }
@@ -14723,7 +15070,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14723
15070
  // ---------------------------------------------------------------------------
14724
15071
  async doWalletStatus() {
14725
15072
  await this.ensureDir();
14726
- const walletPath = join30(this.nexusDir, "wallet.enc");
15073
+ const walletPath = join31(this.nexusDir, "wallet.enc");
14727
15074
  if (!existsSync23(walletPath)) {
14728
15075
  return "No wallet configured. Use wallet_create to set one up.";
14729
15076
  }
@@ -14762,7 +15109,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14762
15109
  }
14763
15110
  async doWalletCreate(args) {
14764
15111
  await this.ensureDir();
14765
- const walletPath = join30(this.nexusDir, "wallet.enc");
15112
+ const walletPath = join31(this.nexusDir, "wallet.enc");
14766
15113
  if (existsSync23(walletPath))
14767
15114
  return "Wallet already exists. Delete wallet.enc to create a new one.";
14768
15115
  const userAddress = args.wallet_address;
@@ -14791,24 +15138,24 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14791
15138
  let privKeyHex;
14792
15139
  try {
14793
15140
  const { privateKeyToAccount } = await import("viem/accounts");
14794
- const privKey = randomBytes6(32);
15141
+ const privKey = randomBytes7(32);
14795
15142
  privKeyHex = privKey.toString("hex");
14796
15143
  const account = privateKeyToAccount(`0x${privKeyHex}`);
14797
15144
  address = account.address;
14798
15145
  privKey.fill(0);
14799
15146
  } catch {
14800
- const privKey = randomBytes6(32);
15147
+ const privKey = randomBytes7(32);
14801
15148
  privKeyHex = privKey.toString("hex");
14802
15149
  address = "0x" + createHash("sha256").update(privKey).digest("hex").slice(0, 40);
14803
15150
  privKey.fill(0);
14804
15151
  }
14805
- const salt = randomBytes6(32);
15152
+ const salt = randomBytes7(32);
14806
15153
  const key = scryptSync(`${hostname()}:${userInfo().username}:nexus-wallet`, salt, 32, { N: 16384, r: 8, p: 1 });
14807
- const iv = randomBytes6(16);
15154
+ const iv = randomBytes7(16);
14808
15155
  const cipher = createCipheriv("aes-256-gcm", key, iv);
14809
15156
  let enc = cipher.update(privKeyHex, "utf8", "hex");
14810
15157
  enc += cipher.final("hex");
14811
- const x402KeyPath = join30(this.nexusDir, "x402-wallet.key");
15158
+ const x402KeyPath = join31(this.nexusDir, "x402-wallet.key");
14812
15159
  const x402Fh = await fsOpen(x402KeyPath, "w", 384);
14813
15160
  await x402Fh.writeFile("0x" + privKeyHex);
14814
15161
  await x402Fh.close();
@@ -14846,31 +15193,31 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14846
15193
  * Silent — no user output, just ensures the files exist.
14847
15194
  */
14848
15195
  async ensureWallet() {
14849
- const walletPath = join30(this.nexusDir, "wallet.enc");
15196
+ const walletPath = join31(this.nexusDir, "wallet.enc");
14850
15197
  if (existsSync23(walletPath))
14851
15198
  return;
14852
15199
  let address;
14853
15200
  let privKeyHex;
14854
15201
  try {
14855
15202
  const { privateKeyToAccount } = await import("viem/accounts");
14856
- const privKey = randomBytes6(32);
15203
+ const privKey = randomBytes7(32);
14857
15204
  privKeyHex = privKey.toString("hex");
14858
15205
  const account = privateKeyToAccount(`0x${privKeyHex}`);
14859
15206
  address = account.address;
14860
15207
  privKey.fill(0);
14861
15208
  } catch {
14862
- const privKey = randomBytes6(32);
15209
+ const privKey = randomBytes7(32);
14863
15210
  privKeyHex = privKey.toString("hex");
14864
15211
  address = "0x" + createHash("sha256").update(privKey).digest("hex").slice(0, 40);
14865
15212
  privKey.fill(0);
14866
15213
  }
14867
- const salt = randomBytes6(32);
15214
+ const salt = randomBytes7(32);
14868
15215
  const key = scryptSync(`${hostname()}:${userInfo().username}:nexus-wallet`, salt, 32, { N: 16384, r: 8, p: 1 });
14869
- const iv = randomBytes6(16);
15216
+ const iv = randomBytes7(16);
14870
15217
  const cipher = createCipheriv("aes-256-gcm", key, iv);
14871
15218
  let enc = cipher.update(privKeyHex, "utf8", "hex");
14872
15219
  enc += cipher.final("hex");
14873
- const x402KeyPath = join30(this.nexusDir, "x402-wallet.key");
15220
+ const x402KeyPath = join31(this.nexusDir, "x402-wallet.key");
14874
15221
  const x402Fh = await fsOpen(x402KeyPath, "w", 384);
14875
15222
  await x402Fh.writeFile("0x" + privKeyHex);
14876
15223
  await x402Fh.close();
@@ -14930,7 +15277,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14930
15277
  // ---------------------------------------------------------------------------
14931
15278
  async doLedgerStatus() {
14932
15279
  await this.ensureDir();
14933
- const ledgerPath = join30(this.nexusDir, "ledger.jsonl");
15280
+ const ledgerPath = join31(this.nexusDir, "ledger.jsonl");
14934
15281
  if (!existsSync23(ledgerPath)) {
14935
15282
  return "No ledger entries. Earnings and spending will be tracked here after x402 transactions.";
14936
15283
  }
@@ -14972,7 +15319,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14972
15319
  }
14973
15320
  }
14974
15321
  async getLedgerSummary() {
14975
- const ledgerPath = join30(this.nexusDir, "ledger.jsonl");
15322
+ const ledgerPath = join31(this.nexusDir, "ledger.jsonl");
14976
15323
  if (!existsSync23(ledgerPath))
14977
15324
  return null;
14978
15325
  try {
@@ -14997,7 +15344,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14997
15344
  }
14998
15345
  async appendLedger(entry) {
14999
15346
  await this.ensureDir();
15000
- const ledgerPath = join30(this.nexusDir, "ledger.jsonl");
15347
+ const ledgerPath = join31(this.nexusDir, "ledger.jsonl");
15001
15348
  const line = JSON.stringify(entry) + "\n";
15002
15349
  await writeFile12(ledgerPath, existsSync23(ledgerPath) ? await readFile13(ledgerPath, "utf8") + line : line);
15003
15350
  }
@@ -15005,7 +15352,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15005
15352
  // Step 4: Budget Policy — Spending limits and auto-approve thresholds
15006
15353
  // ---------------------------------------------------------------------------
15007
15354
  async loadBudget() {
15008
- const budgetPath = join30(this.nexusDir, "budget.json");
15355
+ const budgetPath = join31(this.nexusDir, "budget.json");
15009
15356
  if (!existsSync23(budgetPath))
15010
15357
  return null;
15011
15358
  try {
@@ -15015,7 +15362,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15015
15362
  }
15016
15363
  }
15017
15364
  async ensureDefaultBudget() {
15018
- const budgetPath = join30(this.nexusDir, "budget.json");
15365
+ const budgetPath = join31(this.nexusDir, "budget.json");
15019
15366
  if (existsSync23(budgetPath))
15020
15367
  return;
15021
15368
  const defaultBudget = {
@@ -15085,12 +15432,12 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15085
15432
  if (changes.length === 0) {
15086
15433
  return "No budget parameters provided. Use daily_limit, per_invoke_max, or auto_approve_below.";
15087
15434
  }
15088
- const budgetPath = join30(this.nexusDir, "budget.json");
15435
+ const budgetPath = join31(this.nexusDir, "budget.json");
15089
15436
  await writeFile12(budgetPath, JSON.stringify(budget, null, 2));
15090
15437
  return `Budget updated: ${changes.join(", ")}`;
15091
15438
  }
15092
15439
  async getTodaySpending() {
15093
- const ledgerPath = join30(this.nexusDir, "ledger.jsonl");
15440
+ const ledgerPath = join31(this.nexusDir, "ledger.jsonl");
15094
15441
  if (!existsSync23(ledgerPath))
15095
15442
  return 0;
15096
15443
  try {
@@ -15134,7 +15481,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15134
15481
  if (todaySpent + amountUsdc > budget.dailyLimitUsdc) {
15135
15482
  return { allowed: false, reason: `Would exceed daily limit ($${((todaySpent + amountUsdc) / 1e6).toFixed(6)} > $${(budget.dailyLimitUsdc / 1e6).toFixed(6)})` };
15136
15483
  }
15137
- const walletPath = join30(this.nexusDir, "wallet.enc");
15484
+ const walletPath = join31(this.nexusDir, "wallet.enc");
15138
15485
  if (existsSync23(walletPath)) {
15139
15486
  try {
15140
15487
  const w = JSON.parse(await readFile13(walletPath, "utf8"));
@@ -15165,7 +15512,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15165
15512
  const budgetResult = await this.checkBudget(amountSmallest, "transfer:direct", targetAddress);
15166
15513
  if (!budgetResult.allowed)
15167
15514
  return `BLOCKED by budget policy: ${budgetResult.reason}`;
15168
- const walletPath = join30(this.nexusDir, "wallet.enc");
15515
+ const walletPath = join31(this.nexusDir, "wallet.enc");
15169
15516
  if (!existsSync23(walletPath))
15170
15517
  throw new Error("No wallet. Use wallet_create first.");
15171
15518
  const w = JSON.parse(await readFile13(walletPath, "utf8"));
@@ -15180,7 +15527,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15180
15527
  try {
15181
15528
  const { privateKeyToAccount } = await import("viem/accounts");
15182
15529
  const account = privateKeyToAccount(`0x${privKeyHex}`);
15183
- const nonce = "0x" + randomBytes6(32).toString("hex");
15530
+ const nonce = "0x" + randomBytes7(32).toString("hex");
15184
15531
  const now = Math.floor(Date.now() / 1e3);
15185
15532
  const validAfter = now - 60;
15186
15533
  const validBefore = now + 3600;
@@ -15226,7 +15573,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15226
15573
  capability: "transfer:direct",
15227
15574
  note: "signed, awaiting submission"
15228
15575
  });
15229
- const proofFile = join30(this.nexusDir, "pending-transfer.json");
15576
+ const proofFile = join31(this.nexusDir, "pending-transfer.json");
15230
15577
  const proof = {
15231
15578
  from: account.address,
15232
15579
  to: targetAddress,
@@ -15268,7 +15615,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15268
15615
  throw new Error("prompt is required");
15269
15616
  const estimatedTokens = Math.ceil(prompt.length / 4) + 1e3;
15270
15617
  let estimatedCostSmallest = 0;
15271
- const pricingPath = join30(this.nexusDir, "pricing.json");
15618
+ const pricingPath = join31(this.nexusDir, "pricing.json");
15272
15619
  if (existsSync23(pricingPath)) {
15273
15620
  try {
15274
15621
  const pricing = JSON.parse(await readFile13(pricingPath, "utf8"));
@@ -15383,12 +15730,12 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15383
15730
  } catch {
15384
15731
  }
15385
15732
  }
15386
- const nonce = randomBytes6(16).toString("hex");
15733
+ const nonce = randomBytes7(16).toString("hex");
15387
15734
  const hash = createHash("sha256").update(`${modelName}:${nonce}:${Date.now()}`).digest("hex");
15388
15735
  const bar = (s) => "\u2588".repeat(Math.round(s / 5)) + "\u2591".repeat(20 - Math.round(s / 5));
15389
15736
  const mem = vramMb > 24e3 ? 95 : vramMb > 16e3 ? 80 : vramMb > 8e3 ? 60 : vramMb > 0 ? 40 : 20;
15390
15737
  await this.ensureDir();
15391
- await writeFile12(join30(this.nexusDir, "inference-proof.json"), JSON.stringify({
15738
+ await writeFile12(join31(this.nexusDir, "inference-proof.json"), JSON.stringify({
15392
15739
  modelName,
15393
15740
  gpuName,
15394
15741
  vramMb,
@@ -15411,14 +15758,14 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15411
15758
  });
15412
15759
 
15413
15760
  // packages/execution/dist/shellRunner.js
15414
- import { spawn as spawn12 } from "node:child_process";
15761
+ import { spawn as spawn13 } from "node:child_process";
15415
15762
  async function runShell(options) {
15416
15763
  const { command, args = [], cwd: cwd4, env, timeoutMs = DEFAULT_TIMEOUT_MS } = options;
15417
15764
  const mergedEnv = env ? { ...process.env, ...env } : process.env;
15418
15765
  return new Promise((resolve32) => {
15419
15766
  const start = Date.now();
15420
15767
  let timedOut = false;
15421
- const child = spawn12(command, args, {
15768
+ const child = spawn13(command, args, {
15422
15769
  cwd: cwd4,
15423
15770
  env: mergedEnv
15424
15771
  // Do NOT use shell:true — we pass command + args separately
@@ -15517,7 +15864,7 @@ var init_gitWorktree = __esm({
15517
15864
  // packages/execution/dist/patchApplier.js
15518
15865
  import { readFileSync as readFileSync17, writeFileSync as writeFileSync7, existsSync as existsSync24, mkdirSync as mkdirSync7 } from "node:fs";
15519
15866
  import { dirname as dirname11 } from "node:path";
15520
- import { spawn as spawn13 } from "node:child_process";
15867
+ import { spawn as spawn14 } from "node:child_process";
15521
15868
  async function applyPatch(patch) {
15522
15869
  switch (patch.type) {
15523
15870
  case "block-replace":
@@ -15567,7 +15914,7 @@ async function applyUnifiedDiff(patch) {
15567
15914
  function runWithStdin(options) {
15568
15915
  const { command, args, cwd: cwd4, stdin } = options;
15569
15916
  return new Promise((resolve32) => {
15570
- const child = spawn13(command, args, {
15917
+ const child = spawn14(command, args, {
15571
15918
  cwd: cwd4,
15572
15919
  stdio: ["pipe", "pipe", "pipe"]
15573
15920
  });
@@ -16051,6 +16398,7 @@ __export(dist_exports, {
16051
16398
  OpenCodeTool: () => OpenCodeTool,
16052
16399
  PdfToTextTool: () => PdfToTextTool,
16053
16400
  ReminderTool: () => ReminderTool,
16401
+ ReplTool: () => ReplTool,
16054
16402
  SchedulerTool: () => SchedulerTool,
16055
16403
  ScreenshotTool: () => ScreenshotTool,
16056
16404
  ShellTool: () => ShellTool,
@@ -16135,6 +16483,7 @@ var init_dist2 = __esm({
16135
16483
  init_transcribe_tool();
16136
16484
  init_structured_file();
16137
16485
  init_code_sandbox();
16486
+ init_repl();
16138
16487
  init_structured_read();
16139
16488
  init_vision();
16140
16489
  init_desktop_click();
@@ -16835,12 +17184,12 @@ var init_dist3 = __esm({
16835
17184
 
16836
17185
  // packages/orchestrator/dist/promptLoader.js
16837
17186
  import { readFileSync as readFileSync18, existsSync as existsSync25 } from "node:fs";
16838
- import { join as join31, dirname as dirname12 } from "node:path";
17187
+ import { join as join32, dirname as dirname12 } from "node:path";
16839
17188
  import { fileURLToPath as fileURLToPath7 } from "node:url";
16840
17189
  function loadPrompt(promptPath, vars) {
16841
17190
  let content = cache.get(promptPath);
16842
17191
  if (content === void 0) {
16843
- const fullPath = join31(PROMPTS_DIR, promptPath);
17192
+ const fullPath = join32(PROMPTS_DIR, promptPath);
16844
17193
  if (!existsSync25(fullPath)) {
16845
17194
  throw new Error(`Prompt file not found: ${fullPath}`);
16846
17195
  }
@@ -16857,7 +17206,7 @@ var init_promptLoader = __esm({
16857
17206
  "use strict";
16858
17207
  __filename = fileURLToPath7(import.meta.url);
16859
17208
  __dirname4 = dirname12(__filename);
16860
- PROMPTS_DIR = join31(__dirname4, "..", "prompts");
17209
+ PROMPTS_DIR = join32(__dirname4, "..", "prompts");
16861
17210
  cache = /* @__PURE__ */ new Map();
16862
17211
  }
16863
17212
  });
@@ -17237,7 +17586,7 @@ var init_code_retriever = __esm({
17237
17586
  import { execFile as execFile5 } from "node:child_process";
17238
17587
  import { promisify as promisify4 } from "node:util";
17239
17588
  import { readFile as readFile14, readdir as readdir4, stat as stat3 } from "node:fs/promises";
17240
- import { join as join32, extname as extname7 } from "node:path";
17589
+ import { join as join33, extname as extname7 } from "node:path";
17241
17590
  async function searchByPath(pathPattern, options) {
17242
17591
  const allFiles = await collectFiles(options.rootDir, options.includeGlobs ?? DEFAULT_INCLUDE_GLOBS, options.excludeGlobs ?? DEFAULT_EXCLUDE_GLOBS);
17243
17592
  const pattern = options.caseInsensitive ? pathPattern.toLowerCase() : pathPattern;
@@ -17379,7 +17728,7 @@ async function walkForFiles(rootDir, dir, excludeGlobs, results) {
17379
17728
  continue;
17380
17729
  if (excludeGlobs.some((g) => entry.name === g || matchesGlob(entry.name, g)))
17381
17730
  continue;
17382
- const absPath = join32(dir, entry.name);
17731
+ const absPath = join33(dir, entry.name);
17383
17732
  if (entry.isDirectory()) {
17384
17733
  await walkForFiles(rootDir, absPath, excludeGlobs, results);
17385
17734
  } else if (entry.isFile()) {
@@ -17686,7 +18035,7 @@ var init_graphExpand = __esm({
17686
18035
 
17687
18036
  // packages/retrieval/dist/snippetPacker.js
17688
18037
  import { readFile as readFile15 } from "node:fs/promises";
17689
- import { join as join33 } from "node:path";
18038
+ import { join as join34 } from "node:path";
17690
18039
  async function packSnippets(requests, opts = {}) {
17691
18040
  const maxTokens = opts.maxTokens ?? DEFAULT_MAX_TOKENS;
17692
18041
  const contextLines = opts.contextLines ?? DEFAULT_CONTEXT_LINES;
@@ -17712,7 +18061,7 @@ async function packSnippets(requests, opts = {}) {
17712
18061
  return { packed, dropped, totalTokens };
17713
18062
  }
17714
18063
  async function extractSnippet(req, repoRoot, contextLines = DEFAULT_CONTEXT_LINES) {
17715
- const absPath = req.filePath.startsWith("/") ? req.filePath : join33(repoRoot, req.filePath);
18064
+ const absPath = req.filePath.startsWith("/") ? req.filePath : join34(repoRoot, req.filePath);
17716
18065
  let content;
17717
18066
  try {
17718
18067
  content = await readFile15(absPath, "utf-8");
@@ -19002,7 +19351,8 @@ var init_agenticRunner = __esm({
19002
19351
  modelTier: options?.modelTier ?? "large",
19003
19352
  contextWindowSize: options?.contextWindowSize ?? 0,
19004
19353
  personality: options?.personality ?? PERSONALITY_PRESETS.balanced,
19005
- personalityName: options?.personalityName ?? ""
19354
+ personalityName: options?.personalityName ?? "",
19355
+ finalVarResolver: options?.finalVarResolver ?? void 0
19006
19356
  };
19007
19357
  }
19008
19358
  /** Update context window size (e.g. after querying Ollama /api/show) */
@@ -20071,6 +20421,17 @@ ${result.output}`;
20071
20421
  summary = content;
20072
20422
  break;
20073
20423
  }
20424
+ const finalVarMatch = content.match(/FINAL_VAR\s*\(\s*["']?(\w+)["']?\s*\)/);
20425
+ if (finalVarMatch && this.options.finalVarResolver) {
20426
+ const varName = finalVarMatch[1];
20427
+ const varValue = await this.options.finalVarResolver(varName);
20428
+ if (varValue !== null) {
20429
+ completed = true;
20430
+ summary = varValue;
20431
+ this.emit({ type: "status", content: `FINAL_VAR(${varName}): resolved ${varValue.length} chars from REPL`, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
20432
+ break;
20433
+ }
20434
+ }
20074
20435
  if (consecutiveTextOnly >= MAX_CONSECUTIVE_TEXT_ONLY) {
20075
20436
  this.emit({
20076
20437
  type: "status",
@@ -20253,8 +20614,8 @@ ${marker}` : marker);
20253
20614
  return;
20254
20615
  try {
20255
20616
  const { mkdirSync: mkdirSync21, writeFileSync: writeFileSync20 } = __require("node:fs");
20256
- const { join: join57 } = __require("node:path");
20257
- const sessionDir = join57(this._workingDirectory, ".oa", "session", this._sessionId);
20617
+ const { join: join58 } = __require("node:path");
20618
+ const sessionDir = join58(this._workingDirectory, ".oa", "session", this._sessionId);
20258
20619
  mkdirSync21(sessionDir, { recursive: true });
20259
20620
  const checkpoint = {
20260
20621
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -20267,7 +20628,7 @@ ${marker}` : marker);
20267
20628
  memexEntryCount: this._memexArchive.size,
20268
20629
  fileRegistrySize: this._fileRegistry.size
20269
20630
  };
20270
- writeFileSync20(join57(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
20631
+ writeFileSync20(join58(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
20271
20632
  } catch {
20272
20633
  }
20273
20634
  }
@@ -21533,11 +21894,11 @@ ${transcript}`
21533
21894
  });
21534
21895
 
21535
21896
  // packages/orchestrator/dist/nexusBackend.js
21536
- import { existsSync as existsSync26, statSync as statSync9, openSync, readSync, closeSync, unlinkSync as unlinkSync3, writeFileSync as writeFileSync8 } from "node:fs";
21897
+ import { existsSync as existsSync26, statSync as statSync9, openSync, readSync, closeSync, unlinkSync as unlinkSync4, writeFileSync as writeFileSync8 } from "node:fs";
21537
21898
  import { watch as fsWatch } from "node:fs";
21538
- import { join as join34 } from "node:path";
21539
- import { tmpdir as tmpdir6 } from "node:os";
21540
- import { randomBytes as randomBytes7 } from "node:crypto";
21899
+ import { join as join35 } from "node:path";
21900
+ import { tmpdir as tmpdir7 } from "node:os";
21901
+ import { randomBytes as randomBytes8 } from "node:crypto";
21541
21902
  var NexusAgenticBackend;
21542
21903
  var init_nexusBackend = __esm({
21543
21904
  "packages/orchestrator/dist/nexusBackend.js"() {
@@ -21685,7 +22046,7 @@ var init_nexusBackend = __esm({
21685
22046
  * Falls back to unary + word-split if streaming setup fails.
21686
22047
  */
21687
22048
  async *chatCompletionStream(request) {
21688
- const streamFile = join34(tmpdir6(), `nexus-stream-${randomBytes7(6).toString("hex")}.jsonl`);
22049
+ const streamFile = join35(tmpdir7(), `nexus-stream-${randomBytes8(6).toString("hex")}.jsonl`);
21689
22050
  writeFileSync8(streamFile, "", "utf8");
21690
22051
  const daemonArgs = {
21691
22052
  model: this.model,
@@ -21706,7 +22067,7 @@ var init_nexusBackend = __esm({
21706
22067
  } catch (sendErr) {
21707
22068
  this.consecutiveFailures++;
21708
22069
  try {
21709
- unlinkSync3(streamFile);
22070
+ unlinkSync4(streamFile);
21710
22071
  } catch {
21711
22072
  }
21712
22073
  throw sendErr;
@@ -21721,7 +22082,7 @@ var init_nexusBackend = __esm({
21721
22082
  }
21722
22083
  if (!isStreaming) {
21723
22084
  try {
21724
- unlinkSync3(streamFile);
22085
+ unlinkSync4(streamFile);
21725
22086
  } catch {
21726
22087
  }
21727
22088
  let parsed;
@@ -21877,7 +22238,7 @@ var init_nexusBackend = __esm({
21877
22238
  }
21878
22239
  } finally {
21879
22240
  try {
21880
- unlinkSync3(streamFile);
22241
+ unlinkSync4(streamFile);
21881
22242
  } catch {
21882
22243
  }
21883
22244
  }
@@ -22720,9 +23081,9 @@ __export(listen_exports, {
22720
23081
  isVideoPath: () => isVideoPath,
22721
23082
  waitForTranscribeCli: () => waitForTranscribeCli
22722
23083
  });
22723
- import { spawn as spawn14, execSync as execSync23 } from "node:child_process";
23084
+ import { spawn as spawn15, execSync as execSync23 } from "node:child_process";
22724
23085
  import { existsSync as existsSync27, mkdirSync as mkdirSync8, writeFileSync as writeFileSync9, readdirSync as readdirSync6 } from "node:fs";
22725
- import { join as join35, dirname as dirname13 } from "node:path";
23086
+ import { join as join36, dirname as dirname13 } from "node:path";
22726
23087
  import { homedir as homedir8 } from "node:os";
22727
23088
  import { fileURLToPath as fileURLToPath8 } from "node:url";
22728
23089
  import { EventEmitter } from "node:events";
@@ -22808,12 +23169,12 @@ function findMicCaptureCommand() {
22808
23169
  function findLiveWhisperScript() {
22809
23170
  const thisDir = dirname13(fileURLToPath8(import.meta.url));
22810
23171
  const candidates = [
22811
- join35(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
22812
- join35(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
22813
- join35(thisDir, "../../execution/scripts/live-whisper.py"),
23172
+ join36(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
23173
+ join36(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
23174
+ join36(thisDir, "../../execution/scripts/live-whisper.py"),
22814
23175
  // npm install layout — scripts bundled alongside dist
22815
- join35(thisDir, "../scripts/live-whisper.py"),
22816
- join35(thisDir, "../../scripts/live-whisper.py")
23176
+ join36(thisDir, "../scripts/live-whisper.py"),
23177
+ join36(thisDir, "../../scripts/live-whisper.py")
22817
23178
  ];
22818
23179
  for (const p of candidates) {
22819
23180
  if (existsSync27(p))
@@ -22826,8 +23187,8 @@ function findLiveWhisperScript() {
22826
23187
  stdio: ["pipe", "pipe", "pipe"]
22827
23188
  }).trim();
22828
23189
  const candidates2 = [
22829
- join35(globalRoot, "open-agents-ai", "dist", "scripts", "live-whisper.py"),
22830
- join35(globalRoot, "open-agents-ai", "scripts", "live-whisper.py")
23190
+ join36(globalRoot, "open-agents-ai", "dist", "scripts", "live-whisper.py"),
23191
+ join36(globalRoot, "open-agents-ai", "scripts", "live-whisper.py")
22831
23192
  ];
22832
23193
  for (const p of candidates2) {
22833
23194
  if (existsSync27(p))
@@ -22835,11 +23196,11 @@ function findLiveWhisperScript() {
22835
23196
  }
22836
23197
  } catch {
22837
23198
  }
22838
- const nvmBase = join35(homedir8(), ".nvm", "versions", "node");
23199
+ const nvmBase = join36(homedir8(), ".nvm", "versions", "node");
22839
23200
  if (existsSync27(nvmBase)) {
22840
23201
  try {
22841
23202
  for (const ver of readdirSync6(nvmBase)) {
22842
- const p = join35(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
23203
+ const p = join36(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
22843
23204
  if (existsSync27(p))
22844
23205
  return p;
22845
23206
  }
@@ -22858,7 +23219,7 @@ function ensureTranscribeCliBackground() {
22858
23219
  timeout: 5e3,
22859
23220
  stdio: ["pipe", "pipe", "pipe"]
22860
23221
  }).trim();
22861
- if (existsSync27(join35(globalRoot, "transcribe-cli", "dist", "index.js"))) {
23222
+ if (existsSync27(join36(globalRoot, "transcribe-cli", "dist", "index.js"))) {
22862
23223
  return true;
22863
23224
  }
22864
23225
  } catch {
@@ -22930,7 +23291,7 @@ var init_listen = __esm({
22930
23291
  const timeout = setTimeout(() => {
22931
23292
  reject(new Error("Whisper fallback: model load timeout (5 min). First run downloads the model."));
22932
23293
  }, 3e5);
22933
- this.process = spawn14("python3", [
23294
+ this.process = spawn15("python3", [
22934
23295
  this.scriptPath,
22935
23296
  "--model",
22936
23297
  this.model,
@@ -23081,24 +23442,24 @@ var init_listen = __esm({
23081
23442
  timeout: 5e3,
23082
23443
  stdio: ["pipe", "pipe", "pipe"]
23083
23444
  }).trim();
23084
- const tcPath = join35(globalRoot, "transcribe-cli");
23085
- if (existsSync27(join35(tcPath, "dist", "index.js"))) {
23445
+ const tcPath = join36(globalRoot, "transcribe-cli");
23446
+ if (existsSync27(join36(tcPath, "dist", "index.js"))) {
23086
23447
  const { createRequire: createRequire4 } = await import("node:module");
23087
23448
  const req = createRequire4(import.meta.url);
23088
- return req(join35(tcPath, "dist", "index.js"));
23449
+ return req(join36(tcPath, "dist", "index.js"));
23089
23450
  }
23090
23451
  } catch {
23091
23452
  }
23092
- const nvmBase = join35(homedir8(), ".nvm", "versions", "node");
23453
+ const nvmBase = join36(homedir8(), ".nvm", "versions", "node");
23093
23454
  if (existsSync27(nvmBase)) {
23094
23455
  try {
23095
23456
  const { readdirSync: readdirSync17 } = await import("node:fs");
23096
23457
  for (const ver of readdirSync17(nvmBase)) {
23097
- const tcPath = join35(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
23098
- if (existsSync27(join35(tcPath, "dist", "index.js"))) {
23458
+ const tcPath = join36(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
23459
+ if (existsSync27(join36(tcPath, "dist", "index.js"))) {
23099
23460
  const { createRequire: createRequire4 } = await import("node:module");
23100
23461
  const req = createRequire4(import.meta.url);
23101
- return req(join35(tcPath, "dist", "index.js"));
23462
+ return req(join36(tcPath, "dist", "index.js"));
23102
23463
  }
23103
23464
  }
23104
23465
  } catch {
@@ -23212,7 +23573,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
23212
23573
  return `Failed to start live transcription: ${msg}${tcHint}`;
23213
23574
  }
23214
23575
  }
23215
- this.micProcess = spawn14(micCmd.cmd, micCmd.args, {
23576
+ this.micProcess = spawn15(micCmd.cmd, micCmd.args, {
23216
23577
  stdio: ["pipe", "pipe", "pipe"],
23217
23578
  env: { ...process.env }
23218
23579
  });
@@ -23380,9 +23741,9 @@ transcribe-cli error: ${transcribeCliError}` : "";
23380
23741
  });
23381
23742
  if (outputDir) {
23382
23743
  const { basename: basename16 } = await import("node:path");
23383
- const transcriptDir = join35(outputDir, ".oa", "transcripts");
23744
+ const transcriptDir = join36(outputDir, ".oa", "transcripts");
23384
23745
  mkdirSync8(transcriptDir, { recursive: true });
23385
- const outFile = join35(transcriptDir, `${basename16(filePath)}.txt`);
23746
+ const outFile = join36(transcriptDir, `${basename16(filePath)}.txt`);
23386
23747
  writeFileSync9(outFile, result.text, "utf-8");
23387
23748
  }
23388
23749
  return {
@@ -25631,7 +25992,7 @@ var require_websocket = __commonJS({
25631
25992
  var http = __require("http");
25632
25993
  var net = __require("net");
25633
25994
  var tls = __require("tls");
25634
- var { randomBytes: randomBytes11, createHash: createHash5 } = __require("crypto");
25995
+ var { randomBytes: randomBytes12, createHash: createHash5 } = __require("crypto");
25635
25996
  var { Duplex, Readable } = __require("stream");
25636
25997
  var { URL: URL3 } = __require("url");
25637
25998
  var PerMessageDeflate = require_permessage_deflate();
@@ -26161,7 +26522,7 @@ var require_websocket = __commonJS({
26161
26522
  }
26162
26523
  }
26163
26524
  const defaultPort = isSecure ? 443 : 80;
26164
- const key = randomBytes11(16).toString("base64");
26525
+ const key = randomBytes12(16).toString("base64");
26165
26526
  const request = isSecure ? https.request : http.request;
26166
26527
  const protocolSet = /* @__PURE__ */ new Set();
26167
26528
  let perMessageDeflate;
@@ -28005,8 +28366,8 @@ var init_render = __esm({
28005
28366
  });
28006
28367
 
28007
28368
  // packages/cli/dist/tui/voice-session.js
28008
- import { createServer } from "node:http";
28009
- import { spawn as spawn15, execSync as execSync24 } from "node:child_process";
28369
+ import { createServer as createServer2 } from "node:http";
28370
+ import { spawn as spawn16, execSync as execSync24 } from "node:child_process";
28010
28371
  import { EventEmitter as EventEmitter2 } from "node:events";
28011
28372
  function generateFrontendHTML() {
28012
28373
  return `<!DOCTYPE html>
@@ -28432,7 +28793,7 @@ var init_voice_session = __esm({
28432
28793
  return "Voice session already active.";
28433
28794
  const port = await this.findFreePort();
28434
28795
  this.state.localPort = port;
28435
- this.server = createServer((req, res) => this.handleHTTP(req, res));
28796
+ this.server = createServer2((req, res) => this.handleHTTP(req, res));
28436
28797
  this.server.timeout = 0;
28437
28798
  this.server.keepAliveTimeout = 0;
28438
28799
  this.wss = new import_websocket_server.default({ server: this.server, path: "/ws" });
@@ -28660,7 +29021,7 @@ var init_voice_session = __esm({
28660
29021
  const timeout = setTimeout(() => {
28661
29022
  reject(new Error("Cloudflared tunnel start timeout (30s)"));
28662
29023
  }, 3e4);
28663
- this.cloudflaredProcess = spawn15("cloudflared", [
29024
+ this.cloudflaredProcess = spawn16("cloudflared", [
28664
29025
  "tunnel",
28665
29026
  "--url",
28666
29027
  `http://127.0.0.1:${port}`
@@ -28715,7 +29076,7 @@ var init_voice_session = __esm({
28715
29076
  // ── Helpers ───────────────────────────────────────────────────────────
28716
29077
  findFreePort() {
28717
29078
  return new Promise((resolve32, reject) => {
28718
- const srv = createServer();
29079
+ const srv = createServer2();
28719
29080
  srv.listen(0, "127.0.0.1", () => {
28720
29081
  const addr = srv.address();
28721
29082
  if (addr && typeof addr === "object") {
@@ -28733,14 +29094,14 @@ var init_voice_session = __esm({
28733
29094
  });
28734
29095
 
28735
29096
  // packages/cli/dist/tui/expose.js
28736
- import { createServer as createServer2, request as httpRequest } from "node:http";
28737
- import { spawn as spawn16, exec } from "node:child_process";
29097
+ import { createServer as createServer3, request as httpRequest } from "node:http";
29098
+ import { spawn as spawn17, exec } from "node:child_process";
28738
29099
  import { EventEmitter as EventEmitter3 } from "node:events";
28739
- import { randomBytes as randomBytes8 } from "node:crypto";
29100
+ import { randomBytes as randomBytes9 } from "node:crypto";
28740
29101
  import { URL as URL2 } from "node:url";
28741
29102
  import { loadavg, cpus, totalmem, freemem } from "node:os";
28742
- import { existsSync as existsSync28, readFileSync as readFileSync19, writeFileSync as writeFileSync10, unlinkSync as unlinkSync4, mkdirSync as mkdirSync9, readdirSync as readdirSync7, statSync as statSync10 } from "node:fs";
28743
- import { join as join36 } from "node:path";
29103
+ import { existsSync as existsSync28, readFileSync as readFileSync19, writeFileSync as writeFileSync10, unlinkSync as unlinkSync5, mkdirSync as mkdirSync9, readdirSync as readdirSync7, statSync as statSync10 } from "node:fs";
29104
+ import { join as join37 } from "node:path";
28744
29105
  function cleanForwardHeaders(raw, targetHost) {
28745
29106
  const out = {};
28746
29107
  for (const [key, value] of Object.entries(raw)) {
@@ -28768,7 +29129,7 @@ function fmtTokens(n) {
28768
29129
  }
28769
29130
  function readExposeState(stateDir) {
28770
29131
  try {
28771
- const path = join36(stateDir, STATE_FILE_NAME);
29132
+ const path = join37(stateDir, STATE_FILE_NAME);
28772
29133
  if (!existsSync28(path))
28773
29134
  return null;
28774
29135
  const raw = readFileSync19(path, "utf8");
@@ -28783,13 +29144,13 @@ function readExposeState(stateDir) {
28783
29144
  function writeExposeState(stateDir, state) {
28784
29145
  try {
28785
29146
  mkdirSync9(stateDir, { recursive: true });
28786
- writeFileSync10(join36(stateDir, STATE_FILE_NAME), JSON.stringify(state, null, 2));
29147
+ writeFileSync10(join37(stateDir, STATE_FILE_NAME), JSON.stringify(state, null, 2));
28787
29148
  } catch {
28788
29149
  }
28789
29150
  }
28790
29151
  function removeExposeState(stateDir) {
28791
29152
  try {
28792
- unlinkSync4(join36(stateDir, STATE_FILE_NAME));
29153
+ unlinkSync5(join37(stateDir, STATE_FILE_NAME));
28793
29154
  } catch {
28794
29155
  }
28795
29156
  }
@@ -28878,7 +29239,7 @@ async function collectSystemMetricsAsync() {
28878
29239
  }
28879
29240
  function readP2PExposeState(stateDir) {
28880
29241
  try {
28881
- const path = join36(stateDir, P2P_STATE_FILE_NAME);
29242
+ const path = join37(stateDir, P2P_STATE_FILE_NAME);
28882
29243
  if (!existsSync28(path))
28883
29244
  return null;
28884
29245
  const raw = readFileSync19(path, "utf8");
@@ -28893,13 +29254,13 @@ function readP2PExposeState(stateDir) {
28893
29254
  function writeP2PExposeState(stateDir, state) {
28894
29255
  try {
28895
29256
  mkdirSync9(stateDir, { recursive: true });
28896
- writeFileSync10(join36(stateDir, P2P_STATE_FILE_NAME), JSON.stringify(state, null, 2));
29257
+ writeFileSync10(join37(stateDir, P2P_STATE_FILE_NAME), JSON.stringify(state, null, 2));
28897
29258
  } catch {
28898
29259
  }
28899
29260
  }
28900
29261
  function removeP2PExposeState(stateDir) {
28901
29262
  try {
28902
- unlinkSync4(join36(stateDir, P2P_STATE_FILE_NAME));
29263
+ unlinkSync5(join37(stateDir, P2P_STATE_FILE_NAME));
28903
29264
  } catch {
28904
29265
  }
28905
29266
  }
@@ -28981,7 +29342,7 @@ var init_expose = __esm({
28981
29342
  this._stateDir = options.stateDir ?? null;
28982
29343
  this._fullAccess = options.fullAccess ?? false;
28983
29344
  if (options.authKey === void 0 || options.authKey === "") {
28984
- this._authKey = randomBytes8(24).toString("base64url");
29345
+ this._authKey = randomBytes9(24).toString("base64url");
28985
29346
  } else {
28986
29347
  this._authKey = options.authKey;
28987
29348
  }
@@ -29124,7 +29485,7 @@ var init_expose = __esm({
29124
29485
  // ── Proxy server ────────────────────────────────────────────────────────
29125
29486
  createProxyServer(localPort) {
29126
29487
  const target = new URL2(this._targetUrl);
29127
- const server = createServer2((req, res) => {
29488
+ const server = createServer3((req, res) => {
29128
29489
  res.on("error", () => {
29129
29490
  });
29130
29491
  const authHeader = req.headers.authorization;
@@ -29400,7 +29761,7 @@ var init_expose = __esm({
29400
29761
  const timeout = setTimeout(() => {
29401
29762
  reject(new Error("Cloudflared tunnel start timeout (30s)"));
29402
29763
  }, 3e4);
29403
- this.cloudflaredProcess = spawn16("cloudflared", [
29764
+ this.cloudflaredProcess = spawn17("cloudflared", [
29404
29765
  "tunnel",
29405
29766
  "--url",
29406
29767
  `http://127.0.0.1:${port}`,
@@ -29515,7 +29876,7 @@ ${this.formatConnectionInfo()}`);
29515
29876
  // ── Helpers ─────────────────────────────────────────────────────────────
29516
29877
  findFreePort() {
29517
29878
  return new Promise((resolve32, reject) => {
29518
- const srv = createServer2();
29879
+ const srv = createServer3();
29519
29880
  srv.listen(0, "127.0.0.1", () => {
29520
29881
  const addr = srv.address();
29521
29882
  if (addr && typeof addr === "object") {
@@ -29691,7 +30052,7 @@ ${this.formatConnectionInfo()}`);
29691
30052
  this._onInfo = options.onInfo;
29692
30053
  this._onError = options.onError;
29693
30054
  if (options.authKey === void 0 || options.authKey === "") {
29694
- this._authKey = randomBytes8(24).toString("base64url");
30055
+ this._authKey = randomBytes9(24).toString("base64url");
29695
30056
  } else {
29696
30057
  this._authKey = options.authKey;
29697
30058
  }
@@ -29729,7 +30090,7 @@ ${this.formatConnectionInfo()}`);
29729
30090
  throw new Error(`Expose failed: ${exposeResult.error}`);
29730
30091
  }
29731
30092
  const nexusDir = this._nexusTool.getNexusDir();
29732
- const statusPath = join36(nexusDir, "status.json");
30093
+ const statusPath = join37(nexusDir, "status.json");
29733
30094
  for (let i = 0; i < 80; i++) {
29734
30095
  try {
29735
30096
  const raw = readFileSync19(statusPath, "utf8");
@@ -29763,7 +30124,7 @@ ${this.formatConnectionInfo()}`);
29763
30124
  });
29764
30125
  }
29765
30126
  try {
29766
- const invocDir = join36(nexusDir, "invocations");
30127
+ const invocDir = join37(nexusDir, "invocations");
29767
30128
  if (existsSync28(invocDir)) {
29768
30129
  this._prevInvocCount = readdirSync7(invocDir).filter((f) => f.endsWith(".json")).length;
29769
30130
  this._stats.totalRequests = this._prevInvocCount;
@@ -29793,7 +30154,7 @@ ${this.formatConnectionInfo()}`);
29793
30154
  if (!state)
29794
30155
  return null;
29795
30156
  const nexusDir = nexusTool.getNexusDir();
29796
- const statusPath = join36(nexusDir, "status.json");
30157
+ const statusPath = join37(nexusDir, "status.json");
29797
30158
  try {
29798
30159
  if (!existsSync28(statusPath)) {
29799
30160
  removeP2PExposeState(stateDir);
@@ -29852,7 +30213,7 @@ ${this.formatConnectionInfo()}`);
29852
30213
  let lastMeteringLineCount = 0;
29853
30214
  this._activityPollTimer = setInterval(() => {
29854
30215
  try {
29855
- const invocDir = join36(nexusDir, "invocations");
30216
+ const invocDir = join37(nexusDir, "invocations");
29856
30217
  if (!existsSync28(invocDir))
29857
30218
  return;
29858
30219
  const files = readdirSync7(invocDir).filter((f) => f.endsWith(".json"));
@@ -29868,13 +30229,13 @@ ${this.formatConnectionInfo()}`);
29868
30229
  let recentActive = 0;
29869
30230
  for (const f of files.slice(-10)) {
29870
30231
  try {
29871
- const st = statSync10(join36(invocDir, f));
30232
+ const st = statSync10(join37(invocDir, f));
29872
30233
  if (now - st.mtimeMs < 1e4)
29873
30234
  recentActive++;
29874
30235
  } catch {
29875
30236
  }
29876
30237
  }
29877
- const meteringFile = join36(nexusDir, "metering.jsonl");
30238
+ const meteringFile = join37(nexusDir, "metering.jsonl");
29878
30239
  let meteringLines = lastMeteringLineCount;
29879
30240
  try {
29880
30241
  if (existsSync28(meteringFile)) {
@@ -29904,7 +30265,7 @@ ${this.formatConnectionInfo()}`);
29904
30265
  this._activityPollTimer.unref();
29905
30266
  this._pollTimer = setInterval(() => {
29906
30267
  try {
29907
- const statusPath = join36(nexusDir, "status.json");
30268
+ const statusPath = join37(nexusDir, "status.json");
29908
30269
  if (existsSync28(statusPath)) {
29909
30270
  const status = JSON.parse(readFileSync19(statusPath, "utf8"));
29910
30271
  if (status.peerId && !this._peerId) {
@@ -29915,7 +30276,7 @@ ${this.formatConnectionInfo()}`);
29915
30276
  } catch {
29916
30277
  }
29917
30278
  try {
29918
- const invocDir = join36(nexusDir, "invocations");
30279
+ const invocDir = join37(nexusDir, "invocations");
29919
30280
  if (existsSync28(invocDir)) {
29920
30281
  const files = readdirSync7(invocDir);
29921
30282
  const invocCount = files.filter((f) => f.endsWith(".json")).length;
@@ -29927,7 +30288,7 @@ ${this.formatConnectionInfo()}`);
29927
30288
  } catch {
29928
30289
  }
29929
30290
  try {
29930
- const meteringFile = join36(nexusDir, "metering.jsonl");
30291
+ const meteringFile = join37(nexusDir, "metering.jsonl");
29931
30292
  if (existsSync28(meteringFile)) {
29932
30293
  const content = readFileSync19(meteringFile, "utf8");
29933
30294
  if (content.length > lastMeteringSize) {
@@ -30137,9 +30498,9 @@ var init_types = __esm({
30137
30498
  });
30138
30499
 
30139
30500
  // packages/cli/dist/tui/p2p/secret-vault.js
30140
- import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes9, scryptSync as scryptSync2, createHash as createHash2 } from "node:crypto";
30501
+ import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes10, scryptSync as scryptSync2, createHash as createHash2 } from "node:crypto";
30141
30502
  import { readFileSync as readFileSync20, writeFileSync as writeFileSync11, existsSync as existsSync29, mkdirSync as mkdirSync10 } from "node:fs";
30142
- import { join as join37, dirname as dirname14 } from "node:path";
30503
+ import { join as join38, dirname as dirname14 } from "node:path";
30143
30504
  var PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, CIPHER_ALGO, SALT_LEN, IV_LEN, KEY_LEN, SecretVault;
30144
30505
  var init_secret_vault = __esm({
30145
30506
  "packages/cli/dist/tui/p2p/secret-vault.js"() {
@@ -30343,9 +30704,9 @@ var init_secret_vault = __esm({
30343
30704
  minTrust: s.minTrust,
30344
30705
  createdAt: s.createdAt
30345
30706
  })));
30346
- const salt = randomBytes9(SALT_LEN);
30707
+ const salt = randomBytes10(SALT_LEN);
30347
30708
  const key = scryptSync2(passphrase, salt, KEY_LEN);
30348
- const iv = randomBytes9(IV_LEN);
30709
+ const iv = randomBytes10(IV_LEN);
30349
30710
  const cipher = createCipheriv2(CIPHER_ALGO, key, iv);
30350
30711
  const encrypted = Buffer.concat([cipher.update(data, "utf8"), cipher.final()]);
30351
30712
  const tag = cipher.getAuthTag();
@@ -30402,8 +30763,8 @@ var init_secret_vault = __esm({
30402
30763
 
30403
30764
  // packages/cli/dist/tui/p2p/peer-mesh.js
30404
30765
  import { EventEmitter as EventEmitter4 } from "node:events";
30405
- import { createServer as createServer3 } from "node:http";
30406
- import { randomBytes as randomBytes10, createHash as createHash3, generateKeyPairSync } from "node:crypto";
30766
+ import { createServer as createServer4 } from "node:http";
30767
+ import { randomBytes as randomBytes11, createHash as createHash3, generateKeyPairSync } from "node:crypto";
30407
30768
  var PING_INTERVAL_MS, PEER_TIMEOUT_MS, GOSSIP_INTERVAL_MS, MAX_PEERS, PeerMesh;
30408
30769
  var init_peer_mesh = __esm({
30409
30770
  "packages/cli/dist/tui/p2p/peer-mesh.js"() {
@@ -30455,14 +30816,14 @@ var init_peer_mesh = __esm({
30455
30816
  this.peerId = createHash3("sha256").update(this.publicKey).digest("base64url").slice(0, 22);
30456
30817
  this.capabilities = options.capabilities;
30457
30818
  this.displayName = options.displayName;
30458
- this._authKey = options.authKey ?? randomBytes10(24).toString("base64url");
30819
+ this._authKey = options.authKey ?? randomBytes11(24).toString("base64url");
30459
30820
  }
30460
30821
  // ── Lifecycle ───────────────────────────────────────────────────────────
30461
30822
  /** Start the mesh node — creates WS server and connects to bootstrap peers */
30462
30823
  async start() {
30463
30824
  const port = await this.findFreePort();
30464
30825
  this._port = port;
30465
- this.server = createServer3();
30826
+ this.server = createServer4();
30466
30827
  this.wss = new import_websocket_server.default({ server: this.server });
30467
30828
  this.wss.on("connection", (ws, req) => {
30468
30829
  this.handleInboundConnection(ws, req.url ?? "");
@@ -30619,7 +30980,7 @@ var init_peer_mesh = __esm({
30619
30980
  if (!ws || ws.readyState !== import_websocket.default.OPEN) {
30620
30981
  throw new Error(`Peer ${peerId} not connected`);
30621
30982
  }
30622
- const msgId = randomBytes10(8).toString("hex");
30983
+ const msgId = randomBytes11(8).toString("hex");
30623
30984
  return new Promise((resolve32, reject) => {
30624
30985
  const timeout = setTimeout(() => {
30625
30986
  this.pendingRequests.delete(msgId);
@@ -30840,7 +31201,7 @@ var init_peer_mesh = __esm({
30840
31201
  const msg = {
30841
31202
  type,
30842
31203
  from: this.peerId,
30843
- msgId: msgId ?? randomBytes10(8).toString("hex"),
31204
+ msgId: msgId ?? randomBytes11(8).toString("hex"),
30844
31205
  ts: (/* @__PURE__ */ new Date()).toISOString(),
30845
31206
  payload
30846
31207
  };
@@ -30848,7 +31209,7 @@ var init_peer_mesh = __esm({
30848
31209
  }
30849
31210
  findFreePort() {
30850
31211
  return new Promise((resolve32, reject) => {
30851
- const srv = createServer3();
31212
+ const srv = createServer4();
30852
31213
  srv.listen(0, "127.0.0.1", () => {
30853
31214
  const addr = srv.address();
30854
31215
  if (addr && typeof addr === "object") {
@@ -31476,13 +31837,13 @@ async function fetchPeerModels(peerId, authKey) {
31476
31837
  try {
31477
31838
  const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
31478
31839
  const { existsSync: existsSync45, readFileSync: readFileSync33 } = await import("node:fs");
31479
- const { join: join57 } = await import("node:path");
31840
+ const { join: join58 } = await import("node:path");
31480
31841
  const cwd4 = process.cwd();
31481
31842
  const nexusTool = new NexusTool2(cwd4);
31482
31843
  const nexusDir = nexusTool.getNexusDir();
31483
31844
  let isLocalPeer = false;
31484
31845
  try {
31485
- const statusPath = join57(nexusDir, "status.json");
31846
+ const statusPath = join58(nexusDir, "status.json");
31486
31847
  if (existsSync45(statusPath)) {
31487
31848
  const status = JSON.parse(readFileSync33(statusPath, "utf8"));
31488
31849
  if (status.peerId === peerId)
@@ -31491,7 +31852,7 @@ async function fetchPeerModels(peerId, authKey) {
31491
31852
  } catch {
31492
31853
  }
31493
31854
  if (isLocalPeer) {
31494
- const pricingPath = join57(nexusDir, "pricing.json");
31855
+ const pricingPath = join58(nexusDir, "pricing.json");
31495
31856
  if (existsSync45(pricingPath)) {
31496
31857
  try {
31497
31858
  const pricing = JSON.parse(readFileSync33(pricingPath, "utf8"));
@@ -31508,7 +31869,7 @@ async function fetchPeerModels(peerId, authKey) {
31508
31869
  }
31509
31870
  }
31510
31871
  }
31511
- const cachePath = join57(nexusDir, "peer-models-cache.json");
31872
+ const cachePath = join58(nexusDir, "peer-models-cache.json");
31512
31873
  if (existsSync45(cachePath)) {
31513
31874
  try {
31514
31875
  const cache4 = JSON.parse(readFileSync33(cachePath, "utf8"));
@@ -31626,7 +31987,7 @@ async function fetchPeerModels(peerId, authKey) {
31626
31987
  } catch {
31627
31988
  }
31628
31989
  if (isLocalPeer) {
31629
- const pricingPath = join57(nexusDir, "pricing.json");
31990
+ const pricingPath = join58(nexusDir, "pricing.json");
31630
31991
  if (existsSync45(pricingPath)) {
31631
31992
  try {
31632
31993
  const pricing = JSON.parse(readFileSync33(pricingPath, "utf8"));
@@ -31899,12 +32260,12 @@ var init_render2 = __esm({
31899
32260
 
31900
32261
  // packages/prompts/dist/promptLoader.js
31901
32262
  import { readFileSync as readFileSync21, existsSync as existsSync30 } from "node:fs";
31902
- import { join as join38, dirname as dirname15 } from "node:path";
32263
+ import { join as join39, dirname as dirname15 } from "node:path";
31903
32264
  import { fileURLToPath as fileURLToPath9 } from "node:url";
31904
32265
  function loadPrompt2(promptPath, vars) {
31905
32266
  let content = cache2.get(promptPath);
31906
32267
  if (content === void 0) {
31907
- const fullPath = join38(PROMPTS_DIR2, promptPath);
32268
+ const fullPath = join39(PROMPTS_DIR2, promptPath);
31908
32269
  if (!existsSync30(fullPath)) {
31909
32270
  throw new Error(`Prompt file not found: ${fullPath}`);
31910
32271
  }
@@ -31921,8 +32282,8 @@ var init_promptLoader2 = __esm({
31921
32282
  "use strict";
31922
32283
  __filename2 = fileURLToPath9(import.meta.url);
31923
32284
  __dirname5 = dirname15(__filename2);
31924
- devPath = join38(__dirname5, "..", "templates");
31925
- publishedPath = join38(__dirname5, "..", "prompts", "templates");
32285
+ devPath = join39(__dirname5, "..", "templates");
32286
+ publishedPath = join39(__dirname5, "..", "prompts", "templates");
31926
32287
  PROMPTS_DIR2 = existsSync30(devPath) ? devPath : publishedPath;
31927
32288
  cache2 = /* @__PURE__ */ new Map();
31928
32289
  }
@@ -32034,7 +32395,7 @@ var init_task_templates = __esm({
32034
32395
  });
32035
32396
 
32036
32397
  // packages/prompts/dist/index.js
32037
- import { join as join39, dirname as dirname16 } from "node:path";
32398
+ import { join as join40, dirname as dirname16 } from "node:path";
32038
32399
  import { fileURLToPath as fileURLToPath10 } from "node:url";
32039
32400
  var _dir, _packageRoot;
32040
32401
  var init_dist6 = __esm({
@@ -32045,21 +32406,21 @@ var init_dist6 = __esm({
32045
32406
  init_task_templates();
32046
32407
  init_render2();
32047
32408
  _dir = dirname16(fileURLToPath10(import.meta.url));
32048
- _packageRoot = join39(_dir, "..");
32409
+ _packageRoot = join40(_dir, "..");
32049
32410
  }
32050
32411
  });
32051
32412
 
32052
32413
  // packages/cli/dist/tui/oa-directory.js
32053
- import { existsSync as existsSync31, mkdirSync as mkdirSync11, readFileSync as readFileSync22, writeFileSync as writeFileSync12, readdirSync as readdirSync8, statSync as statSync11, unlinkSync as unlinkSync5 } from "node:fs";
32054
- import { join as join40, relative as relative2, basename as basename9, extname as extname8 } from "node:path";
32414
+ import { existsSync as existsSync31, mkdirSync as mkdirSync11, readFileSync as readFileSync22, writeFileSync as writeFileSync12, readdirSync as readdirSync8, statSync as statSync11, unlinkSync as unlinkSync6 } from "node:fs";
32415
+ import { join as join41, relative as relative2, basename as basename9, extname as extname8 } from "node:path";
32055
32416
  import { homedir as homedir9 } from "node:os";
32056
32417
  function initOaDirectory(repoRoot) {
32057
- const oaPath = join40(repoRoot, OA_DIR);
32418
+ const oaPath = join41(repoRoot, OA_DIR);
32058
32419
  for (const sub of SUBDIRS) {
32059
- mkdirSync11(join40(oaPath, sub), { recursive: true });
32420
+ mkdirSync11(join41(oaPath, sub), { recursive: true });
32060
32421
  }
32061
32422
  try {
32062
- const gitignorePath = join40(repoRoot, ".gitignore");
32423
+ const gitignorePath = join41(repoRoot, ".gitignore");
32063
32424
  const settingsPattern = ".oa/settings.json";
32064
32425
  if (existsSync31(gitignorePath)) {
32065
32426
  const content = readFileSync22(gitignorePath, "utf-8");
@@ -32072,10 +32433,10 @@ function initOaDirectory(repoRoot) {
32072
32433
  return oaPath;
32073
32434
  }
32074
32435
  function hasOaDirectory(repoRoot) {
32075
- return existsSync31(join40(repoRoot, OA_DIR, "index"));
32436
+ return existsSync31(join41(repoRoot, OA_DIR, "index"));
32076
32437
  }
32077
32438
  function loadProjectSettings(repoRoot) {
32078
- const settingsPath = join40(repoRoot, OA_DIR, "settings.json");
32439
+ const settingsPath = join41(repoRoot, OA_DIR, "settings.json");
32079
32440
  try {
32080
32441
  if (existsSync31(settingsPath)) {
32081
32442
  return JSON.parse(readFileSync22(settingsPath, "utf-8"));
@@ -32085,14 +32446,14 @@ function loadProjectSettings(repoRoot) {
32085
32446
  return {};
32086
32447
  }
32087
32448
  function saveProjectSettings(repoRoot, settings) {
32088
- const oaPath = join40(repoRoot, OA_DIR);
32449
+ const oaPath = join41(repoRoot, OA_DIR);
32089
32450
  mkdirSync11(oaPath, { recursive: true });
32090
32451
  const existing = loadProjectSettings(repoRoot);
32091
32452
  const merged = { ...existing, ...settings };
32092
- writeFileSync12(join40(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
32453
+ writeFileSync12(join41(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
32093
32454
  }
32094
32455
  function loadGlobalSettings() {
32095
- const settingsPath = join40(homedir9(), ".open-agents", "settings.json");
32456
+ const settingsPath = join41(homedir9(), ".open-agents", "settings.json");
32096
32457
  try {
32097
32458
  if (existsSync31(settingsPath)) {
32098
32459
  return JSON.parse(readFileSync22(settingsPath, "utf-8"));
@@ -32102,11 +32463,11 @@ function loadGlobalSettings() {
32102
32463
  return {};
32103
32464
  }
32104
32465
  function saveGlobalSettings(settings) {
32105
- const dir = join40(homedir9(), ".open-agents");
32466
+ const dir = join41(homedir9(), ".open-agents");
32106
32467
  mkdirSync11(dir, { recursive: true });
32107
32468
  const existing = loadGlobalSettings();
32108
32469
  const merged = { ...existing, ...settings };
32109
- writeFileSync12(join40(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
32470
+ writeFileSync12(join41(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
32110
32471
  }
32111
32472
  function resolveSettings(repoRoot) {
32112
32473
  const global = loadGlobalSettings();
@@ -32121,7 +32482,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
32121
32482
  while (dir && !visited.has(dir)) {
32122
32483
  visited.add(dir);
32123
32484
  for (const name of CONTEXT_FILES) {
32124
- const filePath = join40(dir, name);
32485
+ const filePath = join41(dir, name);
32125
32486
  const normalizedName = name.toLowerCase();
32126
32487
  if (existsSync31(filePath) && !seen.has(filePath)) {
32127
32488
  seen.add(filePath);
@@ -32140,7 +32501,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
32140
32501
  }
32141
32502
  }
32142
32503
  }
32143
- const projectMap = join40(dir, OA_DIR, "context", "project-map.md");
32504
+ const projectMap = join41(dir, OA_DIR, "context", "project-map.md");
32144
32505
  if (existsSync31(projectMap) && !seen.has(projectMap)) {
32145
32506
  seen.add(projectMap);
32146
32507
  try {
@@ -32156,7 +32517,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
32156
32517
  } catch {
32157
32518
  }
32158
32519
  }
32159
- const parent = join40(dir, "..");
32520
+ const parent = join41(dir, "..");
32160
32521
  if (parent === dir)
32161
32522
  break;
32162
32523
  dir = parent;
@@ -32174,7 +32535,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
32174
32535
  return found;
32175
32536
  }
32176
32537
  function readIndexMeta(repoRoot) {
32177
- const metaPath = join40(repoRoot, OA_DIR, "index", "meta.json");
32538
+ const metaPath = join41(repoRoot, OA_DIR, "index", "meta.json");
32178
32539
  try {
32179
32540
  return JSON.parse(readFileSync22(metaPath, "utf-8"));
32180
32541
  } catch {
@@ -32227,28 +32588,28 @@ ${tree}\`\`\`
32227
32588
  sections.push("");
32228
32589
  }
32229
32590
  const content = sections.join("\n");
32230
- const contextDir = join40(repoRoot, OA_DIR, "context");
32591
+ const contextDir = join41(repoRoot, OA_DIR, "context");
32231
32592
  mkdirSync11(contextDir, { recursive: true });
32232
- writeFileSync12(join40(contextDir, "project-map.md"), content, "utf-8");
32593
+ writeFileSync12(join41(contextDir, "project-map.md"), content, "utf-8");
32233
32594
  return content;
32234
32595
  }
32235
32596
  function saveSession(repoRoot, session) {
32236
- const historyDir = join40(repoRoot, OA_DIR, "history");
32597
+ const historyDir = join41(repoRoot, OA_DIR, "history");
32237
32598
  mkdirSync11(historyDir, { recursive: true });
32238
- writeFileSync12(join40(historyDir, `${session.id}.json`), JSON.stringify(session, null, 2), "utf-8");
32599
+ writeFileSync12(join41(historyDir, `${session.id}.json`), JSON.stringify(session, null, 2), "utf-8");
32239
32600
  }
32240
32601
  function loadRecentSessions(repoRoot, limit = 5) {
32241
- const historyDir = join40(repoRoot, OA_DIR, "history");
32602
+ const historyDir = join41(repoRoot, OA_DIR, "history");
32242
32603
  if (!existsSync31(historyDir))
32243
32604
  return [];
32244
32605
  try {
32245
32606
  const files = readdirSync8(historyDir).filter((f) => f.endsWith(".json") && f !== "pending-task.json").map((f) => {
32246
- const stat5 = statSync11(join40(historyDir, f));
32607
+ const stat5 = statSync11(join41(historyDir, f));
32247
32608
  return { file: f, mtime: stat5.mtimeMs };
32248
32609
  }).sort((a, b) => b.mtime - a.mtime).slice(0, limit);
32249
32610
  return files.map((f) => {
32250
32611
  try {
32251
- return JSON.parse(readFileSync22(join40(historyDir, f.file), "utf-8"));
32612
+ return JSON.parse(readFileSync22(join41(historyDir, f.file), "utf-8"));
32252
32613
  } catch {
32253
32614
  return null;
32254
32615
  }
@@ -32258,18 +32619,18 @@ function loadRecentSessions(repoRoot, limit = 5) {
32258
32619
  }
32259
32620
  }
32260
32621
  function savePendingTask(repoRoot, task) {
32261
- const historyDir = join40(repoRoot, OA_DIR, "history");
32622
+ const historyDir = join41(repoRoot, OA_DIR, "history");
32262
32623
  mkdirSync11(historyDir, { recursive: true });
32263
- writeFileSync12(join40(historyDir, PENDING_TASK_FILE), JSON.stringify(task, null, 2) + "\n", "utf-8");
32624
+ writeFileSync12(join41(historyDir, PENDING_TASK_FILE), JSON.stringify(task, null, 2) + "\n", "utf-8");
32264
32625
  }
32265
32626
  function loadPendingTask(repoRoot) {
32266
- const filePath = join40(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
32627
+ const filePath = join41(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
32267
32628
  try {
32268
32629
  if (!existsSync31(filePath))
32269
32630
  return null;
32270
32631
  const data = JSON.parse(readFileSync22(filePath, "utf-8"));
32271
32632
  try {
32272
- unlinkSync5(filePath);
32633
+ unlinkSync6(filePath);
32273
32634
  } catch {
32274
32635
  }
32275
32636
  return data;
@@ -32278,9 +32639,9 @@ function loadPendingTask(repoRoot) {
32278
32639
  }
32279
32640
  }
32280
32641
  function saveSessionContext(repoRoot, entry) {
32281
- const contextDir = join40(repoRoot, OA_DIR, "context");
32642
+ const contextDir = join41(repoRoot, OA_DIR, "context");
32282
32643
  mkdirSync11(contextDir, { recursive: true });
32283
- const filePath = join40(contextDir, CONTEXT_SAVE_FILE);
32644
+ const filePath = join41(contextDir, CONTEXT_SAVE_FILE);
32284
32645
  let ctx;
32285
32646
  try {
32286
32647
  if (existsSync31(filePath)) {
@@ -32299,7 +32660,7 @@ function saveSessionContext(repoRoot, entry) {
32299
32660
  writeFileSync12(filePath, JSON.stringify(ctx, null, 2) + "\n", "utf-8");
32300
32661
  }
32301
32662
  function loadSessionContext(repoRoot) {
32302
- const filePath = join40(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
32663
+ const filePath = join41(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
32303
32664
  try {
32304
32665
  if (!existsSync31(filePath))
32305
32666
  return null;
@@ -32350,7 +32711,7 @@ function detectManifests(repoRoot) {
32350
32711
  { file: "docker-compose.yaml", type: "Docker Compose" }
32351
32712
  ];
32352
32713
  for (const check of checks) {
32353
- const filePath = join40(repoRoot, check.file);
32714
+ const filePath = join41(repoRoot, check.file);
32354
32715
  if (existsSync31(filePath)) {
32355
32716
  let name;
32356
32717
  if (check.nameField) {
@@ -32384,7 +32745,7 @@ function findKeyFiles(repoRoot) {
32384
32745
  { pattern: "CLAUDE.md", description: "Claude Code context" }
32385
32746
  ];
32386
32747
  for (const check of checks) {
32387
- if (existsSync31(join40(repoRoot, check.pattern))) {
32748
+ if (existsSync31(join41(repoRoot, check.pattern))) {
32388
32749
  keyFiles.push({ path: check.pattern, description: check.description });
32389
32750
  }
32390
32751
  }
@@ -32410,12 +32771,12 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
32410
32771
  if (entry.isDirectory()) {
32411
32772
  let fileCount = 0;
32412
32773
  try {
32413
- fileCount = readdirSync8(join40(root, entry.name)).filter((f) => !f.startsWith(".")).length;
32774
+ fileCount = readdirSync8(join41(root, entry.name)).filter((f) => !f.startsWith(".")).length;
32414
32775
  } catch {
32415
32776
  }
32416
32777
  result += `${prefix}${connector}${entry.name}/ (${fileCount})
32417
32778
  `;
32418
- result += buildDirTree(join40(root, entry.name), maxDepth, childPrefix, depth + 1);
32779
+ result += buildDirTree(join41(root, entry.name), maxDepth, childPrefix, depth + 1);
32419
32780
  } else if (depth < maxDepth) {
32420
32781
  result += `${prefix}${connector}${entry.name}
32421
32782
  `;
@@ -32435,7 +32796,7 @@ function loadUsageFile(filePath) {
32435
32796
  return { records: [] };
32436
32797
  }
32437
32798
  function saveUsageFile(filePath, data) {
32438
- const dir = join40(filePath, "..");
32799
+ const dir = join41(filePath, "..");
32439
32800
  mkdirSync11(dir, { recursive: true });
32440
32801
  writeFileSync12(filePath, JSON.stringify(data, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
32441
32802
  }
@@ -32465,15 +32826,15 @@ function recordUsage(kind, value, opts) {
32465
32826
  }
32466
32827
  saveUsageFile(filePath, data);
32467
32828
  };
32468
- update(join40(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
32829
+ update(join41(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
32469
32830
  if (opts?.repoRoot) {
32470
- update(join40(opts.repoRoot, OA_DIR, USAGE_HISTORY_FILE));
32831
+ update(join41(opts.repoRoot, OA_DIR, USAGE_HISTORY_FILE));
32471
32832
  }
32472
32833
  }
32473
32834
  function loadUsageHistory(kind, repoRoot) {
32474
- const globalPath = join40(homedir9(), ".open-agents", USAGE_HISTORY_FILE);
32835
+ const globalPath = join41(homedir9(), ".open-agents", USAGE_HISTORY_FILE);
32475
32836
  const globalData = loadUsageFile(globalPath);
32476
- const localData = repoRoot ? loadUsageFile(join40(repoRoot, OA_DIR, USAGE_HISTORY_FILE)) : { records: [] };
32837
+ const localData = repoRoot ? loadUsageFile(join41(repoRoot, OA_DIR, USAGE_HISTORY_FILE)) : { records: [] };
32477
32838
  const map = /* @__PURE__ */ new Map();
32478
32839
  for (const r of globalData.records) {
32479
32840
  if (r.kind !== kind)
@@ -32504,9 +32865,9 @@ function deleteUsageRecord(kind, value, repoRoot) {
32504
32865
  saveUsageFile(filePath, data);
32505
32866
  }
32506
32867
  };
32507
- remove(join40(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
32868
+ remove(join41(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
32508
32869
  if (repoRoot) {
32509
- remove(join40(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
32870
+ remove(join41(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
32510
32871
  }
32511
32872
  }
32512
32873
  var OA_DIR, SUBDIRS, CONTEXT_FILES, PENDING_TASK_FILE, CONTEXT_SAVE_FILE, MAX_CONTEXT_ENTRIES, SKIP_DIRS, USAGE_HISTORY_FILE, MAX_HISTORY_RECORDS;
@@ -32554,10 +32915,10 @@ var init_oa_directory = __esm({
32554
32915
 
32555
32916
  // packages/cli/dist/tui/setup.js
32556
32917
  import * as readline from "node:readline";
32557
- import { execSync as execSync25, spawn as spawn17, exec as exec2 } from "node:child_process";
32918
+ import { execSync as execSync25, spawn as spawn18, exec as exec2 } from "node:child_process";
32558
32919
  import { promisify as promisify5 } from "node:util";
32559
32920
  import { existsSync as existsSync32, writeFileSync as writeFileSync13, readFileSync as readFileSync23, appendFileSync as appendFileSync2, mkdirSync as mkdirSync12 } from "node:fs";
32560
- import { join as join41 } from "node:path";
32921
+ import { join as join42 } from "node:path";
32561
32922
  import { homedir as homedir10, platform } from "node:os";
32562
32923
  function detectSystemSpecs() {
32563
32924
  let totalRamGB = 0;
@@ -32952,7 +33313,7 @@ async function ensureOllamaRunning(backendUrl, rl) {
32952
33313
  process.stdout.write(` ${c2.cyan("\u25CF")} Starting ollama serve...
32953
33314
  `);
32954
33315
  try {
32955
- const child = spawn17("ollama", ["serve"], { stdio: "ignore", detached: true });
33316
+ const child = spawn18("ollama", ["serve"], { stdio: "ignore", detached: true });
32956
33317
  child.unref();
32957
33318
  } catch {
32958
33319
  process.stdout.write(` ${c2.yellow("\u26A0")} Could not start ollama serve.
@@ -33420,7 +33781,7 @@ async function doSetup(config, rl) {
33420
33781
  ${c2.cyan("\u25CF")} Ollama is installed but not running. Starting automatically...
33421
33782
  `);
33422
33783
  try {
33423
- const child = spawn17("ollama", ["serve"], { stdio: "ignore", detached: true });
33784
+ const child = spawn18("ollama", ["serve"], { stdio: "ignore", detached: true });
33424
33785
  child.unref();
33425
33786
  await new Promise((resolve32) => setTimeout(resolve32, 3e3));
33426
33787
  try {
@@ -33448,7 +33809,7 @@ async function doSetup(config, rl) {
33448
33809
  ${c2.cyan("\u25CF")} Starting ollama serve...
33449
33810
  `);
33450
33811
  try {
33451
- const child = spawn17("ollama", ["serve"], { stdio: "ignore", detached: true });
33812
+ const child = spawn18("ollama", ["serve"], { stdio: "ignore", detached: true });
33452
33813
  child.unref();
33453
33814
  await new Promise((resolve32) => setTimeout(resolve32, 3e3));
33454
33815
  try {
@@ -33598,9 +33959,9 @@ async function doSetup(config, rl) {
33598
33959
  `PARAMETER num_predict ${numPredict}`,
33599
33960
  `PARAMETER stop "<|endoftext|>"`
33600
33961
  ].join("\n");
33601
- const modelDir2 = join41(homedir10(), ".open-agents", "models");
33962
+ const modelDir2 = join42(homedir10(), ".open-agents", "models");
33602
33963
  mkdirSync12(modelDir2, { recursive: true });
33603
- const modelfilePath = join41(modelDir2, `Modelfile.${customName}`);
33964
+ const modelfilePath = join42(modelDir2, `Modelfile.${customName}`);
33604
33965
  writeFileSync13(modelfilePath, modelfileContent + "\n", "utf8");
33605
33966
  process.stdout.write(` ${c2.dim("Creating model...")} `);
33606
33967
  execSync25(`ollama create ${customName} -f ${modelfilePath}`, {
@@ -33646,7 +34007,7 @@ async function isModelAvailable(config) {
33646
34007
  }
33647
34008
  function isFirstRun() {
33648
34009
  try {
33649
- return !existsSync32(join41(homedir10(), ".open-agents", "config.json"));
34010
+ return !existsSync32(join42(homedir10(), ".open-agents", "config.json"));
33650
34011
  } catch {
33651
34012
  return true;
33652
34013
  }
@@ -33683,7 +34044,7 @@ function detectPkgManager() {
33683
34044
  return null;
33684
34045
  }
33685
34046
  function getVenvDir() {
33686
- return join41(homedir10(), ".open-agents", "venv");
34047
+ return join42(homedir10(), ".open-agents", "venv");
33687
34048
  }
33688
34049
  function hasVenvModule() {
33689
34050
  try {
@@ -33695,7 +34056,7 @@ function hasVenvModule() {
33695
34056
  }
33696
34057
  function ensureVenv(log) {
33697
34058
  const venvDir = getVenvDir();
33698
- const venvPip = join41(venvDir, "bin", "pip");
34059
+ const venvPip = join42(venvDir, "bin", "pip");
33699
34060
  if (existsSync32(venvPip))
33700
34061
  return venvDir;
33701
34062
  log("Creating Python venv for vision deps...");
@@ -33708,9 +34069,9 @@ function ensureVenv(log) {
33708
34069
  return null;
33709
34070
  }
33710
34071
  try {
33711
- mkdirSync12(join41(homedir10(), ".open-agents"), { recursive: true });
34072
+ mkdirSync12(join42(homedir10(), ".open-agents"), { recursive: true });
33712
34073
  execSync25(`python3 -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
33713
- execSync25(`"${join41(venvDir, "bin", "pip")}" install --upgrade pip`, {
34074
+ execSync25(`"${join42(venvDir, "bin", "pip")}" install --upgrade pip`, {
33714
34075
  stdio: "pipe",
33715
34076
  timeout: 6e4
33716
34077
  });
@@ -33901,11 +34262,11 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
33901
34262
  }
33902
34263
  }
33903
34264
  const venvDir = getVenvDir();
33904
- const venvBin = join41(venvDir, "bin");
33905
- const venvMoondream = join41(venvBin, "moondream-station");
34265
+ const venvBin = join42(venvDir, "bin");
34266
+ const venvMoondream = join42(venvBin, "moondream-station");
33906
34267
  const venv = ensureVenv(log);
33907
34268
  if (venv && !hasCmd("moondream-station") && !existsSync32(venvMoondream)) {
33908
- const venvPip = join41(venvBin, "pip");
34269
+ const venvPip = join42(venvBin, "pip");
33909
34270
  log("Installing moondream-station in ~/.open-agents/venv...");
33910
34271
  try {
33911
34272
  execSync25(`"${venvPip}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
@@ -33926,8 +34287,8 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
33926
34287
  }
33927
34288
  }
33928
34289
  if (venv) {
33929
- const venvPython = join41(venvBin, "python");
33930
- const venvPip2 = join41(venvBin, "pip");
34290
+ const venvPython = join42(venvBin, "python");
34291
+ const venvPip2 = join42(venvBin, "pip");
33931
34292
  let ocrStackInstalled = false;
33932
34293
  try {
33933
34294
  execSync25(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
@@ -34071,9 +34432,9 @@ async function createExpandedVariantAsync(baseModel, specs, sizeGB, kvBytesPerTo
34071
34432
  `PARAMETER num_predict ${numPredict}`,
34072
34433
  `PARAMETER stop "<|endoftext|>"`
34073
34434
  ].join("\n");
34074
- const modelDir2 = join41(homedir10(), ".open-agents", "models");
34435
+ const modelDir2 = join42(homedir10(), ".open-agents", "models");
34075
34436
  mkdirSync12(modelDir2, { recursive: true });
34076
- const modelfilePath = join41(modelDir2, `Modelfile.${customName}`);
34437
+ const modelfilePath = join42(modelDir2, `Modelfile.${customName}`);
34077
34438
  writeFileSync13(modelfilePath, modelfileContent + "\n", "utf8");
34078
34439
  await execAsync(`ollama create ${customName} -f ${modelfilePath}`, {
34079
34440
  timeout: 12e4
@@ -34148,8 +34509,8 @@ async function ensureNeovim() {
34148
34509
  const platform5 = process.platform;
34149
34510
  const arch = process.arch;
34150
34511
  if (platform5 === "linux") {
34151
- const binDir = join41(homedir10(), ".local", "bin");
34152
- const nvimDest = join41(binDir, "nvim");
34512
+ const binDir = join42(homedir10(), ".local", "bin");
34513
+ const nvimDest = join42(binDir, "nvim");
34153
34514
  try {
34154
34515
  mkdirSync12(binDir, { recursive: true });
34155
34516
  } catch {
@@ -34220,7 +34581,7 @@ async function ensureNeovim() {
34220
34581
  }
34221
34582
  function ensurePathInShellRc(binDir) {
34222
34583
  const shell = process.env.SHELL ?? "";
34223
- const rcFile = shell.includes("zsh") ? join41(homedir10(), ".zshrc") : join41(homedir10(), ".bashrc");
34584
+ const rcFile = shell.includes("zsh") ? join42(homedir10(), ".zshrc") : join42(homedir10(), ".bashrc");
34224
34585
  try {
34225
34586
  const rcContent = existsSync32(rcFile) ? readFileSync23(rcFile, "utf8") : "";
34226
34587
  if (rcContent.includes(binDir))
@@ -34990,9 +35351,9 @@ var init_drop_panel = __esm({
34990
35351
  });
34991
35352
 
34992
35353
  // packages/cli/dist/tui/neovim-mode.js
34993
- import { existsSync as existsSync34, unlinkSync as unlinkSync6 } from "node:fs";
34994
- import { tmpdir as tmpdir7 } from "node:os";
34995
- import { join as join42 } from "node:path";
35354
+ import { existsSync as existsSync34, unlinkSync as unlinkSync7 } from "node:fs";
35355
+ import { tmpdir as tmpdir8 } from "node:os";
35356
+ import { join as join43 } from "node:path";
34996
35357
  import { execSync as execSync26 } from "node:child_process";
34997
35358
  function isNeovimActive() {
34998
35359
  return _state !== null && !_state.cleanedUp;
@@ -35040,10 +35401,10 @@ async function startNeovimMode(opts) {
35040
35401
  );
35041
35402
  } catch {
35042
35403
  }
35043
- const socketPath = join42(tmpdir7(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
35404
+ const socketPath = join43(tmpdir8(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
35044
35405
  try {
35045
35406
  if (existsSync34(socketPath))
35046
- unlinkSync6(socketPath);
35407
+ unlinkSync7(socketPath);
35047
35408
  } catch {
35048
35409
  }
35049
35410
  const ptyCols = opts.cols;
@@ -35336,7 +35697,7 @@ function doCleanup(state) {
35336
35697
  }
35337
35698
  try {
35338
35699
  if (existsSync34(state.socketPath))
35339
- unlinkSync6(state.socketPath);
35700
+ unlinkSync7(state.socketPath);
35340
35701
  } catch {
35341
35702
  }
35342
35703
  if (state.stdinHandler) {
@@ -35391,9 +35752,9 @@ __export(voice_exports, {
35391
35752
  registerCustomOnnxModel: () => registerCustomOnnxModel,
35392
35753
  resetNarrationContext: () => resetNarrationContext
35393
35754
  });
35394
- import { existsSync as existsSync35, mkdirSync as mkdirSync13, writeFileSync as writeFileSync14, readFileSync as readFileSync24, unlinkSync as unlinkSync7, readdirSync as readdirSync9, renameSync, statSync as statSync12 } from "node:fs";
35395
- import { join as join43 } from "node:path";
35396
- import { homedir as homedir11, tmpdir as tmpdir8, platform as platform2 } from "node:os";
35755
+ import { existsSync as existsSync35, mkdirSync as mkdirSync13, writeFileSync as writeFileSync14, readFileSync as readFileSync24, unlinkSync as unlinkSync8, readdirSync as readdirSync9, renameSync, statSync as statSync12 } from "node:fs";
35756
+ import { join as join44 } from "node:path";
35757
+ import { homedir as homedir11, tmpdir as tmpdir9, platform as platform2 } from "node:os";
35397
35758
  import { execSync as execSync27, spawn as nodeSpawn } from "node:child_process";
35398
35759
  import { createRequire } from "node:module";
35399
35760
  function registerCustomOnnxModel(id, label) {
@@ -35414,34 +35775,34 @@ function listVoiceModels() {
35414
35775
  }));
35415
35776
  }
35416
35777
  function voiceDir() {
35417
- return join43(homedir11(), ".open-agents", "voice");
35778
+ return join44(homedir11(), ".open-agents", "voice");
35418
35779
  }
35419
35780
  function modelsDir() {
35420
- return join43(voiceDir(), "models");
35781
+ return join44(voiceDir(), "models");
35421
35782
  }
35422
35783
  function modelDir(id) {
35423
- return join43(modelsDir(), id);
35784
+ return join44(modelsDir(), id);
35424
35785
  }
35425
35786
  function modelOnnxPath(id) {
35426
- return join43(modelDir(id), "model.onnx");
35787
+ return join44(modelDir(id), "model.onnx");
35427
35788
  }
35428
35789
  function modelConfigPath(id) {
35429
- return join43(modelDir(id), "config.json");
35790
+ return join44(modelDir(id), "config.json");
35430
35791
  }
35431
35792
  function luxttsVenvDir() {
35432
- return join43(voiceDir(), "luxtts-venv");
35793
+ return join44(voiceDir(), "luxtts-venv");
35433
35794
  }
35434
35795
  function luxttsVenvPy() {
35435
- return platform2() === "win32" ? join43(luxttsVenvDir(), "Scripts", "python.exe") : join43(luxttsVenvDir(), "bin", "python3");
35796
+ return platform2() === "win32" ? join44(luxttsVenvDir(), "Scripts", "python.exe") : join44(luxttsVenvDir(), "bin", "python3");
35436
35797
  }
35437
35798
  function luxttsRepoDir() {
35438
- return join43(voiceDir(), "LuxTTS");
35799
+ return join44(voiceDir(), "LuxTTS");
35439
35800
  }
35440
35801
  function luxttsCloneRefsDir() {
35441
- return join43(voiceDir(), "clone-refs");
35802
+ return join44(voiceDir(), "clone-refs");
35442
35803
  }
35443
35804
  function luxttsInferScript() {
35444
- return join43(voiceDir(), "luxtts-infer.py");
35805
+ return join44(voiceDir(), "luxtts-infer.py");
35445
35806
  }
35446
35807
  function emotionToPitchBias(emotion, stark = false, autist = false) {
35447
35808
  if (autist)
@@ -36249,7 +36610,7 @@ var init_voice = __esm({
36249
36610
  const refsDir = luxttsCloneRefsDir();
36250
36611
  const targets = ["glados", "overwatch"];
36251
36612
  for (const modelId of targets) {
36252
- const refFile = join43(refsDir, `${modelId}-ref.wav`);
36613
+ const refFile = join44(refsDir, `${modelId}-ref.wav`);
36253
36614
  if (existsSync35(refFile))
36254
36615
  continue;
36255
36616
  try {
@@ -36329,7 +36690,7 @@ var init_voice = __esm({
36329
36690
  }
36330
36691
  p = p.replace(/\\ /g, " ");
36331
36692
  if (p.startsWith("~/") || p === "~") {
36332
- p = join43(homedir11(), p.slice(1));
36693
+ p = join44(homedir11(), p.slice(1));
36333
36694
  }
36334
36695
  if (!existsSync35(p)) {
36335
36696
  return `File not found: ${p}
@@ -36343,7 +36704,7 @@ var init_voice = __esm({
36343
36704
  const srcName = (audioPath.split("/").pop() ?? "clone").replace(/\.[^.]+$/, "").replace(/[^a-zA-Z0-9_-]/g, "-");
36344
36705
  const ts = Date.now().toString(36);
36345
36706
  const destFilename = `clone-${srcName}-${ts}.${ext}`;
36346
- const destPath = join43(refsDir, destFilename);
36707
+ const destPath = join44(refsDir, destFilename);
36347
36708
  try {
36348
36709
  const data = readFileSync24(audioPath);
36349
36710
  writeFileSync14(destPath, data);
@@ -36388,7 +36749,7 @@ var init_voice = __esm({
36388
36749
  const refsDir = luxttsCloneRefsDir();
36389
36750
  if (!existsSync35(refsDir))
36390
36751
  mkdirSync13(refsDir, { recursive: true });
36391
- const destPath = join43(refsDir, `${sourceModelId}-ref.wav`);
36752
+ const destPath = join44(refsDir, `${sourceModelId}-ref.wav`);
36392
36753
  const sampleRate = this.config?.audio?.sample_rate ?? 22050;
36393
36754
  this.writeWav(audioData, sampleRate, destPath);
36394
36755
  this.luxttsCloneRef = destPath;
@@ -36404,7 +36765,7 @@ var init_voice = __esm({
36404
36765
  // -------------------------------------------------------------------------
36405
36766
  /** Metadata file for friendly names of clone refs */
36406
36767
  static cloneMetaFile() {
36407
- return join43(luxttsCloneRefsDir(), "meta.json");
36768
+ return join44(luxttsCloneRefsDir(), "meta.json");
36408
36769
  }
36409
36770
  loadCloneMeta() {
36410
36771
  const p = _VoiceEngine.cloneMetaFile();
@@ -36438,7 +36799,7 @@ var init_voice = __esm({
36438
36799
  return _VoiceEngine.AUDIO_EXTS.has(ext);
36439
36800
  });
36440
36801
  return files.map((f) => {
36441
- const p = join43(dir, f);
36802
+ const p = join44(dir, f);
36442
36803
  let size = 0;
36443
36804
  try {
36444
36805
  size = statSync12(p).size;
@@ -36455,11 +36816,11 @@ var init_voice = __esm({
36455
36816
  }
36456
36817
  /** Delete a clone reference file by filename. Returns true if deleted. */
36457
36818
  deleteCloneRef(filename) {
36458
- const p = join43(luxttsCloneRefsDir(), filename);
36819
+ const p = join44(luxttsCloneRefsDir(), filename);
36459
36820
  if (!existsSync35(p))
36460
36821
  return false;
36461
36822
  try {
36462
- unlinkSync7(p);
36823
+ unlinkSync8(p);
36463
36824
  const meta = this.loadCloneMeta();
36464
36825
  delete meta[filename];
36465
36826
  this.saveCloneMeta(meta);
@@ -36480,7 +36841,7 @@ var init_voice = __esm({
36480
36841
  }
36481
36842
  /** Set the active clone reference by filename. */
36482
36843
  setActiveCloneRef(filename) {
36483
- const p = join43(luxttsCloneRefsDir(), filename);
36844
+ const p = join44(luxttsCloneRefsDir(), filename);
36484
36845
  if (!existsSync35(p))
36485
36846
  return `File not found: ${filename}`;
36486
36847
  this.luxttsCloneRef = p;
@@ -36766,11 +37127,11 @@ var init_voice = __esm({
36766
37127
  }
36767
37128
  this.onPCMOutput(Buffer.from(int16.buffer), sampleRate);
36768
37129
  }
36769
- const wavPath = join43(tmpdir8(), `oa-voice-${Date.now()}.wav`);
37130
+ const wavPath = join44(tmpdir9(), `oa-voice-${Date.now()}.wav`);
36770
37131
  this.writeWav(audioData, sampleRate, wavPath);
36771
37132
  await this.playWav(wavPath);
36772
37133
  try {
36773
- unlinkSync7(wavPath);
37134
+ unlinkSync8(wavPath);
36774
37135
  } catch {
36775
37136
  }
36776
37137
  }
@@ -37015,7 +37376,7 @@ var init_voice = __esm({
37015
37376
  return new Promise((resolve32, reject) => {
37016
37377
  const proc = nodeSpawn("sh", ["-c", command], {
37017
37378
  stdio: ["ignore", "pipe", "pipe"],
37018
- cwd: tmpdir8()
37379
+ cwd: tmpdir9()
37019
37380
  });
37020
37381
  let stdout = "";
37021
37382
  let stderr = "";
@@ -37109,7 +37470,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
37109
37470
  const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
37110
37471
  const mlxVoice = model.mlxVoice ?? "af_heart";
37111
37472
  const mlxLangCode = model.mlxLangCode ?? "a";
37112
- const wavPath = join43(tmpdir8(), `oa-mlx-${Date.now()}.wav`);
37473
+ const wavPath = join44(tmpdir9(), `oa-mlx-${Date.now()}.wav`);
37113
37474
  const pyScript = [
37114
37475
  "import sys, json",
37115
37476
  "from mlx_audio.tts import generate as tts_gen",
@@ -37117,11 +37478,11 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
37117
37478
  `tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
37118
37479
  ].join("; ");
37119
37480
  try {
37120
- execSync27(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir8() });
37481
+ execSync27(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
37121
37482
  } catch (err) {
37122
37483
  try {
37123
37484
  const safeText = cleaned.replace(/'/g, "'\\''");
37124
- execSync27(`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir8() });
37485
+ execSync27(`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
37125
37486
  } catch (err2) {
37126
37487
  return;
37127
37488
  }
@@ -37156,7 +37517,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
37156
37517
  }
37157
37518
  await this.playWav(wavPath);
37158
37519
  try {
37159
- unlinkSync7(wavPath);
37520
+ unlinkSync8(wavPath);
37160
37521
  } catch {
37161
37522
  }
37162
37523
  }
@@ -37177,7 +37538,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
37177
37538
  const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
37178
37539
  const mlxVoice = model.mlxVoice ?? "af_heart";
37179
37540
  const mlxLangCode = model.mlxLangCode ?? "a";
37180
- const wavPath = join43(tmpdir8(), `oa-mlx-buf-${Date.now()}.wav`);
37541
+ const wavPath = join44(tmpdir9(), `oa-mlx-buf-${Date.now()}.wav`);
37181
37542
  const pyScript = [
37182
37543
  "import sys, json",
37183
37544
  "from mlx_audio.tts import generate as tts_gen",
@@ -37185,11 +37546,11 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
37185
37546
  `tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
37186
37547
  ].join("; ");
37187
37548
  try {
37188
- execSync27(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir8() });
37549
+ execSync27(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
37189
37550
  } catch {
37190
37551
  try {
37191
37552
  const safeText = cleaned.replace(/'/g, "'\\''");
37192
- execSync27(`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir8() });
37553
+ execSync27(`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
37193
37554
  } catch {
37194
37555
  return null;
37195
37556
  }
@@ -37198,7 +37559,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
37198
37559
  return null;
37199
37560
  try {
37200
37561
  const data = readFileSync24(wavPath);
37201
- unlinkSync7(wavPath);
37562
+ unlinkSync8(wavPath);
37202
37563
  return data;
37203
37564
  } catch {
37204
37565
  return null;
@@ -37288,7 +37649,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
37288
37649
  }
37289
37650
  }
37290
37651
  const repoDir = luxttsRepoDir();
37291
- if (!existsSync35(join43(repoDir, "zipvoice", "luxvoice.py"))) {
37652
+ if (!existsSync35(join44(repoDir, "zipvoice", "luxvoice.py"))) {
37292
37653
  renderInfo(" Cloning LuxTTS repository...");
37293
37654
  try {
37294
37655
  if (existsSync35(repoDir)) {
@@ -37337,7 +37698,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
37337
37698
  if (!existsSync35(refsDir))
37338
37699
  return;
37339
37700
  for (const name of ["custom-clone.wav", "custom-clone.mp3", "glados-ref.wav", "overwatch-ref.wav"]) {
37340
- const p = join43(refsDir, name);
37701
+ const p = join44(refsDir, name);
37341
37702
  if (existsSync35(p)) {
37342
37703
  this.luxttsCloneRef = p;
37343
37704
  return;
@@ -37452,7 +37813,7 @@ if __name__ == '__main__':
37452
37813
  const env = { ...process.env, LUXTTS_REPO_PATH: luxttsRepoDir() };
37453
37814
  const daemon = nodeSpawn(venvPy, [luxttsInferScript()], {
37454
37815
  stdio: ["pipe", "pipe", "pipe"],
37455
- cwd: tmpdir8(),
37816
+ cwd: tmpdir9(),
37456
37817
  env
37457
37818
  });
37458
37819
  this._luxttsDaemon = daemon;
@@ -37534,7 +37895,7 @@ if __name__ == '__main__':
37534
37895
  const ready = await this.ensureLuxttsDaemon();
37535
37896
  if (!ready)
37536
37897
  return;
37537
- const wavPath = join43(tmpdir8(), `oa-luxtts-${Date.now()}.wav`);
37898
+ const wavPath = join44(tmpdir9(), `oa-luxtts-${Date.now()}.wav`);
37538
37899
  try {
37539
37900
  await this.luxttsRequest({
37540
37901
  action: "synthesize",
@@ -37591,7 +37952,7 @@ if __name__ == '__main__':
37591
37952
  }
37592
37953
  await this.playWav(wavPath);
37593
37954
  try {
37594
- unlinkSync7(wavPath);
37955
+ unlinkSync8(wavPath);
37595
37956
  } catch {
37596
37957
  }
37597
37958
  }
@@ -37608,7 +37969,7 @@ if __name__ == '__main__':
37608
37969
  const ready = await this.ensureLuxttsDaemon();
37609
37970
  if (!ready)
37610
37971
  return null;
37611
- const wavPath = join43(tmpdir8(), `oa-luxtts-buf-${Date.now()}.wav`);
37972
+ const wavPath = join44(tmpdir9(), `oa-luxtts-buf-${Date.now()}.wav`);
37612
37973
  try {
37613
37974
  await this.luxttsRequest({
37614
37975
  action: "synthesize",
@@ -37624,7 +37985,7 @@ if __name__ == '__main__':
37624
37985
  return null;
37625
37986
  try {
37626
37987
  const data = readFileSync24(wavPath);
37627
- unlinkSync7(wavPath);
37988
+ unlinkSync8(wavPath);
37628
37989
  return data;
37629
37990
  } catch {
37630
37991
  return null;
@@ -37638,7 +37999,7 @@ if __name__ == '__main__':
37638
37999
  return;
37639
38000
  const arch = process.arch;
37640
38001
  mkdirSync13(voiceDir(), { recursive: true });
37641
- const pkgPath = join43(voiceDir(), "package.json");
38002
+ const pkgPath = join44(voiceDir(), "package.json");
37642
38003
  const expectedDeps = {
37643
38004
  "onnxruntime-node": "^1.21.0",
37644
38005
  "phonemizer": "^1.2.1"
@@ -37660,17 +38021,17 @@ if __name__ == '__main__':
37660
38021
  dependencies: expectedDeps
37661
38022
  }, null, 2));
37662
38023
  }
37663
- const voiceRequire = createRequire(join43(voiceDir(), "index.js"));
38024
+ const voiceRequire = createRequire(join44(voiceDir(), "index.js"));
37664
38025
  const probeOnnx = () => {
37665
38026
  try {
37666
- const result = execSync27(`node -e "try { require('onnxruntime-node'); console.log('OK'); } catch(e) { console.log('FAIL:' + e.message); }"`, { cwd: voiceDir(), stdio: "pipe", timeout: 15e3, env: { ...process.env, NODE_PATH: join43(voiceDir(), "node_modules") } });
38027
+ const result = execSync27(`node -e "try { require('onnxruntime-node'); console.log('OK'); } catch(e) { console.log('FAIL:' + e.message); }"`, { cwd: voiceDir(), stdio: "pipe", timeout: 15e3, env: { ...process.env, NODE_PATH: join44(voiceDir(), "node_modules") } });
37667
38028
  const output = result.toString().trim();
37668
38029
  return output === "OK";
37669
38030
  } catch {
37670
38031
  return false;
37671
38032
  }
37672
38033
  };
37673
- const onnxNodeModules = join43(voiceDir(), "node_modules", "onnxruntime-node");
38034
+ const onnxNodeModules = join44(voiceDir(), "node_modules", "onnxruntime-node");
37674
38035
  const onnxInstalled = existsSync35(onnxNodeModules);
37675
38036
  if (onnxInstalled && !probeOnnx()) {
37676
38037
  throw new Error(`Voice synthesis unavailable: ONNX runtime crashes on this CPU (${process.platform}-${arch}). This is a known issue with some ARM SoCs where the CPU vendor is not recognized. Voice feedback will be disabled but all other features work normally.`);
@@ -40014,8 +40375,8 @@ async function handlePeerEndpoint(peerId, authKey, ctx, local) {
40014
40375
  if (models.length > 0) {
40015
40376
  try {
40016
40377
  const { writeFileSync: writeFileSync20, mkdirSync: mkdirSync21 } = await import("node:fs");
40017
- const { join: join57, dirname: dirname20 } = await import("node:path");
40018
- const cachePath = join57(ctx.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
40378
+ const { join: join58, dirname: dirname20 } = await import("node:path");
40379
+ const cachePath = join58(ctx.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
40019
40380
  mkdirSync21(dirname20(cachePath), { recursive: true });
40020
40381
  writeFileSync20(cachePath, JSON.stringify({
40021
40382
  peerId,
@@ -40168,8 +40529,8 @@ Environment="OLLAMA_NUM_PARALLEL=${n}"
40168
40529
  }
40169
40530
  await new Promise((r) => setTimeout(r, 1e3));
40170
40531
  process.env.OLLAMA_NUM_PARALLEL = String(n);
40171
- const { spawn: spawn19 } = await import("node:child_process");
40172
- const child = spawn19("ollama", ["serve"], {
40532
+ const { spawn: spawn20 } = await import("node:child_process");
40533
+ const child = spawn20("ollama", ["serve"], {
40173
40534
  stdio: "ignore",
40174
40535
  detached: true,
40175
40536
  env: { ...process.env, OLLAMA_NUM_PARALLEL: String(n) }
@@ -40216,14 +40577,14 @@ async function handleUpdate(subcommand, ctx) {
40216
40577
  try {
40217
40578
  const { createRequire: createRequire4 } = await import("node:module");
40218
40579
  const { fileURLToPath: fileURLToPath14 } = await import("node:url");
40219
- const { dirname: dirname20, join: join57 } = await import("node:path");
40580
+ const { dirname: dirname20, join: join58 } = await import("node:path");
40220
40581
  const { existsSync: existsSync45 } = await import("node:fs");
40221
40582
  const req = createRequire4(import.meta.url);
40222
40583
  const thisDir = dirname20(fileURLToPath14(import.meta.url));
40223
40584
  const candidates = [
40224
- join57(thisDir, "..", "package.json"),
40225
- join57(thisDir, "..", "..", "package.json"),
40226
- join57(thisDir, "..", "..", "..", "package.json")
40585
+ join58(thisDir, "..", "package.json"),
40586
+ join58(thisDir, "..", "..", "package.json"),
40587
+ join58(thisDir, "..", "..", "..", "package.json")
40227
40588
  ];
40228
40589
  for (const pkgPath of candidates) {
40229
40590
  if (existsSync45(pkgPath)) {
@@ -40941,7 +41302,7 @@ var init_commands = __esm({
40941
41302
 
40942
41303
  // packages/cli/dist/tui/project-context.js
40943
41304
  import { existsSync as existsSync36, readFileSync as readFileSync25, readdirSync as readdirSync10 } from "node:fs";
40944
- import { join as join44, basename as basename10 } from "node:path";
41305
+ import { join as join45, basename as basename10 } from "node:path";
40945
41306
  import { execSync as execSync28 } from "node:child_process";
40946
41307
  import { homedir as homedir12, platform as platform3, release } from "node:os";
40947
41308
  function getModelTier(modelName) {
@@ -40976,7 +41337,7 @@ function loadProjectMap(repoRoot) {
40976
41337
  if (!hasOaDirectory(repoRoot)) {
40977
41338
  initOaDirectory(repoRoot);
40978
41339
  }
40979
- const mapPath = join44(repoRoot, OA_DIR, "context", "project-map.md");
41340
+ const mapPath = join45(repoRoot, OA_DIR, "context", "project-map.md");
40980
41341
  if (existsSync36(mapPath)) {
40981
41342
  try {
40982
41343
  const content = readFileSync25(mapPath, "utf-8");
@@ -41020,17 +41381,17 @@ ${log}`);
41020
41381
  }
41021
41382
  function loadMemoryContext(repoRoot) {
41022
41383
  const sections = [];
41023
- const oaMemDir = join44(repoRoot, OA_DIR, "memory");
41384
+ const oaMemDir = join45(repoRoot, OA_DIR, "memory");
41024
41385
  const oaEntries = loadMemoryDir(oaMemDir, "project");
41025
41386
  if (oaEntries)
41026
41387
  sections.push(oaEntries);
41027
- const legacyMemDir = join44(repoRoot, ".open-agents", "memory");
41388
+ const legacyMemDir = join45(repoRoot, ".open-agents", "memory");
41028
41389
  if (legacyMemDir !== oaMemDir && existsSync36(legacyMemDir)) {
41029
41390
  const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
41030
41391
  if (legacyEntries)
41031
41392
  sections.push(legacyEntries);
41032
41393
  }
41033
- const globalMemDir = join44(homedir12(), ".open-agents", "memory");
41394
+ const globalMemDir = join45(homedir12(), ".open-agents", "memory");
41034
41395
  const globalEntries = loadMemoryDir(globalMemDir, "global");
41035
41396
  if (globalEntries)
41036
41397
  sections.push(globalEntries);
@@ -41044,7 +41405,7 @@ function loadMemoryDir(memDir, scope) {
41044
41405
  const files = readdirSync10(memDir).filter((f) => f.endsWith(".json"));
41045
41406
  for (const file of files.slice(0, 10)) {
41046
41407
  try {
41047
- const raw = readFileSync25(join44(memDir, file), "utf-8");
41408
+ const raw = readFileSync25(join45(memDir, file), "utf-8");
41048
41409
  const entries = JSON.parse(raw);
41049
41410
  const topic = basename10(file, ".json");
41050
41411
  const keys = Object.keys(entries);
@@ -42068,9 +42429,9 @@ var init_carousel = __esm({
42068
42429
 
42069
42430
  // packages/cli/dist/tui/carousel-descriptors.js
42070
42431
  import { existsSync as existsSync37, readFileSync as readFileSync26, writeFileSync as writeFileSync15, mkdirSync as mkdirSync14, readdirSync as readdirSync11 } from "node:fs";
42071
- import { join as join45, basename as basename11 } from "node:path";
42432
+ import { join as join46, basename as basename11 } from "node:path";
42072
42433
  function loadToolProfile(repoRoot) {
42073
- const filePath = join45(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
42434
+ const filePath = join46(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
42074
42435
  try {
42075
42436
  if (!existsSync37(filePath))
42076
42437
  return null;
@@ -42080,9 +42441,9 @@ function loadToolProfile(repoRoot) {
42080
42441
  }
42081
42442
  }
42082
42443
  function saveToolProfile(repoRoot, profile) {
42083
- const contextDir = join45(repoRoot, OA_DIR, "context");
42444
+ const contextDir = join46(repoRoot, OA_DIR, "context");
42084
42445
  mkdirSync14(contextDir, { recursive: true });
42085
- writeFileSync15(join45(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
42446
+ writeFileSync15(join46(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
42086
42447
  }
42087
42448
  function categorizeToolCall(toolName) {
42088
42449
  for (const cat of TOOL_CATEGORIES) {
@@ -42140,7 +42501,7 @@ function weightedColor(profile) {
42140
42501
  return selectedCat.colors[Math.floor(Math.random() * selectedCat.colors.length)];
42141
42502
  }
42142
42503
  function loadCachedDescriptors(repoRoot) {
42143
- const filePath = join45(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
42504
+ const filePath = join46(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
42144
42505
  try {
42145
42506
  if (!existsSync37(filePath))
42146
42507
  return null;
@@ -42151,14 +42512,14 @@ function loadCachedDescriptors(repoRoot) {
42151
42512
  }
42152
42513
  }
42153
42514
  function saveCachedDescriptors(repoRoot, phrases, sourceHash) {
42154
- const contextDir = join45(repoRoot, OA_DIR, "context");
42515
+ const contextDir = join46(repoRoot, OA_DIR, "context");
42155
42516
  mkdirSync14(contextDir, { recursive: true });
42156
42517
  const cached = {
42157
42518
  phrases,
42158
42519
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
42159
42520
  sourceHash
42160
42521
  };
42161
- writeFileSync15(join45(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
42522
+ writeFileSync15(join46(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
42162
42523
  }
42163
42524
  function generateDescriptors(repoRoot) {
42164
42525
  const profile = loadToolProfile(repoRoot);
@@ -42206,7 +42567,7 @@ function generateDescriptors(repoRoot) {
42206
42567
  return phrases;
42207
42568
  }
42208
42569
  function extractFromPackageJson(repoRoot, tags) {
42209
- const pkgPath = join45(repoRoot, "package.json");
42570
+ const pkgPath = join46(repoRoot, "package.json");
42210
42571
  try {
42211
42572
  if (!existsSync37(pkgPath))
42212
42573
  return;
@@ -42254,7 +42615,7 @@ function extractFromManifests(repoRoot, tags) {
42254
42615
  { file: ".github/workflows", tag: "ci/cd" }
42255
42616
  ];
42256
42617
  for (const check of manifestChecks) {
42257
- if (existsSync37(join45(repoRoot, check.file))) {
42618
+ if (existsSync37(join46(repoRoot, check.file))) {
42258
42619
  tags.push(check.tag);
42259
42620
  }
42260
42621
  }
@@ -42276,7 +42637,7 @@ function extractFromSessions(repoRoot, tags) {
42276
42637
  }
42277
42638
  }
42278
42639
  function extractFromMemory(repoRoot, tags) {
42279
- const memoryDir = join45(repoRoot, OA_DIR, "memory");
42640
+ const memoryDir = join46(repoRoot, OA_DIR, "memory");
42280
42641
  try {
42281
42642
  if (!existsSync37(memoryDir))
42282
42643
  return;
@@ -42285,7 +42646,7 @@ function extractFromMemory(repoRoot, tags) {
42285
42646
  const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
42286
42647
  tags.push(topic);
42287
42648
  try {
42288
- const data = JSON.parse(readFileSync26(join45(memoryDir, file), "utf-8"));
42649
+ const data = JSON.parse(readFileSync26(join46(memoryDir, file), "utf-8"));
42289
42650
  if (data && typeof data === "object") {
42290
42651
  const keys = Object.keys(data).slice(0, 3);
42291
42652
  for (const key of keys) {
@@ -42908,10 +43269,10 @@ var init_stream_renderer = __esm({
42908
43269
 
42909
43270
  // packages/cli/dist/tui/edit-history.js
42910
43271
  import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync15 } from "node:fs";
42911
- import { join as join46 } from "node:path";
43272
+ import { join as join47 } from "node:path";
42912
43273
  function createEditHistoryLogger(repoRoot, sessionId) {
42913
- const historyDir = join46(repoRoot, ".oa", "history");
42914
- const logPath = join46(historyDir, "edits.jsonl");
43274
+ const historyDir = join47(repoRoot, ".oa", "history");
43275
+ const logPath = join47(historyDir, "edits.jsonl");
42915
43276
  try {
42916
43277
  mkdirSync15(historyDir, { recursive: true });
42917
43278
  } catch {
@@ -43023,12 +43384,12 @@ var init_edit_history = __esm({
43023
43384
 
43024
43385
  // packages/cli/dist/tui/promptLoader.js
43025
43386
  import { readFileSync as readFileSync27, existsSync as existsSync38 } from "node:fs";
43026
- import { join as join47, dirname as dirname17 } from "node:path";
43387
+ import { join as join48, dirname as dirname17 } from "node:path";
43027
43388
  import { fileURLToPath as fileURLToPath11 } from "node:url";
43028
43389
  function loadPrompt3(promptPath, vars) {
43029
43390
  let content = cache3.get(promptPath);
43030
43391
  if (content === void 0) {
43031
- const fullPath = join47(PROMPTS_DIR3, promptPath);
43392
+ const fullPath = join48(PROMPTS_DIR3, promptPath);
43032
43393
  if (!existsSync38(fullPath)) {
43033
43394
  throw new Error(`Prompt file not found: ${fullPath}`);
43034
43395
  }
@@ -43045,8 +43406,8 @@ var init_promptLoader3 = __esm({
43045
43406
  "use strict";
43046
43407
  __filename3 = fileURLToPath11(import.meta.url);
43047
43408
  __dirname6 = dirname17(__filename3);
43048
- devPath2 = join47(__dirname6, "..", "..", "prompts");
43049
- publishedPath2 = join47(__dirname6, "..", "prompts");
43409
+ devPath2 = join48(__dirname6, "..", "..", "prompts");
43410
+ publishedPath2 = join48(__dirname6, "..", "prompts");
43050
43411
  PROMPTS_DIR3 = existsSync38(devPath2) ? devPath2 : publishedPath2;
43051
43412
  cache3 = /* @__PURE__ */ new Map();
43052
43413
  }
@@ -43054,10 +43415,10 @@ var init_promptLoader3 = __esm({
43054
43415
 
43055
43416
  // packages/cli/dist/tui/dream-engine.js
43056
43417
  import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync16, readFileSync as readFileSync28, existsSync as existsSync39, cpSync, rmSync, readdirSync as readdirSync12 } from "node:fs";
43057
- import { join as join48, basename as basename12 } from "node:path";
43418
+ import { join as join49, basename as basename12 } from "node:path";
43058
43419
  import { execSync as execSync29 } from "node:child_process";
43059
43420
  function loadAutoresearchMemory(repoRoot) {
43060
- const memoryPath = join48(repoRoot, ".oa", "memory", "autoresearch.json");
43421
+ const memoryPath = join49(repoRoot, ".oa", "memory", "autoresearch.json");
43061
43422
  if (!existsSync39(memoryPath))
43062
43423
  return "";
43063
43424
  try {
@@ -43251,12 +43612,12 @@ var init_dream_engine = __esm({
43251
43612
  const content = String(args["content"] ?? "");
43252
43613
  if (!rawPath)
43253
43614
  return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
43254
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join48(this.autoresearchDir, basename12(rawPath)) : join48(this.autoresearchDir, rawPath);
43615
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join49(this.autoresearchDir, basename12(rawPath)) : join49(this.autoresearchDir, rawPath);
43255
43616
  if (!targetPath.startsWith(this.autoresearchDir)) {
43256
43617
  return { success: false, output: "", error: "Autoresearch mode: writes are confined to .oa/autoresearch/", durationMs: Date.now() - start };
43257
43618
  }
43258
43619
  try {
43259
- const dir = join48(targetPath, "..");
43620
+ const dir = join49(targetPath, "..");
43260
43621
  mkdirSync16(dir, { recursive: true });
43261
43622
  writeFileSync16(targetPath, content, "utf-8");
43262
43623
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
@@ -43286,7 +43647,7 @@ var init_dream_engine = __esm({
43286
43647
  const rawPath = String(args["path"] ?? "");
43287
43648
  const oldStr = String(args["old_string"] ?? "");
43288
43649
  const newStr = String(args["new_string"] ?? "");
43289
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join48(this.autoresearchDir, basename12(rawPath)) : join48(this.autoresearchDir, rawPath);
43650
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join49(this.autoresearchDir, basename12(rawPath)) : join49(this.autoresearchDir, rawPath);
43290
43651
  if (!targetPath.startsWith(this.autoresearchDir)) {
43291
43652
  return { success: false, output: "", error: "Autoresearch mode: edits are confined to .oa/autoresearch/", durationMs: Date.now() - start };
43292
43653
  }
@@ -43340,12 +43701,12 @@ var init_dream_engine = __esm({
43340
43701
  const content = String(args["content"] ?? "");
43341
43702
  if (!rawPath)
43342
43703
  return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
43343
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join48(this.dreamsDir, basename12(rawPath)) : join48(this.dreamsDir, rawPath);
43704
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join49(this.dreamsDir, basename12(rawPath)) : join49(this.dreamsDir, rawPath);
43344
43705
  if (!targetPath.startsWith(this.dreamsDir)) {
43345
43706
  return { success: false, output: "", error: "Dream mode: writes are confined to .oa/dreams/", durationMs: Date.now() - start };
43346
43707
  }
43347
43708
  try {
43348
- const dir = join48(targetPath, "..");
43709
+ const dir = join49(targetPath, "..");
43349
43710
  mkdirSync16(dir, { recursive: true });
43350
43711
  writeFileSync16(targetPath, content, "utf-8");
43351
43712
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
@@ -43375,7 +43736,7 @@ var init_dream_engine = __esm({
43375
43736
  const rawPath = String(args["path"] ?? "");
43376
43737
  const oldStr = String(args["old_string"] ?? "");
43377
43738
  const newStr = String(args["new_string"] ?? "");
43378
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join48(this.dreamsDir, basename12(rawPath)) : join48(this.dreamsDir, rawPath);
43739
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join49(this.dreamsDir, basename12(rawPath)) : join49(this.dreamsDir, rawPath);
43379
43740
  if (!targetPath.startsWith(this.dreamsDir)) {
43380
43741
  return { success: false, output: "", error: "Dream mode: edits are confined to .oa/dreams/", durationMs: Date.now() - start };
43381
43742
  }
@@ -43442,7 +43803,7 @@ var init_dream_engine = __esm({
43442
43803
  constructor(config, repoRoot) {
43443
43804
  this.config = config;
43444
43805
  this.repoRoot = repoRoot;
43445
- this.dreamsDir = join48(repoRoot, ".oa", "dreams");
43806
+ this.dreamsDir = join49(repoRoot, ".oa", "dreams");
43446
43807
  this.state = {
43447
43808
  mode: "default",
43448
43809
  active: false,
@@ -43526,7 +43887,7 @@ ${result.summary}`;
43526
43887
  if (mode !== "default" || cycle === totalCycles) {
43527
43888
  renderDreamContraction(cycle);
43528
43889
  const cycleSummary = this.buildCycleSummary(cycle, previousFindings);
43529
- const summaryPath = join48(this.dreamsDir, `cycle-${cycle}-summary.md`);
43890
+ const summaryPath = join49(this.dreamsDir, `cycle-${cycle}-summary.md`);
43530
43891
  writeFileSync16(summaryPath, cycleSummary, "utf-8");
43531
43892
  }
43532
43893
  if (mode === "lucid" && !this.abortController.signal.aborted) {
@@ -43739,7 +44100,7 @@ After synthesis, call task_complete with the final prioritized summary.`, toolMo
43739
44100
  }
43740
44101
  /** Build role-specific tool sets for swarm agents */
43741
44102
  buildSwarmTools(role, _workspace) {
43742
- const autoresearchDir = join48(this.repoRoot, ".oa", "autoresearch");
44103
+ const autoresearchDir = join49(this.repoRoot, ".oa", "autoresearch");
43743
44104
  const taskComplete = this.createSwarmTaskCompleteTool(role);
43744
44105
  switch (role) {
43745
44106
  case "researcher": {
@@ -44103,7 +44464,7 @@ INSTRUCTIONS:
44103
44464
  2. Summarize the key learnings and next steps
44104
44465
 
44105
44466
  Call task_complete with a human-readable summary of the autoresearch session.`, workspace, onEvent);
44106
- const reportPath = join48(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
44467
+ const reportPath = join49(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
44107
44468
  const report = `# Autoresearch Swarm Report \u2014 Cycle ${cycleNum}
44108
44469
 
44109
44470
  **Date**: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
@@ -44192,7 +44553,7 @@ ${summaryResult}
44192
44553
  }
44193
44554
  /** Save workspace backup for lucid mode */
44194
44555
  saveVersionCheckpoint(cycle) {
44195
- const checkpointDir = join48(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
44556
+ const checkpointDir = join49(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
44196
44557
  try {
44197
44558
  mkdirSync16(checkpointDir, { recursive: true });
44198
44559
  try {
@@ -44211,10 +44572,10 @@ ${summaryResult}
44211
44572
  encoding: "utf-8",
44212
44573
  timeout: 5e3
44213
44574
  }).trim();
44214
- writeFileSync16(join48(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
44215
- writeFileSync16(join48(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
44216
- writeFileSync16(join48(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
44217
- writeFileSync16(join48(checkpointDir, "checkpoint.json"), JSON.stringify({
44575
+ writeFileSync16(join49(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
44576
+ writeFileSync16(join49(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
44577
+ writeFileSync16(join49(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
44578
+ writeFileSync16(join49(checkpointDir, "checkpoint.json"), JSON.stringify({
44218
44579
  cycle,
44219
44580
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
44220
44581
  gitHash,
@@ -44222,7 +44583,7 @@ ${summaryResult}
44222
44583
  }, null, 2), "utf-8");
44223
44584
  renderInfo(`Checkpoint saved: cycle ${cycle} (${gitHash.slice(0, 8)})`);
44224
44585
  } catch {
44225
- writeFileSync16(join48(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
44586
+ writeFileSync16(join49(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
44226
44587
  renderInfo(`Checkpoint saved: cycle ${cycle} (no git)`);
44227
44588
  }
44228
44589
  } catch (err) {
@@ -44280,14 +44641,14 @@ ${files.map((f) => `- [\`${f}\`](./${f})`).join("\n")}
44280
44641
  ---
44281
44642
  *Auto-generated by open-agents dream engine*
44282
44643
  `;
44283
- writeFileSync16(join48(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
44644
+ writeFileSync16(join49(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
44284
44645
  } catch {
44285
44646
  }
44286
44647
  }
44287
44648
  /** Save dream state for resume/inspection */
44288
44649
  saveDreamState() {
44289
44650
  try {
44290
- writeFileSync16(join48(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
44651
+ writeFileSync16(join49(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
44291
44652
  } catch {
44292
44653
  }
44293
44654
  }
@@ -44661,8 +45022,8 @@ var init_bless_engine = __esm({
44661
45022
  });
44662
45023
 
44663
45024
  // packages/cli/dist/tui/dmn-engine.js
44664
- import { existsSync as existsSync40, readFileSync as readFileSync29, writeFileSync as writeFileSync17, mkdirSync as mkdirSync17, readdirSync as readdirSync13, unlinkSync as unlinkSync8 } from "node:fs";
44665
- import { join as join49, basename as basename13 } from "node:path";
45025
+ import { existsSync as existsSync40, readFileSync as readFileSync29, writeFileSync as writeFileSync17, mkdirSync as mkdirSync17, readdirSync as readdirSync13, unlinkSync as unlinkSync9 } from "node:fs";
45026
+ import { join as join50, basename as basename13 } from "node:path";
44666
45027
  function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
44667
45028
  const competenceReport = competence.length > 0 ? competence.map((c3) => {
44668
45029
  const rate = c3.attempts > 0 ? Math.round(c3.successes / c3.attempts * 100) : 0;
@@ -44775,8 +45136,8 @@ var init_dmn_engine = __esm({
44775
45136
  constructor(config, repoRoot) {
44776
45137
  this.config = config;
44777
45138
  this.repoRoot = repoRoot;
44778
- this.stateDir = join49(repoRoot, ".oa", "dmn");
44779
- this.historyDir = join49(repoRoot, ".oa", "dmn", "cycles");
45139
+ this.stateDir = join50(repoRoot, ".oa", "dmn");
45140
+ this.historyDir = join50(repoRoot, ".oa", "dmn", "cycles");
44780
45141
  mkdirSync17(this.historyDir, { recursive: true });
44781
45142
  this.loadState();
44782
45143
  }
@@ -45366,8 +45727,8 @@ OUTPUT: Call task_complete with JSON:
45366
45727
  async gatherMemoryTopics() {
45367
45728
  const topics = [];
45368
45729
  const dirs = [
45369
- join49(this.repoRoot, ".oa", "memory"),
45370
- join49(this.repoRoot, ".open-agents", "memory")
45730
+ join50(this.repoRoot, ".oa", "memory"),
45731
+ join50(this.repoRoot, ".open-agents", "memory")
45371
45732
  ];
45372
45733
  for (const dir of dirs) {
45373
45734
  if (!existsSync40(dir))
@@ -45386,7 +45747,7 @@ OUTPUT: Call task_complete with JSON:
45386
45747
  }
45387
45748
  // ── State persistence ─────────────────────────────────────────────────
45388
45749
  loadState() {
45389
- const path = join49(this.stateDir, "state.json");
45750
+ const path = join50(this.stateDir, "state.json");
45390
45751
  if (existsSync40(path)) {
45391
45752
  try {
45392
45753
  this.state = JSON.parse(readFileSync29(path, "utf-8"));
@@ -45396,19 +45757,19 @@ OUTPUT: Call task_complete with JSON:
45396
45757
  }
45397
45758
  saveState() {
45398
45759
  try {
45399
- writeFileSync17(join49(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
45760
+ writeFileSync17(join50(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
45400
45761
  } catch {
45401
45762
  }
45402
45763
  }
45403
45764
  saveCycleResult(result) {
45404
45765
  try {
45405
45766
  const filename = `cycle-${result.cycleNumber}-${Date.now()}.json`;
45406
- writeFileSync17(join49(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
45767
+ writeFileSync17(join50(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
45407
45768
  const files = readdirSync13(this.historyDir).filter((f) => f.startsWith("cycle-") && f.endsWith(".json")).sort();
45408
45769
  if (files.length > 50) {
45409
45770
  for (const old of files.slice(0, files.length - 50)) {
45410
45771
  try {
45411
- unlinkSync8(join49(this.historyDir, old));
45772
+ unlinkSync9(join50(this.historyDir, old));
45412
45773
  } catch {
45413
45774
  }
45414
45775
  }
@@ -45422,7 +45783,7 @@ OUTPUT: Call task_complete with JSON:
45422
45783
 
45423
45784
  // packages/cli/dist/tui/snr-engine.js
45424
45785
  import { existsSync as existsSync41, readdirSync as readdirSync14, readFileSync as readFileSync30 } from "node:fs";
45425
- import { join as join50, basename as basename14 } from "node:path";
45786
+ import { join as join51, basename as basename14 } from "node:path";
45426
45787
  function computeDPrime(signalScores, noiseScores) {
45427
45788
  if (signalScores.length === 0 || noiseScores.length === 0)
45428
45789
  return 0;
@@ -45662,8 +46023,8 @@ Call task_complete with the JSON array when done.`, onEvent)
45662
46023
  loadMemoryEntries(topics) {
45663
46024
  const entries = [];
45664
46025
  const dirs = [
45665
- join50(this.repoRoot, ".oa", "memory"),
45666
- join50(this.repoRoot, ".open-agents", "memory")
46026
+ join51(this.repoRoot, ".oa", "memory"),
46027
+ join51(this.repoRoot, ".open-agents", "memory")
45667
46028
  ];
45668
46029
  for (const dir of dirs) {
45669
46030
  if (!existsSync41(dir))
@@ -45675,7 +46036,7 @@ Call task_complete with the JSON array when done.`, onEvent)
45675
46036
  if (topics.length > 0 && !topics.includes(topic))
45676
46037
  continue;
45677
46038
  try {
45678
- const data = JSON.parse(readFileSync30(join50(dir, f), "utf-8"));
46039
+ const data = JSON.parse(readFileSync30(join51(dir, f), "utf-8"));
45679
46040
  for (const [key, val] of Object.entries(data)) {
45680
46041
  const value = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
45681
46042
  entries.push({ topic, key, value });
@@ -46242,8 +46603,8 @@ var init_tool_policy = __esm({
46242
46603
  });
46243
46604
 
46244
46605
  // packages/cli/dist/tui/telegram-bridge.js
46245
- import { mkdirSync as mkdirSync18, existsSync as existsSync42, unlinkSync as unlinkSync9, readdirSync as readdirSync15, statSync as statSync13 } from "node:fs";
46246
- import { join as join51, resolve as resolve28 } from "node:path";
46606
+ import { mkdirSync as mkdirSync18, existsSync as existsSync42, unlinkSync as unlinkSync10, readdirSync as readdirSync15, statSync as statSync13 } from "node:fs";
46607
+ import { join as join52, resolve as resolve28 } from "node:path";
46247
46608
  import { writeFile as writeFileAsync } from "node:fs/promises";
46248
46609
  function convertMarkdownToTelegramHTML(md) {
46249
46610
  let html = md;
@@ -47008,7 +47369,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
47008
47369
  return null;
47009
47370
  const buffer = Buffer.from(await res.arrayBuffer());
47010
47371
  const fileName = `${Date.now()}-${fileId.slice(0, 8)}${extension}`;
47011
- const localPath = join51(this.mediaCacheDir, fileName);
47372
+ const localPath = join52(this.mediaCacheDir, fileName);
47012
47373
  await writeFileAsync(localPath, buffer);
47013
47374
  return localPath;
47014
47375
  } catch {
@@ -47096,7 +47457,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
47096
47457
  for (const [key, entry] of this.mediaCache) {
47097
47458
  if (now - entry.cachedAt > MEDIA_CACHE_TTL_MS) {
47098
47459
  try {
47099
- unlinkSync9(entry.localPath);
47460
+ unlinkSync10(entry.localPath);
47100
47461
  } catch {
47101
47462
  }
47102
47463
  this.mediaCache.delete(key);
@@ -47172,11 +47533,11 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
47172
47533
  let mimeType = "audio/wav";
47173
47534
  try {
47174
47535
  const { execSync: execSyncLocal } = await import("node:child_process");
47175
- const { tmpdir: tmpdir10 } = await import("node:os");
47536
+ const { tmpdir: tmpdir11 } = await import("node:os");
47176
47537
  const { join: joinPath } = await import("node:path");
47177
47538
  const { writeFileSync: writeFs, readFileSync: readFs, unlinkSync: unlinkFs } = await import("node:fs");
47178
- const tmpWav = joinPath(tmpdir10(), `oa-tg-voice-${Date.now()}.wav`);
47179
- const tmpOgg = joinPath(tmpdir10(), `oa-tg-voice-${Date.now()}.ogg`);
47539
+ const tmpWav = joinPath(tmpdir11(), `oa-tg-voice-${Date.now()}.wav`);
47540
+ const tmpOgg = joinPath(tmpdir11(), `oa-tg-voice-${Date.now()}.ogg`);
47180
47541
  writeFs(tmpWav, wavBuffer);
47181
47542
  execSyncLocal(`ffmpeg -i "${tmpWav}" -c:a libopus -b:a 48k -ar 48000 -ac 1 "${tmpOgg}" -y 2>/dev/null`, {
47182
47543
  timeout: 15e3,
@@ -49446,7 +49807,7 @@ var init_status_bar = __esm({
49446
49807
  import * as readline2 from "node:readline";
49447
49808
  import { Writable } from "node:stream";
49448
49809
  import { cwd } from "node:process";
49449
- import { resolve as resolve29, join as join52, dirname as dirname18, extname as extname10 } from "node:path";
49810
+ import { resolve as resolve29, join as join53, dirname as dirname18, extname as extname10 } from "node:path";
49450
49811
  import { createRequire as createRequire2 } from "node:module";
49451
49812
  import { fileURLToPath as fileURLToPath12 } from "node:url";
49452
49813
  import { readFileSync as readFileSync32, writeFileSync as writeFileSync18, appendFileSync as appendFileSync4, rmSync as rmSync2, readdirSync as readdirSync16, mkdirSync as mkdirSync19 } from "node:fs";
@@ -49470,9 +49831,9 @@ function getVersion3() {
49470
49831
  const require2 = createRequire2(import.meta.url);
49471
49832
  const thisDir = dirname18(fileURLToPath12(import.meta.url));
49472
49833
  const candidates = [
49473
- join52(thisDir, "..", "package.json"),
49474
- join52(thisDir, "..", "..", "package.json"),
49475
- join52(thisDir, "..", "..", "..", "package.json")
49834
+ join53(thisDir, "..", "package.json"),
49835
+ join53(thisDir, "..", "..", "package.json"),
49836
+ join53(thisDir, "..", "..", "..", "package.json")
49476
49837
  ];
49477
49838
  for (const pkgPath of candidates) {
49478
49839
  if (existsSync43(pkgPath)) {
@@ -49563,6 +49924,8 @@ function buildTools(repoRoot, config, contextWindowSize) {
49563
49924
  new StructuredFileTool(repoRoot),
49564
49925
  // Code sandbox (isolated code execution)
49565
49926
  new CodeSandboxTool(repoRoot),
49927
+ // Persistent Python REPL — RLM (arxiv:2512.24601)
49928
+ new ReplTool(repoRoot),
49566
49929
  // Structured file reading (CSV, JSON, Markdown, binary detection)
49567
49930
  new StructuredReadTool(repoRoot),
49568
49931
  // Vision tools (Moondream — desktop awareness + point-and-click)
@@ -49682,15 +50045,15 @@ Use task_status("${taskId}") or task_output("${taskId}") to check progress.`
49682
50045
  function gatherMemorySnippets(root) {
49683
50046
  const snippets = [];
49684
50047
  const dirs = [
49685
- join52(root, ".oa", "memory"),
49686
- join52(root, ".open-agents", "memory")
50048
+ join53(root, ".oa", "memory"),
50049
+ join53(root, ".open-agents", "memory")
49687
50050
  ];
49688
50051
  for (const dir of dirs) {
49689
50052
  if (!existsSync43(dir))
49690
50053
  continue;
49691
50054
  try {
49692
50055
  for (const f of readdirSync16(dir).filter((f2) => f2.endsWith(".json"))) {
49693
- const data = JSON.parse(readFileSync32(join52(dir, f), "utf-8"));
50056
+ const data = JSON.parse(readFileSync32(join53(dir, f), "utf-8"));
49694
50057
  for (const val of Object.values(data)) {
49695
50058
  const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
49696
50059
  if (v.length > 10)
@@ -49906,6 +50269,33 @@ function startTask(task, config, repoRoot, voice, stream, taskStores, bruteForce
49906
50269
  tool.setActiveModel(config.model, hasVision);
49907
50270
  }
49908
50271
  }
50272
+ for (const tool of tools) {
50273
+ if ("setLlmQueryHandler" in tool && typeof tool.setLlmQueryHandler === "function") {
50274
+ tool.setLlmQueryHandler(async (prompt, context) => {
50275
+ const subPrompt = context ? `${prompt}
50276
+
50277
+ Context:
50278
+ ${context}` : prompt;
50279
+ const response = await backend.chatCompletion({
50280
+ messages: [
50281
+ { role: "system", content: "You are a helpful assistant. Respond concisely and accurately." },
50282
+ { role: "user", content: subPrompt }
50283
+ ],
50284
+ tools: [],
50285
+ temperature: 0,
50286
+ maxTokens: 4096,
50287
+ timeoutMs: 12e4
50288
+ });
50289
+ return response.choices?.[0]?.message?.content ?? "";
50290
+ });
50291
+ }
50292
+ }
50293
+ const replToolForFinalVar = tools.find((t) => t.name === "repl_exec");
50294
+ if (replToolForFinalVar && "readVariable" in replToolForFinalVar) {
50295
+ runner.options.finalVarResolver = async (varName) => {
50296
+ return replToolForFinalVar.readVariable(varName);
50297
+ };
50298
+ }
49909
50299
  runner.registerTools(tools);
49910
50300
  runner.registerTool({
49911
50301
  name: "memex_retrieve",
@@ -50364,7 +50754,30 @@ ${entry.fullContent}`
50364
50754
 
50365
50755
  ${emotionContext}` : `Working directory: ${repoRoot}`;
50366
50756
  resetNarrationContext();
50367
- const promise = runner.run(task, systemContext).then((result) => {
50757
+ let effectiveTask = task;
50758
+ const estimatedTaskTokens = Math.ceil(task.length / 4);
50759
+ const externalizeThreshold = contextWindowSize ? Math.floor(contextWindowSize * 0.4) : 3e4;
50760
+ if (estimatedTaskTokens > externalizeThreshold) {
50761
+ const replTool = tools.find((t) => t.name === "repl_exec");
50762
+ if (replTool && "loadContext" in replTool) {
50763
+ replTool.loadContext(task);
50764
+ const prefix = task.slice(0, 500).replace(/\n/g, " ");
50765
+ effectiveTask = `[RLM MODE \u2014 Large input externalized to REPL]
50766
+ Your input has been stored as the variable \`context\` in the persistent Python REPL.
50767
+ Context length: ${task.length} characters (~${estimatedTaskTokens} tokens)
50768
+ Prefix: "${prefix}..."
50769
+
50770
+ Use repl_exec to examine and process the context. For example:
50771
+ repl_exec(code="print(context[:1000])") # see the beginning
50772
+ repl_exec(code="print(len(context))") # check length
50773
+ repl_exec(code="chunks = context.split('\\n\\n')") # split into chunks
50774
+
50775
+ Use llm_query(prompt, chunk) inside repl_exec to analyze chunks.
50776
+ When done, either call task_complete with your answer, or use FINAL_VAR(variable_name) to return a REPL variable as the output.`;
50777
+ contentWrite(() => renderInfo(`RLM: Externalized ${task.length} chars (~${estimatedTaskTokens} tokens) to REPL context variable`));
50778
+ }
50779
+ }
50780
+ const promise = runner.run(effectiveTask, systemContext).then((result) => {
50368
50781
  const tokens = { total: result.totalTokens, estimated: result.estimatedTokens };
50369
50782
  contentWrite(() => {
50370
50783
  if (result.completed) {
@@ -50654,7 +51067,7 @@ async function startInteractive(config, repoPath) {
50654
51067
  let p2pGateway = null;
50655
51068
  let peerMesh = null;
50656
51069
  let inferenceRouter = null;
50657
- const secretVault = new SecretVault(join52(repoRoot, ".oa", "vault.enc"));
51070
+ const secretVault = new SecretVault(join53(repoRoot, ".oa", "vault.enc"));
50658
51071
  let adminSessionKey = null;
50659
51072
  const callSubAgents = /* @__PURE__ */ new Map();
50660
51073
  const streamRenderer = new StreamRenderer();
@@ -50863,8 +51276,8 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
50863
51276
  const hits = allCompletions.filter((c3) => c3.toLowerCase().startsWith(lower));
50864
51277
  return [hits, line];
50865
51278
  }
50866
- const HISTORY_DIR = join52(homedir13(), ".open-agents");
50867
- const HISTORY_FILE = join52(HISTORY_DIR, "repl-history");
51279
+ const HISTORY_DIR = join53(homedir13(), ".open-agents");
51280
+ const HISTORY_FILE = join53(HISTORY_DIR, "repl-history");
50868
51281
  const MAX_HISTORY_LINES = 500;
50869
51282
  let savedHistory = [];
50870
51283
  try {
@@ -51074,7 +51487,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
51074
51487
  } catch {
51075
51488
  }
51076
51489
  try {
51077
- const oaDir = join52(repoRoot, ".oa");
51490
+ const oaDir = join53(repoRoot, ".oa");
51078
51491
  const reconnected = await ExposeGateway.checkAndReconnect(oaDir, {
51079
51492
  onInfo: (msg) => writeContent(() => renderInfo(msg)),
51080
51493
  onError: (msg) => writeContent(() => renderWarning(msg))
@@ -51097,7 +51510,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
51097
51510
  } catch {
51098
51511
  }
51099
51512
  try {
51100
- const oaDir = join52(repoRoot, ".oa");
51513
+ const oaDir = join53(repoRoot, ".oa");
51101
51514
  const reconnectedP2P = await ExposeP2PGateway.checkAndReconnect(oaDir, new NexusTool(repoRoot), {
51102
51515
  onInfo: (msg) => writeContent(() => renderInfo(msg)),
51103
51516
  onError: (msg) => writeContent(() => renderWarning(msg))
@@ -51916,7 +52329,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
51916
52329
  kind,
51917
52330
  targetUrl,
51918
52331
  authKey,
51919
- stateDir: join52(repoRoot, ".oa"),
52332
+ stateDir: join53(repoRoot, ".oa"),
51920
52333
  passthrough: passthrough ?? false,
51921
52334
  loadbalance: loadbalance ?? false,
51922
52335
  endpointAuth: passthrough ? currentConfig.apiKey : void 0,
@@ -51964,7 +52377,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
51964
52377
  await tunnelGateway.stop();
51965
52378
  tunnelGateway = null;
51966
52379
  }
51967
- const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join52(repoRoot, ".oa") });
52380
+ const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join53(repoRoot, ".oa") });
51968
52381
  newTunnel.on("stats", (stats) => {
51969
52382
  statusBar.setExposeStatus({
51970
52383
  status: stats.status,
@@ -52226,7 +52639,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
52226
52639
  }
52227
52640
  },
52228
52641
  destroyProject() {
52229
- const oaPath = join52(repoRoot, OA_DIR);
52642
+ const oaPath = join53(repoRoot, OA_DIR);
52230
52643
  if (existsSync43(oaPath)) {
52231
52644
  try {
52232
52645
  rmSync2(oaPath, { recursive: true, force: true });
@@ -53161,7 +53574,7 @@ import { glob } from "glob";
53161
53574
  import ignore from "ignore";
53162
53575
  import { readFile as readFile17, stat as stat4 } from "node:fs/promises";
53163
53576
  import { createHash as createHash4 } from "node:crypto";
53164
- import { join as join53, relative as relative3, extname as extname11, basename as basename15 } from "node:path";
53577
+ import { join as join54, relative as relative3, extname as extname11, basename as basename15 } from "node:path";
53165
53578
  var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
53166
53579
  var init_codebase_indexer = __esm({
53167
53580
  "packages/indexer/dist/codebase-indexer.js"() {
@@ -53205,7 +53618,7 @@ var init_codebase_indexer = __esm({
53205
53618
  const ig = ignore.default();
53206
53619
  if (this.config.respectGitignore) {
53207
53620
  try {
53208
- const gitignoreContent = await readFile17(join53(this.config.rootDir, ".gitignore"), "utf-8");
53621
+ const gitignoreContent = await readFile17(join54(this.config.rootDir, ".gitignore"), "utf-8");
53209
53622
  ig.add(gitignoreContent);
53210
53623
  } catch {
53211
53624
  }
@@ -53220,7 +53633,7 @@ var init_codebase_indexer = __esm({
53220
53633
  for (const relativePath of files) {
53221
53634
  if (ig.ignores(relativePath))
53222
53635
  continue;
53223
- const fullPath = join53(this.config.rootDir, relativePath);
53636
+ const fullPath = join54(this.config.rootDir, relativePath);
53224
53637
  try {
53225
53638
  const fileStat = await stat4(fullPath);
53226
53639
  if (fileStat.size > this.config.maxFileSize)
@@ -53266,7 +53679,7 @@ var init_codebase_indexer = __esm({
53266
53679
  if (!child) {
53267
53680
  child = {
53268
53681
  name: part,
53269
- path: join53(current.path, part),
53682
+ path: join54(current.path, part),
53270
53683
  type: "directory",
53271
53684
  children: []
53272
53685
  };
@@ -53607,7 +54020,7 @@ var config_exports = {};
53607
54020
  __export(config_exports, {
53608
54021
  configCommand: () => configCommand
53609
54022
  });
53610
- import { join as join54, resolve as resolve31 } from "node:path";
54023
+ import { join as join55, resolve as resolve31 } from "node:path";
53611
54024
  import { homedir as homedir14 } from "node:os";
53612
54025
  import { cwd as cwd3 } from "node:process";
53613
54026
  function redactIfSensitive(key, value) {
@@ -53690,7 +54103,7 @@ function handleShow(opts, config) {
53690
54103
  }
53691
54104
  }
53692
54105
  printSection("Config File");
53693
- printInfo(`~/.open-agents/config.json (${join54(homedir14(), ".open-agents", "config.json")})`);
54106
+ printInfo(`~/.open-agents/config.json (${join55(homedir14(), ".open-agents", "config.json")})`);
53694
54107
  printSection("Priority Chain");
53695
54108
  printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
53696
54109
  printInfo(" 2. Project .oa/settings.json (--local)");
@@ -53729,7 +54142,7 @@ function handleSet(opts, _config) {
53729
54142
  const coerced = coerceForSettings(key, value);
53730
54143
  saveProjectSettings(repoRoot, { [key]: coerced });
53731
54144
  printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value)}`);
53732
- printInfo(`Saved to ${join54(repoRoot, ".oa", "settings.json")}`);
54145
+ printInfo(`Saved to ${join55(repoRoot, ".oa", "settings.json")}`);
53733
54146
  printInfo("This override applies only when running in this workspace.");
53734
54147
  } catch (err) {
53735
54148
  printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
@@ -53829,7 +54242,7 @@ var serve_exports = {};
53829
54242
  __export(serve_exports, {
53830
54243
  serveCommand: () => serveCommand
53831
54244
  });
53832
- import { spawn as spawn18 } from "node:child_process";
54245
+ import { spawn as spawn19 } from "node:child_process";
53833
54246
  async function serveCommand(opts, config) {
53834
54247
  const backendType = config.backendType;
53835
54248
  if (backendType === "ollama") {
@@ -53922,7 +54335,7 @@ async function serveVllm(opts, config) {
53922
54335
  }
53923
54336
  async function runVllmServer(args, verbose) {
53924
54337
  return new Promise((resolve32, reject) => {
53925
- const child = spawn18("python", args, {
54338
+ const child = spawn19("python", args, {
53926
54339
  stdio: verbose ? "inherit" : ["ignore", "pipe", "pipe"],
53927
54340
  env: { ...process.env }
53928
54341
  });
@@ -53986,9 +54399,9 @@ var eval_exports = {};
53986
54399
  __export(eval_exports, {
53987
54400
  evalCommand: () => evalCommand
53988
54401
  });
53989
- import { tmpdir as tmpdir9 } from "node:os";
54402
+ import { tmpdir as tmpdir10 } from "node:os";
53990
54403
  import { mkdirSync as mkdirSync20, writeFileSync as writeFileSync19 } from "node:fs";
53991
- import { join as join55 } from "node:path";
54404
+ import { join as join56 } from "node:path";
53992
54405
  async function evalCommand(opts, config) {
53993
54406
  const suiteName = opts.suite ?? "basic";
53994
54407
  const suite = SUITES[suiteName];
@@ -54113,9 +54526,9 @@ async function evalCommand(opts, config) {
54113
54526
  process.exit(failed > 0 ? 1 : 0);
54114
54527
  }
54115
54528
  function createTempEvalRepo() {
54116
- const dir = join55(tmpdir9(), `open-agents-eval-${Date.now()}`);
54529
+ const dir = join56(tmpdir10(), `open-agents-eval-${Date.now()}`);
54117
54530
  mkdirSync20(dir, { recursive: true });
54118
- writeFileSync19(join55(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
54531
+ writeFileSync19(join56(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
54119
54532
  return dir;
54120
54533
  }
54121
54534
  var BASIC_SUITE, FULL_SUITE, SUITES;
@@ -54175,7 +54588,7 @@ init_updater();
54175
54588
  import { parseArgs as nodeParseArgs2 } from "node:util";
54176
54589
  import { createRequire as createRequire3 } from "node:module";
54177
54590
  import { fileURLToPath as fileURLToPath13 } from "node:url";
54178
- import { dirname as dirname19, join as join56 } from "node:path";
54591
+ import { dirname as dirname19, join as join57 } from "node:path";
54179
54592
 
54180
54593
  // packages/cli/dist/cli.js
54181
54594
  import { createInterface } from "node:readline";
@@ -54282,7 +54695,7 @@ init_output();
54282
54695
  function getVersion4() {
54283
54696
  try {
54284
54697
  const require2 = createRequire3(import.meta.url);
54285
- const pkgPath = join56(dirname19(fileURLToPath13(import.meta.url)), "..", "package.json");
54698
+ const pkgPath = join57(dirname19(fileURLToPath13(import.meta.url)), "..", "package.json");
54286
54699
  const pkg = require2(pkgPath);
54287
54700
  return pkg.version;
54288
54701
  } catch {