open-agents-ai 0.91.0 → 0.93.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 +763 -418
  2. package/package.json +5 -2
package/dist/index.js CHANGED
@@ -10743,10 +10743,319 @@ var init_opencode = __esm({
10743
10743
  }
10744
10744
  });
10745
10745
 
10746
+ // packages/execution/dist/tools/factory.js
10747
+ import { execSync as execSync20, spawn as spawn10 } from "node:child_process";
10748
+ import { existsSync as existsSync21 } from "node:fs";
10749
+ import { join as join27 } from "node:path";
10750
+ function findDroid() {
10751
+ for (const cmd of ["droid"]) {
10752
+ try {
10753
+ const path = execSync20(`which ${cmd} 2>/dev/null`, { stdio: "pipe" }).toString().trim();
10754
+ if (path)
10755
+ return path;
10756
+ } catch {
10757
+ }
10758
+ }
10759
+ const homeDir = process.env.HOME || process.env.USERPROFILE || "";
10760
+ const candidates = [
10761
+ join27(homeDir, ".factory", "bin", "droid"),
10762
+ join27(homeDir, "bin", "droid"),
10763
+ "/usr/local/bin/droid"
10764
+ ];
10765
+ for (const p of candidates) {
10766
+ if (existsSync21(p))
10767
+ return p;
10768
+ }
10769
+ return null;
10770
+ }
10771
+ function getVersion2(binary) {
10772
+ try {
10773
+ return execSync20(`${binary} --version 2>/dev/null`, { stdio: "pipe", timeout: 1e4 }).toString().trim();
10774
+ } catch {
10775
+ return "unknown";
10776
+ }
10777
+ }
10778
+ function installDroid() {
10779
+ const platform4 = process.platform;
10780
+ try {
10781
+ if (platform4 === "win32") {
10782
+ execSync20('powershell -Command "irm https://app.factory.ai/cli/windows | iex"', {
10783
+ stdio: "pipe",
10784
+ timeout: 12e4
10785
+ });
10786
+ } else {
10787
+ execSync20("curl -fsSL https://app.factory.ai/cli | sh", {
10788
+ stdio: "pipe",
10789
+ timeout: 12e4
10790
+ });
10791
+ }
10792
+ const binary = findDroid();
10793
+ if (binary) {
10794
+ const version = getVersion2(binary);
10795
+ return { success: true, message: `Factory CLI installed successfully (${version}) at ${binary}` };
10796
+ }
10797
+ return { success: false, message: "Install script completed but droid binary not found in PATH" };
10798
+ } catch (err) {
10799
+ return {
10800
+ success: false,
10801
+ message: `Installation failed: ${err instanceof Error ? err.message : String(err)}`
10802
+ };
10803
+ }
10804
+ }
10805
+ var FactoryTool;
10806
+ var init_factory = __esm({
10807
+ "packages/execution/dist/tools/factory.js"() {
10808
+ "use strict";
10809
+ FactoryTool = class {
10810
+ name = "factory";
10811
+ description = "Delegate coding tasks to Factory AI's Droid, a high-performance autonomous coding agent. Actions: 'install' the Factory CLI if not present, 'run' a coding task via droid exec (non-interactive, fully autonomous), 'status' check availability and API key. Factory's Droid leads the Terminal Bench for code generation. Use this to offload complex coding tasks to a separate agent that can read, write, search, test, and commit code independently. Requires FACTORY_API_KEY environment variable.";
10812
+ parameters = {
10813
+ type: "object",
10814
+ properties: {
10815
+ action: {
10816
+ type: "string",
10817
+ enum: ["install", "run", "status"],
10818
+ description: "Action: 'install' Factory CLI, 'run' a coding task, 'status' check availability"
10819
+ },
10820
+ task: {
10821
+ type: "string",
10822
+ description: "The coding task to delegate (for 'run' action). Be specific about what files to modify and what outcome to achieve."
10823
+ },
10824
+ auto: {
10825
+ type: "string",
10826
+ enum: ["low", "medium", "high"],
10827
+ description: "Autonomy level controlling what droid can do. 'low': file edits only, 'medium': + install deps/git commit/build, 'high': + git push/prod deploys. Default: read-only (no --auto flag)."
10828
+ },
10829
+ model: {
10830
+ type: "string",
10831
+ description: "Model ID to use (optional, uses Factory default if omitted)"
10832
+ },
10833
+ directory: {
10834
+ type: "string",
10835
+ description: "Working directory for the task (optional, defaults to current project root)"
10836
+ },
10837
+ timeout_seconds: {
10838
+ type: "number",
10839
+ description: "Maximum execution time in seconds (default: 600 = 10 minutes)"
10840
+ },
10841
+ reasoning_effort: {
10842
+ type: "string",
10843
+ enum: ["low", "medium", "high"],
10844
+ description: "Reasoning effort level (optional, defaults to medium)"
10845
+ },
10846
+ output_format: {
10847
+ type: "string",
10848
+ enum: ["text", "json", "stream-json"],
10849
+ description: "Output format: 'text' for human-readable, 'json' for structured, 'stream-json' for JSONL events (default: 'text')"
10850
+ },
10851
+ session_id: {
10852
+ type: "string",
10853
+ description: "Continue an existing session by ID (optional)"
10854
+ }
10855
+ },
10856
+ required: ["action"]
10857
+ };
10858
+ workingDir;
10859
+ constructor(workingDir) {
10860
+ this.workingDir = workingDir;
10861
+ }
10862
+ async execute(args) {
10863
+ const start = performance.now();
10864
+ const action = String(args["action"] ?? "status");
10865
+ try {
10866
+ switch (action) {
10867
+ case "install":
10868
+ return this.doInstall(start);
10869
+ case "run":
10870
+ return await this.doRun(args, start);
10871
+ case "status":
10872
+ return this.doStatus(start);
10873
+ default:
10874
+ return {
10875
+ success: false,
10876
+ output: "",
10877
+ error: `Unknown action '${action}'. Use: install, run, status`,
10878
+ durationMs: performance.now() - start
10879
+ };
10880
+ }
10881
+ } catch (err) {
10882
+ return {
10883
+ success: false,
10884
+ output: "",
10885
+ error: `factory error: ${err instanceof Error ? err.message : String(err)}`,
10886
+ durationMs: performance.now() - start
10887
+ };
10888
+ }
10889
+ }
10890
+ doInstall(start) {
10891
+ const existing = findDroid();
10892
+ if (existing) {
10893
+ const version = getVersion2(existing);
10894
+ return {
10895
+ success: true,
10896
+ output: `Factory CLI (droid) is already installed at ${existing} (${version}). No action needed.`,
10897
+ durationMs: performance.now() - start
10898
+ };
10899
+ }
10900
+ const result = installDroid();
10901
+ return {
10902
+ success: result.success,
10903
+ output: result.success ? result.message : "",
10904
+ error: result.success ? void 0 : result.message,
10905
+ durationMs: performance.now() - start
10906
+ };
10907
+ }
10908
+ async doRun(args, start) {
10909
+ const task = String(args["task"] ?? "");
10910
+ if (!task) {
10911
+ return { success: false, output: "", error: "task is required for run action", durationMs: performance.now() - start };
10912
+ }
10913
+ if (!process.env.FACTORY_API_KEY) {
10914
+ return {
10915
+ success: false,
10916
+ output: "",
10917
+ error: "FACTORY_API_KEY environment variable is not set. Get one from https://app.factory.ai/settings and export FACTORY_API_KEY=fk-...",
10918
+ durationMs: performance.now() - start
10919
+ };
10920
+ }
10921
+ let binary = findDroid();
10922
+ if (!binary) {
10923
+ const installResult = installDroid();
10924
+ if (!installResult.success) {
10925
+ return {
10926
+ success: false,
10927
+ output: "",
10928
+ error: `droid CLI not found and auto-install failed: ${installResult.message}`,
10929
+ durationMs: performance.now() - start
10930
+ };
10931
+ }
10932
+ binary = findDroid();
10933
+ if (!binary) {
10934
+ return {
10935
+ success: false,
10936
+ output: "",
10937
+ error: "Factory CLI installed but droid binary not found in PATH. Try adding it to your PATH.",
10938
+ durationMs: performance.now() - start
10939
+ };
10940
+ }
10941
+ }
10942
+ const dir = String(args["directory"] ?? this.workingDir);
10943
+ const model = args["model"] ? String(args["model"]) : void 0;
10944
+ const auto = args["auto"] ? String(args["auto"]) : void 0;
10945
+ const outputFormat = args["output_format"] ? String(args["output_format"]) : "text";
10946
+ const reasoningEffort = args["reasoning_effort"] ? String(args["reasoning_effort"]) : void 0;
10947
+ const sessionId = args["session_id"] ? String(args["session_id"]) : void 0;
10948
+ const timeoutSec = typeof args["timeout_seconds"] === "number" ? args["timeout_seconds"] : 600;
10949
+ const cmdArgs = ["exec"];
10950
+ if (model)
10951
+ cmdArgs.push("--model", model);
10952
+ if (auto)
10953
+ cmdArgs.push("--auto", auto);
10954
+ if (outputFormat !== "text")
10955
+ cmdArgs.push("--output-format", outputFormat);
10956
+ if (reasoningEffort)
10957
+ cmdArgs.push("--reasoning-effort", reasoningEffort);
10958
+ if (sessionId)
10959
+ cmdArgs.push("--session-id", sessionId);
10960
+ cmdArgs.push("--cwd", dir);
10961
+ cmdArgs.push(task);
10962
+ return new Promise((resolvePromise) => {
10963
+ let output = "";
10964
+ const maxOutput = 5e5;
10965
+ let timedOut = false;
10966
+ const child = spawn10(binary, cmdArgs, {
10967
+ cwd: dir,
10968
+ env: { ...process.env },
10969
+ stdio: ["ignore", "pipe", "pipe"]
10970
+ });
10971
+ child.stdout?.on("data", (chunk) => {
10972
+ if (output.length < maxOutput) {
10973
+ output += chunk.toString();
10974
+ }
10975
+ });
10976
+ child.stderr?.on("data", (chunk) => {
10977
+ if (output.length < maxOutput) {
10978
+ output += chunk.toString();
10979
+ }
10980
+ });
10981
+ const timer = setTimeout(() => {
10982
+ timedOut = true;
10983
+ try {
10984
+ child.kill("SIGTERM");
10985
+ } catch {
10986
+ }
10987
+ }, timeoutSec * 1e3);
10988
+ child.on("close", (code) => {
10989
+ clearTimeout(timer);
10990
+ if (timedOut) {
10991
+ resolvePromise({
10992
+ success: false,
10993
+ output: output.slice(-1e4),
10994
+ error: `droid exec timed out after ${timeoutSec}s. Partial output included.`,
10995
+ durationMs: performance.now() - start
10996
+ });
10997
+ return;
10998
+ }
10999
+ const truncated = output.length > 5e4 ? output.slice(0, 5e3) + "\n\n...(truncated)...\n\n" + output.slice(-1e4) : output;
11000
+ resolvePromise({
11001
+ success: code === 0,
11002
+ output: truncated || "(no output)",
11003
+ error: code !== 0 ? `droid exec exited with code ${code}` : void 0,
11004
+ durationMs: performance.now() - start
11005
+ });
11006
+ });
11007
+ child.on("error", (err) => {
11008
+ clearTimeout(timer);
11009
+ resolvePromise({
11010
+ success: false,
11011
+ output: "",
11012
+ error: `Failed to spawn droid: ${err.message}`,
11013
+ durationMs: performance.now() - start
11014
+ });
11015
+ });
11016
+ });
11017
+ }
11018
+ doStatus(start) {
11019
+ const binary = findDroid();
11020
+ const hasApiKey = !!process.env.FACTORY_API_KEY;
11021
+ if (binary) {
11022
+ const version = getVersion2(binary);
11023
+ const lines = [
11024
+ `Factory CLI (droid) is installed`,
11025
+ ` Binary: ${binary}`,
11026
+ ` Version: ${version}`,
11027
+ ` API Key: ${hasApiKey ? "set" : "NOT SET \u2014 export FACTORY_API_KEY=fk-..."}`,
11028
+ ``,
11029
+ `Usage: factory(action='run', task='your coding task', auto='low')`,
11030
+ ` Autonomy levels: omit for read-only, 'low' for edits, 'medium' for builds/deps, 'high' for git push`,
11031
+ ` The task runs fully autonomously via droid exec.`
11032
+ ];
11033
+ return {
11034
+ success: true,
11035
+ output: lines.join("\n"),
11036
+ durationMs: performance.now() - start
11037
+ };
11038
+ }
11039
+ return {
11040
+ success: true,
11041
+ output: [
11042
+ `Factory CLI (droid) is NOT installed.`,
11043
+ ` API Key: ${hasApiKey ? "set" : "NOT SET \u2014 export FACTORY_API_KEY=fk-..."}`,
11044
+ ``,
11045
+ `Use factory(action='install') to install it.`,
11046
+ `Manual install: curl -fsSL https://app.factory.ai/cli | sh`
11047
+ ].join("\n"),
11048
+ durationMs: performance.now() - start
11049
+ };
11050
+ }
11051
+ };
11052
+ }
11053
+ });
11054
+
10746
11055
  // packages/execution/dist/tools/cron-agent.js
10747
- import { execSync as execSync20 } from "node:child_process";
11056
+ import { execSync as execSync21 } from "node:child_process";
10748
11057
  import { readFile as readFile12, writeFile as writeFile11, mkdir as mkdir7 } from "node:fs/promises";
10749
- import { resolve as resolve25, join as join27 } from "node:path";
11058
+ import { resolve as resolve25, join as join28 } from "node:path";
10750
11059
  import { randomBytes as randomBytes5 } from "node:crypto";
10751
11060
  function isValidCron2(expr) {
10752
11061
  const parts = expr.trim().split(/\s+/);
@@ -10808,19 +11117,19 @@ function resolveSchedule2(schedule) {
10808
11117
  }
10809
11118
  function getCurrentCrontab2() {
10810
11119
  try {
10811
- return execSync20("crontab -l 2>/dev/null", { stdio: "pipe" }).toString().split("\n");
11120
+ return execSync21("crontab -l 2>/dev/null", { stdio: "pipe" }).toString().split("\n");
10812
11121
  } catch {
10813
11122
  return [];
10814
11123
  }
10815
11124
  }
10816
11125
  function writeCrontab2(lines) {
10817
11126
  const content = lines.join("\n") + "\n";
10818
- execSync20(`echo ${JSON.stringify(content)} | crontab -`, { stdio: "pipe" });
11127
+ execSync21(`echo ${JSON.stringify(content)} | crontab -`, { stdio: "pipe" });
10819
11128
  }
10820
11129
  function findOaBinary2() {
10821
11130
  for (const cmd of ["oa", "open-agents"]) {
10822
11131
  try {
10823
- const path = execSync20(`which ${cmd} 2>/dev/null`, { stdio: "pipe" }).toString().trim();
11132
+ const path = execSync21(`which ${cmd} 2>/dev/null`, { stdio: "pipe" }).toString().trim();
10824
11133
  if (path)
10825
11134
  return path;
10826
11135
  } catch {
@@ -10832,7 +11141,7 @@ function installCronAgentJob(job, workingDir) {
10832
11141
  const lines = getCurrentCrontab2();
10833
11142
  const oaBin = findOaBinary2();
10834
11143
  const logDir = resolve25(workingDir, ".oa", "cron-agents", "logs");
10835
- const logFile = join27(logDir, `${job.id}.log`);
11144
+ const logFile = join28(logDir, `${job.id}.log`);
10836
11145
  const storeFile = resolve25(workingDir, ".oa", "cron-agents", "store.json");
10837
11146
  const taskEscaped = job.task.replace(/'/g, "'\\''");
10838
11147
  const jobId = job.id;
@@ -10871,9 +11180,9 @@ async function loadStore2(workingDir) {
10871
11180
  async function saveStore2(workingDir, store) {
10872
11181
  const dir = resolve25(workingDir, ".oa", "cron-agents");
10873
11182
  await mkdir7(dir, { recursive: true });
10874
- await mkdir7(join27(dir, "logs"), { recursive: true });
11183
+ await mkdir7(join28(dir, "logs"), { recursive: true });
10875
11184
  store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
10876
- await writeFile11(join27(dir, "store.json"), JSON.stringify(store, null, 2), "utf-8");
11185
+ await writeFile11(join28(dir, "store.json"), JSON.stringify(store, null, 2), "utf-8");
10877
11186
  }
10878
11187
  var LONG_HORIZON_PRESETS, CRON_AGENT_MARKER, CronAgentTool;
10879
11188
  var init_cron_agent = __esm({
@@ -11163,7 +11472,7 @@ ${truncated}`, durationMs: performance.now() - start };
11163
11472
  ];
11164
11473
  if (job.verifyCommand) {
11165
11474
  try {
11166
- const result = execSync20(job.verifyCommand, {
11475
+ const result = execSync21(job.verifyCommand, {
11167
11476
  cwd: this.workingDir,
11168
11477
  stdio: "pipe",
11169
11478
  timeout: 3e4
@@ -11210,10 +11519,10 @@ ${truncated}`, durationMs: performance.now() - start };
11210
11519
 
11211
11520
  // packages/execution/dist/tools/nexus.js
11212
11521
  import { readFile as readFile13, writeFile as writeFile12, mkdir as mkdir8, chmod, unlink, readdir as readdir3, open as fsOpen } from "node:fs/promises";
11213
- import { existsSync as existsSync21, readFileSync as readFileSync15 } from "node:fs";
11214
- import { resolve as resolve26, join as join28 } from "node:path";
11522
+ import { existsSync as existsSync22, readFileSync as readFileSync15 } from "node:fs";
11523
+ import { resolve as resolve26, join as join29 } from "node:path";
11215
11524
  import { randomBytes as randomBytes6, createCipheriv, createDecipheriv, scryptSync, createHash } from "node:crypto";
11216
- import { execSync as execSync21, spawn as spawn10 } from "node:child_process";
11525
+ import { execSync as execSync22, spawn as spawn11 } from "node:child_process";
11217
11526
  import { hostname, userInfo } from "node:os";
11218
11527
  function containsKeyMaterial(input) {
11219
11528
  for (const pattern of KEY_PATTERNS) {
@@ -12247,7 +12556,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
12247
12556
  this.nexusDir = resolve26(repoRoot, ".oa", "nexus");
12248
12557
  }
12249
12558
  async ensureDir() {
12250
- if (!existsSync21(this.nexusDir)) {
12559
+ if (!existsSync22(this.nexusDir)) {
12251
12560
  await mkdir8(this.nexusDir, { recursive: true });
12252
12561
  }
12253
12562
  }
@@ -12362,8 +12671,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
12362
12671
  // Daemon management
12363
12672
  // =========================================================================
12364
12673
  getDaemonPid() {
12365
- const pidFile = join28(this.nexusDir, "daemon.pid");
12366
- if (!existsSync21(pidFile))
12674
+ const pidFile = join29(this.nexusDir, "daemon.pid");
12675
+ if (!existsSync22(pidFile))
12367
12676
  return null;
12368
12677
  try {
12369
12678
  const pid = parseInt(readFileSync15(pidFile, "utf8").trim(), 10);
@@ -12378,16 +12687,16 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
12378
12687
  if (!pid)
12379
12688
  throw new Error("Nexus daemon not running. Use action 'connect' first.");
12380
12689
  const cmdId = randomBytes6(8).toString("hex");
12381
- const cmdFile = join28(this.nexusDir, "cmd.json");
12382
- const respFile = join28(this.nexusDir, "resp.json");
12383
- if (existsSync21(respFile))
12690
+ const cmdFile = join29(this.nexusDir, "cmd.json");
12691
+ const respFile = join29(this.nexusDir, "resp.json");
12692
+ if (existsSync22(respFile))
12384
12693
  await unlink(respFile).catch(() => {
12385
12694
  });
12386
12695
  await writeFile12(cmdFile, JSON.stringify({ id: cmdId, action, args }, null, 2));
12387
12696
  const polls = Math.ceil(timeoutMs / 500);
12388
12697
  for (let i = 0; i < polls; i++) {
12389
12698
  await new Promise((r) => setTimeout(r, 500));
12390
- if (!existsSync21(respFile))
12699
+ if (!existsSync22(respFile))
12391
12700
  continue;
12392
12701
  try {
12393
12702
  const resp = JSON.parse(await readFile13(respFile, "utf8"));
@@ -12414,8 +12723,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
12414
12723
  await this.ensureDir();
12415
12724
  const existingPid = this.getDaemonPid();
12416
12725
  if (existingPid) {
12417
- const statusFile2 = join28(this.nexusDir, "status.json");
12418
- if (existsSync21(statusFile2)) {
12726
+ const statusFile2 = join29(this.nexusDir, "status.json");
12727
+ if (existsSync22(statusFile2)) {
12419
12728
  try {
12420
12729
  const status = JSON.parse(await readFile13(statusFile2, "utf8"));
12421
12730
  if (status.connected && status.peerId) {
@@ -12431,8 +12740,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
12431
12740
  await new Promise((r) => setTimeout(r, 500));
12432
12741
  }
12433
12742
  for (const f of ["daemon.pid", "status.json", "cmd.json", "resp.json"]) {
12434
- const p = join28(this.nexusDir, f);
12435
- if (existsSync21(p))
12743
+ const p = join29(this.nexusDir, f);
12744
+ if (existsSync22(p))
12436
12745
  await unlink(p).catch(() => {
12437
12746
  });
12438
12747
  }
@@ -12440,8 +12749,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
12440
12749
  let nexusResolved = false;
12441
12750
  let installedVersion = "";
12442
12751
  try {
12443
- const nexusPkg = join28(nodeModulesDir, "open-agents-nexus", "package.json");
12444
- if (existsSync21(nexusPkg)) {
12752
+ const nexusPkg = join29(nodeModulesDir, "open-agents-nexus", "package.json");
12753
+ if (existsSync22(nexusPkg)) {
12445
12754
  nexusResolved = true;
12446
12755
  try {
12447
12756
  const pkg = JSON.parse(readFileSync15(nexusPkg, "utf8"));
@@ -12449,9 +12758,9 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
12449
12758
  } catch {
12450
12759
  }
12451
12760
  } else {
12452
- const globalDir = execSync21("npm root -g", { encoding: "utf8", timeout: 5e3 }).trim();
12453
- const globalPkg = join28(globalDir, "open-agents-nexus", "package.json");
12454
- if (existsSync21(globalPkg)) {
12761
+ const globalDir = execSync22("npm root -g", { encoding: "utf8", timeout: 5e3 }).trim();
12762
+ const globalPkg = join29(globalDir, "open-agents-nexus", "package.json");
12763
+ if (existsSync22(globalPkg)) {
12455
12764
  nexusResolved = true;
12456
12765
  try {
12457
12766
  const pkg = JSON.parse(readFileSync15(globalPkg, "utf8"));
@@ -12464,13 +12773,13 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
12464
12773
  }
12465
12774
  if (nexusResolved && installedVersion) {
12466
12775
  try {
12467
- const latestRaw = execSync21("npm view open-agents-nexus version 2>/dev/null", {
12776
+ const latestRaw = execSync22("npm view open-agents-nexus version 2>/dev/null", {
12468
12777
  encoding: "utf8",
12469
12778
  timeout: 8e3
12470
12779
  }).trim();
12471
12780
  if (latestRaw && latestRaw !== installedVersion) {
12472
12781
  try {
12473
- execSync21(`npm install open-agents-nexus@${latestRaw} --save 2>&1`, {
12782
+ execSync22(`npm install open-agents-nexus@${latestRaw} --save 2>&1`, {
12474
12783
  cwd: this.repoRoot,
12475
12784
  stdio: "pipe",
12476
12785
  timeout: 6e4
@@ -12484,30 +12793,30 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
12484
12793
  }
12485
12794
  if (!nexusResolved) {
12486
12795
  try {
12487
- execSync21("npm install open-agents-nexus@latest 2>&1", {
12796
+ execSync22("npm install open-agents-nexus@latest 2>&1", {
12488
12797
  cwd: this.repoRoot,
12489
12798
  stdio: "pipe",
12490
12799
  timeout: 12e4
12491
12800
  });
12492
12801
  } catch {
12493
12802
  try {
12494
- execSync21("npm install -g open-agents-nexus@latest 2>&1", { stdio: "pipe", timeout: 12e4 });
12803
+ execSync22("npm install -g open-agents-nexus@latest 2>&1", { stdio: "pipe", timeout: 12e4 });
12495
12804
  } catch {
12496
12805
  throw new Error("Failed to install open-agents-nexus. Run: npm install open-agents-nexus");
12497
12806
  }
12498
12807
  }
12499
12808
  }
12500
- const daemonPath = join28(this.nexusDir, "nexus-daemon.mjs");
12809
+ const daemonPath = join29(this.nexusDir, "nexus-daemon.mjs");
12501
12810
  await writeFile12(daemonPath, DAEMON_SCRIPT);
12502
12811
  const agentName = args.agent_name || "open-agents-node";
12503
12812
  const agentType = args.agent_type || "general";
12504
12813
  const nodePaths = [nodeModulesDir];
12505
12814
  try {
12506
- const globalDir = execSync21("npm root -g", { encoding: "utf8", timeout: 5e3 }).trim();
12815
+ const globalDir = execSync22("npm root -g", { encoding: "utf8", timeout: 5e3 }).trim();
12507
12816
  nodePaths.push(globalDir);
12508
12817
  } catch {
12509
12818
  }
12510
- const child = spawn10("node", [daemonPath, this.nexusDir, agentName, agentType], {
12819
+ const child = spawn11("node", [daemonPath, this.nexusDir, agentName, agentType], {
12511
12820
  detached: true,
12512
12821
  stdio: ["ignore", "pipe", "pipe"],
12513
12822
  cwd: this.repoRoot,
@@ -12522,10 +12831,10 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
12522
12831
  child.stderr?.on("data", (d) => {
12523
12832
  earlyError += d.toString();
12524
12833
  });
12525
- const statusFile = join28(this.nexusDir, "status.json");
12834
+ const statusFile = join29(this.nexusDir, "status.json");
12526
12835
  for (let i = 0; i < 40; i++) {
12527
12836
  await new Promise((r) => setTimeout(r, 500));
12528
- if (existsSync21(statusFile)) {
12837
+ if (existsSync22(statusFile)) {
12529
12838
  try {
12530
12839
  const status = JSON.parse(await readFile13(statusFile, "utf8"));
12531
12840
  if (status.error) {
@@ -12566,8 +12875,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
12566
12875
  } catch {
12567
12876
  }
12568
12877
  for (const f of ["daemon.pid", "status.json", "cmd.json", "resp.json"]) {
12569
- const p = join28(this.nexusDir, f);
12570
- if (existsSync21(p))
12878
+ const p = join29(this.nexusDir, f);
12879
+ if (existsSync22(p))
12571
12880
  await unlink(p).catch(() => {
12572
12881
  });
12573
12882
  }
@@ -12577,8 +12886,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
12577
12886
  const pid = this.getDaemonPid();
12578
12887
  if (!pid)
12579
12888
  return "Nexus daemon not running. Use action 'connect' to start.";
12580
- const statusFile = join28(this.nexusDir, "status.json");
12581
- if (!existsSync21(statusFile))
12889
+ const statusFile = join29(this.nexusDir, "status.json");
12890
+ if (!existsSync22(statusFile))
12582
12891
  return `Daemon running (pid: ${pid}) but no status yet.`;
12583
12892
  try {
12584
12893
  const status = JSON.parse(await readFile13(statusFile, "utf8"));
@@ -12592,8 +12901,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
12592
12901
  ` Capabilities: ${(status.capabilities || []).length ? (status.capabilities || []).join(", ") : "none"}`,
12593
12902
  ` Blocked peers: ${(status.blockedPeers || []).length || 0}`
12594
12903
  ];
12595
- const walletPath = join28(this.nexusDir, "wallet.enc");
12596
- if (existsSync21(walletPath)) {
12904
+ const walletPath = join29(this.nexusDir, "wallet.enc");
12905
+ if (existsSync22(walletPath)) {
12597
12906
  try {
12598
12907
  const w = JSON.parse(await readFile13(walletPath, "utf8"));
12599
12908
  lines.push(` Wallet: ${w.address}`);
@@ -12603,14 +12912,14 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
12603
12912
  } else {
12604
12913
  lines.push(` Wallet: not configured`);
12605
12914
  }
12606
- const inboxDir = join28(this.nexusDir, "inbox");
12607
- if (existsSync21(inboxDir)) {
12915
+ const inboxDir = join29(this.nexusDir, "inbox");
12916
+ if (existsSync22(inboxDir)) {
12608
12917
  try {
12609
12918
  const roomDirs = await readdir3(inboxDir);
12610
12919
  let totalMsgs = 0;
12611
12920
  for (const rd of roomDirs) {
12612
12921
  try {
12613
- totalMsgs += (await readdir3(join28(inboxDir, rd))).length;
12922
+ totalMsgs += (await readdir3(join29(inboxDir, rd))).length;
12614
12923
  } catch {
12615
12924
  }
12616
12925
  }
@@ -12657,10 +12966,10 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
12657
12966
  }
12658
12967
  async doReadMessages(args) {
12659
12968
  const roomId = args.room_id;
12660
- const inboxDir = join28(this.nexusDir, "inbox");
12969
+ const inboxDir = join29(this.nexusDir, "inbox");
12661
12970
  if (roomId) {
12662
- const roomInbox = join28(inboxDir, roomId);
12663
- if (!existsSync21(roomInbox))
12971
+ const roomInbox = join29(inboxDir, roomId);
12972
+ if (!existsSync22(roomInbox))
12664
12973
  return `No messages in room: ${roomId}`;
12665
12974
  const files = (await readdir3(roomInbox)).sort().slice(-20);
12666
12975
  if (files.length === 0)
@@ -12668,7 +12977,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
12668
12977
  const messages = [`Messages in ${roomId} (last ${files.length}):`];
12669
12978
  for (const f of files) {
12670
12979
  try {
12671
- const msg = JSON.parse(await readFile13(join28(roomInbox, f), "utf8"));
12980
+ const msg = JSON.parse(await readFile13(join29(roomInbox, f), "utf8"));
12672
12981
  const sender = (msg.sender || "unknown").slice(0, 12);
12673
12982
  messages.push(` [${new Date(msg.timestamp).toLocaleTimeString()}] ${sender}...: ${msg.content}`);
12674
12983
  } catch {
@@ -12676,7 +12985,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
12676
12985
  }
12677
12986
  return messages.join("\n");
12678
12987
  }
12679
- if (!existsSync21(inboxDir))
12988
+ if (!existsSync22(inboxDir))
12680
12989
  return "No messages received yet.";
12681
12990
  const roomDirs = await readdir3(inboxDir);
12682
12991
  if (roomDirs.length === 0)
@@ -12684,7 +12993,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
12684
12993
  const lines = ["Inbox:"];
12685
12994
  for (const rd of roomDirs) {
12686
12995
  try {
12687
- const count = (await readdir3(join28(inboxDir, rd))).length;
12996
+ const count = (await readdir3(join29(inboxDir, rd))).length;
12688
12997
  lines.push(` ${rd}: ${count} message(s)`);
12689
12998
  } catch {
12690
12999
  }
@@ -12696,8 +13005,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
12696
13005
  // ---------------------------------------------------------------------------
12697
13006
  async doWalletStatus() {
12698
13007
  await this.ensureDir();
12699
- const walletPath = join28(this.nexusDir, "wallet.enc");
12700
- if (!existsSync21(walletPath)) {
13008
+ const walletPath = join29(this.nexusDir, "wallet.enc");
13009
+ if (!existsSync22(walletPath)) {
12701
13010
  return "No wallet configured. Use wallet_create to set one up.";
12702
13011
  }
12703
13012
  try {
@@ -12735,8 +13044,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
12735
13044
  }
12736
13045
  async doWalletCreate(args) {
12737
13046
  await this.ensureDir();
12738
- const walletPath = join28(this.nexusDir, "wallet.enc");
12739
- if (existsSync21(walletPath))
13047
+ const walletPath = join29(this.nexusDir, "wallet.enc");
13048
+ if (existsSync22(walletPath))
12740
13049
  return "Wallet already exists. Delete wallet.enc to create a new one.";
12741
13050
  const userAddress = args.wallet_address;
12742
13051
  if (userAddress) {
@@ -12781,7 +13090,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
12781
13090
  const cipher = createCipheriv("aes-256-gcm", key, iv);
12782
13091
  let enc = cipher.update(privKeyHex, "utf8", "hex");
12783
13092
  enc += cipher.final("hex");
12784
- const x402KeyPath = join28(this.nexusDir, "x402-wallet.key");
13093
+ const x402KeyPath = join29(this.nexusDir, "x402-wallet.key");
12785
13094
  const x402Fh = await fsOpen(x402KeyPath, "w", 384);
12786
13095
  await x402Fh.writeFile("0x" + privKeyHex);
12787
13096
  await x402Fh.close();
@@ -12852,8 +13161,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
12852
13161
  // ---------------------------------------------------------------------------
12853
13162
  async doLedgerStatus() {
12854
13163
  await this.ensureDir();
12855
- const ledgerPath = join28(this.nexusDir, "ledger.jsonl");
12856
- if (!existsSync21(ledgerPath)) {
13164
+ const ledgerPath = join29(this.nexusDir, "ledger.jsonl");
13165
+ if (!existsSync22(ledgerPath)) {
12857
13166
  return "No ledger entries. Earnings and spending will be tracked here after x402 transactions.";
12858
13167
  }
12859
13168
  try {
@@ -12894,8 +13203,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
12894
13203
  }
12895
13204
  }
12896
13205
  async getLedgerSummary() {
12897
- const ledgerPath = join28(this.nexusDir, "ledger.jsonl");
12898
- if (!existsSync21(ledgerPath))
13206
+ const ledgerPath = join29(this.nexusDir, "ledger.jsonl");
13207
+ if (!existsSync22(ledgerPath))
12899
13208
  return null;
12900
13209
  try {
12901
13210
  const raw = await readFile13(ledgerPath, "utf8");
@@ -12919,16 +13228,16 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
12919
13228
  }
12920
13229
  async appendLedger(entry) {
12921
13230
  await this.ensureDir();
12922
- const ledgerPath = join28(this.nexusDir, "ledger.jsonl");
13231
+ const ledgerPath = join29(this.nexusDir, "ledger.jsonl");
12923
13232
  const line = JSON.stringify(entry) + "\n";
12924
- await writeFile12(ledgerPath, existsSync21(ledgerPath) ? await readFile13(ledgerPath, "utf8") + line : line);
13233
+ await writeFile12(ledgerPath, existsSync22(ledgerPath) ? await readFile13(ledgerPath, "utf8") + line : line);
12925
13234
  }
12926
13235
  // ---------------------------------------------------------------------------
12927
13236
  // Step 4: Budget Policy — Spending limits and auto-approve thresholds
12928
13237
  // ---------------------------------------------------------------------------
12929
13238
  async loadBudget() {
12930
- const budgetPath = join28(this.nexusDir, "budget.json");
12931
- if (!existsSync21(budgetPath))
13239
+ const budgetPath = join29(this.nexusDir, "budget.json");
13240
+ if (!existsSync22(budgetPath))
12932
13241
  return null;
12933
13242
  try {
12934
13243
  return JSON.parse(await readFile13(budgetPath, "utf8"));
@@ -12937,8 +13246,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
12937
13246
  }
12938
13247
  }
12939
13248
  async ensureDefaultBudget() {
12940
- const budgetPath = join28(this.nexusDir, "budget.json");
12941
- if (existsSync21(budgetPath))
13249
+ const budgetPath = join29(this.nexusDir, "budget.json");
13250
+ if (existsSync22(budgetPath))
12942
13251
  return;
12943
13252
  const defaultBudget = {
12944
13253
  version: 1,
@@ -13007,13 +13316,13 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
13007
13316
  if (changes.length === 0) {
13008
13317
  return "No budget parameters provided. Use daily_limit, per_invoke_max, or auto_approve_below.";
13009
13318
  }
13010
- const budgetPath = join28(this.nexusDir, "budget.json");
13319
+ const budgetPath = join29(this.nexusDir, "budget.json");
13011
13320
  await writeFile12(budgetPath, JSON.stringify(budget, null, 2));
13012
13321
  return `Budget updated: ${changes.join(", ")}`;
13013
13322
  }
13014
13323
  async getTodaySpending() {
13015
- const ledgerPath = join28(this.nexusDir, "ledger.jsonl");
13016
- if (!existsSync21(ledgerPath))
13324
+ const ledgerPath = join29(this.nexusDir, "ledger.jsonl");
13325
+ if (!existsSync22(ledgerPath))
13017
13326
  return 0;
13018
13327
  try {
13019
13328
  const todayPrefix = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
@@ -13056,8 +13365,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
13056
13365
  if (todaySpent + amountUsdc > budget.dailyLimitUsdc) {
13057
13366
  return { allowed: false, reason: `Would exceed daily limit ($${((todaySpent + amountUsdc) / 1e6).toFixed(6)} > $${(budget.dailyLimitUsdc / 1e6).toFixed(6)})` };
13058
13367
  }
13059
- const walletPath = join28(this.nexusDir, "wallet.enc");
13060
- if (existsSync21(walletPath)) {
13368
+ const walletPath = join29(this.nexusDir, "wallet.enc");
13369
+ if (existsSync22(walletPath)) {
13061
13370
  try {
13062
13371
  const w = JSON.parse(await readFile13(walletPath, "utf8"));
13063
13372
  if (w.version === 2 && w.address) {
@@ -13087,8 +13396,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
13087
13396
  const budgetResult = await this.checkBudget(amountSmallest, "transfer:direct", targetAddress);
13088
13397
  if (!budgetResult.allowed)
13089
13398
  return `BLOCKED by budget policy: ${budgetResult.reason}`;
13090
- const walletPath = join28(this.nexusDir, "wallet.enc");
13091
- if (!existsSync21(walletPath))
13399
+ const walletPath = join29(this.nexusDir, "wallet.enc");
13400
+ if (!existsSync22(walletPath))
13092
13401
  throw new Error("No wallet. Use wallet_create first.");
13093
13402
  const w = JSON.parse(await readFile13(walletPath, "utf8"));
13094
13403
  if (!w.encryptedKey)
@@ -13148,7 +13457,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
13148
13457
  capability: "transfer:direct",
13149
13458
  note: "signed, awaiting submission"
13150
13459
  });
13151
- const proofFile = join28(this.nexusDir, "pending-transfer.json");
13460
+ const proofFile = join29(this.nexusDir, "pending-transfer.json");
13152
13461
  const proof = {
13153
13462
  from: account.address,
13154
13463
  to: targetAddress,
@@ -13190,8 +13499,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
13190
13499
  throw new Error("prompt is required");
13191
13500
  const estimatedTokens = Math.ceil(prompt.length / 4) + 1e3;
13192
13501
  let estimatedCostSmallest = 0;
13193
- const pricingPath = join28(this.nexusDir, "pricing.json");
13194
- if (existsSync21(pricingPath)) {
13502
+ const pricingPath = join29(this.nexusDir, "pricing.json");
13503
+ if (existsSync22(pricingPath)) {
13195
13504
  try {
13196
13505
  const pricing = JSON.parse(await readFile13(pricingPath, "utf8"));
13197
13506
  const modelPricing = (pricing.models || []).find((m) => m.model === model || m.model.startsWith(model.split(":")[0]));
@@ -13283,7 +13592,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
13283
13592
  }
13284
13593
  async doInferenceProof() {
13285
13594
  try {
13286
- const psRaw = execSync21("ollama ps 2>/dev/null", { timeout: 1e4, encoding: "utf8" });
13595
+ const psRaw = execSync22("ollama ps 2>/dev/null", { timeout: 1e4, encoding: "utf8" });
13287
13596
  const lines = psRaw.trim().split("\n").filter((l) => l.trim());
13288
13597
  if (lines.length < 2)
13289
13598
  return "No model loaded. Run 'ollama ps' to check.";
@@ -13291,7 +13600,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
13291
13600
  const modelName = parts[0] || "unknown";
13292
13601
  let gpuName = "none", vramMb = 0;
13293
13602
  try {
13294
- const smi = execSync21("nvidia-smi --query-gpu=name,memory.total --format=csv,noheader 2>/dev/null", {
13603
+ const smi = execSync22("nvidia-smi --query-gpu=name,memory.total --format=csv,noheader 2>/dev/null", {
13295
13604
  timeout: 5e3,
13296
13605
  encoding: "utf8"
13297
13606
  });
@@ -13300,7 +13609,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
13300
13609
  vramMb = parseInt(gp[1]?.trim() || "0", 10);
13301
13610
  } catch {
13302
13611
  try {
13303
- execSync21("rocm-smi 2>/dev/null", { timeout: 5e3 });
13612
+ execSync22("rocm-smi 2>/dev/null", { timeout: 5e3 });
13304
13613
  gpuName = "AMD GPU";
13305
13614
  } catch {
13306
13615
  }
@@ -13310,7 +13619,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
13310
13619
  const bar = (s) => "\u2588".repeat(Math.round(s / 5)) + "\u2591".repeat(20 - Math.round(s / 5));
13311
13620
  const mem = vramMb > 24e3 ? 95 : vramMb > 16e3 ? 80 : vramMb > 8e3 ? 60 : vramMb > 0 ? 40 : 20;
13312
13621
  await this.ensureDir();
13313
- await writeFile12(join28(this.nexusDir, "inference-proof.json"), JSON.stringify({
13622
+ await writeFile12(join29(this.nexusDir, "inference-proof.json"), JSON.stringify({
13314
13623
  modelName,
13315
13624
  gpuName,
13316
13625
  vramMb,
@@ -13453,6 +13762,7 @@ var init_dist2 = __esm({
13453
13762
  init_reminder();
13454
13763
  init_agenda();
13455
13764
  init_opencode();
13765
+ init_factory();
13456
13766
  init_cron_agent();
13457
13767
  init_nexus();
13458
13768
  init_system_deps();
@@ -14139,14 +14449,14 @@ var init_dist3 = __esm({
14139
14449
  });
14140
14450
 
14141
14451
  // packages/orchestrator/dist/promptLoader.js
14142
- import { readFileSync as readFileSync16, existsSync as existsSync22 } from "node:fs";
14143
- import { join as join29, dirname as dirname10 } from "node:path";
14452
+ import { readFileSync as readFileSync16, existsSync as existsSync23 } from "node:fs";
14453
+ import { join as join30, dirname as dirname10 } from "node:path";
14144
14454
  import { fileURLToPath as fileURLToPath7 } from "node:url";
14145
14455
  function loadPrompt(promptPath, vars) {
14146
14456
  let content = cache.get(promptPath);
14147
14457
  if (content === void 0) {
14148
- const fullPath = join29(PROMPTS_DIR, promptPath);
14149
- if (!existsSync22(fullPath)) {
14458
+ const fullPath = join30(PROMPTS_DIR, promptPath);
14459
+ if (!existsSync23(fullPath)) {
14150
14460
  throw new Error(`Prompt file not found: ${fullPath}`);
14151
14461
  }
14152
14462
  content = readFileSync16(fullPath, "utf-8");
@@ -14162,7 +14472,7 @@ var init_promptLoader = __esm({
14162
14472
  "use strict";
14163
14473
  __filename = fileURLToPath7(import.meta.url);
14164
14474
  __dirname3 = dirname10(__filename);
14165
- PROMPTS_DIR = join29(__dirname3, "..", "prompts");
14475
+ PROMPTS_DIR = join30(__dirname3, "..", "prompts");
14166
14476
  cache = /* @__PURE__ */ new Map();
14167
14477
  }
14168
14478
  });
@@ -14542,7 +14852,7 @@ var init_code_retriever = __esm({
14542
14852
  import { execFile as execFile5 } from "node:child_process";
14543
14853
  import { promisify as promisify4 } from "node:util";
14544
14854
  import { readFile as readFile14, readdir as readdir4, stat as stat3 } from "node:fs/promises";
14545
- import { join as join30, extname as extname7 } from "node:path";
14855
+ import { join as join31, extname as extname7 } from "node:path";
14546
14856
  async function searchByPath(pathPattern, options) {
14547
14857
  const allFiles = await collectFiles(options.rootDir, options.includeGlobs ?? DEFAULT_INCLUDE_GLOBS, options.excludeGlobs ?? DEFAULT_EXCLUDE_GLOBS);
14548
14858
  const pattern = options.caseInsensitive ? pathPattern.toLowerCase() : pathPattern;
@@ -14684,7 +14994,7 @@ async function walkForFiles(rootDir, dir, excludeGlobs, results) {
14684
14994
  continue;
14685
14995
  if (excludeGlobs.some((g) => entry.name === g || matchesGlob(entry.name, g)))
14686
14996
  continue;
14687
- const absPath = join30(dir, entry.name);
14997
+ const absPath = join31(dir, entry.name);
14688
14998
  if (entry.isDirectory()) {
14689
14999
  await walkForFiles(rootDir, absPath, excludeGlobs, results);
14690
15000
  } else if (entry.isFile()) {
@@ -14991,7 +15301,7 @@ var init_graphExpand = __esm({
14991
15301
 
14992
15302
  // packages/retrieval/dist/snippetPacker.js
14993
15303
  import { readFile as readFile15 } from "node:fs/promises";
14994
- import { join as join31 } from "node:path";
15304
+ import { join as join32 } from "node:path";
14995
15305
  async function packSnippets(requests, opts = {}) {
14996
15306
  const maxTokens = opts.maxTokens ?? DEFAULT_MAX_TOKENS;
14997
15307
  const contextLines = opts.contextLines ?? DEFAULT_CONTEXT_LINES;
@@ -15017,7 +15327,7 @@ async function packSnippets(requests, opts = {}) {
15017
15327
  return { packed, dropped, totalTokens };
15018
15328
  }
15019
15329
  async function extractSnippet(req, repoRoot, contextLines = DEFAULT_CONTEXT_LINES) {
15020
- const absPath = req.filePath.startsWith("/") ? req.filePath : join31(repoRoot, req.filePath);
15330
+ const absPath = req.filePath.startsWith("/") ? req.filePath : join32(repoRoot, req.filePath);
15021
15331
  let content;
15022
15332
  try {
15023
15333
  content = await readFile15(absPath, "utf-8");
@@ -17186,10 +17496,10 @@ ${marker}` : marker);
17186
17496
  if (!this._workingDirectory)
17187
17497
  return;
17188
17498
  try {
17189
- const { mkdirSync: mkdirSync17, writeFileSync: writeFileSync15 } = __require("node:fs");
17190
- const { join: join52 } = __require("node:path");
17191
- const sessionDir = join52(this._workingDirectory, ".oa", "session", this._sessionId);
17192
- mkdirSync17(sessionDir, { recursive: true });
17499
+ const { mkdirSync: mkdirSync18, writeFileSync: writeFileSync16 } = __require("node:fs");
17500
+ const { join: join53 } = __require("node:path");
17501
+ const sessionDir = join53(this._workingDirectory, ".oa", "session", this._sessionId);
17502
+ mkdirSync18(sessionDir, { recursive: true });
17193
17503
  const checkpoint = {
17194
17504
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
17195
17505
  sessionId: this._sessionId,
@@ -17201,7 +17511,7 @@ ${marker}` : marker);
17201
17511
  memexEntryCount: this._memexArchive.size,
17202
17512
  fileRegistrySize: this._fileRegistry.size
17203
17513
  };
17204
- writeFileSync15(join52(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
17514
+ writeFileSync16(join53(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
17205
17515
  } catch {
17206
17516
  }
17207
17517
  }
@@ -18978,9 +19288,9 @@ __export(listen_exports, {
18978
19288
  isVideoPath: () => isVideoPath,
18979
19289
  waitForTranscribeCli: () => waitForTranscribeCli
18980
19290
  });
18981
- import { spawn as spawn11, execSync as execSync22 } from "node:child_process";
18982
- import { existsSync as existsSync23, mkdirSync as mkdirSync6, writeFileSync as writeFileSync6, readdirSync as readdirSync6 } from "node:fs";
18983
- import { join as join32, dirname as dirname11 } from "node:path";
19291
+ import { spawn as spawn12, execSync as execSync23 } from "node:child_process";
19292
+ import { existsSync as existsSync24, mkdirSync as mkdirSync6, writeFileSync as writeFileSync6, readdirSync as readdirSync6 } from "node:fs";
19293
+ import { join as join33, dirname as dirname11 } from "node:path";
18984
19294
  import { homedir as homedir8 } from "node:os";
18985
19295
  import { fileURLToPath as fileURLToPath8 } from "node:url";
18986
19296
  import { EventEmitter } from "node:events";
@@ -19000,7 +19310,7 @@ function findMicCaptureCommand() {
19000
19310
  const platform4 = process.platform;
19001
19311
  if (platform4 === "linux") {
19002
19312
  try {
19003
- execSync22("which arecord", { stdio: "pipe" });
19313
+ execSync23("which arecord", { stdio: "pipe" });
19004
19314
  return {
19005
19315
  cmd: "arecord",
19006
19316
  args: ["-f", "S16_LE", "-r", "16000", "-c", "1", "-t", "raw", "-q", "-"]
@@ -19010,7 +19320,7 @@ function findMicCaptureCommand() {
19010
19320
  }
19011
19321
  if (platform4 === "darwin") {
19012
19322
  try {
19013
- execSync22("which sox", { stdio: "pipe" });
19323
+ execSync23("which sox", { stdio: "pipe" });
19014
19324
  return {
19015
19325
  cmd: "sox",
19016
19326
  args: ["-d", "-t", "raw", "-r", "16000", "-c", "1", "-b", "16", "-e", "signed-integer", "-"]
@@ -19019,7 +19329,7 @@ function findMicCaptureCommand() {
19019
19329
  }
19020
19330
  }
19021
19331
  try {
19022
- execSync22("which ffmpeg", { stdio: "pipe" });
19332
+ execSync23("which ffmpeg", { stdio: "pipe" });
19023
19333
  if (platform4 === "linux") {
19024
19334
  return {
19025
19335
  cmd: "ffmpeg",
@@ -19066,39 +19376,39 @@ function findMicCaptureCommand() {
19066
19376
  function findLiveWhisperScript() {
19067
19377
  const thisDir = dirname11(fileURLToPath8(import.meta.url));
19068
19378
  const candidates = [
19069
- join32(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
19070
- join32(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
19071
- join32(thisDir, "../../execution/scripts/live-whisper.py"),
19379
+ join33(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
19380
+ join33(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
19381
+ join33(thisDir, "../../execution/scripts/live-whisper.py"),
19072
19382
  // npm install layout — scripts bundled alongside dist
19073
- join32(thisDir, "../scripts/live-whisper.py"),
19074
- join32(thisDir, "../../scripts/live-whisper.py")
19383
+ join33(thisDir, "../scripts/live-whisper.py"),
19384
+ join33(thisDir, "../../scripts/live-whisper.py")
19075
19385
  ];
19076
19386
  for (const p of candidates) {
19077
- if (existsSync23(p))
19387
+ if (existsSync24(p))
19078
19388
  return p;
19079
19389
  }
19080
19390
  try {
19081
- const globalRoot = execSync22("npm root -g", {
19391
+ const globalRoot = execSync23("npm root -g", {
19082
19392
  encoding: "utf-8",
19083
19393
  timeout: 5e3,
19084
19394
  stdio: ["pipe", "pipe", "pipe"]
19085
19395
  }).trim();
19086
19396
  const candidates2 = [
19087
- join32(globalRoot, "open-agents-ai", "dist", "scripts", "live-whisper.py"),
19088
- join32(globalRoot, "open-agents-ai", "scripts", "live-whisper.py")
19397
+ join33(globalRoot, "open-agents-ai", "dist", "scripts", "live-whisper.py"),
19398
+ join33(globalRoot, "open-agents-ai", "scripts", "live-whisper.py")
19089
19399
  ];
19090
19400
  for (const p of candidates2) {
19091
- if (existsSync23(p))
19401
+ if (existsSync24(p))
19092
19402
  return p;
19093
19403
  }
19094
19404
  } catch {
19095
19405
  }
19096
- const nvmBase = join32(homedir8(), ".nvm", "versions", "node");
19097
- if (existsSync23(nvmBase)) {
19406
+ const nvmBase = join33(homedir8(), ".nvm", "versions", "node");
19407
+ if (existsSync24(nvmBase)) {
19098
19408
  try {
19099
19409
  for (const ver of readdirSync6(nvmBase)) {
19100
- const p = join32(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
19101
- if (existsSync23(p))
19410
+ const p = join33(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
19411
+ if (existsSync24(p))
19102
19412
  return p;
19103
19413
  }
19104
19414
  } catch {
@@ -19111,12 +19421,12 @@ function ensureTranscribeCliBackground() {
19111
19421
  return;
19112
19422
  _bgInstallPromise = (async () => {
19113
19423
  try {
19114
- const globalRoot = execSync22("npm root -g", {
19424
+ const globalRoot = execSync23("npm root -g", {
19115
19425
  encoding: "utf-8",
19116
19426
  timeout: 5e3,
19117
19427
  stdio: ["pipe", "pipe", "pipe"]
19118
19428
  }).trim();
19119
- if (existsSync23(join32(globalRoot, "transcribe-cli", "dist", "index.js"))) {
19429
+ if (existsSync24(join33(globalRoot, "transcribe-cli", "dist", "index.js"))) {
19120
19430
  return true;
19121
19431
  }
19122
19432
  } catch {
@@ -19188,7 +19498,7 @@ var init_listen = __esm({
19188
19498
  const timeout = setTimeout(() => {
19189
19499
  reject(new Error("Whisper fallback: model load timeout (5 min). First run downloads the model."));
19190
19500
  }, 3e5);
19191
- this.process = spawn11("python3", [
19501
+ this.process = spawn12("python3", [
19192
19502
  this.scriptPath,
19193
19503
  "--model",
19194
19504
  this.model,
@@ -19317,7 +19627,7 @@ var init_listen = __esm({
19317
19627
  }
19318
19628
  if (!this.transcribeCliAvailable) {
19319
19629
  try {
19320
- execSync22("which transcribe-cli", { stdio: "pipe" });
19630
+ execSync23("which transcribe-cli", { stdio: "pipe" });
19321
19631
  this.transcribeCliAvailable = true;
19322
19632
  } catch {
19323
19633
  this.transcribeCliAvailable = false;
@@ -19334,29 +19644,29 @@ var init_listen = __esm({
19334
19644
  } catch {
19335
19645
  }
19336
19646
  try {
19337
- const globalRoot = execSync22("npm root -g", {
19647
+ const globalRoot = execSync23("npm root -g", {
19338
19648
  encoding: "utf-8",
19339
19649
  timeout: 5e3,
19340
19650
  stdio: ["pipe", "pipe", "pipe"]
19341
19651
  }).trim();
19342
- const tcPath = join32(globalRoot, "transcribe-cli");
19343
- if (existsSync23(join32(tcPath, "dist", "index.js"))) {
19652
+ const tcPath = join33(globalRoot, "transcribe-cli");
19653
+ if (existsSync24(join33(tcPath, "dist", "index.js"))) {
19344
19654
  const { createRequire: createRequire4 } = await import("node:module");
19345
19655
  const req = createRequire4(import.meta.url);
19346
- return req(join32(tcPath, "dist", "index.js"));
19656
+ return req(join33(tcPath, "dist", "index.js"));
19347
19657
  }
19348
19658
  } catch {
19349
19659
  }
19350
- const nvmBase = join32(homedir8(), ".nvm", "versions", "node");
19351
- if (existsSync23(nvmBase)) {
19660
+ const nvmBase = join33(homedir8(), ".nvm", "versions", "node");
19661
+ if (existsSync24(nvmBase)) {
19352
19662
  try {
19353
19663
  const { readdirSync: readdirSync15 } = await import("node:fs");
19354
19664
  for (const ver of readdirSync15(nvmBase)) {
19355
- const tcPath = join32(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
19356
- if (existsSync23(join32(tcPath, "dist", "index.js"))) {
19665
+ const tcPath = join33(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
19666
+ if (existsSync24(join33(tcPath, "dist", "index.js"))) {
19357
19667
  const { createRequire: createRequire4 } = await import("node:module");
19358
19668
  const req = createRequire4(import.meta.url);
19359
- return req(join32(tcPath, "dist", "index.js"));
19669
+ return req(join33(tcPath, "dist", "index.js"));
19360
19670
  }
19361
19671
  }
19362
19672
  } catch {
@@ -19384,7 +19694,7 @@ var init_listen = __esm({
19384
19694
  }
19385
19695
  if (!tc) {
19386
19696
  try {
19387
- execSync22("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
19697
+ execSync23("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
19388
19698
  this.transcribeCliAvailable = null;
19389
19699
  tc = await this.loadTranscribeCli();
19390
19700
  } catch {
@@ -19470,7 +19780,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
19470
19780
  return `Failed to start live transcription: ${msg}${tcHint}`;
19471
19781
  }
19472
19782
  }
19473
- this.micProcess = spawn11(micCmd.cmd, micCmd.args, {
19783
+ this.micProcess = spawn12(micCmd.cmd, micCmd.args, {
19474
19784
  stdio: ["pipe", "pipe", "pipe"],
19475
19785
  env: { ...process.env }
19476
19786
  });
@@ -19567,7 +19877,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
19567
19877
  }
19568
19878
  if (!tc) {
19569
19879
  try {
19570
- execSync22("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
19880
+ execSync23("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
19571
19881
  this.transcribeCliAvailable = null;
19572
19882
  tc = await this.loadTranscribeCli();
19573
19883
  } catch {
@@ -19621,7 +19931,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
19621
19931
  }
19622
19932
  if (!tc) {
19623
19933
  try {
19624
- execSync22("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
19934
+ execSync23("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
19625
19935
  this.transcribeCliAvailable = null;
19626
19936
  tc = await this.loadTranscribeCli();
19627
19937
  } catch {
@@ -19638,9 +19948,9 @@ transcribe-cli error: ${transcribeCliError}` : "";
19638
19948
  });
19639
19949
  if (outputDir) {
19640
19950
  const { basename: basename16 } = await import("node:path");
19641
- const transcriptDir = join32(outputDir, ".oa", "transcripts");
19951
+ const transcriptDir = join33(outputDir, ".oa", "transcripts");
19642
19952
  mkdirSync6(transcriptDir, { recursive: true });
19643
- const outFile = join32(transcriptDir, `${basename16(filePath)}.txt`);
19953
+ const outFile = join33(transcriptDir, `${basename16(filePath)}.txt`);
19644
19954
  writeFileSync6(outFile, result.text, "utf-8");
19645
19955
  }
19646
19956
  return {
@@ -24209,7 +24519,7 @@ var init_render = __esm({
24209
24519
 
24210
24520
  // packages/cli/dist/tui/voice-session.js
24211
24521
  import { createServer } from "node:http";
24212
- import { spawn as spawn12, execSync as execSync23 } from "node:child_process";
24522
+ import { spawn as spawn13, execSync as execSync24 } from "node:child_process";
24213
24523
  import { EventEmitter as EventEmitter2 } from "node:events";
24214
24524
  function generateFrontendHTML() {
24215
24525
  return `<!DOCTYPE html>
@@ -24863,7 +25173,7 @@ var init_voice_session = __esm({
24863
25173
  const timeout = setTimeout(() => {
24864
25174
  reject(new Error("Cloudflared tunnel start timeout (30s)"));
24865
25175
  }, 3e4);
24866
- this.cloudflaredProcess = spawn12("cloudflared", [
25176
+ this.cloudflaredProcess = spawn13("cloudflared", [
24867
25177
  "tunnel",
24868
25178
  "--url",
24869
25179
  `http://127.0.0.1:${port}`
@@ -24937,7 +25247,7 @@ var init_voice_session = __esm({
24937
25247
 
24938
25248
  // packages/cli/dist/tui/expose.js
24939
25249
  import { createServer as createServer2, request as httpRequest } from "node:http";
24940
- import { spawn as spawn13 } from "node:child_process";
25250
+ import { spawn as spawn14 } from "node:child_process";
24941
25251
  import { EventEmitter as EventEmitter3 } from "node:events";
24942
25252
  import { randomBytes as randomBytes7 } from "node:crypto";
24943
25253
  import { URL as URL2 } from "node:url";
@@ -25113,7 +25423,7 @@ var init_expose = __esm({
25113
25423
  const timeout = setTimeout(() => {
25114
25424
  reject(new Error("Cloudflared tunnel start timeout (30s)"));
25115
25425
  }, 3e4);
25116
- this.cloudflaredProcess = spawn13("cloudflared", [
25426
+ this.cloudflaredProcess = spawn14("cloudflared", [
25117
25427
  "tunnel",
25118
25428
  "--url",
25119
25429
  `http://127.0.0.1:${port}`
@@ -25216,8 +25526,8 @@ var init_types = __esm({
25216
25526
 
25217
25527
  // packages/cli/dist/tui/p2p/secret-vault.js
25218
25528
  import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes8, scryptSync as scryptSync2, createHash as createHash2 } from "node:crypto";
25219
- import { readFileSync as readFileSync17, writeFileSync as writeFileSync7, existsSync as existsSync24, mkdirSync as mkdirSync7 } from "node:fs";
25220
- import { join as join33, dirname as dirname12 } from "node:path";
25529
+ import { readFileSync as readFileSync17, writeFileSync as writeFileSync7, existsSync as existsSync25, mkdirSync as mkdirSync7 } from "node:fs";
25530
+ import { join as join34, dirname as dirname12 } from "node:path";
25221
25531
  var PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, CIPHER_ALGO, SALT_LEN, IV_LEN, KEY_LEN, SecretVault;
25222
25532
  var init_secret_vault = __esm({
25223
25533
  "packages/cli/dist/tui/p2p/secret-vault.js"() {
@@ -25429,7 +25739,7 @@ var init_secret_vault = __esm({
25429
25739
  const tag = cipher.getAuthTag();
25430
25740
  const blob = Buffer.concat([salt, iv, tag, encrypted]);
25431
25741
  const dir = dirname12(this.storePath);
25432
- if (!existsSync24(dir))
25742
+ if (!existsSync25(dir))
25433
25743
  mkdirSync7(dir, { recursive: true });
25434
25744
  writeFileSync7(this.storePath, blob, { mode: 384 });
25435
25745
  }
@@ -25438,7 +25748,7 @@ var init_secret_vault = __esm({
25438
25748
  * Returns the number of secrets loaded.
25439
25749
  */
25440
25750
  load(passphrase) {
25441
- if (!this.storePath || !existsSync24(this.storePath))
25751
+ if (!this.storePath || !existsSync25(this.storePath))
25442
25752
  return 0;
25443
25753
  const blob = readFileSync17(this.storePath);
25444
25754
  if (blob.length < SALT_LEN + IV_LEN + 16) {
@@ -26660,14 +26970,14 @@ var init_render2 = __esm({
26660
26970
  });
26661
26971
 
26662
26972
  // packages/prompts/dist/promptLoader.js
26663
- import { readFileSync as readFileSync18, existsSync as existsSync25 } from "node:fs";
26664
- import { join as join34, dirname as dirname13 } from "node:path";
26973
+ import { readFileSync as readFileSync18, existsSync as existsSync26 } from "node:fs";
26974
+ import { join as join35, dirname as dirname13 } from "node:path";
26665
26975
  import { fileURLToPath as fileURLToPath9 } from "node:url";
26666
26976
  function loadPrompt2(promptPath, vars) {
26667
26977
  let content = cache2.get(promptPath);
26668
26978
  if (content === void 0) {
26669
- const fullPath = join34(PROMPTS_DIR2, promptPath);
26670
- if (!existsSync25(fullPath)) {
26979
+ const fullPath = join35(PROMPTS_DIR2, promptPath);
26980
+ if (!existsSync26(fullPath)) {
26671
26981
  throw new Error(`Prompt file not found: ${fullPath}`);
26672
26982
  }
26673
26983
  content = readFileSync18(fullPath, "utf-8");
@@ -26683,9 +26993,9 @@ var init_promptLoader2 = __esm({
26683
26993
  "use strict";
26684
26994
  __filename2 = fileURLToPath9(import.meta.url);
26685
26995
  __dirname4 = dirname13(__filename2);
26686
- devPath = join34(__dirname4, "..", "templates");
26687
- publishedPath = join34(__dirname4, "..", "prompts", "templates");
26688
- PROMPTS_DIR2 = existsSync25(devPath) ? devPath : publishedPath;
26996
+ devPath = join35(__dirname4, "..", "templates");
26997
+ publishedPath = join35(__dirname4, "..", "prompts", "templates");
26998
+ PROMPTS_DIR2 = existsSync26(devPath) ? devPath : publishedPath;
26689
26999
  cache2 = /* @__PURE__ */ new Map();
26690
27000
  }
26691
27001
  });
@@ -26796,7 +27106,7 @@ var init_task_templates = __esm({
26796
27106
  });
26797
27107
 
26798
27108
  // packages/prompts/dist/index.js
26799
- import { join as join35, dirname as dirname14 } from "node:path";
27109
+ import { join as join36, dirname as dirname14 } from "node:path";
26800
27110
  import { fileURLToPath as fileURLToPath10 } from "node:url";
26801
27111
  var _dir, _packageRoot;
26802
27112
  var init_dist6 = __esm({
@@ -26807,23 +27117,23 @@ var init_dist6 = __esm({
26807
27117
  init_task_templates();
26808
27118
  init_render2();
26809
27119
  _dir = dirname14(fileURLToPath10(import.meta.url));
26810
- _packageRoot = join35(_dir, "..");
27120
+ _packageRoot = join36(_dir, "..");
26811
27121
  }
26812
27122
  });
26813
27123
 
26814
27124
  // packages/cli/dist/tui/oa-directory.js
26815
- import { existsSync as existsSync26, mkdirSync as mkdirSync8, readFileSync as readFileSync19, writeFileSync as writeFileSync8, readdirSync as readdirSync7, statSync as statSync9, unlinkSync as unlinkSync3 } from "node:fs";
26816
- import { join as join36, relative as relative2, basename as basename9, extname as extname8 } from "node:path";
27125
+ import { existsSync as existsSync27, mkdirSync as mkdirSync8, readFileSync as readFileSync19, writeFileSync as writeFileSync8, readdirSync as readdirSync7, statSync as statSync9, unlinkSync as unlinkSync3 } from "node:fs";
27126
+ import { join as join37, relative as relative2, basename as basename9, extname as extname8 } from "node:path";
26817
27127
  import { homedir as homedir9 } from "node:os";
26818
27128
  function initOaDirectory(repoRoot) {
26819
- const oaPath = join36(repoRoot, OA_DIR);
27129
+ const oaPath = join37(repoRoot, OA_DIR);
26820
27130
  for (const sub of SUBDIRS) {
26821
- mkdirSync8(join36(oaPath, sub), { recursive: true });
27131
+ mkdirSync8(join37(oaPath, sub), { recursive: true });
26822
27132
  }
26823
27133
  try {
26824
- const gitignorePath = join36(repoRoot, ".gitignore");
27134
+ const gitignorePath = join37(repoRoot, ".gitignore");
26825
27135
  const settingsPattern = ".oa/settings.json";
26826
- if (existsSync26(gitignorePath)) {
27136
+ if (existsSync27(gitignorePath)) {
26827
27137
  const content = readFileSync19(gitignorePath, "utf-8");
26828
27138
  if (!content.includes(settingsPattern)) {
26829
27139
  writeFileSync8(gitignorePath, content.trimEnd() + "\n" + settingsPattern + "\n", "utf-8");
@@ -26834,12 +27144,12 @@ function initOaDirectory(repoRoot) {
26834
27144
  return oaPath;
26835
27145
  }
26836
27146
  function hasOaDirectory(repoRoot) {
26837
- return existsSync26(join36(repoRoot, OA_DIR, "index"));
27147
+ return existsSync27(join37(repoRoot, OA_DIR, "index"));
26838
27148
  }
26839
27149
  function loadProjectSettings(repoRoot) {
26840
- const settingsPath = join36(repoRoot, OA_DIR, "settings.json");
27150
+ const settingsPath = join37(repoRoot, OA_DIR, "settings.json");
26841
27151
  try {
26842
- if (existsSync26(settingsPath)) {
27152
+ if (existsSync27(settingsPath)) {
26843
27153
  return JSON.parse(readFileSync19(settingsPath, "utf-8"));
26844
27154
  }
26845
27155
  } catch {
@@ -26847,16 +27157,16 @@ function loadProjectSettings(repoRoot) {
26847
27157
  return {};
26848
27158
  }
26849
27159
  function saveProjectSettings(repoRoot, settings) {
26850
- const oaPath = join36(repoRoot, OA_DIR);
27160
+ const oaPath = join37(repoRoot, OA_DIR);
26851
27161
  mkdirSync8(oaPath, { recursive: true });
26852
27162
  const existing = loadProjectSettings(repoRoot);
26853
27163
  const merged = { ...existing, ...settings };
26854
- writeFileSync8(join36(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
27164
+ writeFileSync8(join37(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
26855
27165
  }
26856
27166
  function loadGlobalSettings() {
26857
- const settingsPath = join36(homedir9(), ".open-agents", "settings.json");
27167
+ const settingsPath = join37(homedir9(), ".open-agents", "settings.json");
26858
27168
  try {
26859
- if (existsSync26(settingsPath)) {
27169
+ if (existsSync27(settingsPath)) {
26860
27170
  return JSON.parse(readFileSync19(settingsPath, "utf-8"));
26861
27171
  }
26862
27172
  } catch {
@@ -26864,11 +27174,11 @@ function loadGlobalSettings() {
26864
27174
  return {};
26865
27175
  }
26866
27176
  function saveGlobalSettings(settings) {
26867
- const dir = join36(homedir9(), ".open-agents");
27177
+ const dir = join37(homedir9(), ".open-agents");
26868
27178
  mkdirSync8(dir, { recursive: true });
26869
27179
  const existing = loadGlobalSettings();
26870
27180
  const merged = { ...existing, ...settings };
26871
- writeFileSync8(join36(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
27181
+ writeFileSync8(join37(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
26872
27182
  }
26873
27183
  function resolveSettings(repoRoot) {
26874
27184
  const global = loadGlobalSettings();
@@ -26883,9 +27193,9 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
26883
27193
  while (dir && !visited.has(dir)) {
26884
27194
  visited.add(dir);
26885
27195
  for (const name of CONTEXT_FILES) {
26886
- const filePath = join36(dir, name);
27196
+ const filePath = join37(dir, name);
26887
27197
  const normalizedName = name.toLowerCase();
26888
- if (existsSync26(filePath) && !seen.has(filePath)) {
27198
+ if (existsSync27(filePath) && !seen.has(filePath)) {
26889
27199
  seen.add(filePath);
26890
27200
  try {
26891
27201
  let content = readFileSync19(filePath, "utf-8");
@@ -26902,8 +27212,8 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
26902
27212
  }
26903
27213
  }
26904
27214
  }
26905
- const projectMap = join36(dir, OA_DIR, "context", "project-map.md");
26906
- if (existsSync26(projectMap) && !seen.has(projectMap)) {
27215
+ const projectMap = join37(dir, OA_DIR, "context", "project-map.md");
27216
+ if (existsSync27(projectMap) && !seen.has(projectMap)) {
26907
27217
  seen.add(projectMap);
26908
27218
  try {
26909
27219
  let content = readFileSync19(projectMap, "utf-8");
@@ -26918,7 +27228,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
26918
27228
  } catch {
26919
27229
  }
26920
27230
  }
26921
- const parent = join36(dir, "..");
27231
+ const parent = join37(dir, "..");
26922
27232
  if (parent === dir)
26923
27233
  break;
26924
27234
  dir = parent;
@@ -26936,7 +27246,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
26936
27246
  return found;
26937
27247
  }
26938
27248
  function readIndexMeta(repoRoot) {
26939
- const metaPath = join36(repoRoot, OA_DIR, "index", "meta.json");
27249
+ const metaPath = join37(repoRoot, OA_DIR, "index", "meta.json");
26940
27250
  try {
26941
27251
  return JSON.parse(readFileSync19(metaPath, "utf-8"));
26942
27252
  } catch {
@@ -26989,28 +27299,28 @@ ${tree}\`\`\`
26989
27299
  sections.push("");
26990
27300
  }
26991
27301
  const content = sections.join("\n");
26992
- const contextDir = join36(repoRoot, OA_DIR, "context");
27302
+ const contextDir = join37(repoRoot, OA_DIR, "context");
26993
27303
  mkdirSync8(contextDir, { recursive: true });
26994
- writeFileSync8(join36(contextDir, "project-map.md"), content, "utf-8");
27304
+ writeFileSync8(join37(contextDir, "project-map.md"), content, "utf-8");
26995
27305
  return content;
26996
27306
  }
26997
27307
  function saveSession(repoRoot, session) {
26998
- const historyDir = join36(repoRoot, OA_DIR, "history");
27308
+ const historyDir = join37(repoRoot, OA_DIR, "history");
26999
27309
  mkdirSync8(historyDir, { recursive: true });
27000
- writeFileSync8(join36(historyDir, `${session.id}.json`), JSON.stringify(session, null, 2), "utf-8");
27310
+ writeFileSync8(join37(historyDir, `${session.id}.json`), JSON.stringify(session, null, 2), "utf-8");
27001
27311
  }
27002
27312
  function loadRecentSessions(repoRoot, limit = 5) {
27003
- const historyDir = join36(repoRoot, OA_DIR, "history");
27004
- if (!existsSync26(historyDir))
27313
+ const historyDir = join37(repoRoot, OA_DIR, "history");
27314
+ if (!existsSync27(historyDir))
27005
27315
  return [];
27006
27316
  try {
27007
27317
  const files = readdirSync7(historyDir).filter((f) => f.endsWith(".json") && f !== "pending-task.json").map((f) => {
27008
- const stat5 = statSync9(join36(historyDir, f));
27318
+ const stat5 = statSync9(join37(historyDir, f));
27009
27319
  return { file: f, mtime: stat5.mtimeMs };
27010
27320
  }).sort((a, b) => b.mtime - a.mtime).slice(0, limit);
27011
27321
  return files.map((f) => {
27012
27322
  try {
27013
- return JSON.parse(readFileSync19(join36(historyDir, f.file), "utf-8"));
27323
+ return JSON.parse(readFileSync19(join37(historyDir, f.file), "utf-8"));
27014
27324
  } catch {
27015
27325
  return null;
27016
27326
  }
@@ -27020,14 +27330,14 @@ function loadRecentSessions(repoRoot, limit = 5) {
27020
27330
  }
27021
27331
  }
27022
27332
  function savePendingTask(repoRoot, task) {
27023
- const historyDir = join36(repoRoot, OA_DIR, "history");
27333
+ const historyDir = join37(repoRoot, OA_DIR, "history");
27024
27334
  mkdirSync8(historyDir, { recursive: true });
27025
- writeFileSync8(join36(historyDir, PENDING_TASK_FILE), JSON.stringify(task, null, 2) + "\n", "utf-8");
27335
+ writeFileSync8(join37(historyDir, PENDING_TASK_FILE), JSON.stringify(task, null, 2) + "\n", "utf-8");
27026
27336
  }
27027
27337
  function loadPendingTask(repoRoot) {
27028
- const filePath = join36(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
27338
+ const filePath = join37(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
27029
27339
  try {
27030
- if (!existsSync26(filePath))
27340
+ if (!existsSync27(filePath))
27031
27341
  return null;
27032
27342
  const data = JSON.parse(readFileSync19(filePath, "utf-8"));
27033
27343
  try {
@@ -27040,12 +27350,12 @@ function loadPendingTask(repoRoot) {
27040
27350
  }
27041
27351
  }
27042
27352
  function saveSessionContext(repoRoot, entry) {
27043
- const contextDir = join36(repoRoot, OA_DIR, "context");
27353
+ const contextDir = join37(repoRoot, OA_DIR, "context");
27044
27354
  mkdirSync8(contextDir, { recursive: true });
27045
- const filePath = join36(contextDir, CONTEXT_SAVE_FILE);
27355
+ const filePath = join37(contextDir, CONTEXT_SAVE_FILE);
27046
27356
  let ctx;
27047
27357
  try {
27048
- if (existsSync26(filePath)) {
27358
+ if (existsSync27(filePath)) {
27049
27359
  ctx = JSON.parse(readFileSync19(filePath, "utf-8"));
27050
27360
  } else {
27051
27361
  ctx = { entries: [], maxEntries: MAX_CONTEXT_ENTRIES, updatedAt: "" };
@@ -27061,9 +27371,9 @@ function saveSessionContext(repoRoot, entry) {
27061
27371
  writeFileSync8(filePath, JSON.stringify(ctx, null, 2) + "\n", "utf-8");
27062
27372
  }
27063
27373
  function loadSessionContext(repoRoot) {
27064
- const filePath = join36(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
27374
+ const filePath = join37(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
27065
27375
  try {
27066
- if (!existsSync26(filePath))
27376
+ if (!existsSync27(filePath))
27067
27377
  return null;
27068
27378
  return JSON.parse(readFileSync19(filePath, "utf-8"));
27069
27379
  } catch {
@@ -27112,8 +27422,8 @@ function detectManifests(repoRoot) {
27112
27422
  { file: "docker-compose.yaml", type: "Docker Compose" }
27113
27423
  ];
27114
27424
  for (const check of checks) {
27115
- const filePath = join36(repoRoot, check.file);
27116
- if (existsSync26(filePath)) {
27425
+ const filePath = join37(repoRoot, check.file);
27426
+ if (existsSync27(filePath)) {
27117
27427
  let name;
27118
27428
  if (check.nameField) {
27119
27429
  try {
@@ -27146,7 +27456,7 @@ function findKeyFiles(repoRoot) {
27146
27456
  { pattern: "CLAUDE.md", description: "Claude Code context" }
27147
27457
  ];
27148
27458
  for (const check of checks) {
27149
- if (existsSync26(join36(repoRoot, check.pattern))) {
27459
+ if (existsSync27(join37(repoRoot, check.pattern))) {
27150
27460
  keyFiles.push({ path: check.pattern, description: check.description });
27151
27461
  }
27152
27462
  }
@@ -27172,12 +27482,12 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
27172
27482
  if (entry.isDirectory()) {
27173
27483
  let fileCount = 0;
27174
27484
  try {
27175
- fileCount = readdirSync7(join36(root, entry.name)).filter((f) => !f.startsWith(".")).length;
27485
+ fileCount = readdirSync7(join37(root, entry.name)).filter((f) => !f.startsWith(".")).length;
27176
27486
  } catch {
27177
27487
  }
27178
27488
  result += `${prefix}${connector}${entry.name}/ (${fileCount})
27179
27489
  `;
27180
- result += buildDirTree(join36(root, entry.name), maxDepth, childPrefix, depth + 1);
27490
+ result += buildDirTree(join37(root, entry.name), maxDepth, childPrefix, depth + 1);
27181
27491
  } else if (depth < maxDepth) {
27182
27492
  result += `${prefix}${connector}${entry.name}
27183
27493
  `;
@@ -27230,9 +27540,9 @@ var init_oa_directory = __esm({
27230
27540
 
27231
27541
  // packages/cli/dist/tui/setup.js
27232
27542
  import * as readline from "node:readline";
27233
- import { execSync as execSync24, spawn as spawn14 } from "node:child_process";
27234
- import { existsSync as existsSync27, writeFileSync as writeFileSync9, mkdirSync as mkdirSync9 } from "node:fs";
27235
- import { join as join37 } from "node:path";
27543
+ import { execSync as execSync25, spawn as spawn15 } from "node:child_process";
27544
+ import { existsSync as existsSync28, writeFileSync as writeFileSync9, mkdirSync as mkdirSync9 } from "node:fs";
27545
+ import { join as join38 } from "node:path";
27236
27546
  import { homedir as homedir10, platform } from "node:os";
27237
27547
  function detectSystemSpecs() {
27238
27548
  let totalRamGB = 0;
@@ -27240,7 +27550,7 @@ function detectSystemSpecs() {
27240
27550
  let gpuVramGB = 0;
27241
27551
  let gpuName = "";
27242
27552
  try {
27243
- const memInfo = execSync24("free -b 2>/dev/null || sysctl -n hw.memsize 2>/dev/null", {
27553
+ const memInfo = execSync25("free -b 2>/dev/null || sysctl -n hw.memsize 2>/dev/null", {
27244
27554
  encoding: "utf8",
27245
27555
  timeout: 5e3
27246
27556
  });
@@ -27260,7 +27570,7 @@ function detectSystemSpecs() {
27260
27570
  } catch {
27261
27571
  }
27262
27572
  try {
27263
- const nvidiaSmi = execSync24("nvidia-smi --query-gpu=memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 5e3 });
27573
+ const nvidiaSmi = execSync25("nvidia-smi --query-gpu=memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 5e3 });
27264
27574
  const lines = nvidiaSmi.trim().split("\n");
27265
27575
  if (lines.length > 0) {
27266
27576
  for (const line of lines) {
@@ -27385,7 +27695,7 @@ function ensureCurl() {
27385
27695
  for (const s of strategies) {
27386
27696
  if (hasCmd(s.check)) {
27387
27697
  try {
27388
- execSync24(s.install, { stdio: "inherit", timeout: 12e4 });
27698
+ execSync25(s.install, { stdio: "inherit", timeout: 12e4 });
27389
27699
  if (hasCmd("curl")) {
27390
27700
  process.stdout.write(` ${c2.green("\u2714")} curl installed via ${s.label}.
27391
27701
  `);
@@ -27399,7 +27709,7 @@ function ensureCurl() {
27399
27709
  }
27400
27710
  if (plat === "darwin") {
27401
27711
  try {
27402
- execSync24("xcode-select --install", { stdio: "inherit", timeout: 3e5 });
27712
+ execSync25("xcode-select --install", { stdio: "inherit", timeout: 3e5 });
27403
27713
  if (hasCmd("curl"))
27404
27714
  return true;
27405
27715
  } catch {
@@ -27434,7 +27744,7 @@ function installOllamaLinux() {
27434
27744
 
27435
27745
  `);
27436
27746
  try {
27437
- execSync24("curl -fsSL https://ollama.com/install.sh | sh", {
27747
+ execSync25("curl -fsSL https://ollama.com/install.sh | sh", {
27438
27748
  stdio: "inherit",
27439
27749
  timeout: 3e5
27440
27750
  });
@@ -27462,10 +27772,10 @@ async function installOllamaMac(_rl) {
27462
27772
 
27463
27773
  `);
27464
27774
  try {
27465
- execSync24('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"', { stdio: "inherit", timeout: 6e5 });
27775
+ execSync25('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"', { stdio: "inherit", timeout: 6e5 });
27466
27776
  if (!hasCmd("brew")) {
27467
27777
  try {
27468
- const brewPrefix = existsSync27("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
27778
+ const brewPrefix = existsSync28("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
27469
27779
  process.env["PATH"] = `${brewPrefix}/bin:${process.env["PATH"]}`;
27470
27780
  } catch {
27471
27781
  }
@@ -27495,7 +27805,7 @@ async function installOllamaMac(_rl) {
27495
27805
 
27496
27806
  `);
27497
27807
  try {
27498
- execSync24("brew install ollama", {
27808
+ execSync25("brew install ollama", {
27499
27809
  stdio: "inherit",
27500
27810
  timeout: 3e5
27501
27811
  });
@@ -27522,7 +27832,7 @@ function installOllamaWindows() {
27522
27832
 
27523
27833
  `);
27524
27834
  try {
27525
- execSync24('powershell -Command "irm https://ollama.com/install.ps1 | iex"', {
27835
+ execSync25('powershell -Command "irm https://ollama.com/install.ps1 | iex"', {
27526
27836
  stdio: "inherit",
27527
27837
  timeout: 3e5
27528
27838
  });
@@ -27573,7 +27883,7 @@ async function ensureOllamaRunning(backendUrl, rl) {
27573
27883
  process.stdout.write(` ${c2.cyan("\u25CF")} Starting ollama serve...
27574
27884
  `);
27575
27885
  try {
27576
- const child = spawn14("ollama", ["serve"], { stdio: "ignore", detached: true });
27886
+ const child = spawn15("ollama", ["serve"], { stdio: "ignore", detached: true });
27577
27887
  child.unref();
27578
27888
  } catch {
27579
27889
  process.stdout.write(` ${c2.yellow("\u26A0")} Could not start ollama serve.
@@ -27603,7 +27913,7 @@ async function ensureOllamaRunning(backendUrl, rl) {
27603
27913
  }
27604
27914
  function pullModelWithAutoUpdate(tag) {
27605
27915
  try {
27606
- execSync24(`ollama pull ${tag}`, {
27916
+ execSync25(`ollama pull ${tag}`, {
27607
27917
  stdio: "inherit",
27608
27918
  timeout: 36e5
27609
27919
  // 1 hour max
@@ -27623,7 +27933,7 @@ function pullModelWithAutoUpdate(tag) {
27623
27933
 
27624
27934
  `);
27625
27935
  try {
27626
- execSync24("curl -fsSL https://ollama.com/install.sh | sh", {
27936
+ execSync25("curl -fsSL https://ollama.com/install.sh | sh", {
27627
27937
  stdio: "inherit",
27628
27938
  timeout: 3e5
27629
27939
  // 5 min max for install
@@ -27634,7 +27944,7 @@ function pullModelWithAutoUpdate(tag) {
27634
27944
  process.stdout.write(` ${c2.cyan("\u25CF")} Retrying pull of ${c2.bold(tag)}...
27635
27945
 
27636
27946
  `);
27637
- execSync24(`ollama pull ${tag}`, {
27947
+ execSync25(`ollama pull ${tag}`, {
27638
27948
  stdio: "inherit",
27639
27949
  timeout: 36e5
27640
27950
  });
@@ -27736,7 +28046,7 @@ function ensurePython3() {
27736
28046
  if (plat === "darwin") {
27737
28047
  if (hasCmd("brew")) {
27738
28048
  try {
27739
- execSync24("brew install python3", { stdio: "inherit", timeout: 3e5 });
28049
+ execSync25("brew install python3", { stdio: "inherit", timeout: 3e5 });
27740
28050
  if (hasCmd("python3")) {
27741
28051
  process.stdout.write(` ${c2.green("\u2714")} Python3 installed via Homebrew.
27742
28052
  `);
@@ -27749,7 +28059,7 @@ function ensurePython3() {
27749
28059
  for (const s of strategies) {
27750
28060
  if (hasCmd(s.check)) {
27751
28061
  try {
27752
- execSync24(s.install, { stdio: "inherit", timeout: 12e4 });
28062
+ execSync25(s.install, { stdio: "inherit", timeout: 12e4 });
27753
28063
  if (hasCmd("python3") || hasCmd("python")) {
27754
28064
  process.stdout.write(` ${c2.green("\u2714")} Python3 installed via ${s.label}.
27755
28065
  `);
@@ -27765,11 +28075,11 @@ function ensurePython3() {
27765
28075
  }
27766
28076
  function checkPythonVenv() {
27767
28077
  try {
27768
- execSync24("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
28078
+ execSync25("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
27769
28079
  return true;
27770
28080
  } catch {
27771
28081
  try {
27772
- execSync24("python -m venv --help", { stdio: "pipe", timeout: 5e3 });
28082
+ execSync25("python -m venv --help", { stdio: "pipe", timeout: 5e3 });
27773
28083
  return true;
27774
28084
  } catch {
27775
28085
  return false;
@@ -27788,7 +28098,7 @@ function ensurePythonVenv() {
27788
28098
  for (const s of strategies) {
27789
28099
  if (hasCmd(s.check)) {
27790
28100
  try {
27791
- execSync24(s.install, { stdio: "inherit", timeout: 12e4 });
28101
+ execSync25(s.install, { stdio: "inherit", timeout: 12e4 });
27792
28102
  if (checkPythonVenv()) {
27793
28103
  process.stdout.write(` ${c2.green("\u2714")} python3-venv installed via ${s.label}.
27794
28104
  `);
@@ -28041,7 +28351,7 @@ async function doSetup(config, rl) {
28041
28351
  ${c2.cyan("\u25CF")} Ollama is installed but not running. Starting automatically...
28042
28352
  `);
28043
28353
  try {
28044
- const child = spawn14("ollama", ["serve"], { stdio: "ignore", detached: true });
28354
+ const child = spawn15("ollama", ["serve"], { stdio: "ignore", detached: true });
28045
28355
  child.unref();
28046
28356
  await new Promise((resolve31) => setTimeout(resolve31, 3e3));
28047
28357
  try {
@@ -28069,7 +28379,7 @@ async function doSetup(config, rl) {
28069
28379
  ${c2.cyan("\u25CF")} Starting ollama serve...
28070
28380
  `);
28071
28381
  try {
28072
- const child = spawn14("ollama", ["serve"], { stdio: "ignore", detached: true });
28382
+ const child = spawn15("ollama", ["serve"], { stdio: "ignore", detached: true });
28073
28383
  child.unref();
28074
28384
  await new Promise((resolve31) => setTimeout(resolve31, 3e3));
28075
28385
  try {
@@ -28219,12 +28529,12 @@ async function doSetup(config, rl) {
28219
28529
  `PARAMETER num_predict ${numPredict}`,
28220
28530
  `PARAMETER stop "<|endoftext|>"`
28221
28531
  ].join("\n");
28222
- const modelDir2 = join37(homedir10(), ".open-agents", "models");
28532
+ const modelDir2 = join38(homedir10(), ".open-agents", "models");
28223
28533
  mkdirSync9(modelDir2, { recursive: true });
28224
- const modelfilePath = join37(modelDir2, `Modelfile.${customName}`);
28534
+ const modelfilePath = join38(modelDir2, `Modelfile.${customName}`);
28225
28535
  writeFileSync9(modelfilePath, modelfileContent + "\n", "utf8");
28226
28536
  process.stdout.write(` ${c2.dim("Creating model...")} `);
28227
- execSync24(`ollama create ${customName} -f ${modelfilePath}`, {
28537
+ execSync25(`ollama create ${customName} -f ${modelfilePath}`, {
28228
28538
  stdio: "pipe",
28229
28539
  timeout: 12e4
28230
28540
  });
@@ -28267,7 +28577,7 @@ async function isModelAvailable(config) {
28267
28577
  }
28268
28578
  function isFirstRun() {
28269
28579
  try {
28270
- return !existsSync27(join37(homedir10(), ".open-agents", "config.json"));
28580
+ return !existsSync28(join38(homedir10(), ".open-agents", "config.json"));
28271
28581
  } catch {
28272
28582
  return true;
28273
28583
  }
@@ -28275,7 +28585,7 @@ function isFirstRun() {
28275
28585
  function hasCmd(cmd) {
28276
28586
  try {
28277
28587
  const whichCmd = process.platform === "win32" ? `where ${cmd}` : `which ${cmd}`;
28278
- execSync24(whichCmd, { stdio: "pipe", timeout: 3e3 });
28588
+ execSync25(whichCmd, { stdio: "pipe", timeout: 3e3 });
28279
28589
  return true;
28280
28590
  } catch {
28281
28591
  return false;
@@ -28304,11 +28614,11 @@ function detectPkgManager() {
28304
28614
  return null;
28305
28615
  }
28306
28616
  function getVenvDir() {
28307
- return join37(homedir10(), ".open-agents", "venv");
28617
+ return join38(homedir10(), ".open-agents", "venv");
28308
28618
  }
28309
28619
  function hasVenvModule() {
28310
28620
  try {
28311
- execSync24("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
28621
+ execSync25("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
28312
28622
  return true;
28313
28623
  } catch {
28314
28624
  return false;
@@ -28316,8 +28626,8 @@ function hasVenvModule() {
28316
28626
  }
28317
28627
  function ensureVenv(log) {
28318
28628
  const venvDir = getVenvDir();
28319
- const venvPip = join37(venvDir, "bin", "pip");
28320
- if (existsSync27(venvPip))
28629
+ const venvPip = join38(venvDir, "bin", "pip");
28630
+ if (existsSync28(venvPip))
28321
28631
  return venvDir;
28322
28632
  log("Creating Python venv for vision deps...");
28323
28633
  if (!hasCmd("python3")) {
@@ -28329,9 +28639,9 @@ function ensureVenv(log) {
28329
28639
  return null;
28330
28640
  }
28331
28641
  try {
28332
- mkdirSync9(join37(homedir10(), ".open-agents"), { recursive: true });
28333
- execSync24(`python3 -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
28334
- execSync24(`"${join37(venvDir, "bin", "pip")}" install --upgrade pip`, {
28642
+ mkdirSync9(join38(homedir10(), ".open-agents"), { recursive: true });
28643
+ execSync25(`python3 -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
28644
+ execSync25(`"${join38(venvDir, "bin", "pip")}" install --upgrade pip`, {
28335
28645
  stdio: "pipe",
28336
28646
  timeout: 6e4
28337
28647
  });
@@ -28344,7 +28654,7 @@ function ensureVenv(log) {
28344
28654
  }
28345
28655
  function trySudoPasswordless(cmd, timeoutMs = 12e4) {
28346
28656
  try {
28347
- execSync24(`sudo -n ${cmd}`, {
28657
+ execSync25(`sudo -n ${cmd}`, {
28348
28658
  stdio: "pipe",
28349
28659
  timeout: timeoutMs,
28350
28660
  env: { ...process.env, DEBIAN_FRONTEND: "noninteractive" }
@@ -28356,7 +28666,7 @@ function trySudoPasswordless(cmd, timeoutMs = 12e4) {
28356
28666
  }
28357
28667
  function runWithSudo(cmd, password, timeoutMs = 12e4) {
28358
28668
  try {
28359
- execSync24(`sudo -S ${cmd}`, {
28669
+ execSync25(`sudo -S ${cmd}`, {
28360
28670
  input: password + "\n",
28361
28671
  stdio: ["pipe", "pipe", "pipe"],
28362
28672
  timeout: timeoutMs,
@@ -28416,7 +28726,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
28416
28726
  } else {
28417
28727
  log("Installing tesseract-ocr...");
28418
28728
  try {
28419
- execSync24(pkg.cmd, { stdio: "pipe", timeout: 12e4 });
28729
+ execSync25(pkg.cmd, { stdio: "pipe", timeout: 12e4 });
28420
28730
  if (hasCmd("tesseract")) {
28421
28731
  log("tesseract-ocr installed successfully.");
28422
28732
  } else {
@@ -28488,7 +28798,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
28488
28798
  } else {
28489
28799
  log(`Installing ${dep.label}...`);
28490
28800
  try {
28491
- execSync24(pkg.cmd, { stdio: "pipe", timeout: 12e4 });
28801
+ execSync25(pkg.cmd, { stdio: "pipe", timeout: 12e4 });
28492
28802
  if (hasCmd(dep.binary)) {
28493
28803
  log(`${dep.label} installed successfully.`);
28494
28804
  } else {
@@ -28519,7 +28829,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
28519
28829
  const venvCmds = {
28520
28830
  apt: () => {
28521
28831
  try {
28522
- const pyVer = execSync24(`python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).trim();
28832
+ const pyVer = execSync25(`python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).trim();
28523
28833
  return `apt-get install -y python3-venv python${pyVer}-venv`;
28524
28834
  } catch {
28525
28835
  return "apt-get install -y python3-venv";
@@ -28540,19 +28850,19 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
28540
28850
  }
28541
28851
  }
28542
28852
  const venvDir = getVenvDir();
28543
- const venvBin = join37(venvDir, "bin");
28544
- const venvMoondream = join37(venvBin, "moondream-station");
28853
+ const venvBin = join38(venvDir, "bin");
28854
+ const venvMoondream = join38(venvBin, "moondream-station");
28545
28855
  const venv = ensureVenv(log);
28546
- if (venv && !hasCmd("moondream-station") && !existsSync27(venvMoondream)) {
28547
- const venvPip = join37(venvBin, "pip");
28856
+ if (venv && !hasCmd("moondream-station") && !existsSync28(venvMoondream)) {
28857
+ const venvPip = join38(venvBin, "pip");
28548
28858
  log("Installing moondream-station in ~/.open-agents/venv...");
28549
28859
  try {
28550
- execSync24(`"${venvPip}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
28551
- if (existsSync27(venvMoondream)) {
28860
+ execSync25(`"${venvPip}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
28861
+ if (existsSync28(venvMoondream)) {
28552
28862
  log("moondream-station installed successfully.");
28553
28863
  } else {
28554
28864
  try {
28555
- const check = execSync24(`"${venvPip}" show moondream-station`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 });
28865
+ const check = execSync25(`"${venvPip}" show moondream-station`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 });
28556
28866
  if (check.includes("moondream")) {
28557
28867
  log("moondream-station package installed.");
28558
28868
  }
@@ -28565,11 +28875,11 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
28565
28875
  }
28566
28876
  }
28567
28877
  if (venv) {
28568
- const venvPython = join37(venvBin, "python");
28569
- const venvPip2 = join37(venvBin, "pip");
28878
+ const venvPython = join38(venvBin, "python");
28879
+ const venvPip2 = join38(venvBin, "pip");
28570
28880
  let ocrStackInstalled = false;
28571
28881
  try {
28572
- execSync24(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
28882
+ execSync25(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
28573
28883
  ocrStackInstalled = true;
28574
28884
  } catch {
28575
28885
  }
@@ -28577,9 +28887,9 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
28577
28887
  const ocrPackages = "pytesseract Pillow opencv-python-headless numpy";
28578
28888
  log("Installing OCR Python stack (pytesseract, OpenCV, Pillow, numpy)...");
28579
28889
  try {
28580
- execSync24(`"${venvPip2}" install ${ocrPackages}`, { stdio: "pipe", timeout: 3e5 });
28890
+ execSync25(`"${venvPip2}" install ${ocrPackages}`, { stdio: "pipe", timeout: 3e5 });
28581
28891
  try {
28582
- execSync24(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
28892
+ execSync25(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
28583
28893
  log("OCR Python stack installed successfully.");
28584
28894
  } catch {
28585
28895
  log("OCR Python stack install completed but import verification failed.");
@@ -28613,7 +28923,7 @@ function ensureCloudflaredBackground(onInfo) {
28613
28923
  const archMap = { x64: "amd64", arm64: "arm64", arm: "arm" };
28614
28924
  const cfArch = archMap[arch] ?? "amd64";
28615
28925
  try {
28616
- execSync24(`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && mkdir -p "${homedir10()}/.local/bin" && mv /tmp/cloudflared "${homedir10()}/.local/bin/cloudflared"`, { stdio: "pipe", timeout: 6e4 });
28926
+ execSync25(`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && mkdir -p "${homedir10()}/.local/bin" && mv /tmp/cloudflared "${homedir10()}/.local/bin/cloudflared"`, { stdio: "pipe", timeout: 6e4 });
28617
28927
  if (!process.env.PATH?.includes(`${homedir10()}/.local/bin`)) {
28618
28928
  process.env.PATH = `${homedir10()}/.local/bin:${process.env.PATH}`;
28619
28929
  }
@@ -28624,7 +28934,7 @@ function ensureCloudflaredBackground(onInfo) {
28624
28934
  } catch {
28625
28935
  }
28626
28936
  try {
28627
- execSync24(`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && sudo mv /tmp/cloudflared /usr/local/bin/cloudflared 2>/dev/null`, { stdio: "pipe", timeout: 6e4 });
28937
+ execSync25(`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && sudo mv /tmp/cloudflared /usr/local/bin/cloudflared 2>/dev/null`, { stdio: "pipe", timeout: 6e4 });
28628
28938
  if (hasCmd("cloudflared")) {
28629
28939
  log("cloudflared installed.");
28630
28940
  return true;
@@ -28633,7 +28943,7 @@ function ensureCloudflaredBackground(onInfo) {
28633
28943
  }
28634
28944
  } else if (os === "darwin") {
28635
28945
  try {
28636
- execSync24("brew install cloudflared", { stdio: "pipe", timeout: 12e4 });
28946
+ execSync25("brew install cloudflared", { stdio: "pipe", timeout: 12e4 });
28637
28947
  if (hasCmd("cloudflared")) {
28638
28948
  log("cloudflared installed via Homebrew.");
28639
28949
  return true;
@@ -28679,11 +28989,11 @@ function createExpandedVariant(baseModel, specs, sizeGB) {
28679
28989
  `PARAMETER num_predict ${numPredict}`,
28680
28990
  `PARAMETER stop "<|endoftext|>"`
28681
28991
  ].join("\n");
28682
- const modelDir2 = join37(homedir10(), ".open-agents", "models");
28992
+ const modelDir2 = join38(homedir10(), ".open-agents", "models");
28683
28993
  mkdirSync9(modelDir2, { recursive: true });
28684
- const modelfilePath = join37(modelDir2, `Modelfile.${customName}`);
28994
+ const modelfilePath = join38(modelDir2, `Modelfile.${customName}`);
28685
28995
  writeFileSync9(modelfilePath, modelfileContent + "\n", "utf8");
28686
- execSync24(`ollama create ${customName} -f ${modelfilePath}`, {
28996
+ execSync25(`ollama create ${customName} -f ${modelfilePath}`, {
28687
28997
  stdio: "pipe",
28688
28998
  timeout: 12e4
28689
28999
  });
@@ -29986,17 +30296,17 @@ async function handleUpdate(subcommand, ctx) {
29986
30296
  try {
29987
30297
  const { createRequire: createRequire4 } = await import("node:module");
29988
30298
  const { fileURLToPath: fileURLToPath14 } = await import("node:url");
29989
- const { dirname: dirname18, join: join52 } = await import("node:path");
29990
- const { existsSync: existsSync38 } = await import("node:fs");
30299
+ const { dirname: dirname18, join: join53 } = await import("node:path");
30300
+ const { existsSync: existsSync39 } = await import("node:fs");
29991
30301
  const req = createRequire4(import.meta.url);
29992
30302
  const thisDir = dirname18(fileURLToPath14(import.meta.url));
29993
30303
  const candidates = [
29994
- join52(thisDir, "..", "package.json"),
29995
- join52(thisDir, "..", "..", "package.json"),
29996
- join52(thisDir, "..", "..", "..", "package.json")
30304
+ join53(thisDir, "..", "package.json"),
30305
+ join53(thisDir, "..", "..", "package.json"),
30306
+ join53(thisDir, "..", "..", "..", "package.json")
29997
30307
  ];
29998
30308
  for (const pkgPath of candidates) {
29999
- if (existsSync38(pkgPath)) {
30309
+ if (existsSync39(pkgPath)) {
30000
30310
  const pkg = req(pkgPath);
30001
30311
  if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
30002
30312
  currentVersion = pkg.version ?? "0.0.0";
@@ -30252,9 +30562,9 @@ var init_commands = __esm({
30252
30562
  });
30253
30563
 
30254
30564
  // packages/cli/dist/tui/project-context.js
30255
- import { existsSync as existsSync28, readFileSync as readFileSync20, readdirSync as readdirSync8 } from "node:fs";
30256
- import { join as join38, basename as basename10 } from "node:path";
30257
- import { execSync as execSync25 } from "node:child_process";
30565
+ import { existsSync as existsSync29, readFileSync as readFileSync20, readdirSync as readdirSync8 } from "node:fs";
30566
+ import { join as join39, basename as basename10 } from "node:path";
30567
+ import { execSync as execSync26 } from "node:child_process";
30258
30568
  import { homedir as homedir11, platform as platform2, release } from "node:os";
30259
30569
  function getModelTier(modelName) {
30260
30570
  const m = modelName.toLowerCase();
@@ -30288,8 +30598,8 @@ function loadProjectMap(repoRoot) {
30288
30598
  if (!hasOaDirectory(repoRoot)) {
30289
30599
  initOaDirectory(repoRoot);
30290
30600
  }
30291
- const mapPath = join38(repoRoot, OA_DIR, "context", "project-map.md");
30292
- if (existsSync28(mapPath)) {
30601
+ const mapPath = join39(repoRoot, OA_DIR, "context", "project-map.md");
30602
+ if (existsSync29(mapPath)) {
30293
30603
  try {
30294
30604
  const content = readFileSync20(mapPath, "utf-8");
30295
30605
  return content;
@@ -30300,19 +30610,19 @@ function loadProjectMap(repoRoot) {
30300
30610
  }
30301
30611
  function getGitInfo(repoRoot) {
30302
30612
  try {
30303
- execSync25("git rev-parse --is-inside-work-tree", { cwd: repoRoot, stdio: "pipe" });
30613
+ execSync26("git rev-parse --is-inside-work-tree", { cwd: repoRoot, stdio: "pipe" });
30304
30614
  } catch {
30305
30615
  return "";
30306
30616
  }
30307
30617
  const lines = [];
30308
30618
  try {
30309
- const branch = execSync25("git branch --show-current", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
30619
+ const branch = execSync26("git branch --show-current", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
30310
30620
  if (branch)
30311
30621
  lines.push(`Branch: ${branch}`);
30312
30622
  } catch {
30313
30623
  }
30314
30624
  try {
30315
- const status = execSync25("git status --porcelain", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
30625
+ const status = execSync26("git status --porcelain", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
30316
30626
  if (status) {
30317
30627
  const changed = status.split("\n").length;
30318
30628
  lines.push(`Working tree: ${changed} changed file(s)`);
@@ -30322,7 +30632,7 @@ function getGitInfo(repoRoot) {
30322
30632
  } catch {
30323
30633
  }
30324
30634
  try {
30325
- const log = execSync25("git log --oneline -5 --no-decorate", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
30635
+ const log = execSync26("git log --oneline -5 --no-decorate", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
30326
30636
  if (log)
30327
30637
  lines.push(`Recent commits:
30328
30638
  ${log}`);
@@ -30332,31 +30642,31 @@ ${log}`);
30332
30642
  }
30333
30643
  function loadMemoryContext(repoRoot) {
30334
30644
  const sections = [];
30335
- const oaMemDir = join38(repoRoot, OA_DIR, "memory");
30645
+ const oaMemDir = join39(repoRoot, OA_DIR, "memory");
30336
30646
  const oaEntries = loadMemoryDir(oaMemDir, "project");
30337
30647
  if (oaEntries)
30338
30648
  sections.push(oaEntries);
30339
- const legacyMemDir = join38(repoRoot, ".open-agents", "memory");
30340
- if (legacyMemDir !== oaMemDir && existsSync28(legacyMemDir)) {
30649
+ const legacyMemDir = join39(repoRoot, ".open-agents", "memory");
30650
+ if (legacyMemDir !== oaMemDir && existsSync29(legacyMemDir)) {
30341
30651
  const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
30342
30652
  if (legacyEntries)
30343
30653
  sections.push(legacyEntries);
30344
30654
  }
30345
- const globalMemDir = join38(homedir11(), ".open-agents", "memory");
30655
+ const globalMemDir = join39(homedir11(), ".open-agents", "memory");
30346
30656
  const globalEntries = loadMemoryDir(globalMemDir, "global");
30347
30657
  if (globalEntries)
30348
30658
  sections.push(globalEntries);
30349
30659
  return sections.join("\n\n");
30350
30660
  }
30351
30661
  function loadMemoryDir(memDir, scope) {
30352
- if (!existsSync28(memDir))
30662
+ if (!existsSync29(memDir))
30353
30663
  return "";
30354
30664
  const lines = [];
30355
30665
  try {
30356
30666
  const files = readdirSync8(memDir).filter((f) => f.endsWith(".json"));
30357
30667
  for (const file of files.slice(0, 10)) {
30358
30668
  try {
30359
- const raw = readFileSync20(join38(memDir, file), "utf-8");
30669
+ const raw = readFileSync20(join39(memDir, file), "utf-8");
30360
30670
  const entries = JSON.parse(raw);
30361
30671
  const topic = basename10(file, ".json");
30362
30672
  const keys = Object.keys(entries);
@@ -31383,12 +31693,12 @@ var init_carousel = __esm({
31383
31693
  });
31384
31694
 
31385
31695
  // packages/cli/dist/tui/carousel-descriptors.js
31386
- import { existsSync as existsSync29, readFileSync as readFileSync21, writeFileSync as writeFileSync10, mkdirSync as mkdirSync10, readdirSync as readdirSync9 } from "node:fs";
31387
- import { join as join39, basename as basename11 } from "node:path";
31696
+ import { existsSync as existsSync30, readFileSync as readFileSync21, writeFileSync as writeFileSync10, mkdirSync as mkdirSync10, readdirSync as readdirSync9 } from "node:fs";
31697
+ import { join as join40, basename as basename11 } from "node:path";
31388
31698
  function loadToolProfile(repoRoot) {
31389
- const filePath = join39(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
31699
+ const filePath = join40(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
31390
31700
  try {
31391
- if (!existsSync29(filePath))
31701
+ if (!existsSync30(filePath))
31392
31702
  return null;
31393
31703
  return JSON.parse(readFileSync21(filePath, "utf-8"));
31394
31704
  } catch {
@@ -31396,9 +31706,9 @@ function loadToolProfile(repoRoot) {
31396
31706
  }
31397
31707
  }
31398
31708
  function saveToolProfile(repoRoot, profile) {
31399
- const contextDir = join39(repoRoot, OA_DIR, "context");
31709
+ const contextDir = join40(repoRoot, OA_DIR, "context");
31400
31710
  mkdirSync10(contextDir, { recursive: true });
31401
- writeFileSync10(join39(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
31711
+ writeFileSync10(join40(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
31402
31712
  }
31403
31713
  function categorizeToolCall(toolName) {
31404
31714
  for (const cat of TOOL_CATEGORIES) {
@@ -31456,9 +31766,9 @@ function weightedColor(profile) {
31456
31766
  return selectedCat.colors[Math.floor(Math.random() * selectedCat.colors.length)];
31457
31767
  }
31458
31768
  function loadCachedDescriptors(repoRoot) {
31459
- const filePath = join39(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
31769
+ const filePath = join40(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
31460
31770
  try {
31461
- if (!existsSync29(filePath))
31771
+ if (!existsSync30(filePath))
31462
31772
  return null;
31463
31773
  const cached = JSON.parse(readFileSync21(filePath, "utf-8"));
31464
31774
  return cached.phrases.length > 0 ? cached.phrases : null;
@@ -31467,14 +31777,14 @@ function loadCachedDescriptors(repoRoot) {
31467
31777
  }
31468
31778
  }
31469
31779
  function saveCachedDescriptors(repoRoot, phrases, sourceHash) {
31470
- const contextDir = join39(repoRoot, OA_DIR, "context");
31780
+ const contextDir = join40(repoRoot, OA_DIR, "context");
31471
31781
  mkdirSync10(contextDir, { recursive: true });
31472
31782
  const cached = {
31473
31783
  phrases,
31474
31784
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
31475
31785
  sourceHash
31476
31786
  };
31477
- writeFileSync10(join39(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
31787
+ writeFileSync10(join40(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
31478
31788
  }
31479
31789
  function generateDescriptors(repoRoot) {
31480
31790
  const profile = loadToolProfile(repoRoot);
@@ -31522,9 +31832,9 @@ function generateDescriptors(repoRoot) {
31522
31832
  return phrases;
31523
31833
  }
31524
31834
  function extractFromPackageJson(repoRoot, tags) {
31525
- const pkgPath = join39(repoRoot, "package.json");
31835
+ const pkgPath = join40(repoRoot, "package.json");
31526
31836
  try {
31527
- if (!existsSync29(pkgPath))
31837
+ if (!existsSync30(pkgPath))
31528
31838
  return;
31529
31839
  const pkg = JSON.parse(readFileSync21(pkgPath, "utf-8"));
31530
31840
  if (pkg.name && typeof pkg.name === "string") {
@@ -31570,7 +31880,7 @@ function extractFromManifests(repoRoot, tags) {
31570
31880
  { file: ".github/workflows", tag: "ci/cd" }
31571
31881
  ];
31572
31882
  for (const check of manifestChecks) {
31573
- if (existsSync29(join39(repoRoot, check.file))) {
31883
+ if (existsSync30(join40(repoRoot, check.file))) {
31574
31884
  tags.push(check.tag);
31575
31885
  }
31576
31886
  }
@@ -31592,16 +31902,16 @@ function extractFromSessions(repoRoot, tags) {
31592
31902
  }
31593
31903
  }
31594
31904
  function extractFromMemory(repoRoot, tags) {
31595
- const memoryDir = join39(repoRoot, OA_DIR, "memory");
31905
+ const memoryDir = join40(repoRoot, OA_DIR, "memory");
31596
31906
  try {
31597
- if (!existsSync29(memoryDir))
31907
+ if (!existsSync30(memoryDir))
31598
31908
  return;
31599
31909
  const files = readdirSync9(memoryDir).filter((f) => f.endsWith(".json"));
31600
31910
  for (const file of files) {
31601
31911
  const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
31602
31912
  tags.push(topic);
31603
31913
  try {
31604
- const data = JSON.parse(readFileSync21(join39(memoryDir, file), "utf-8"));
31914
+ const data = JSON.parse(readFileSync21(join40(memoryDir, file), "utf-8"));
31605
31915
  if (data && typeof data === "object") {
31606
31916
  const keys = Object.keys(data).slice(0, 3);
31607
31917
  for (const key of keys) {
@@ -31736,25 +32046,25 @@ var init_carousel_descriptors = __esm({
31736
32046
  });
31737
32047
 
31738
32048
  // packages/cli/dist/tui/voice.js
31739
- import { existsSync as existsSync30, mkdirSync as mkdirSync11, writeFileSync as writeFileSync11, readFileSync as readFileSync22, unlinkSync as unlinkSync4 } from "node:fs";
31740
- import { join as join40 } from "node:path";
32049
+ import { existsSync as existsSync31, mkdirSync as mkdirSync11, writeFileSync as writeFileSync11, readFileSync as readFileSync22, unlinkSync as unlinkSync4 } from "node:fs";
32050
+ import { join as join41 } from "node:path";
31741
32051
  import { homedir as homedir12, tmpdir as tmpdir6, platform as platform3 } from "node:os";
31742
- import { execSync as execSync26, spawn as nodeSpawn } from "node:child_process";
32052
+ import { execSync as execSync27, spawn as nodeSpawn } from "node:child_process";
31743
32053
  import { createRequire } from "node:module";
31744
32054
  function voiceDir() {
31745
- return join40(homedir12(), ".open-agents", "voice");
32055
+ return join41(homedir12(), ".open-agents", "voice");
31746
32056
  }
31747
32057
  function modelsDir() {
31748
- return join40(voiceDir(), "models");
32058
+ return join41(voiceDir(), "models");
31749
32059
  }
31750
32060
  function modelDir(id) {
31751
- return join40(modelsDir(), id);
32061
+ return join41(modelsDir(), id);
31752
32062
  }
31753
32063
  function modelOnnxPath(id) {
31754
- return join40(modelDir(id), "model.onnx");
32064
+ return join41(modelDir(id), "model.onnx");
31755
32065
  }
31756
32066
  function modelConfigPath(id) {
31757
- return join40(modelDir(id), "config.json");
32067
+ return join41(modelDir(id), "config.json");
31758
32068
  }
31759
32069
  function emotionToPitchBias(emotion) {
31760
32070
  const raw = emotion.valence * 0.6 + (emotion.arousal - 0.5) * 0.4;
@@ -32477,7 +32787,7 @@ var init_voice = __esm({
32477
32787
  }
32478
32788
  this.onPCMOutput(Buffer.from(int16.buffer), sampleRate);
32479
32789
  }
32480
- const wavPath = join40(tmpdir6(), `oa-voice-${Date.now()}.wav`);
32790
+ const wavPath = join41(tmpdir6(), `oa-voice-${Date.now()}.wav`);
32481
32791
  this.writeWav(audioData, sampleRate, wavPath);
32482
32792
  await this.playWav(wavPath);
32483
32793
  try {
@@ -32659,7 +32969,7 @@ var init_voice = __esm({
32659
32969
  }
32660
32970
  for (const player of ["paplay", "pw-play", "aplay"]) {
32661
32971
  try {
32662
- execSync26(`which ${player}`, { stdio: "pipe" });
32972
+ execSync27(`which ${player}`, { stdio: "pipe" });
32663
32973
  return [player, path];
32664
32974
  } catch {
32665
32975
  }
@@ -32683,12 +32993,12 @@ var init_voice = __esm({
32683
32993
  return;
32684
32994
  const arch = process.arch;
32685
32995
  mkdirSync11(voiceDir(), { recursive: true });
32686
- const pkgPath = join40(voiceDir(), "package.json");
32996
+ const pkgPath = join41(voiceDir(), "package.json");
32687
32997
  const expectedDeps = {
32688
32998
  "onnxruntime-node": "^1.21.0",
32689
32999
  "phonemizer": "^1.2.1"
32690
33000
  };
32691
- if (existsSync30(pkgPath)) {
33001
+ if (existsSync31(pkgPath)) {
32692
33002
  try {
32693
33003
  const existing = JSON.parse(readFileSync22(pkgPath, "utf8"));
32694
33004
  if (!existing.dependencies?.["phonemizer"]) {
@@ -32698,17 +33008,17 @@ var init_voice = __esm({
32698
33008
  } catch {
32699
33009
  }
32700
33010
  }
32701
- if (!existsSync30(pkgPath)) {
33011
+ if (!existsSync31(pkgPath)) {
32702
33012
  writeFileSync11(pkgPath, JSON.stringify({
32703
33013
  name: "open-agents-voice",
32704
33014
  private: true,
32705
33015
  dependencies: expectedDeps
32706
33016
  }, null, 2));
32707
33017
  }
32708
- const voiceRequire = createRequire(join40(voiceDir(), "index.js"));
33018
+ const voiceRequire = createRequire(join41(voiceDir(), "index.js"));
32709
33019
  const probeOnnx = () => {
32710
33020
  try {
32711
- const result = execSync26(`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: join40(voiceDir(), "node_modules") } });
33021
+ 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: join41(voiceDir(), "node_modules") } });
32712
33022
  const output = result.toString().trim();
32713
33023
  if (output === "OK")
32714
33024
  return true;
@@ -32725,8 +33035,8 @@ var init_voice = __esm({
32725
33035
  return false;
32726
33036
  }
32727
33037
  };
32728
- const onnxNodeModules = join40(voiceDir(), "node_modules", "onnxruntime-node");
32729
- const onnxInstalled = existsSync30(onnxNodeModules);
33038
+ const onnxNodeModules = join41(voiceDir(), "node_modules", "onnxruntime-node");
33039
+ const onnxInstalled = existsSync31(onnxNodeModules);
32730
33040
  if (onnxInstalled && !probeOnnx()) {
32731
33041
  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.`);
32732
33042
  }
@@ -32735,7 +33045,7 @@ var init_voice = __esm({
32735
33045
  } catch {
32736
33046
  renderInfo("Installing ONNX runtime for voice synthesis...");
32737
33047
  try {
32738
- execSync26("npm install --no-audit --no-fund", {
33048
+ execSync27("npm install --no-audit --no-fund", {
32739
33049
  cwd: voiceDir(),
32740
33050
  stdio: "pipe",
32741
33051
  timeout: 12e4
@@ -32760,7 +33070,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
32760
33070
  } catch {
32761
33071
  renderInfo("Installing phonemizer for voice synthesis...");
32762
33072
  try {
32763
- execSync26("npm install --no-audit --no-fund", {
33073
+ execSync27("npm install --no-audit --no-fund", {
32764
33074
  cwd: voiceDir(),
32765
33075
  stdio: "pipe",
32766
33076
  timeout: 12e4
@@ -32784,10 +33094,10 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
32784
33094
  const dir = modelDir(id);
32785
33095
  const onnxPath = modelOnnxPath(id);
32786
33096
  const configPath = modelConfigPath(id);
32787
- if (existsSync30(onnxPath) && existsSync30(configPath))
33097
+ if (existsSync31(onnxPath) && existsSync31(configPath))
32788
33098
  return;
32789
33099
  mkdirSync11(dir, { recursive: true });
32790
- if (!existsSync30(configPath)) {
33100
+ if (!existsSync31(configPath)) {
32791
33101
  renderInfo(`Downloading ${model.label} voice config...`);
32792
33102
  const configResp = await fetch(model.configUrl);
32793
33103
  if (!configResp.ok)
@@ -32795,7 +33105,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
32795
33105
  const configText = await configResp.text();
32796
33106
  writeFileSync11(configPath, configText);
32797
33107
  }
32798
- if (!existsSync30(onnxPath)) {
33108
+ if (!existsSync31(onnxPath)) {
32799
33109
  renderInfo(`Downloading ${model.label} voice model (this may take a minute)...`);
32800
33110
  const onnxResp = await fetch(model.onnxUrl);
32801
33111
  if (!onnxResp.ok)
@@ -32831,7 +33141,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
32831
33141
  throw new Error("ONNX runtime not loaded");
32832
33142
  const onnxPath = modelOnnxPath(this.modelId);
32833
33143
  const configPath = modelConfigPath(this.modelId);
32834
- if (!existsSync30(onnxPath) || !existsSync30(configPath)) {
33144
+ if (!existsSync31(onnxPath) || !existsSync31(configPath)) {
32835
33145
  throw new Error(`Model files not found for ${this.modelId}`);
32836
33146
  }
32837
33147
  this.config = JSON.parse(readFileSync22(configPath, "utf8"));
@@ -33698,10 +34008,10 @@ var init_stream_renderer = __esm({
33698
34008
 
33699
34009
  // packages/cli/dist/tui/edit-history.js
33700
34010
  import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync12 } from "node:fs";
33701
- import { join as join41 } from "node:path";
34011
+ import { join as join42 } from "node:path";
33702
34012
  function createEditHistoryLogger(repoRoot, sessionId) {
33703
- const historyDir = join41(repoRoot, ".oa", "history");
33704
- const logPath = join41(historyDir, "edits.jsonl");
34013
+ const historyDir = join42(repoRoot, ".oa", "history");
34014
+ const logPath = join42(historyDir, "edits.jsonl");
33705
34015
  try {
33706
34016
  mkdirSync12(historyDir, { recursive: true });
33707
34017
  } catch {
@@ -33812,14 +34122,14 @@ var init_edit_history = __esm({
33812
34122
  });
33813
34123
 
33814
34124
  // packages/cli/dist/tui/promptLoader.js
33815
- import { readFileSync as readFileSync23, existsSync as existsSync31 } from "node:fs";
33816
- import { join as join42, dirname as dirname15 } from "node:path";
34125
+ import { readFileSync as readFileSync23, existsSync as existsSync32 } from "node:fs";
34126
+ import { join as join43, dirname as dirname15 } from "node:path";
33817
34127
  import { fileURLToPath as fileURLToPath11 } from "node:url";
33818
34128
  function loadPrompt3(promptPath, vars) {
33819
34129
  let content = cache3.get(promptPath);
33820
34130
  if (content === void 0) {
33821
- const fullPath = join42(PROMPTS_DIR3, promptPath);
33822
- if (!existsSync31(fullPath)) {
34131
+ const fullPath = join43(PROMPTS_DIR3, promptPath);
34132
+ if (!existsSync32(fullPath)) {
33823
34133
  throw new Error(`Prompt file not found: ${fullPath}`);
33824
34134
  }
33825
34135
  content = readFileSync23(fullPath, "utf-8");
@@ -33835,20 +34145,20 @@ var init_promptLoader3 = __esm({
33835
34145
  "use strict";
33836
34146
  __filename3 = fileURLToPath11(import.meta.url);
33837
34147
  __dirname5 = dirname15(__filename3);
33838
- devPath2 = join42(__dirname5, "..", "..", "prompts");
33839
- publishedPath2 = join42(__dirname5, "..", "prompts");
33840
- PROMPTS_DIR3 = existsSync31(devPath2) ? devPath2 : publishedPath2;
34148
+ devPath2 = join43(__dirname5, "..", "..", "prompts");
34149
+ publishedPath2 = join43(__dirname5, "..", "prompts");
34150
+ PROMPTS_DIR3 = existsSync32(devPath2) ? devPath2 : publishedPath2;
33841
34151
  cache3 = /* @__PURE__ */ new Map();
33842
34152
  }
33843
34153
  });
33844
34154
 
33845
34155
  // packages/cli/dist/tui/dream-engine.js
33846
- import { mkdirSync as mkdirSync13, writeFileSync as writeFileSync12, readFileSync as readFileSync24, existsSync as existsSync32, cpSync, rmSync, readdirSync as readdirSync10 } from "node:fs";
33847
- import { join as join43, basename as basename12 } from "node:path";
33848
- import { execSync as execSync27 } from "node:child_process";
34156
+ import { mkdirSync as mkdirSync13, writeFileSync as writeFileSync12, readFileSync as readFileSync24, existsSync as existsSync33, cpSync, rmSync, readdirSync as readdirSync10 } from "node:fs";
34157
+ import { join as join44, basename as basename12 } from "node:path";
34158
+ import { execSync as execSync28 } from "node:child_process";
33849
34159
  function loadAutoresearchMemory(repoRoot) {
33850
- const memoryPath = join43(repoRoot, ".oa", "memory", "autoresearch.json");
33851
- if (!existsSync32(memoryPath))
34160
+ const memoryPath = join44(repoRoot, ".oa", "memory", "autoresearch.json");
34161
+ if (!existsSync33(memoryPath))
33852
34162
  return "";
33853
34163
  try {
33854
34164
  const raw = readFileSync24(memoryPath, "utf-8");
@@ -34041,12 +34351,12 @@ var init_dream_engine = __esm({
34041
34351
  const content = String(args["content"] ?? "");
34042
34352
  if (!rawPath)
34043
34353
  return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
34044
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join43(this.autoresearchDir, basename12(rawPath)) : join43(this.autoresearchDir, rawPath);
34354
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join44(this.autoresearchDir, basename12(rawPath)) : join44(this.autoresearchDir, rawPath);
34045
34355
  if (!targetPath.startsWith(this.autoresearchDir)) {
34046
34356
  return { success: false, output: "", error: "Autoresearch mode: writes are confined to .oa/autoresearch/", durationMs: Date.now() - start };
34047
34357
  }
34048
34358
  try {
34049
- const dir = join43(targetPath, "..");
34359
+ const dir = join44(targetPath, "..");
34050
34360
  mkdirSync13(dir, { recursive: true });
34051
34361
  writeFileSync12(targetPath, content, "utf-8");
34052
34362
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
@@ -34076,12 +34386,12 @@ var init_dream_engine = __esm({
34076
34386
  const rawPath = String(args["path"] ?? "");
34077
34387
  const oldStr = String(args["old_string"] ?? "");
34078
34388
  const newStr = String(args["new_string"] ?? "");
34079
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join43(this.autoresearchDir, basename12(rawPath)) : join43(this.autoresearchDir, rawPath);
34389
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join44(this.autoresearchDir, basename12(rawPath)) : join44(this.autoresearchDir, rawPath);
34080
34390
  if (!targetPath.startsWith(this.autoresearchDir)) {
34081
34391
  return { success: false, output: "", error: "Autoresearch mode: edits are confined to .oa/autoresearch/", durationMs: Date.now() - start };
34082
34392
  }
34083
34393
  try {
34084
- if (!existsSync32(targetPath)) {
34394
+ if (!existsSync33(targetPath)) {
34085
34395
  return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
34086
34396
  }
34087
34397
  let content = readFileSync24(targetPath, "utf-8");
@@ -34130,12 +34440,12 @@ var init_dream_engine = __esm({
34130
34440
  const content = String(args["content"] ?? "");
34131
34441
  if (!rawPath)
34132
34442
  return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
34133
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join43(this.dreamsDir, basename12(rawPath)) : join43(this.dreamsDir, rawPath);
34443
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join44(this.dreamsDir, basename12(rawPath)) : join44(this.dreamsDir, rawPath);
34134
34444
  if (!targetPath.startsWith(this.dreamsDir)) {
34135
34445
  return { success: false, output: "", error: "Dream mode: writes are confined to .oa/dreams/", durationMs: Date.now() - start };
34136
34446
  }
34137
34447
  try {
34138
- const dir = join43(targetPath, "..");
34448
+ const dir = join44(targetPath, "..");
34139
34449
  mkdirSync13(dir, { recursive: true });
34140
34450
  writeFileSync12(targetPath, content, "utf-8");
34141
34451
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
@@ -34165,12 +34475,12 @@ var init_dream_engine = __esm({
34165
34475
  const rawPath = String(args["path"] ?? "");
34166
34476
  const oldStr = String(args["old_string"] ?? "");
34167
34477
  const newStr = String(args["new_string"] ?? "");
34168
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join43(this.dreamsDir, basename12(rawPath)) : join43(this.dreamsDir, rawPath);
34478
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join44(this.dreamsDir, basename12(rawPath)) : join44(this.dreamsDir, rawPath);
34169
34479
  if (!targetPath.startsWith(this.dreamsDir)) {
34170
34480
  return { success: false, output: "", error: "Dream mode: edits are confined to .oa/dreams/", durationMs: Date.now() - start };
34171
34481
  }
34172
34482
  try {
34173
- if (!existsSync32(targetPath)) {
34483
+ if (!existsSync33(targetPath)) {
34174
34484
  return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
34175
34485
  }
34176
34486
  let content = readFileSync24(targetPath, "utf-8");
@@ -34209,7 +34519,7 @@ var init_dream_engine = __esm({
34209
34519
  }
34210
34520
  }
34211
34521
  try {
34212
- const output = execSync27(cmd, {
34522
+ const output = execSync28(cmd, {
34213
34523
  cwd: this.repoRoot,
34214
34524
  timeout: 3e4,
34215
34525
  encoding: "utf-8",
@@ -34232,7 +34542,7 @@ var init_dream_engine = __esm({
34232
34542
  constructor(config, repoRoot) {
34233
34543
  this.config = config;
34234
34544
  this.repoRoot = repoRoot;
34235
- this.dreamsDir = join43(repoRoot, ".oa", "dreams");
34545
+ this.dreamsDir = join44(repoRoot, ".oa", "dreams");
34236
34546
  this.state = {
34237
34547
  mode: "default",
34238
34548
  active: false,
@@ -34316,7 +34626,7 @@ ${result.summary}`;
34316
34626
  if (mode !== "default" || cycle === totalCycles) {
34317
34627
  renderDreamContraction(cycle);
34318
34628
  const cycleSummary = this.buildCycleSummary(cycle, previousFindings);
34319
- const summaryPath = join43(this.dreamsDir, `cycle-${cycle}-summary.md`);
34629
+ const summaryPath = join44(this.dreamsDir, `cycle-${cycle}-summary.md`);
34320
34630
  writeFileSync12(summaryPath, cycleSummary, "utf-8");
34321
34631
  }
34322
34632
  if (mode === "lucid" && !this.abortController.signal.aborted) {
@@ -34529,7 +34839,7 @@ After synthesis, call task_complete with the final prioritized summary.`, toolMo
34529
34839
  }
34530
34840
  /** Build role-specific tool sets for swarm agents */
34531
34841
  buildSwarmTools(role, _workspace) {
34532
- const autoresearchDir = join43(this.repoRoot, ".oa", "autoresearch");
34842
+ const autoresearchDir = join44(this.repoRoot, ".oa", "autoresearch");
34533
34843
  const taskComplete = this.createSwarmTaskCompleteTool(role);
34534
34844
  switch (role) {
34535
34845
  case "researcher": {
@@ -34893,7 +35203,7 @@ INSTRUCTIONS:
34893
35203
  2. Summarize the key learnings and next steps
34894
35204
 
34895
35205
  Call task_complete with a human-readable summary of the autoresearch session.`, workspace, onEvent);
34896
- const reportPath = join43(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
35206
+ const reportPath = join44(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
34897
35207
  const report = `# Autoresearch Swarm Report \u2014 Cycle ${cycleNum}
34898
35208
 
34899
35209
  **Date**: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
@@ -34982,29 +35292,29 @@ ${summaryResult}
34982
35292
  }
34983
35293
  /** Save workspace backup for lucid mode */
34984
35294
  saveVersionCheckpoint(cycle) {
34985
- const checkpointDir = join43(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
35295
+ const checkpointDir = join44(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
34986
35296
  try {
34987
35297
  mkdirSync13(checkpointDir, { recursive: true });
34988
35298
  try {
34989
- const gitStatus = execSync27("git status --porcelain", {
35299
+ const gitStatus = execSync28("git status --porcelain", {
34990
35300
  cwd: this.repoRoot,
34991
35301
  encoding: "utf-8",
34992
35302
  timeout: 1e4
34993
35303
  });
34994
- const gitDiff = execSync27("git diff", {
35304
+ const gitDiff = execSync28("git diff", {
34995
35305
  cwd: this.repoRoot,
34996
35306
  encoding: "utf-8",
34997
35307
  timeout: 1e4
34998
35308
  });
34999
- const gitHash = execSync27("git rev-parse HEAD 2>/dev/null || echo 'no-git'", {
35309
+ const gitHash = execSync28("git rev-parse HEAD 2>/dev/null || echo 'no-git'", {
35000
35310
  cwd: this.repoRoot,
35001
35311
  encoding: "utf-8",
35002
35312
  timeout: 5e3
35003
35313
  }).trim();
35004
- writeFileSync12(join43(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
35005
- writeFileSync12(join43(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
35006
- writeFileSync12(join43(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
35007
- writeFileSync12(join43(checkpointDir, "checkpoint.json"), JSON.stringify({
35314
+ writeFileSync12(join44(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
35315
+ writeFileSync12(join44(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
35316
+ writeFileSync12(join44(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
35317
+ writeFileSync12(join44(checkpointDir, "checkpoint.json"), JSON.stringify({
35008
35318
  cycle,
35009
35319
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
35010
35320
  gitHash,
@@ -35012,7 +35322,7 @@ ${summaryResult}
35012
35322
  }, null, 2), "utf-8");
35013
35323
  renderInfo(`Checkpoint saved: cycle ${cycle} (${gitHash.slice(0, 8)})`);
35014
35324
  } catch {
35015
- writeFileSync12(join43(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
35325
+ writeFileSync12(join44(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
35016
35326
  renderInfo(`Checkpoint saved: cycle ${cycle} (no git)`);
35017
35327
  }
35018
35328
  } catch (err) {
@@ -35070,14 +35380,14 @@ ${files.map((f) => `- [\`${f}\`](./${f})`).join("\n")}
35070
35380
  ---
35071
35381
  *Auto-generated by open-agents dream engine*
35072
35382
  `;
35073
- writeFileSync12(join43(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
35383
+ writeFileSync12(join44(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
35074
35384
  } catch {
35075
35385
  }
35076
35386
  }
35077
35387
  /** Save dream state for resume/inspection */
35078
35388
  saveDreamState() {
35079
35389
  try {
35080
- writeFileSync12(join43(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
35390
+ writeFileSync12(join44(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
35081
35391
  } catch {
35082
35392
  }
35083
35393
  }
@@ -35451,8 +35761,8 @@ var init_bless_engine = __esm({
35451
35761
  });
35452
35762
 
35453
35763
  // packages/cli/dist/tui/dmn-engine.js
35454
- import { existsSync as existsSync33, readFileSync as readFileSync25, writeFileSync as writeFileSync13, mkdirSync as mkdirSync14, readdirSync as readdirSync11, unlinkSync as unlinkSync5 } from "node:fs";
35455
- import { join as join44, basename as basename13 } from "node:path";
35764
+ import { existsSync as existsSync34, readFileSync as readFileSync25, writeFileSync as writeFileSync13, mkdirSync as mkdirSync14, readdirSync as readdirSync11, unlinkSync as unlinkSync5 } from "node:fs";
35765
+ import { join as join45, basename as basename13 } from "node:path";
35456
35766
  function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
35457
35767
  const competenceReport = competence.length > 0 ? competence.map((c3) => {
35458
35768
  const rate = c3.attempts > 0 ? Math.round(c3.successes / c3.attempts * 100) : 0;
@@ -35565,8 +35875,8 @@ var init_dmn_engine = __esm({
35565
35875
  constructor(config, repoRoot) {
35566
35876
  this.config = config;
35567
35877
  this.repoRoot = repoRoot;
35568
- this.stateDir = join44(repoRoot, ".oa", "dmn");
35569
- this.historyDir = join44(repoRoot, ".oa", "dmn", "cycles");
35878
+ this.stateDir = join45(repoRoot, ".oa", "dmn");
35879
+ this.historyDir = join45(repoRoot, ".oa", "dmn", "cycles");
35570
35880
  mkdirSync14(this.historyDir, { recursive: true });
35571
35881
  this.loadState();
35572
35882
  }
@@ -36156,11 +36466,11 @@ OUTPUT: Call task_complete with JSON:
36156
36466
  async gatherMemoryTopics() {
36157
36467
  const topics = [];
36158
36468
  const dirs = [
36159
- join44(this.repoRoot, ".oa", "memory"),
36160
- join44(this.repoRoot, ".open-agents", "memory")
36469
+ join45(this.repoRoot, ".oa", "memory"),
36470
+ join45(this.repoRoot, ".open-agents", "memory")
36161
36471
  ];
36162
36472
  for (const dir of dirs) {
36163
- if (!existsSync33(dir))
36473
+ if (!existsSync34(dir))
36164
36474
  continue;
36165
36475
  try {
36166
36476
  const files = readdirSync11(dir).filter((f) => f.endsWith(".json"));
@@ -36176,8 +36486,8 @@ OUTPUT: Call task_complete with JSON:
36176
36486
  }
36177
36487
  // ── State persistence ─────────────────────────────────────────────────
36178
36488
  loadState() {
36179
- const path = join44(this.stateDir, "state.json");
36180
- if (existsSync33(path)) {
36489
+ const path = join45(this.stateDir, "state.json");
36490
+ if (existsSync34(path)) {
36181
36491
  try {
36182
36492
  this.state = JSON.parse(readFileSync25(path, "utf-8"));
36183
36493
  } catch {
@@ -36186,19 +36496,19 @@ OUTPUT: Call task_complete with JSON:
36186
36496
  }
36187
36497
  saveState() {
36188
36498
  try {
36189
- writeFileSync13(join44(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
36499
+ writeFileSync13(join45(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
36190
36500
  } catch {
36191
36501
  }
36192
36502
  }
36193
36503
  saveCycleResult(result) {
36194
36504
  try {
36195
36505
  const filename = `cycle-${result.cycleNumber}-${Date.now()}.json`;
36196
- writeFileSync13(join44(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
36506
+ writeFileSync13(join45(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
36197
36507
  const files = readdirSync11(this.historyDir).filter((f) => f.startsWith("cycle-") && f.endsWith(".json")).sort();
36198
36508
  if (files.length > 50) {
36199
36509
  for (const old of files.slice(0, files.length - 50)) {
36200
36510
  try {
36201
- unlinkSync5(join44(this.historyDir, old));
36511
+ unlinkSync5(join45(this.historyDir, old));
36202
36512
  } catch {
36203
36513
  }
36204
36514
  }
@@ -36211,8 +36521,8 @@ OUTPUT: Call task_complete with JSON:
36211
36521
  });
36212
36522
 
36213
36523
  // packages/cli/dist/tui/snr-engine.js
36214
- import { existsSync as existsSync34, readdirSync as readdirSync12, readFileSync as readFileSync26 } from "node:fs";
36215
- import { join as join45, basename as basename14 } from "node:path";
36524
+ import { existsSync as existsSync35, readdirSync as readdirSync12, readFileSync as readFileSync26 } from "node:fs";
36525
+ import { join as join46, basename as basename14 } from "node:path";
36216
36526
  function computeDPrime(signalScores, noiseScores) {
36217
36527
  if (signalScores.length === 0 || noiseScores.length === 0)
36218
36528
  return 0;
@@ -36452,11 +36762,11 @@ Call task_complete with the JSON array when done.`, onEvent)
36452
36762
  loadMemoryEntries(topics) {
36453
36763
  const entries = [];
36454
36764
  const dirs = [
36455
- join45(this.repoRoot, ".oa", "memory"),
36456
- join45(this.repoRoot, ".open-agents", "memory")
36765
+ join46(this.repoRoot, ".oa", "memory"),
36766
+ join46(this.repoRoot, ".open-agents", "memory")
36457
36767
  ];
36458
36768
  for (const dir of dirs) {
36459
- if (!existsSync34(dir))
36769
+ if (!existsSync35(dir))
36460
36770
  continue;
36461
36771
  try {
36462
36772
  const files = readdirSync12(dir).filter((f) => f.endsWith(".json"));
@@ -36465,7 +36775,7 @@ Call task_complete with the JSON array when done.`, onEvent)
36465
36775
  if (topics.length > 0 && !topics.includes(topic))
36466
36776
  continue;
36467
36777
  try {
36468
- const data = JSON.parse(readFileSync26(join45(dir, f), "utf-8"));
36778
+ const data = JSON.parse(readFileSync26(join46(dir, f), "utf-8"));
36469
36779
  for (const [key, val] of Object.entries(data)) {
36470
36780
  const value = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
36471
36781
  entries.push({ topic, key, value });
@@ -37016,8 +37326,8 @@ var init_tool_policy = __esm({
37016
37326
  });
37017
37327
 
37018
37328
  // packages/cli/dist/tui/telegram-bridge.js
37019
- import { mkdirSync as mkdirSync15, existsSync as existsSync35, unlinkSync as unlinkSync6, readdirSync as readdirSync13, statSync as statSync10 } from "node:fs";
37020
- import { join as join46, resolve as resolve27 } from "node:path";
37329
+ import { mkdirSync as mkdirSync15, existsSync as existsSync36, unlinkSync as unlinkSync6, readdirSync as readdirSync13, statSync as statSync10 } from "node:fs";
37330
+ import { join as join47, resolve as resolve27 } from "node:path";
37021
37331
  import { writeFile as writeFileAsync } from "node:fs/promises";
37022
37332
  function convertMarkdownToTelegramHTML(md) {
37023
37333
  let html = md;
@@ -37782,7 +38092,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
37782
38092
  return null;
37783
38093
  const buffer = Buffer.from(await res.arrayBuffer());
37784
38094
  const fileName = `${Date.now()}-${fileId.slice(0, 8)}${extension}`;
37785
- const localPath = join46(this.mediaCacheDir, fileName);
38095
+ const localPath = join47(this.mediaCacheDir, fileName);
37786
38096
  await writeFileAsync(localPath, buffer);
37787
38097
  return localPath;
37788
38098
  } catch {
@@ -38991,7 +39301,7 @@ var init_status_bar = __esm({
38991
39301
  return;
38992
39302
  const rows = process.stdout.rows ?? 24;
38993
39303
  const pos = this.rowPositions(rows);
38994
- process.stdout.write(`\x1B[${pos.inputStartRow};1H\x1B[2K`);
39304
+ process.stdout.write(`\x1B[${pos.inputStartRow};1H\x1B[2K\x1B[?25h`);
38995
39305
  }
38996
39306
  /** Strip ANSI escape codes to measure visible character width */
38997
39307
  static visWidth(s) {
@@ -39358,7 +39668,7 @@ var init_status_bar = __esm({
39358
39668
  buf += `\x1B[${row};1H\x1B[2K${prefix}${inputWrap.lines[i]}`;
39359
39669
  }
39360
39670
  const cursorTermRow = pos.inputStartRow + inputWrap.cursorRow;
39361
- buf += `\x1B[${pos.bottomSepRow};1H\x1B[2K${sep}\x1B[${pos.metricsRow};1H\x1B[2K${this.buildMetricsLine()}\x1B[?7h\x1B[?25h\x1B[${cursorTermRow};${inputWrap.cursorCol}H`;
39671
+ buf += `\x1B[${pos.bottomSepRow};1H\x1B[2K${sep}\x1B[${pos.metricsRow};1H\x1B[2K${this.buildMetricsLine()}\x1B[?7h\x1B[${cursorTermRow};${inputWrap.cursorCol}H\x1B[?25h`;
39362
39672
  process.stdout.write(buf);
39363
39673
  }
39364
39674
  /**
@@ -39386,7 +39696,8 @@ var init_status_bar = __esm({
39386
39696
  const w = getTermWidth();
39387
39697
  const pos = this.rowPositions(rows);
39388
39698
  const sep = c2.dim("\u2500".repeat(w));
39389
- const buf = `\x1B7\x1B[?7l\x1B[${pos.bufferRow};1H\x1B[2K${this.buildBufferContent(w)}\x1B[${pos.topSepRow};1H\x1B[2K${sep}\x1B[${pos.bottomSepRow};1H\x1B[2K${sep}\x1B[${pos.metricsRow};1H\x1B[2K${this.buildMetricsLine()}\x1B[?7h\x1B8`;
39699
+ const buf = `\x1B7\x1B[?7l\x1B[${pos.bufferRow};1H\x1B[2K${this.buildBufferContent(w)}\x1B[${pos.topSepRow};1H\x1B[2K${sep}\x1B[${pos.bottomSepRow};1H\x1B[2K${sep}\x1B[${pos.metricsRow};1H\x1B[2K${this.buildMetricsLine()}\x1B[?7h\x1B8` + // DEC restore cursor
39700
+ (this.writeDepth === 0 ? "\x1B[?25h" : "");
39390
39701
  process.stdout.write(buf);
39391
39702
  }
39392
39703
  /**
@@ -39504,11 +39815,12 @@ var init_status_bar = __esm({
39504
39815
  import * as readline2 from "node:readline";
39505
39816
  import { Writable } from "node:stream";
39506
39817
  import { cwd } from "node:process";
39507
- import { resolve as resolve28, join as join47, dirname as dirname16, extname as extname9 } from "node:path";
39818
+ import { resolve as resolve28, join as join48, dirname as dirname16, extname as extname9 } from "node:path";
39508
39819
  import { createRequire as createRequire2 } from "node:module";
39509
39820
  import { fileURLToPath as fileURLToPath12 } from "node:url";
39510
- import { readFileSync as readFileSync27, rmSync as rmSync2, readdirSync as readdirSync14 } from "node:fs";
39511
- import { existsSync as existsSync36 } from "node:fs";
39821
+ import { readFileSync as readFileSync27, writeFileSync as writeFileSync14, appendFileSync as appendFileSync3, rmSync as rmSync2, readdirSync as readdirSync14, mkdirSync as mkdirSync16 } from "node:fs";
39822
+ import { existsSync as existsSync37 } from "node:fs";
39823
+ import { homedir as homedir13 } from "node:os";
39512
39824
  function formatTimeAgo(date) {
39513
39825
  const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
39514
39826
  if (seconds < 60)
@@ -39522,17 +39834,17 @@ function formatTimeAgo(date) {
39522
39834
  const days = Math.floor(hours / 24);
39523
39835
  return `${days}d ago`;
39524
39836
  }
39525
- function getVersion2() {
39837
+ function getVersion3() {
39526
39838
  try {
39527
39839
  const require2 = createRequire2(import.meta.url);
39528
39840
  const thisDir = dirname16(fileURLToPath12(import.meta.url));
39529
39841
  const candidates = [
39530
- join47(thisDir, "..", "package.json"),
39531
- join47(thisDir, "..", "..", "package.json"),
39532
- join47(thisDir, "..", "..", "..", "package.json")
39842
+ join48(thisDir, "..", "package.json"),
39843
+ join48(thisDir, "..", "..", "package.json"),
39844
+ join48(thisDir, "..", "..", "..", "package.json")
39533
39845
  ];
39534
39846
  for (const pkgPath of candidates) {
39535
- if (existsSync36(pkgPath)) {
39847
+ if (existsSync37(pkgPath)) {
39536
39848
  const pkg = require2(pkgPath);
39537
39849
  if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
39538
39850
  return pkg.version ?? "0.0.0";
@@ -39639,8 +39951,9 @@ function buildTools(repoRoot, config, contextWindowSize) {
39639
39951
  new SchedulerTool(repoRoot),
39640
39952
  new ReminderTool(repoRoot),
39641
39953
  new AgendaTool(repoRoot),
39642
- // OpenCode delegation + long-horizon cron agent
39954
+ // OpenCode + Factory AI delegation + long-horizon cron agent
39643
39955
  new OpenCodeTool(repoRoot),
39956
+ new FactoryTool(repoRoot),
39644
39957
  new CronAgentTool(repoRoot),
39645
39958
  // Nexus P2P networking + x402 micropayments
39646
39959
  new NexusTool(repoRoot)
@@ -39737,15 +40050,15 @@ Use task_status("${taskId}") or task_output("${taskId}") to check progress.`
39737
40050
  function gatherMemorySnippets(root) {
39738
40051
  const snippets = [];
39739
40052
  const dirs = [
39740
- join47(root, ".oa", "memory"),
39741
- join47(root, ".open-agents", "memory")
40053
+ join48(root, ".oa", "memory"),
40054
+ join48(root, ".open-agents", "memory")
39742
40055
  ];
39743
40056
  for (const dir of dirs) {
39744
- if (!existsSync36(dir))
40057
+ if (!existsSync37(dir))
39745
40058
  continue;
39746
40059
  try {
39747
40060
  for (const f of readdirSync14(dir).filter((f2) => f2.endsWith(".json"))) {
39748
- const data = JSON.parse(readFileSync27(join47(dir, f), "utf-8"));
40061
+ const data = JSON.parse(readFileSync27(join48(dir, f), "utf-8"));
39749
40062
  for (const val of Object.values(data)) {
39750
40063
  const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
39751
40064
  if (v.length > 10)
@@ -40283,7 +40596,7 @@ async function startInteractive(config, repoPath) {
40283
40596
  }
40284
40597
  const carousel = new Carousel(carouselPhrases ?? void 0);
40285
40598
  let carouselLines = 0;
40286
- const version = getVersion2();
40599
+ const version = getVersion3();
40287
40600
  if (isResumed) {
40288
40601
  const resumeMsg = hasTaskToResume ? `Updated to v${version} \u2014 picking up where you left off.
40289
40602
  ` : `Updated to v${version}.
@@ -40395,7 +40708,7 @@ async function startInteractive(config, repoPath) {
40395
40708
  let exposeGateway = null;
40396
40709
  let peerMesh = null;
40397
40710
  let inferenceRouter = null;
40398
- const secretVault = new SecretVault(join47(repoRoot, ".oa", "vault.enc"));
40711
+ const secretVault = new SecretVault(join48(repoRoot, ".oa", "vault.enc"));
40399
40712
  let adminSessionKey = null;
40400
40713
  const callSubAgents = /* @__PURE__ */ new Map();
40401
40714
  const streamRenderer = new StreamRenderer();
@@ -40600,14 +40913,42 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
40600
40913
  const hits = allCompletions.filter((c3) => c3.toLowerCase().startsWith(lower));
40601
40914
  return [hits, line];
40602
40915
  }
40916
+ const HISTORY_DIR = join48(homedir13(), ".open-agents");
40917
+ const HISTORY_FILE = join48(HISTORY_DIR, "repl-history");
40918
+ const MAX_HISTORY_LINES = 500;
40919
+ let savedHistory = [];
40920
+ try {
40921
+ if (existsSync37(HISTORY_FILE)) {
40922
+ const raw = readFileSync27(HISTORY_FILE, "utf8").trim();
40923
+ if (raw)
40924
+ savedHistory = raw.split("\n").reverse();
40925
+ }
40926
+ } catch {
40927
+ }
40603
40928
  const rl = readline2.createInterface({
40604
40929
  input: process.stdin,
40605
40930
  output: process.stdout,
40606
40931
  prompt: idlePrompt,
40607
40932
  terminal: true,
40608
- historySize: 100,
40933
+ historySize: MAX_HISTORY_LINES,
40934
+ history: savedHistory,
40609
40935
  completer
40610
40936
  });
40937
+ function persistHistoryLine(line) {
40938
+ if (!line.trim())
40939
+ return;
40940
+ try {
40941
+ mkdirSync16(HISTORY_DIR, { recursive: true });
40942
+ appendFileSync3(HISTORY_FILE, line + "\n", "utf8");
40943
+ if (Math.random() < 0.02) {
40944
+ const all = readFileSync27(HISTORY_FILE, "utf8").trim().split("\n");
40945
+ if (all.length > MAX_HISTORY_LINES) {
40946
+ writeFileSync14(HISTORY_FILE, all.slice(-MAX_HISTORY_LINES).join("\n") + "\n", "utf8");
40947
+ }
40948
+ }
40949
+ } catch {
40950
+ }
40951
+ }
40611
40952
  statusBar.setPromptText(idlePrompt, 2);
40612
40953
  statusBar.setCompletions(allCompletions);
40613
40954
  if (statusBar.isActive) {
@@ -40646,8 +40987,11 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
40646
40987
  function writeContent(fn) {
40647
40988
  if (statusBar.isActive) {
40648
40989
  statusBar.beginContentWrite();
40649
- fn();
40650
- statusBar.endContentWrite();
40990
+ try {
40991
+ fn();
40992
+ } finally {
40993
+ statusBar.endContentWrite();
40994
+ }
40651
40995
  } else {
40652
40996
  fn();
40653
40997
  }
@@ -41453,8 +41797,8 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
41453
41797
  return true;
41454
41798
  },
41455
41799
  destroyProject() {
41456
- const oaPath = join47(repoRoot, OA_DIR);
41457
- if (existsSync36(oaPath)) {
41800
+ const oaPath = join48(repoRoot, OA_DIR);
41801
+ if (existsSync37(oaPath)) {
41458
41802
  try {
41459
41803
  rmSync2(oaPath, { recursive: true, force: true });
41460
41804
  writeContent(() => renderInfo(`Removed ${OA_DIR}/ directory.`));
@@ -41617,6 +41961,7 @@ ${sessionCtx}` : "",
41617
41961
  pasteIndicatorShown = true;
41618
41962
  }
41619
41963
  rl.on("line", (line) => {
41964
+ persistHistoryLine(line);
41620
41965
  const input = line.trim();
41621
41966
  if (pendingSessionRestore) {
41622
41967
  pendingSessionRestore = false;
@@ -41754,8 +42099,8 @@ Execute this skill now. Follow the behavioral guidance above.`;
41754
42099
  }
41755
42100
  }
41756
42101
  const cleanPath = input.replace(/^['"]|['"]$/g, "").trim();
41757
- const isImage = isImagePath(cleanPath) && existsSync36(resolve28(repoRoot, cleanPath));
41758
- const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync36(resolve28(repoRoot, cleanPath));
42102
+ const isImage = isImagePath(cleanPath) && existsSync37(resolve28(repoRoot, cleanPath));
42103
+ const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync37(resolve28(repoRoot, cleanPath));
41759
42104
  if (activeTask) {
41760
42105
  if (isImage) {
41761
42106
  try {
@@ -42274,7 +42619,7 @@ import { glob } from "glob";
42274
42619
  import ignore from "ignore";
42275
42620
  import { readFile as readFile16, stat as stat4 } from "node:fs/promises";
42276
42621
  import { createHash as createHash4 } from "node:crypto";
42277
- import { join as join48, relative as relative3, extname as extname10, basename as basename15 } from "node:path";
42622
+ import { join as join49, relative as relative3, extname as extname10, basename as basename15 } from "node:path";
42278
42623
  var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
42279
42624
  var init_codebase_indexer = __esm({
42280
42625
  "packages/indexer/dist/codebase-indexer.js"() {
@@ -42318,7 +42663,7 @@ var init_codebase_indexer = __esm({
42318
42663
  const ig = ignore.default();
42319
42664
  if (this.config.respectGitignore) {
42320
42665
  try {
42321
- const gitignoreContent = await readFile16(join48(this.config.rootDir, ".gitignore"), "utf-8");
42666
+ const gitignoreContent = await readFile16(join49(this.config.rootDir, ".gitignore"), "utf-8");
42322
42667
  ig.add(gitignoreContent);
42323
42668
  } catch {
42324
42669
  }
@@ -42333,7 +42678,7 @@ var init_codebase_indexer = __esm({
42333
42678
  for (const relativePath of files) {
42334
42679
  if (ig.ignores(relativePath))
42335
42680
  continue;
42336
- const fullPath = join48(this.config.rootDir, relativePath);
42681
+ const fullPath = join49(this.config.rootDir, relativePath);
42337
42682
  try {
42338
42683
  const fileStat = await stat4(fullPath);
42339
42684
  if (fileStat.size > this.config.maxFileSize)
@@ -42379,7 +42724,7 @@ var init_codebase_indexer = __esm({
42379
42724
  if (!child) {
42380
42725
  child = {
42381
42726
  name: part,
42382
- path: join48(current.path, part),
42727
+ path: join49(current.path, part),
42383
42728
  type: "directory",
42384
42729
  children: []
42385
42730
  };
@@ -42462,13 +42807,13 @@ __export(index_repo_exports, {
42462
42807
  indexRepoCommand: () => indexRepoCommand
42463
42808
  });
42464
42809
  import { resolve as resolve29 } from "node:path";
42465
- import { existsSync as existsSync37, statSync as statSync11 } from "node:fs";
42810
+ import { existsSync as existsSync38, statSync as statSync11 } from "node:fs";
42466
42811
  import { cwd as cwd2 } from "node:process";
42467
42812
  async function indexRepoCommand(opts, _config) {
42468
42813
  const repoRoot = resolve29(opts.repoPath ?? cwd2());
42469
42814
  printHeader("Index Repository");
42470
42815
  printInfo(`Indexing: ${repoRoot}`);
42471
- if (!existsSync37(repoRoot)) {
42816
+ if (!existsSync38(repoRoot)) {
42472
42817
  printError(`Path does not exist: ${repoRoot}`);
42473
42818
  process.exit(1);
42474
42819
  }
@@ -42720,8 +43065,8 @@ var config_exports = {};
42720
43065
  __export(config_exports, {
42721
43066
  configCommand: () => configCommand
42722
43067
  });
42723
- import { join as join49, resolve as resolve30 } from "node:path";
42724
- import { homedir as homedir13 } from "node:os";
43068
+ import { join as join50, resolve as resolve30 } from "node:path";
43069
+ import { homedir as homedir14 } from "node:os";
42725
43070
  import { cwd as cwd3 } from "node:process";
42726
43071
  function redactIfSensitive(key, value) {
42727
43072
  if (SENSITIVE_KEYS.has(key) && typeof value === "string" && value.length > 0) {
@@ -42779,7 +43124,7 @@ function handleShow(opts, config) {
42779
43124
  }
42780
43125
  }
42781
43126
  printSection("Config File");
42782
- printInfo(`~/.open-agents/config.json (${join49(homedir13(), ".open-agents", "config.json")})`);
43127
+ printInfo(`~/.open-agents/config.json (${join50(homedir14(), ".open-agents", "config.json")})`);
42783
43128
  printSection("Priority Chain");
42784
43129
  printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
42785
43130
  printInfo(" 2. Project .oa/settings.json (--local)");
@@ -42818,7 +43163,7 @@ function handleSet(opts, _config) {
42818
43163
  const coerced = coerceForSettings(key, value);
42819
43164
  saveProjectSettings(repoRoot, { [key]: coerced });
42820
43165
  printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value)}`);
42821
- printInfo(`Saved to ${join49(repoRoot, ".oa", "settings.json")}`);
43166
+ printInfo(`Saved to ${join50(repoRoot, ".oa", "settings.json")}`);
42822
43167
  printInfo("This override applies only when running in this workspace.");
42823
43168
  } catch (err) {
42824
43169
  printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
@@ -42879,7 +43224,7 @@ var serve_exports = {};
42879
43224
  __export(serve_exports, {
42880
43225
  serveCommand: () => serveCommand
42881
43226
  });
42882
- import { spawn as spawn15 } from "node:child_process";
43227
+ import { spawn as spawn16 } from "node:child_process";
42883
43228
  async function serveCommand(opts, config) {
42884
43229
  const backendType = config.backendType;
42885
43230
  if (backendType === "ollama") {
@@ -42972,7 +43317,7 @@ async function serveVllm(opts, config) {
42972
43317
  }
42973
43318
  async function runVllmServer(args, verbose) {
42974
43319
  return new Promise((resolve31, reject) => {
42975
- const child = spawn15("python", args, {
43320
+ const child = spawn16("python", args, {
42976
43321
  stdio: verbose ? "inherit" : ["ignore", "pipe", "pipe"],
42977
43322
  env: { ...process.env }
42978
43323
  });
@@ -43037,8 +43382,8 @@ __export(eval_exports, {
43037
43382
  evalCommand: () => evalCommand
43038
43383
  });
43039
43384
  import { tmpdir as tmpdir7 } from "node:os";
43040
- import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync14 } from "node:fs";
43041
- import { join as join50 } from "node:path";
43385
+ import { mkdirSync as mkdirSync17, writeFileSync as writeFileSync15 } from "node:fs";
43386
+ import { join as join51 } from "node:path";
43042
43387
  async function evalCommand(opts, config) {
43043
43388
  const suiteName = opts.suite ?? "basic";
43044
43389
  const suite = SUITES[suiteName];
@@ -43163,9 +43508,9 @@ async function evalCommand(opts, config) {
43163
43508
  process.exit(failed > 0 ? 1 : 0);
43164
43509
  }
43165
43510
  function createTempEvalRepo() {
43166
- const dir = join50(tmpdir7(), `open-agents-eval-${Date.now()}`);
43167
- mkdirSync16(dir, { recursive: true });
43168
- writeFileSync14(join50(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
43511
+ const dir = join51(tmpdir7(), `open-agents-eval-${Date.now()}`);
43512
+ mkdirSync17(dir, { recursive: true });
43513
+ writeFileSync15(join51(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
43169
43514
  return dir;
43170
43515
  }
43171
43516
  var BASIC_SUITE, FULL_SUITE, SUITES;
@@ -43225,7 +43570,7 @@ init_updater();
43225
43570
  import { parseArgs as nodeParseArgs2 } from "node:util";
43226
43571
  import { createRequire as createRequire3 } from "node:module";
43227
43572
  import { fileURLToPath as fileURLToPath13 } from "node:url";
43228
- import { dirname as dirname17, join as join51 } from "node:path";
43573
+ import { dirname as dirname17, join as join52 } from "node:path";
43229
43574
 
43230
43575
  // packages/cli/dist/cli.js
43231
43576
  import { createInterface } from "node:readline";
@@ -43329,10 +43674,10 @@ Options:
43329
43674
  init_config();
43330
43675
  init_spinner();
43331
43676
  init_output();
43332
- function getVersion3() {
43677
+ function getVersion4() {
43333
43678
  try {
43334
43679
  const require2 = createRequire3(import.meta.url);
43335
- const pkgPath = join51(dirname17(fileURLToPath13(import.meta.url)), "..", "package.json");
43680
+ const pkgPath = join52(dirname17(fileURLToPath13(import.meta.url)), "..", "package.json");
43336
43681
  const pkg = require2(pkgPath);
43337
43682
  return pkg.version;
43338
43683
  } catch {
@@ -43479,7 +43824,7 @@ Examples:
43479
43824
  process.stdout.write(text + "\n");
43480
43825
  }
43481
43826
  async function main() {
43482
- const version = getVersion3();
43827
+ const version = getVersion4();
43483
43828
  const parsed = parseCliArgs(process.argv);
43484
43829
  if (parsed.version) {
43485
43830
  process.stdout.write(`open-agents v${version}