open-agents-ai 0.71.6 → 0.71.7

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 +204 -170
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -255,6 +255,7 @@ var init_output = __esm({
255
255
  });
256
256
 
257
257
  // packages/cli/dist/updater.js
258
+ import { execSync } from "node:child_process";
258
259
  import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "node:fs";
259
260
  import { join as join2 } from "node:path";
260
261
  import { homedir as homedir2 } from "node:os";
@@ -319,6 +320,17 @@ async function checkForUpdate(currentVersion, forceCheck = false) {
319
320
  latestVersion: latest
320
321
  };
321
322
  }
323
+ function performSilentUpdate() {
324
+ try {
325
+ execSync(`npm install -g ${PACKAGE_NAME}@latest --prefer-online`, {
326
+ stdio: "pipe",
327
+ timeout: 12e4
328
+ });
329
+ return true;
330
+ } catch {
331
+ return false;
332
+ }
333
+ }
322
334
  function formatUpdateBanner(info) {
323
335
  return `
324
336
  Update available: v${info.currentVersion} \u2192 v${info.latestVersion}
@@ -3124,7 +3136,7 @@ var init_list_directory = __esm({
3124
3136
  });
3125
3137
 
3126
3138
  // packages/execution/dist/tools/aiwg-setup.js
3127
- import { execSync } from "node:child_process";
3139
+ import { execSync as execSync2 } from "node:child_process";
3128
3140
  var AiwgSetupTool;
3129
3141
  var init_aiwg_setup = __esm({
3130
3142
  "packages/execution/dist/tools/aiwg-setup.js"() {
@@ -3163,7 +3175,7 @@ var init_aiwg_setup = __esm({
3163
3175
  };
3164
3176
  }
3165
3177
  try {
3166
- const output = execSync(`aiwg use ${framework}`, {
3178
+ const output = execSync2(`aiwg use ${framework}`, {
3167
3179
  cwd: projectDir,
3168
3180
  encoding: "utf8",
3169
3181
  timeout: 6e4,
@@ -3187,7 +3199,7 @@ ${output}`,
3187
3199
  }
3188
3200
  isAiwgInstalled() {
3189
3201
  try {
3190
- execSync("aiwg --version", {
3202
+ execSync2("aiwg --version", {
3191
3203
  encoding: "utf8",
3192
3204
  timeout: 5e3,
3193
3205
  stdio: ["pipe", "pipe", "pipe"]
@@ -3202,7 +3214,7 @@ ${output}`,
3202
3214
  });
3203
3215
 
3204
3216
  // packages/execution/dist/tools/aiwg-health.js
3205
- import { execSync as execSync2 } from "node:child_process";
3217
+ import { execSync as execSync3 } from "node:child_process";
3206
3218
  import { existsSync as existsSync5, readdirSync as readdirSync2, readFileSync as readFileSync3, statSync as statSync2 } from "node:fs";
3207
3219
  import { join as join8 } from "node:path";
3208
3220
  var AiwgHealthTool;
@@ -3282,7 +3294,7 @@ var init_aiwg_health = __esm({
3282
3294
  }
3283
3295
  if (this.isAiwgInstalled()) {
3284
3296
  try {
3285
- const runtimeInfo = execSync2("aiwg runtime-info 2>/dev/null", {
3297
+ const runtimeInfo = execSync3("aiwg runtime-info 2>/dev/null", {
3286
3298
  cwd: projectDir,
3287
3299
  encoding: "utf8",
3288
3300
  timeout: 15e3
@@ -3403,7 +3415,7 @@ var init_aiwg_health = __esm({
3403
3415
  }
3404
3416
  isAiwgInstalled() {
3405
3417
  try {
3406
- execSync2("aiwg --version", { encoding: "utf8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] });
3418
+ execSync3("aiwg --version", { encoding: "utf8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] });
3407
3419
  return true;
3408
3420
  } catch {
3409
3421
  return false;
@@ -3414,7 +3426,7 @@ var init_aiwg_health = __esm({
3414
3426
  });
3415
3427
 
3416
3428
  // packages/execution/dist/tools/aiwg-workflow.js
3417
- import { execSync as execSync3 } from "node:child_process";
3429
+ import { execSync as execSync4 } from "node:child_process";
3418
3430
  var AiwgWorkflowTool;
3419
3431
  var init_aiwg_workflow = __esm({
3420
3432
  "packages/execution/dist/tools/aiwg-workflow.js"() {
@@ -3462,7 +3474,7 @@ var init_aiwg_workflow = __esm({
3462
3474
  }
3463
3475
  const sanitized = command.replace(/[;&|`$()]/g, "");
3464
3476
  try {
3465
- const output = execSync3(`aiwg ${sanitized}`, {
3477
+ const output = execSync4(`aiwg ${sanitized}`, {
3466
3478
  cwd: projectDir,
3467
3479
  encoding: "utf8",
3468
3480
  timeout: 12e4,
@@ -3488,7 +3500,7 @@ var init_aiwg_workflow = __esm({
3488
3500
  }
3489
3501
  isAiwgInstalled() {
3490
3502
  try {
3491
- execSync3("aiwg --version", { encoding: "utf8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] });
3503
+ execSync4("aiwg --version", { encoding: "utf8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] });
3492
3504
  return true;
3493
3505
  } catch {
3494
3506
  return false;
@@ -4085,7 +4097,7 @@ var init_codebase_map = __esm({
4085
4097
  });
4086
4098
 
4087
4099
  // packages/execution/dist/tools/diagnostic.js
4088
- import { execSync as execSync4 } from "node:child_process";
4100
+ import { execSync as execSync5 } from "node:child_process";
4089
4101
  import { existsSync as existsSync7, readFileSync as readFileSync5 } from "node:fs";
4090
4102
  import { join as join10 } from "node:path";
4091
4103
  var DiagnosticTool;
@@ -4200,7 +4212,7 @@ var init_diagnostic = __esm({
4200
4212
  runStep(step, command, cwd4) {
4201
4213
  const start = performance.now();
4202
4214
  try {
4203
- const output = execSync4(command, {
4215
+ const output = execSync5(command, {
4204
4216
  cwd: cwd4,
4205
4217
  encoding: "utf8",
4206
4218
  timeout: 12e4,
@@ -4230,7 +4242,7 @@ ${err.stderr ?? ""}`.trim(),
4230
4242
  });
4231
4243
 
4232
4244
  // packages/execution/dist/tools/git-info.js
4233
- import { execSync as execSync5 } from "node:child_process";
4245
+ import { execSync as execSync6 } from "node:child_process";
4234
4246
  import { existsSync as existsSync8 } from "node:fs";
4235
4247
  import { join as join11 } from "node:path";
4236
4248
  var GitInfoTool;
@@ -4346,7 +4358,7 @@ var init_git_info = __esm({
4346
4358
  }
4347
4359
  git(cwd4, cmd) {
4348
4360
  try {
4349
- return execSync5(`git ${cmd}`, {
4361
+ return execSync6(`git ${cmd}`, {
4350
4362
  cwd: cwd4,
4351
4363
  encoding: "utf8",
4352
4364
  timeout: 1e4,
@@ -4649,7 +4661,7 @@ Exit code: ${task.exitCode ?? "N/A"}`,
4649
4661
  });
4650
4662
 
4651
4663
  // packages/execution/dist/system-deps.js
4652
- import { execSync as execSync6 } from "node:child_process";
4664
+ import { execSync as execSync7 } from "node:child_process";
4653
4665
  function detectPackageManager() {
4654
4666
  if (_detectedPkgManager !== void 0)
4655
4667
  return _detectedPkgManager;
@@ -4682,7 +4694,7 @@ function detectPackageManager() {
4682
4694
  function hasCommand(cmd) {
4683
4695
  try {
4684
4696
  const whichCmd = process.platform === "win32" ? `where ${cmd}` : `which ${cmd}`;
4685
- execSync6(whichCmd, { stdio: "pipe", timeout: 3e3 });
4697
+ execSync7(whichCmd, { stdio: "pipe", timeout: 3e3 });
4686
4698
  return true;
4687
4699
  } catch {
4688
4700
  return false;
@@ -4698,7 +4710,7 @@ function runInstall(installCmd) {
4698
4710
  cmd = `sudo -n ${installCmd}`;
4699
4711
  }
4700
4712
  }
4701
- execSync6(cmd, {
4713
+ execSync7(cmd, {
4702
4714
  stdio: "pipe",
4703
4715
  timeout: 12e4,
4704
4716
  // 2 min for package install
@@ -4843,7 +4855,7 @@ var init_system_deps = __esm({
4843
4855
  // packages/execution/dist/tools/image.js
4844
4856
  import { existsSync as existsSync9, readFileSync as readFileSync6, statSync as statSync4 } from "node:fs";
4845
4857
  import { resolve as resolve12, extname as extname2, basename as basename2 } from "node:path";
4846
- import { execSync as execSync7 } from "node:child_process";
4858
+ import { execSync as execSync8 } from "node:child_process";
4847
4859
  import { tmpdir } from "node:os";
4848
4860
  import { join as join12 } from "node:path";
4849
4861
  function isImagePath(path) {
@@ -4870,7 +4882,7 @@ function getMimeType(filePath) {
4870
4882
  }
4871
4883
  function getImageDimensions(filePath) {
4872
4884
  try {
4873
- const out = execSync7(`identify -format "%w %h" ${JSON.stringify(filePath)}`, {
4885
+ const out = execSync8(`identify -format "%w %h" ${JSON.stringify(filePath)}`, {
4874
4886
  encoding: "utf8",
4875
4887
  stdio: ["pipe", "pipe", "pipe"],
4876
4888
  timeout: 5e3
@@ -4882,7 +4894,7 @@ function getImageDimensions(filePath) {
4882
4894
  const dep = ensureCommand("identify");
4883
4895
  if (dep.installed) {
4884
4896
  try {
4885
- const out = execSync7(`identify -format "%w %h" ${JSON.stringify(filePath)}`, {
4897
+ const out = execSync8(`identify -format "%w %h" ${JSON.stringify(filePath)}`, {
4886
4898
  encoding: "utf8",
4887
4899
  stdio: ["pipe", "pipe", "pipe"],
4888
4900
  timeout: 5e3
@@ -4895,7 +4907,7 @@ function getImageDimensions(filePath) {
4895
4907
  }
4896
4908
  }
4897
4909
  try {
4898
- const out = execSync7(`file ${JSON.stringify(filePath)}`, {
4910
+ const out = execSync8(`file ${JSON.stringify(filePath)}`, {
4899
4911
  encoding: "utf8",
4900
4912
  stdio: ["pipe", "pipe", "pipe"],
4901
4913
  timeout: 5e3
@@ -4909,7 +4921,7 @@ function getImageDimensions(filePath) {
4909
4921
  }
4910
4922
  function hasTesseract() {
4911
4923
  try {
4912
- execSync7("tesseract --version", { stdio: "pipe", timeout: 5e3 });
4924
+ execSync8("tesseract --version", { stdio: "pipe", timeout: 5e3 });
4913
4925
  return true;
4914
4926
  } catch {
4915
4927
  const dep = ensureCommand("tesseract");
@@ -4918,7 +4930,7 @@ function hasTesseract() {
4918
4930
  }
4919
4931
  function runOCR(filePath) {
4920
4932
  try {
4921
- return execSync7(`tesseract ${JSON.stringify(filePath)} stdout 2>/dev/null`, {
4933
+ return execSync8(`tesseract ${JSON.stringify(filePath)} stdout 2>/dev/null`, {
4922
4934
  encoding: "utf8",
4923
4935
  stdio: ["pipe", "pipe", "pipe"],
4924
4936
  timeout: 3e4
@@ -5052,7 +5064,7 @@ ${ocrText}`);
5052
5064
  };
5053
5065
  }
5054
5066
  try {
5055
- execSync7(cmd, { stdio: "pipe", timeout: 1e4 });
5067
+ execSync8(cmd, { stdio: "pipe", timeout: 1e4 });
5056
5068
  } catch (err) {
5057
5069
  return {
5058
5070
  success: false,
@@ -5100,7 +5112,7 @@ ${ocrText}`);
5100
5112
  if (plat === "linux") {
5101
5113
  for (const tool of ["scrot", "gnome-screenshot", "import"]) {
5102
5114
  try {
5103
- execSync7(`which ${tool}`, { stdio: "pipe" });
5115
+ execSync8(`which ${tool}`, { stdio: "pipe" });
5104
5116
  if (tool === "scrot") {
5105
5117
  if (region === "active")
5106
5118
  return `scrot -u ${out}`;
@@ -5187,14 +5199,14 @@ ${ocrText}`);
5187
5199
  if (x != null && y != null && w != null && h != null) {
5188
5200
  const croppedPath = join12(tmpdir(), `oa-ocr-crop-${Date.now()}.png`);
5189
5201
  try {
5190
- execSync7(`convert ${JSON.stringify(fullPath)} -crop ${w}x${h}+${x}+${y} +repage ${JSON.stringify(croppedPath)}`, { stdio: "pipe", timeout: 1e4 });
5202
+ execSync8(`convert ${JSON.stringify(fullPath)} -crop ${w}x${h}+${x}+${y} +repage ${JSON.stringify(croppedPath)}`, { stdio: "pipe", timeout: 1e4 });
5191
5203
  inputPath = croppedPath;
5192
5204
  } catch {
5193
5205
  }
5194
5206
  }
5195
5207
  }
5196
5208
  try {
5197
- const text = execSync7(`tesseract ${JSON.stringify(inputPath)} stdout -l ${language} --psm ${psm} 2>/dev/null`, { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"], timeout: 3e4 }).trim();
5209
+ const text = execSync8(`tesseract ${JSON.stringify(inputPath)} stdout -l ${language} --psm ${psm} 2>/dev/null`, { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"], timeout: 3e4 }).trim();
5198
5210
  if (!text) {
5199
5211
  return { success: true, output: "(no text detected in image)", durationMs: Date.now() - start };
5200
5212
  }
@@ -5729,7 +5741,7 @@ var init_tool_creator = __esm({
5729
5741
  import { existsSync as existsSync11, readdirSync as readdirSync5, readFileSync as readFileSync8 } from "node:fs";
5730
5742
  import { join as join14, basename as basename3, dirname as dirname3 } from "node:path";
5731
5743
  import { homedir as homedir5 } from "node:os";
5732
- import { execSync as execSync8 } from "node:child_process";
5744
+ import { execSync as execSync9 } from "node:child_process";
5733
5745
  function getAiwgPaths() {
5734
5746
  const dataDir = join14(homedir5(), ".local", "share", "ai-writing-guide");
5735
5747
  return {
@@ -5742,7 +5754,7 @@ function findAiwgPackageRoot() {
5742
5754
  if (_cachedAiwgPkgRoot !== void 0)
5743
5755
  return _cachedAiwgPkgRoot;
5744
5756
  try {
5745
- const globalRoot = execSync8("npm root -g", {
5757
+ const globalRoot = execSync9("npm root -g", {
5746
5758
  encoding: "utf-8",
5747
5759
  timeout: 5e3,
5748
5760
  stdio: ["pipe", "pipe", "pipe"]
@@ -6129,7 +6141,7 @@ ${content}`,
6129
6141
  import { existsSync as existsSync12, mkdirSync as mkdirSync4, writeFileSync as writeFileSync4, readFileSync as readFileSync9, unlinkSync } from "node:fs";
6130
6142
  import { join as join15, basename as basename4, extname as extname3, resolve as resolve13 } from "node:path";
6131
6143
  import { homedir as homedir6 } from "node:os";
6132
- import { execSync as execSync9, spawn as spawn4 } from "node:child_process";
6144
+ import { execSync as execSync10, spawn as spawn4 } from "node:child_process";
6133
6145
  function isTranscribable(path) {
6134
6146
  const ext = extname3(path).toLowerCase();
6135
6147
  return AUDIO_EXTS.has(ext) || VIDEO_EXTS.has(ext);
@@ -6139,7 +6151,7 @@ async function loadTranscribeCli() {
6139
6151
  return _tcModule;
6140
6152
  _tcChecked = true;
6141
6153
  try {
6142
- const globalRoot = execSync9("npm root -g", {
6154
+ const globalRoot = execSync10("npm root -g", {
6143
6155
  encoding: "utf-8",
6144
6156
  timeout: 5e3,
6145
6157
  stdio: ["pipe", "pipe", "pipe"]
@@ -6304,7 +6316,7 @@ var init_transcribe_tool = __esm({
6304
6316
  const args = [filePath, "-m", model, "-f", "txt"];
6305
6317
  if (diarize)
6306
6318
  args.push("--diarize");
6307
- const output = execSync9(`transcribe-cli ${args.join(" ")}`, {
6319
+ const output = execSync10(`transcribe-cli ${args.join(" ")}`, {
6308
6320
  encoding: "utf-8",
6309
6321
  timeout: 3e5,
6310
6322
  // 5 min max
@@ -6371,12 +6383,12 @@ var init_transcribe_tool = __esm({
6371
6383
  const tmpFile = join15(tmpDir, `download-${Date.now()}${ext}`);
6372
6384
  try {
6373
6385
  try {
6374
- execSync9(`curl -sL -o "${tmpFile}" "${url}"`, {
6386
+ execSync10(`curl -sL -o "${tmpFile}" "${url}"`, {
6375
6387
  timeout: 12e4,
6376
6388
  stdio: ["pipe", "pipe", "pipe"]
6377
6389
  });
6378
6390
  } catch {
6379
- execSync9(`wget -q -O "${tmpFile}" "${url}"`, {
6391
+ execSync10(`wget -q -O "${tmpFile}" "${url}"`, {
6380
6392
  timeout: 12e4,
6381
6393
  stdio: ["pipe", "pipe", "pipe"]
6382
6394
  });
@@ -7189,7 +7201,7 @@ ${parts.join("\n\n")}`,
7189
7201
 
7190
7202
  // packages/execution/dist/tools/vision.js
7191
7203
  import { readFileSync as readFileSync10, existsSync as existsSync13, statSync as statSync5 } from "node:fs";
7192
- import { execSync as execSync10, spawn as spawn6 } from "node:child_process";
7204
+ import { execSync as execSync11, spawn as spawn6 } from "node:child_process";
7193
7205
  import { resolve as resolve16, extname as extname6, basename as basename5, dirname as dirname5, join as join17 } from "node:path";
7194
7206
  import { fileURLToPath as fileURLToPath2 } from "node:url";
7195
7207
  async function probeStation(endpoint) {
@@ -7208,7 +7220,7 @@ function findStationBinary() {
7208
7220
  const oaVenvPython = join17(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "python");
7209
7221
  if (existsSync13(oaVenvPython)) {
7210
7222
  try {
7211
- execSync10(`${JSON.stringify(oaVenvPython)} -c "import moondream_station"`, { stdio: "pipe", timeout: 5e3 });
7223
+ execSync11(`${JSON.stringify(oaVenvPython)} -c "import moondream_station"`, { stdio: "pipe", timeout: 5e3 });
7212
7224
  return oaVenvPython;
7213
7225
  } catch {
7214
7226
  }
@@ -7224,14 +7236,14 @@ function findStationBinary() {
7224
7236
  for (const p of localVenvPaths) {
7225
7237
  if (existsSync13(p)) {
7226
7238
  try {
7227
- execSync10(`${JSON.stringify(p)} -c "import moondream_station"`, { stdio: "pipe", timeout: 5e3 });
7239
+ execSync11(`${JSON.stringify(p)} -c "import moondream_station"`, { stdio: "pipe", timeout: 5e3 });
7228
7240
  return p;
7229
7241
  } catch {
7230
7242
  }
7231
7243
  }
7232
7244
  }
7233
7245
  try {
7234
- const path = execSync10("which moondream-station", { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"], timeout: 3e3 }).trim();
7246
+ const path = execSync11("which moondream-station", { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"], timeout: 3e3 }).trim();
7235
7247
  if (path)
7236
7248
  return path;
7237
7249
  } catch {
@@ -7559,13 +7571,13 @@ ${response}`, durationMs: performance.now() - start };
7559
7571
 
7560
7572
  // packages/execution/dist/tools/desktop-click.js
7561
7573
  import { readFileSync as readFileSync11, existsSync as existsSync14 } from "node:fs";
7562
- import { execSync as execSync11 } from "node:child_process";
7574
+ import { execSync as execSync12 } from "node:child_process";
7563
7575
  import { tmpdir as tmpdir3 } from "node:os";
7564
7576
  import { join as join18, dirname as dirname6 } from "node:path";
7565
7577
  import { fileURLToPath as fileURLToPath3 } from "node:url";
7566
7578
  function hasCommand2(cmd) {
7567
7579
  try {
7568
- execSync11(`which ${cmd}`, { stdio: "pipe", timeout: 3e3 });
7580
+ execSync12(`which ${cmd}`, { stdio: "pipe", timeout: 3e3 });
7569
7581
  return true;
7570
7582
  } catch {
7571
7583
  return false;
@@ -7573,7 +7585,7 @@ function hasCommand2(cmd) {
7573
7585
  }
7574
7586
  function getImageDimensions2(filePath) {
7575
7587
  try {
7576
- const out = execSync11(`identify -format "%w %h" ${JSON.stringify(filePath)}`, {
7588
+ const out = execSync12(`identify -format "%w %h" ${JSON.stringify(filePath)}`, {
7577
7589
  encoding: "utf8",
7578
7590
  stdio: ["pipe", "pipe", "pipe"],
7579
7591
  timeout: 5e3
@@ -7584,14 +7596,14 @@ function getImageDimensions2(filePath) {
7584
7596
  } catch {
7585
7597
  }
7586
7598
  try {
7587
- const out = execSync11(`python3 -c "from PIL import Image; i=Image.open(${JSON.stringify(filePath)}); print(i.size[0], i.size[1])"`, { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"], timeout: 5e3 }).trim();
7599
+ const out = execSync12(`python3 -c "from PIL import Image; i=Image.open(${JSON.stringify(filePath)}); print(i.size[0], i.size[1])"`, { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"], timeout: 5e3 }).trim();
7588
7600
  const [w, h] = out.split(" ").map(Number);
7589
7601
  if (w && h)
7590
7602
  return { width: w, height: h };
7591
7603
  } catch {
7592
7604
  }
7593
7605
  try {
7594
- const out = execSync11(`file ${JSON.stringify(filePath)}`, {
7606
+ const out = execSync12(`file ${JSON.stringify(filePath)}`, {
7595
7607
  encoding: "utf8",
7596
7608
  stdio: ["pipe", "pipe", "pipe"],
7597
7609
  timeout: 5e3
@@ -7622,7 +7634,7 @@ function captureScreenshot(outputPath) {
7622
7634
  cmd = `scrot ${out}`;
7623
7635
  } else {
7624
7636
  try {
7625
- execSync11(`DISPLAY=:0 python3 -c "from PIL import ImageGrab; ImageGrab.grab().save(${JSON.stringify(outputPath)})"`, { stdio: "pipe", timeout: 1e4 });
7637
+ execSync12(`DISPLAY=:0 python3 -c "from PIL import ImageGrab; ImageGrab.grab().save(${JSON.stringify(outputPath)})"`, { stdio: "pipe", timeout: 1e4 });
7626
7638
  if (existsSync14(outputPath))
7627
7639
  return;
7628
7640
  } catch {
@@ -7633,7 +7645,7 @@ function captureScreenshot(outputPath) {
7633
7645
  if (!cmd) {
7634
7646
  throw new Error("No screenshot tool found. Auto-install failed. Try manually: sudo apt install scrot");
7635
7647
  }
7636
- execSync11(cmd, { stdio: "pipe", timeout: 1e4 });
7648
+ execSync12(cmd, { stdio: "pipe", timeout: 1e4 });
7637
7649
  if (!existsSync14(outputPath)) {
7638
7650
  throw new Error("Screenshot file was not created");
7639
7651
  }
@@ -7651,11 +7663,11 @@ function clickAt(x, y, button, clickType) {
7651
7663
  hasXdotool = dep.available;
7652
7664
  }
7653
7665
  if (hasXdotool) {
7654
- execSync11(`xdotool mousemove --sync ${rx} ${ry}`, { stdio: "pipe", timeout: 5e3 });
7666
+ execSync12(`xdotool mousemove --sync ${rx} ${ry}`, { stdio: "pipe", timeout: 5e3 });
7655
7667
  if (clickType === "double") {
7656
- execSync11(`xdotool click --repeat 2 --delay 50 ${buttonNum}`, { stdio: "pipe", timeout: 5e3 });
7668
+ execSync12(`xdotool click --repeat 2 --delay 50 ${buttonNum}`, { stdio: "pipe", timeout: 5e3 });
7657
7669
  } else {
7658
- execSync11(`xdotool click ${buttonNum}`, { stdio: "pipe", timeout: 5e3 });
7670
+ execSync12(`xdotool click ${buttonNum}`, { stdio: "pipe", timeout: 5e3 });
7659
7671
  }
7660
7672
  return;
7661
7673
  }
@@ -7680,13 +7692,13 @@ for i in range(${clicks}):
7680
7692
  time.sleep(0.05)
7681
7693
  `.trim().replace(/\n/g, "; ");
7682
7694
  try {
7683
- execSync11(`DISPLAY=:0 python3 -c "${pyScript}"`, { stdio: "pipe", timeout: 5e3 });
7695
+ execSync12(`DISPLAY=:0 python3 -c "${pyScript}"`, { stdio: "pipe", timeout: 5e3 });
7684
7696
  return;
7685
7697
  } catch {
7686
7698
  }
7687
7699
  try {
7688
7700
  const venvPy = join18(__dirname, "../../../../.moondream-venv/bin/python");
7689
- execSync11(`DISPLAY=:0 ${JSON.stringify(venvPy)} -c "${pyScript}"`, { stdio: "pipe", timeout: 5e3 });
7701
+ execSync12(`DISPLAY=:0 ${JSON.stringify(venvPy)} -c "${pyScript}"`, { stdio: "pipe", timeout: 5e3 });
7690
7702
  return;
7691
7703
  } catch {
7692
7704
  }
@@ -7698,11 +7710,11 @@ for i in range(${clicks}):
7698
7710
  const rx2 = Math.round(x);
7699
7711
  const ry2 = Math.round(y);
7700
7712
  if (clickType === "double") {
7701
- execSync11(`cliclick dc:${rx2},${ry2}`, { stdio: "pipe", timeout: 5e3 });
7713
+ execSync12(`cliclick dc:${rx2},${ry2}`, { stdio: "pipe", timeout: 5e3 });
7702
7714
  } else if (button === "right") {
7703
- execSync11(`cliclick rc:${rx2},${ry2}`, { stdio: "pipe", timeout: 5e3 });
7715
+ execSync12(`cliclick rc:${rx2},${ry2}`, { stdio: "pipe", timeout: 5e3 });
7704
7716
  } else {
7705
- execSync11(`cliclick c:${rx2},${ry2}`, { stdio: "pipe", timeout: 5e3 });
7717
+ execSync12(`cliclick c:${rx2},${ry2}`, { stdio: "pipe", timeout: 5e3 });
7706
7718
  }
7707
7719
  } else {
7708
7720
  throw new Error(`Desktop click not supported on platform: ${plat}`);
@@ -8018,7 +8030,7 @@ ${data.response}`);
8018
8030
  const tess = ensureCommand("tesseract");
8019
8031
  if (tess.available) {
8020
8032
  try {
8021
- ocrText = execSync11(`tesseract ${JSON.stringify(screenshotPath)} stdout 2>/dev/null`, {
8033
+ ocrText = execSync12(`tesseract ${JSON.stringify(screenshotPath)} stdout 2>/dev/null`, {
8022
8034
  encoding: "utf8",
8023
8035
  timeout: 15e3
8024
8036
  }).trim();
@@ -8069,7 +8081,7 @@ Screen: ${dims.width}x${dims.height}`);
8069
8081
  // packages/execution/dist/tools/ocr-pdf.js
8070
8082
  import { existsSync as existsSync15, statSync as statSync6 } from "node:fs";
8071
8083
  import { resolve as resolve17, basename as basename6 } from "node:path";
8072
- import { execSync as execSync12 } from "node:child_process";
8084
+ import { execSync as execSync13 } from "node:child_process";
8073
8085
  var OcrPdfTool;
8074
8086
  var init_ocr_pdf = __esm({
8075
8087
  "packages/execution/dist/tools/ocr-pdf.js"() {
@@ -8156,7 +8168,7 @@ var init_ocr_pdf = __esm({
8156
8168
  cmdParts.push(JSON.stringify(inputPath));
8157
8169
  cmdParts.push(JSON.stringify(outputPath));
8158
8170
  try {
8159
- const stdout = execSync12(cmdParts.join(" "), {
8171
+ const stdout = execSync13(cmdParts.join(" "), {
8160
8172
  encoding: "utf8",
8161
8173
  stdio: ["pipe", "pipe", "pipe"],
8162
8174
  timeout: 6e5,
@@ -8192,7 +8204,7 @@ Language: ${language}
8192
8204
  // packages/execution/dist/tools/pdf-to-text.js
8193
8205
  import { existsSync as existsSync16, statSync as statSync7, readFileSync as readFileSync12, unlinkSync as unlinkSync2 } from "node:fs";
8194
8206
  import { resolve as resolve18, basename as basename7, join as join19 } from "node:path";
8195
- import { execSync as execSync13 } from "node:child_process";
8207
+ import { execSync as execSync14 } from "node:child_process";
8196
8208
  import { tmpdir as tmpdir4 } from "node:os";
8197
8209
  var PdfToTextTool;
8198
8210
  var init_pdf_to_text = __esm({
@@ -8288,7 +8300,7 @@ var init_pdf_to_text = __esm({
8288
8300
  cmdParts.push("-l", String(lastPage));
8289
8301
  cmdParts.push(JSON.stringify(fullPath), "-");
8290
8302
  try {
8291
- let text = execSync13(cmdParts.join(" "), {
8303
+ let text = execSync14(cmdParts.join(" "), {
8292
8304
  encoding: "utf8",
8293
8305
  stdio: ["pipe", "pipe", "pipe"],
8294
8306
  timeout: 12e4
@@ -8348,14 +8360,14 @@ ${text}`,
8348
8360
  const tmpPdf = join19(tmpdir4(), `oa-ocr-${Date.now()}.pdf`);
8349
8361
  try {
8350
8362
  const ocrCmd = `ocrmypdf -l ${language} --skip-text ${JSON.stringify(inputPath)} ${JSON.stringify(tmpPdf)}`;
8351
- execSync13(ocrCmd, { stdio: "pipe", timeout: 6e5 });
8363
+ execSync14(ocrCmd, { stdio: "pipe", timeout: 6e5 });
8352
8364
  const textCmdParts = ["pdftotext"];
8353
8365
  if (firstPage)
8354
8366
  textCmdParts.push("-f", String(firstPage));
8355
8367
  if (lastPage)
8356
8368
  textCmdParts.push("-l", String(lastPage));
8357
8369
  textCmdParts.push(JSON.stringify(tmpPdf), "-");
8358
- const text = execSync13(textCmdParts.join(" "), {
8370
+ const text = execSync14(textCmdParts.join(" "), {
8359
8371
  encoding: "utf8",
8360
8372
  stdio: ["pipe", "pipe", "pipe"],
8361
8373
  timeout: 12e4
@@ -8377,7 +8389,7 @@ ${text}`,
8377
8389
  // packages/execution/dist/tools/ocr-image-advanced.js
8378
8390
  import { existsSync as existsSync17, statSync as statSync8 } from "node:fs";
8379
8391
  import { resolve as resolve19, basename as basename8, dirname as dirname7, join as join20 } from "node:path";
8380
- import { execSync as execSync14 } from "node:child_process";
8392
+ import { execSync as execSync15 } from "node:child_process";
8381
8393
  import { fileURLToPath as fileURLToPath4 } from "node:url";
8382
8394
  import { homedir as homedir7, tmpdir as tmpdir5 } from "node:os";
8383
8395
  function findOcrScript() {
@@ -8397,7 +8409,7 @@ function findPython() {
8397
8409
  const venvPython = join20(homedir7(), ".open-agents", "venv", "bin", "python");
8398
8410
  if (existsSync17(venvPython)) {
8399
8411
  try {
8400
- execSync14(`${JSON.stringify(venvPython)} -c "import cv2, pytesseract, numpy, PIL"`, {
8412
+ execSync15(`${JSON.stringify(venvPython)} -c "import cv2, pytesseract, numpy, PIL"`, {
8401
8413
  stdio: "pipe",
8402
8414
  timeout: 5e3
8403
8415
  });
@@ -8406,7 +8418,7 @@ function findPython() {
8406
8418
  }
8407
8419
  }
8408
8420
  try {
8409
- execSync14(`python3 -c "import cv2, pytesseract, numpy, PIL"`, {
8421
+ execSync15(`python3 -c "import cv2, pytesseract, numpy, PIL"`, {
8410
8422
  stdio: "pipe",
8411
8423
  timeout: 5e3
8412
8424
  });
@@ -8544,7 +8556,7 @@ var init_ocr_image_advanced = __esm({
8544
8556
  cmdParts.push("--debug-dir", debugDir);
8545
8557
  }
8546
8558
  try {
8547
- const stdout = execSync14(cmdParts.join(" "), {
8559
+ const stdout = execSync15(cmdParts.join(" "), {
8548
8560
  encoding: "utf8",
8549
8561
  stdio: ["pipe", "pipe", "pipe"],
8550
8562
  timeout: 3e5,
@@ -8640,14 +8652,14 @@ var init_ocr_image_advanced = __esm({
8640
8652
  try {
8641
8653
  const [x, y, w, h] = region.split(",").map(Number);
8642
8654
  const croppedPath = join20(tmpdir5(), `oa-ocr-crop-${Date.now()}.png`);
8643
- execSync14(`convert ${JSON.stringify(imagePath)} -crop ${w}x${h}+${x}+${y} +repage ${JSON.stringify(croppedPath)}`, { stdio: "pipe", timeout: 1e4 });
8655
+ execSync15(`convert ${JSON.stringify(imagePath)} -crop ${w}x${h}+${x}+${y} +repage ${JSON.stringify(croppedPath)}`, { stdio: "pipe", timeout: 1e4 });
8644
8656
  inputPath = croppedPath;
8645
8657
  } catch {
8646
8658
  }
8647
8659
  }
8648
8660
  const psmArg = psm ?? 6;
8649
8661
  try {
8650
- const text = execSync14(`tesseract ${JSON.stringify(inputPath)} stdout -l ${language} --psm ${psmArg} 2>/dev/null`, { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"], timeout: 6e4 }).trim();
8662
+ const text = execSync15(`tesseract ${JSON.stringify(inputPath)} stdout -l ${language} --psm ${psmArg} 2>/dev/null`, { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"], timeout: 6e4 }).trim();
8651
8663
  if (!text) {
8652
8664
  return {
8653
8665
  success: true,
@@ -8678,7 +8690,7 @@ Note: Advanced Python pipeline not available \u2014 install pytesseract, opencv-
8678
8690
  });
8679
8691
 
8680
8692
  // packages/execution/dist/tools/browser-action.js
8681
- import { execSync as execSync15, spawn as spawn7 } from "node:child_process";
8693
+ import { execSync as execSync16, spawn as spawn7 } from "node:child_process";
8682
8694
  import { existsSync as existsSync18, readFileSync as readFileSync13 } from "node:fs";
8683
8695
  import { join as join21, dirname as dirname8 } from "node:path";
8684
8696
  import { fileURLToPath as fileURLToPath5 } from "node:url";
@@ -8696,7 +8708,7 @@ async function probeService() {
8696
8708
  function findPython2() {
8697
8709
  for (const cmd of ["python3", "python"]) {
8698
8710
  try {
8699
- const ver = execSync15(`${cmd} --version 2>&1`, { stdio: "pipe", timeout: 5e3 }).toString().trim();
8711
+ const ver = execSync16(`${cmd} --version 2>&1`, { stdio: "pipe", timeout: 5e3 }).toString().trim();
8700
8712
  if (ver.includes("Python 3"))
8701
8713
  return cmd;
8702
8714
  } catch {
@@ -8931,7 +8943,7 @@ var init_browser_action = __esm({
8931
8943
  });
8932
8944
 
8933
8945
  // packages/execution/dist/tools/autoresearch.js
8934
- import { execSync as execSync16, spawn as spawn8 } from "node:child_process";
8946
+ import { execSync as execSync17, spawn as spawn8 } from "node:child_process";
8935
8947
  import { existsSync as existsSync19, readFileSync as readFileSync14, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5, appendFileSync, copyFileSync } from "node:fs";
8936
8948
  import { join as join22, resolve as resolve20, dirname as dirname9 } from "node:path";
8937
8949
  import { fileURLToPath as fileURLToPath6 } from "node:url";
@@ -9061,13 +9073,13 @@ Requires: NVIDIA GPU, Python 3.10+, uv (astral.sh package manager).`;
9061
9073
  async setup(workspace, args, start) {
9062
9074
  const output = [];
9063
9075
  try {
9064
- execSync16("which uv", { encoding: "utf-8", timeout: 5e3 });
9076
+ execSync17("which uv", { encoding: "utf-8", timeout: 5e3 });
9065
9077
  output.push("uv: found");
9066
9078
  } catch {
9067
9079
  return { success: false, output: "", error: "uv not found. Install with: curl -LsSf https://astral.sh/uv/install.sh | sh", durationMs: Date.now() - start };
9068
9080
  }
9069
9081
  try {
9070
- const gpuInfo = execSync16("nvidia-smi --query-gpu=name,memory.total --format=csv,noheader 2>/dev/null || echo 'no GPU'", { encoding: "utf-8", timeout: 1e4 }).trim();
9082
+ const gpuInfo = execSync17("nvidia-smi --query-gpu=name,memory.total --format=csv,noheader 2>/dev/null || echo 'no GPU'", { encoding: "utf-8", timeout: 1e4 }).trim();
9071
9083
  output.push(`GPU: ${gpuInfo}`);
9072
9084
  } catch {
9073
9085
  output.push("GPU: detection failed (nvidia-smi not available)");
@@ -9117,10 +9129,10 @@ explicit = true
9117
9129
  writeFileSync5(join22(workspace, "pyproject.toml"), pyprojectContent, "utf-8");
9118
9130
  output.push("Created pyproject.toml");
9119
9131
  try {
9120
- execSync16("git rev-parse --git-dir", { cwd: workspace, encoding: "utf-8", timeout: 5e3 });
9132
+ execSync17("git rev-parse --git-dir", { cwd: workspace, encoding: "utf-8", timeout: 5e3 });
9121
9133
  output.push("Git: already initialized");
9122
9134
  } catch {
9123
- execSync16("git init && git add -A && git commit -m 'autoresearch: initial setup'", {
9135
+ execSync17("git init && git add -A && git commit -m 'autoresearch: initial setup'", {
9124
9136
  cwd: workspace,
9125
9137
  encoding: "utf-8",
9126
9138
  timeout: 1e4
@@ -9130,14 +9142,14 @@ explicit = true
9130
9142
  const tag = String(args["tag"] ?? (/* @__PURE__ */ new Date()).toISOString().slice(5, 10).replace("-", ""));
9131
9143
  const branchName = `autoresearch/${tag}`;
9132
9144
  try {
9133
- execSync16(`git checkout -b ${branchName}`, { cwd: workspace, encoding: "utf-8", timeout: 5e3 });
9145
+ execSync17(`git checkout -b ${branchName}`, { cwd: workspace, encoding: "utf-8", timeout: 5e3 });
9134
9146
  output.push(`Branch: created ${branchName}`);
9135
9147
  } catch {
9136
9148
  output.push(`Branch: ${branchName} may already exist, staying on current branch`);
9137
9149
  }
9138
9150
  output.push("Installing dependencies with uv sync (this may take a while)...");
9139
9151
  try {
9140
- const uvOut = execSync16("uv sync 2>&1", { cwd: workspace, encoding: "utf-8", timeout: 3e5 });
9152
+ const uvOut = execSync17("uv sync 2>&1", { cwd: workspace, encoding: "utf-8", timeout: 3e5 });
9141
9153
  output.push(`uv sync: ${uvOut.trim().split("\n").slice(-3).join(" | ")}`);
9142
9154
  } catch (err) {
9143
9155
  const e = err;
@@ -9146,7 +9158,7 @@ explicit = true
9146
9158
  const numShards = Number(args["num_shards"] ?? 10);
9147
9159
  output.push(`Preparing data (${numShards} shards)...`);
9148
9160
  try {
9149
- const prepOut = execSync16(`uv run prepare.py --num-shards ${numShards} 2>&1`, {
9161
+ const prepOut = execSync17(`uv run prepare.py --num-shards ${numShards} 2>&1`, {
9150
9162
  cwd: workspace,
9151
9163
  encoding: "utf-8",
9152
9164
  timeout: 6e5
@@ -9183,7 +9195,7 @@ Next steps:
9183
9195
  }
9184
9196
  if (!existsSync19(join22(workspace, ".venv")) && existsSync19(join22(workspace, "pyproject.toml"))) {
9185
9197
  try {
9186
- execSync16("uv sync 2>&1", { cwd: workspace, encoding: "utf-8", timeout: 3e5 });
9198
+ execSync17("uv sync 2>&1", { cwd: workspace, encoding: "utf-8", timeout: 3e5 });
9187
9199
  } catch {
9188
9200
  }
9189
9201
  }
@@ -9333,15 +9345,15 @@ Run autoresearch(action="setup") to begin.`,
9333
9345
  }
9334
9346
  output.push(`Workspace: ${workspace}`);
9335
9347
  try {
9336
- const branch = execSync16("git branch --show-current", { cwd: workspace, encoding: "utf-8", timeout: 5e3 }).trim();
9348
+ const branch = execSync17("git branch --show-current", { cwd: workspace, encoding: "utf-8", timeout: 5e3 }).trim();
9337
9349
  output.push(`Branch: ${branch}`);
9338
- const lastCommit = execSync16("git log --oneline -1", { cwd: workspace, encoding: "utf-8", timeout: 5e3 }).trim();
9350
+ const lastCommit = execSync17("git log --oneline -1", { cwd: workspace, encoding: "utf-8", timeout: 5e3 }).trim();
9339
9351
  output.push(`Last commit: ${lastCommit}`);
9340
9352
  } catch {
9341
9353
  output.push("Git: not initialized");
9342
9354
  }
9343
9355
  try {
9344
- const gpuInfo = execSync16("nvidia-smi --query-gpu=name,memory.total,memory.used --format=csv,noheader 2>/dev/null", { encoding: "utf-8", timeout: 1e4 }).trim();
9356
+ const gpuInfo = execSync17("nvidia-smi --query-gpu=name,memory.total,memory.used --format=csv,noheader 2>/dev/null", { encoding: "utf-8", timeout: 1e4 }).trim();
9345
9357
  output.push(`GPU: ${gpuInfo}`);
9346
9358
  } catch {
9347
9359
  output.push("GPU: not detected");
@@ -9384,12 +9396,12 @@ Run autoresearch(action="setup") to begin.`,
9384
9396
  memGb = memGb ?? 0;
9385
9397
  let commitHash = "0000000";
9386
9398
  try {
9387
- execSync16("git add train.py", { cwd: workspace, encoding: "utf-8", timeout: 5e3 });
9388
- execSync16(`git commit -m "autoresearch: ${desc}"`, { cwd: workspace, encoding: "utf-8", timeout: 1e4 });
9389
- commitHash = execSync16("git rev-parse --short HEAD", { cwd: workspace, encoding: "utf-8", timeout: 5e3 }).trim();
9399
+ execSync17("git add train.py", { cwd: workspace, encoding: "utf-8", timeout: 5e3 });
9400
+ execSync17(`git commit -m "autoresearch: ${desc}"`, { cwd: workspace, encoding: "utf-8", timeout: 1e4 });
9401
+ commitHash = execSync17("git rev-parse --short HEAD", { cwd: workspace, encoding: "utf-8", timeout: 5e3 }).trim();
9390
9402
  } catch {
9391
9403
  try {
9392
- commitHash = execSync16("git rev-parse --short HEAD", { cwd: workspace, encoding: "utf-8", timeout: 5e3 }).trim();
9404
+ commitHash = execSync17("git rev-parse --short HEAD", { cwd: workspace, encoding: "utf-8", timeout: 5e3 }).trim();
9393
9405
  } catch {
9394
9406
  }
9395
9407
  }
@@ -9423,14 +9435,14 @@ Branch advanced. Ready for next experiment.`,
9423
9435
  memGb = memGb ?? 0;
9424
9436
  let commitHash = "0000000";
9425
9437
  try {
9426
- commitHash = execSync16("git rev-parse --short HEAD", { cwd: workspace, encoding: "utf-8", timeout: 5e3 }).trim();
9438
+ commitHash = execSync17("git rev-parse --short HEAD", { cwd: workspace, encoding: "utf-8", timeout: 5e3 }).trim();
9427
9439
  } catch {
9428
9440
  }
9429
9441
  const row = `${commitHash} ${valBpb.toFixed(6)} ${memGb.toFixed(1)} discard ${desc}
9430
9442
  `;
9431
9443
  appendFileSync(tsvPath, row, "utf-8");
9432
9444
  try {
9433
- execSync16("git checkout -- train.py", { cwd: workspace, encoding: "utf-8", timeout: 5e3 });
9445
+ execSync17("git checkout -- train.py", { cwd: workspace, encoding: "utf-8", timeout: 5e3 });
9434
9446
  } catch {
9435
9447
  return {
9436
9448
  success: false,
@@ -9451,7 +9463,7 @@ train.py reverted to last kept state. Ready for next experiment.`,
9451
9463
  });
9452
9464
 
9453
9465
  // packages/execution/dist/tools/scheduler.js
9454
- import { execSync as execSync17, exec as execCb } from "node:child_process";
9466
+ import { execSync as execSync18, exec as execCb } from "node:child_process";
9455
9467
  import { readFile as readFile9, writeFile as writeFile8, mkdir as mkdir4 } from "node:fs/promises";
9456
9468
  import { resolve as resolve21, join as join23 } from "node:path";
9457
9469
  import { randomBytes as randomBytes2 } from "node:crypto";
@@ -9513,19 +9525,19 @@ function describeCron(expr) {
9513
9525
  }
9514
9526
  function getCurrentCrontab() {
9515
9527
  try {
9516
- return execSync17("crontab -l 2>/dev/null", { stdio: "pipe" }).toString().split("\n");
9528
+ return execSync18("crontab -l 2>/dev/null", { stdio: "pipe" }).toString().split("\n");
9517
9529
  } catch {
9518
9530
  return [];
9519
9531
  }
9520
9532
  }
9521
9533
  function writeCrontab(lines) {
9522
9534
  const content = lines.join("\n") + "\n";
9523
- execSync17(`echo ${JSON.stringify(content)} | crontab -`, { stdio: "pipe" });
9535
+ execSync18(`echo ${JSON.stringify(content)} | crontab -`, { stdio: "pipe" });
9524
9536
  }
9525
9537
  function findOaBinary() {
9526
9538
  for (const cmd of ["oa", "open-agents"]) {
9527
9539
  try {
9528
- const path = execSync17(`which ${cmd} 2>/dev/null`, { stdio: "pipe" }).toString().trim();
9540
+ const path = execSync18(`which ${cmd} 2>/dev/null`, { stdio: "pipe" }).toString().trim();
9529
9541
  if (path)
9530
9542
  return path;
9531
9543
  } catch {
@@ -10440,13 +10452,13 @@ ${sections.join("\n")}`,
10440
10452
  });
10441
10453
 
10442
10454
  // packages/execution/dist/tools/opencode.js
10443
- import { execSync as execSync18, spawn as spawn9 } from "node:child_process";
10455
+ import { execSync as execSync19, spawn as spawn9 } from "node:child_process";
10444
10456
  import { existsSync as existsSync20 } from "node:fs";
10445
10457
  import { join as join26, resolve as resolve24 } from "node:path";
10446
10458
  function findOpencode() {
10447
10459
  for (const cmd of ["opencode"]) {
10448
10460
  try {
10449
- const path = execSync18(`which ${cmd} 2>/dev/null`, { stdio: "pipe" }).toString().trim();
10461
+ const path = execSync19(`which ${cmd} 2>/dev/null`, { stdio: "pipe" }).toString().trim();
10450
10462
  if (path)
10451
10463
  return path;
10452
10464
  } catch {
@@ -10466,7 +10478,7 @@ function findOpencode() {
10466
10478
  }
10467
10479
  function getVersion(binary) {
10468
10480
  try {
10469
- return execSync18(`${binary} --version 2>/dev/null`, { stdio: "pipe", timeout: 1e4 }).toString().trim();
10481
+ return execSync19(`${binary} --version 2>/dev/null`, { stdio: "pipe", timeout: 1e4 }).toString().trim();
10470
10482
  } catch {
10471
10483
  return "unknown";
10472
10484
  }
@@ -10475,12 +10487,12 @@ function installOpencode() {
10475
10487
  const platform4 = process.platform;
10476
10488
  try {
10477
10489
  if (platform4 === "win32") {
10478
- execSync18('powershell -Command "irm https://opencode.ai/install | iex"', {
10490
+ execSync19('powershell -Command "irm https://opencode.ai/install | iex"', {
10479
10491
  stdio: "pipe",
10480
10492
  timeout: 12e4
10481
10493
  });
10482
10494
  } else {
10483
- execSync18("curl -fsSL https://opencode.ai/install | bash", {
10495
+ execSync19("curl -fsSL https://opencode.ai/install | bash", {
10484
10496
  stdio: "pipe",
10485
10497
  timeout: 12e4
10486
10498
  });
@@ -10714,7 +10726,7 @@ var init_opencode = __esm({
10714
10726
  });
10715
10727
 
10716
10728
  // packages/execution/dist/tools/cron-agent.js
10717
- import { execSync as execSync19 } from "node:child_process";
10729
+ import { execSync as execSync20 } from "node:child_process";
10718
10730
  import { readFile as readFile12, writeFile as writeFile11, mkdir as mkdir7 } from "node:fs/promises";
10719
10731
  import { resolve as resolve25, join as join27 } from "node:path";
10720
10732
  import { randomBytes as randomBytes5 } from "node:crypto";
@@ -10778,19 +10790,19 @@ function resolveSchedule2(schedule) {
10778
10790
  }
10779
10791
  function getCurrentCrontab2() {
10780
10792
  try {
10781
- return execSync19("crontab -l 2>/dev/null", { stdio: "pipe" }).toString().split("\n");
10793
+ return execSync20("crontab -l 2>/dev/null", { stdio: "pipe" }).toString().split("\n");
10782
10794
  } catch {
10783
10795
  return [];
10784
10796
  }
10785
10797
  }
10786
10798
  function writeCrontab2(lines) {
10787
10799
  const content = lines.join("\n") + "\n";
10788
- execSync19(`echo ${JSON.stringify(content)} | crontab -`, { stdio: "pipe" });
10800
+ execSync20(`echo ${JSON.stringify(content)} | crontab -`, { stdio: "pipe" });
10789
10801
  }
10790
10802
  function findOaBinary2() {
10791
10803
  for (const cmd of ["oa", "open-agents"]) {
10792
10804
  try {
10793
- const path = execSync19(`which ${cmd} 2>/dev/null`, { stdio: "pipe" }).toString().trim();
10805
+ const path = execSync20(`which ${cmd} 2>/dev/null`, { stdio: "pipe" }).toString().trim();
10794
10806
  if (path)
10795
10807
  return path;
10796
10808
  } catch {
@@ -11120,7 +11132,7 @@ ${truncated}`, durationMs: performance.now() - start };
11120
11132
  ];
11121
11133
  if (job.verifyCommand) {
11122
11134
  try {
11123
- const result = execSync19(job.verifyCommand, {
11135
+ const result = execSync20(job.verifyCommand, {
11124
11136
  cwd: this.workingDir,
11125
11137
  stdio: "pipe",
11126
11138
  timeout: 3e4
@@ -11170,7 +11182,7 @@ import { readFile as readFile13, writeFile as writeFile12, mkdir as mkdir8, chmo
11170
11182
  import { existsSync as existsSync21 } from "node:fs";
11171
11183
  import { resolve as resolve26, join as join28 } from "node:path";
11172
11184
  import { randomBytes as randomBytes6, createCipheriv, createDecipheriv, scryptSync, createHash } from "node:crypto";
11173
- import { execSync as execSync20, spawn as spawn10 } from "node:child_process";
11185
+ import { execSync as execSync21, spawn as spawn10 } from "node:child_process";
11174
11186
  function containsKeyMaterial(input) {
11175
11187
  for (const pattern of KEY_PATTERNS) {
11176
11188
  if (pattern.test(input))
@@ -11536,7 +11548,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
11536
11548
  if (existsSync21(nexusPkg)) {
11537
11549
  nexusResolved = true;
11538
11550
  } else {
11539
- const globalDir = execSync20("npm root -g", { encoding: "utf8", timeout: 5e3 }).trim();
11551
+ const globalDir = execSync21("npm root -g", { encoding: "utf8", timeout: 5e3 }).trim();
11540
11552
  if (existsSync21(join28(globalDir, "open-agents-nexus", "package.json"))) {
11541
11553
  nexusResolved = true;
11542
11554
  }
@@ -11545,14 +11557,14 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
11545
11557
  }
11546
11558
  if (!nexusResolved) {
11547
11559
  try {
11548
- execSync20("npm install open-agents-nexus@latest 2>&1", {
11560
+ execSync21("npm install open-agents-nexus@latest 2>&1", {
11549
11561
  cwd: this.repoRoot,
11550
11562
  stdio: "pipe",
11551
11563
  timeout: 12e4
11552
11564
  });
11553
11565
  } catch {
11554
11566
  try {
11555
- execSync20("npm install -g open-agents-nexus@latest 2>&1", { stdio: "pipe", timeout: 12e4 });
11567
+ execSync21("npm install -g open-agents-nexus@latest 2>&1", { stdio: "pipe", timeout: 12e4 });
11556
11568
  } catch {
11557
11569
  throw new Error("Failed to install open-agents-nexus. Run: npm install open-agents-nexus");
11558
11570
  }
@@ -11564,7 +11576,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
11564
11576
  const agentType = args.agent_type || "general";
11565
11577
  const nodePaths = [nodeModulesDir];
11566
11578
  try {
11567
- const globalDir = execSync20("npm root -g", { encoding: "utf8", timeout: 5e3 }).trim();
11579
+ const globalDir = execSync21("npm root -g", { encoding: "utf8", timeout: 5e3 }).trim();
11568
11580
  nodePaths.push(globalDir);
11569
11581
  } catch {
11570
11582
  }
@@ -11805,7 +11817,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
11805
11817
  }
11806
11818
  async doInferenceProof() {
11807
11819
  try {
11808
- const psRaw = execSync20("ollama ps 2>/dev/null", { timeout: 1e4, encoding: "utf8" });
11820
+ const psRaw = execSync21("ollama ps 2>/dev/null", { timeout: 1e4, encoding: "utf8" });
11809
11821
  const lines = psRaw.trim().split("\n").filter((l) => l.trim());
11810
11822
  if (lines.length < 2)
11811
11823
  return "No model loaded. Run 'ollama ps' to check.";
@@ -11813,7 +11825,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
11813
11825
  const modelName = parts[0] || "unknown";
11814
11826
  let gpuName = "none", vramMb = 0;
11815
11827
  try {
11816
- const smi = execSync20("nvidia-smi --query-gpu=name,memory.total --format=csv,noheader 2>/dev/null", {
11828
+ const smi = execSync21("nvidia-smi --query-gpu=name,memory.total --format=csv,noheader 2>/dev/null", {
11817
11829
  timeout: 5e3,
11818
11830
  encoding: "utf8"
11819
11831
  });
@@ -11822,7 +11834,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
11822
11834
  vramMb = parseInt(gp[1]?.trim() || "0", 10);
11823
11835
  } catch {
11824
11836
  try {
11825
- execSync20("rocm-smi 2>/dev/null", { timeout: 5e3 });
11837
+ execSync21("rocm-smi 2>/dev/null", { timeout: 5e3 });
11826
11838
  gpuName = "AMD GPU";
11827
11839
  } catch {
11828
11840
  }
@@ -17663,7 +17675,7 @@ __export(listen_exports, {
17663
17675
  isVideoPath: () => isVideoPath,
17664
17676
  waitForTranscribeCli: () => waitForTranscribeCli
17665
17677
  });
17666
- import { spawn as spawn11, execSync as execSync21 } from "node:child_process";
17678
+ import { spawn as spawn11, execSync as execSync22 } from "node:child_process";
17667
17679
  import { existsSync as existsSync22, mkdirSync as mkdirSync6, writeFileSync as writeFileSync6, readdirSync as readdirSync6 } from "node:fs";
17668
17680
  import { join as join31, dirname as dirname10 } from "node:path";
17669
17681
  import { homedir as homedir8 } from "node:os";
@@ -17685,7 +17697,7 @@ function findMicCaptureCommand() {
17685
17697
  const platform4 = process.platform;
17686
17698
  if (platform4 === "linux") {
17687
17699
  try {
17688
- execSync21("which arecord", { stdio: "pipe" });
17700
+ execSync22("which arecord", { stdio: "pipe" });
17689
17701
  return {
17690
17702
  cmd: "arecord",
17691
17703
  args: ["-f", "S16_LE", "-r", "16000", "-c", "1", "-t", "raw", "-q", "-"]
@@ -17695,7 +17707,7 @@ function findMicCaptureCommand() {
17695
17707
  }
17696
17708
  if (platform4 === "darwin") {
17697
17709
  try {
17698
- execSync21("which sox", { stdio: "pipe" });
17710
+ execSync22("which sox", { stdio: "pipe" });
17699
17711
  return {
17700
17712
  cmd: "sox",
17701
17713
  args: ["-d", "-t", "raw", "-r", "16000", "-c", "1", "-b", "16", "-e", "signed-integer", "-"]
@@ -17704,7 +17716,7 @@ function findMicCaptureCommand() {
17704
17716
  }
17705
17717
  }
17706
17718
  try {
17707
- execSync21("which ffmpeg", { stdio: "pipe" });
17719
+ execSync22("which ffmpeg", { stdio: "pipe" });
17708
17720
  if (platform4 === "linux") {
17709
17721
  return {
17710
17722
  cmd: "ffmpeg",
@@ -17763,7 +17775,7 @@ function findLiveWhisperScript() {
17763
17775
  return p;
17764
17776
  }
17765
17777
  try {
17766
- const globalRoot = execSync21("npm root -g", {
17778
+ const globalRoot = execSync22("npm root -g", {
17767
17779
  encoding: "utf-8",
17768
17780
  timeout: 5e3,
17769
17781
  stdio: ["pipe", "pipe", "pipe"]
@@ -17796,7 +17808,7 @@ function ensureTranscribeCliBackground() {
17796
17808
  return;
17797
17809
  _bgInstallPromise = (async () => {
17798
17810
  try {
17799
- const globalRoot = execSync21("npm root -g", {
17811
+ const globalRoot = execSync22("npm root -g", {
17800
17812
  encoding: "utf-8",
17801
17813
  timeout: 5e3,
17802
17814
  stdio: ["pipe", "pipe", "pipe"]
@@ -18002,7 +18014,7 @@ var init_listen = __esm({
18002
18014
  }
18003
18015
  if (!this.transcribeCliAvailable) {
18004
18016
  try {
18005
- execSync21("which transcribe-cli", { stdio: "pipe" });
18017
+ execSync22("which transcribe-cli", { stdio: "pipe" });
18006
18018
  this.transcribeCliAvailable = true;
18007
18019
  } catch {
18008
18020
  this.transcribeCliAvailable = false;
@@ -18019,7 +18031,7 @@ var init_listen = __esm({
18019
18031
  } catch {
18020
18032
  }
18021
18033
  try {
18022
- const globalRoot = execSync21("npm root -g", {
18034
+ const globalRoot = execSync22("npm root -g", {
18023
18035
  encoding: "utf-8",
18024
18036
  timeout: 5e3,
18025
18037
  stdio: ["pipe", "pipe", "pipe"]
@@ -18069,7 +18081,7 @@ var init_listen = __esm({
18069
18081
  }
18070
18082
  if (!tc) {
18071
18083
  try {
18072
- execSync21("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
18084
+ execSync22("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
18073
18085
  this.transcribeCliAvailable = null;
18074
18086
  tc = await this.loadTranscribeCli();
18075
18087
  } catch {
@@ -18252,7 +18264,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
18252
18264
  }
18253
18265
  if (!tc) {
18254
18266
  try {
18255
- execSync21("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
18267
+ execSync22("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
18256
18268
  this.transcribeCliAvailable = null;
18257
18269
  tc = await this.loadTranscribeCli();
18258
18270
  } catch {
@@ -18306,7 +18318,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
18306
18318
  }
18307
18319
  if (!tc) {
18308
18320
  try {
18309
- execSync21("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
18321
+ execSync22("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
18310
18322
  this.transcribeCliAvailable = null;
18311
18323
  tc = await this.loadTranscribeCli();
18312
18324
  } catch {
@@ -22818,6 +22830,7 @@ var init_render = __esm({
22818
22830
  };
22819
22831
  _contentWriteHook = null;
22820
22832
  HINTS = [
22833
+ "Ask the agent to connect to the Open Agents Nexus for P2P agent networking",
22821
22834
  "Use /voice to enable TTS voice feedback while the agent works",
22822
22835
  "Drop an image file onto the terminal to give the agent visual context",
22823
22836
  "Type while the agent works (+ prompt) to steer its approach",
@@ -22829,7 +22842,8 @@ var init_render = __esm({
22829
22842
  "Use /update to check for and install the latest version",
22830
22843
  "The agent can take screenshots and OCR text from images autonomously",
22831
22844
  "Sub-agents can run independent tasks in parallel via sub_agent tool",
22832
- "Background tasks let the agent run tests while making other changes"
22845
+ "Background tasks let the agent run tests while making other changes",
22846
+ "Use /nexus connect to join the decentralized agent mesh network"
22833
22847
  ];
22834
22848
  TOOL_NAMES = [
22835
22849
  "file_read",
@@ -22891,7 +22905,7 @@ var init_render = __esm({
22891
22905
 
22892
22906
  // packages/cli/dist/tui/voice-session.js
22893
22907
  import { createServer } from "node:http";
22894
- import { spawn as spawn12, execSync as execSync22 } from "node:child_process";
22908
+ import { spawn as spawn12, execSync as execSync23 } from "node:child_process";
22895
22909
  import { EventEmitter as EventEmitter2 } from "node:events";
22896
22910
  function generateFrontendHTML() {
22897
22911
  return `<!DOCTYPE html>
@@ -25930,7 +25944,7 @@ var init_oa_directory = __esm({
25930
25944
 
25931
25945
  // packages/cli/dist/tui/setup.js
25932
25946
  import * as readline from "node:readline";
25933
- import { execSync as execSync23, spawn as spawn14 } from "node:child_process";
25947
+ import { execSync as execSync24, spawn as spawn14 } from "node:child_process";
25934
25948
  import { existsSync as existsSync25, writeFileSync as writeFileSync9, mkdirSync as mkdirSync9 } from "node:fs";
25935
25949
  import { join as join35 } from "node:path";
25936
25950
  import { homedir as homedir10, platform } from "node:os";
@@ -25940,7 +25954,7 @@ function detectSystemSpecs() {
25940
25954
  let gpuVramGB = 0;
25941
25955
  let gpuName = "";
25942
25956
  try {
25943
- const memInfo = execSync23("free -b 2>/dev/null || sysctl -n hw.memsize 2>/dev/null", {
25957
+ const memInfo = execSync24("free -b 2>/dev/null || sysctl -n hw.memsize 2>/dev/null", {
25944
25958
  encoding: "utf8",
25945
25959
  timeout: 5e3
25946
25960
  });
@@ -25960,7 +25974,7 @@ function detectSystemSpecs() {
25960
25974
  } catch {
25961
25975
  }
25962
25976
  try {
25963
- const nvidiaSmi = execSync23("nvidia-smi --query-gpu=memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 5e3 });
25977
+ const nvidiaSmi = execSync24("nvidia-smi --query-gpu=memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 5e3 });
25964
25978
  const lines = nvidiaSmi.trim().split("\n");
25965
25979
  if (lines.length > 0) {
25966
25980
  for (const line of lines) {
@@ -26085,7 +26099,7 @@ function ensureCurl() {
26085
26099
  for (const s of strategies) {
26086
26100
  if (hasCmd(s.check)) {
26087
26101
  try {
26088
- execSync23(s.install, { stdio: "inherit", timeout: 12e4 });
26102
+ execSync24(s.install, { stdio: "inherit", timeout: 12e4 });
26089
26103
  if (hasCmd("curl")) {
26090
26104
  process.stdout.write(` ${c2.green("\u2714")} curl installed via ${s.label}.
26091
26105
  `);
@@ -26099,7 +26113,7 @@ function ensureCurl() {
26099
26113
  }
26100
26114
  if (plat === "darwin") {
26101
26115
  try {
26102
- execSync23("xcode-select --install", { stdio: "inherit", timeout: 3e5 });
26116
+ execSync24("xcode-select --install", { stdio: "inherit", timeout: 3e5 });
26103
26117
  if (hasCmd("curl"))
26104
26118
  return true;
26105
26119
  } catch {
@@ -26134,7 +26148,7 @@ function installOllamaLinux() {
26134
26148
 
26135
26149
  `);
26136
26150
  try {
26137
- execSync23("curl -fsSL https://ollama.com/install.sh | sh", {
26151
+ execSync24("curl -fsSL https://ollama.com/install.sh | sh", {
26138
26152
  stdio: "inherit",
26139
26153
  timeout: 3e5
26140
26154
  });
@@ -26162,7 +26176,7 @@ async function installOllamaMac(_rl) {
26162
26176
 
26163
26177
  `);
26164
26178
  try {
26165
- execSync23('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"', { stdio: "inherit", timeout: 6e5 });
26179
+ execSync24('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"', { stdio: "inherit", timeout: 6e5 });
26166
26180
  if (!hasCmd("brew")) {
26167
26181
  try {
26168
26182
  const brewPrefix = existsSync25("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
@@ -26195,7 +26209,7 @@ async function installOllamaMac(_rl) {
26195
26209
 
26196
26210
  `);
26197
26211
  try {
26198
- execSync23("brew install ollama", {
26212
+ execSync24("brew install ollama", {
26199
26213
  stdio: "inherit",
26200
26214
  timeout: 3e5
26201
26215
  });
@@ -26222,7 +26236,7 @@ function installOllamaWindows() {
26222
26236
 
26223
26237
  `);
26224
26238
  try {
26225
- execSync23('powershell -Command "irm https://ollama.com/install.ps1 | iex"', {
26239
+ execSync24('powershell -Command "irm https://ollama.com/install.ps1 | iex"', {
26226
26240
  stdio: "inherit",
26227
26241
  timeout: 3e5
26228
26242
  });
@@ -26303,7 +26317,7 @@ async function ensureOllamaRunning(backendUrl, rl) {
26303
26317
  }
26304
26318
  function pullModelWithAutoUpdate(tag) {
26305
26319
  try {
26306
- execSync23(`ollama pull ${tag}`, {
26320
+ execSync24(`ollama pull ${tag}`, {
26307
26321
  stdio: "inherit",
26308
26322
  timeout: 36e5
26309
26323
  // 1 hour max
@@ -26323,7 +26337,7 @@ function pullModelWithAutoUpdate(tag) {
26323
26337
 
26324
26338
  `);
26325
26339
  try {
26326
- execSync23("curl -fsSL https://ollama.com/install.sh | sh", {
26340
+ execSync24("curl -fsSL https://ollama.com/install.sh | sh", {
26327
26341
  stdio: "inherit",
26328
26342
  timeout: 3e5
26329
26343
  // 5 min max for install
@@ -26334,7 +26348,7 @@ function pullModelWithAutoUpdate(tag) {
26334
26348
  process.stdout.write(` ${c2.cyan("\u25CF")} Retrying pull of ${c2.bold(tag)}...
26335
26349
 
26336
26350
  `);
26337
- execSync23(`ollama pull ${tag}`, {
26351
+ execSync24(`ollama pull ${tag}`, {
26338
26352
  stdio: "inherit",
26339
26353
  timeout: 36e5
26340
26354
  });
@@ -26436,7 +26450,7 @@ function ensurePython3() {
26436
26450
  if (plat === "darwin") {
26437
26451
  if (hasCmd("brew")) {
26438
26452
  try {
26439
- execSync23("brew install python3", { stdio: "inherit", timeout: 3e5 });
26453
+ execSync24("brew install python3", { stdio: "inherit", timeout: 3e5 });
26440
26454
  if (hasCmd("python3")) {
26441
26455
  process.stdout.write(` ${c2.green("\u2714")} Python3 installed via Homebrew.
26442
26456
  `);
@@ -26449,7 +26463,7 @@ function ensurePython3() {
26449
26463
  for (const s of strategies) {
26450
26464
  if (hasCmd(s.check)) {
26451
26465
  try {
26452
- execSync23(s.install, { stdio: "inherit", timeout: 12e4 });
26466
+ execSync24(s.install, { stdio: "inherit", timeout: 12e4 });
26453
26467
  if (hasCmd("python3") || hasCmd("python")) {
26454
26468
  process.stdout.write(` ${c2.green("\u2714")} Python3 installed via ${s.label}.
26455
26469
  `);
@@ -26465,11 +26479,11 @@ function ensurePython3() {
26465
26479
  }
26466
26480
  function checkPythonVenv() {
26467
26481
  try {
26468
- execSync23("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
26482
+ execSync24("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
26469
26483
  return true;
26470
26484
  } catch {
26471
26485
  try {
26472
- execSync23("python -m venv --help", { stdio: "pipe", timeout: 5e3 });
26486
+ execSync24("python -m venv --help", { stdio: "pipe", timeout: 5e3 });
26473
26487
  return true;
26474
26488
  } catch {
26475
26489
  return false;
@@ -26488,7 +26502,7 @@ function ensurePythonVenv() {
26488
26502
  for (const s of strategies) {
26489
26503
  if (hasCmd(s.check)) {
26490
26504
  try {
26491
- execSync23(s.install, { stdio: "inherit", timeout: 12e4 });
26505
+ execSync24(s.install, { stdio: "inherit", timeout: 12e4 });
26492
26506
  if (checkPythonVenv()) {
26493
26507
  process.stdout.write(` ${c2.green("\u2714")} python3-venv installed via ${s.label}.
26494
26508
  `);
@@ -26924,7 +26938,7 @@ async function doSetup(config, rl) {
26924
26938
  const modelfilePath = join35(modelDir2, `Modelfile.${customName}`);
26925
26939
  writeFileSync9(modelfilePath, modelfileContent + "\n", "utf8");
26926
26940
  process.stdout.write(` ${c2.dim("Creating model...")} `);
26927
- execSync23(`ollama create ${customName} -f ${modelfilePath}`, {
26941
+ execSync24(`ollama create ${customName} -f ${modelfilePath}`, {
26928
26942
  stdio: "pipe",
26929
26943
  timeout: 12e4
26930
26944
  });
@@ -26975,7 +26989,7 @@ function isFirstRun() {
26975
26989
  function hasCmd(cmd) {
26976
26990
  try {
26977
26991
  const whichCmd = process.platform === "win32" ? `where ${cmd}` : `which ${cmd}`;
26978
- execSync23(whichCmd, { stdio: "pipe", timeout: 3e3 });
26992
+ execSync24(whichCmd, { stdio: "pipe", timeout: 3e3 });
26979
26993
  return true;
26980
26994
  } catch {
26981
26995
  return false;
@@ -27008,7 +27022,7 @@ function getVenvDir() {
27008
27022
  }
27009
27023
  function hasVenvModule() {
27010
27024
  try {
27011
- execSync23("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
27025
+ execSync24("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
27012
27026
  return true;
27013
27027
  } catch {
27014
27028
  return false;
@@ -27030,8 +27044,8 @@ function ensureVenv(log) {
27030
27044
  }
27031
27045
  try {
27032
27046
  mkdirSync9(join35(homedir10(), ".open-agents"), { recursive: true });
27033
- execSync23(`python3 -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
27034
- execSync23(`"${join35(venvDir, "bin", "pip")}" install --upgrade pip`, {
27047
+ execSync24(`python3 -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
27048
+ execSync24(`"${join35(venvDir, "bin", "pip")}" install --upgrade pip`, {
27035
27049
  stdio: "pipe",
27036
27050
  timeout: 6e4
27037
27051
  });
@@ -27044,7 +27058,7 @@ function ensureVenv(log) {
27044
27058
  }
27045
27059
  function trySudoPasswordless(cmd, timeoutMs = 12e4) {
27046
27060
  try {
27047
- execSync23(`sudo -n ${cmd}`, {
27061
+ execSync24(`sudo -n ${cmd}`, {
27048
27062
  stdio: "pipe",
27049
27063
  timeout: timeoutMs,
27050
27064
  env: { ...process.env, DEBIAN_FRONTEND: "noninteractive" }
@@ -27056,7 +27070,7 @@ function trySudoPasswordless(cmd, timeoutMs = 12e4) {
27056
27070
  }
27057
27071
  function runWithSudo(cmd, password, timeoutMs = 12e4) {
27058
27072
  try {
27059
- execSync23(`sudo -S ${cmd}`, {
27073
+ execSync24(`sudo -S ${cmd}`, {
27060
27074
  input: password + "\n",
27061
27075
  stdio: ["pipe", "pipe", "pipe"],
27062
27076
  timeout: timeoutMs,
@@ -27116,7 +27130,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
27116
27130
  } else {
27117
27131
  log("Installing tesseract-ocr...");
27118
27132
  try {
27119
- execSync23(pkg.cmd, { stdio: "pipe", timeout: 12e4 });
27133
+ execSync24(pkg.cmd, { stdio: "pipe", timeout: 12e4 });
27120
27134
  if (hasCmd("tesseract")) {
27121
27135
  log("tesseract-ocr installed successfully.");
27122
27136
  } else {
@@ -27188,7 +27202,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
27188
27202
  } else {
27189
27203
  log(`Installing ${dep.label}...`);
27190
27204
  try {
27191
- execSync23(pkg.cmd, { stdio: "pipe", timeout: 12e4 });
27205
+ execSync24(pkg.cmd, { stdio: "pipe", timeout: 12e4 });
27192
27206
  if (hasCmd(dep.binary)) {
27193
27207
  log(`${dep.label} installed successfully.`);
27194
27208
  } else {
@@ -27219,7 +27233,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
27219
27233
  const venvCmds = {
27220
27234
  apt: () => {
27221
27235
  try {
27222
- const pyVer = execSync23(`python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).trim();
27236
+ const pyVer = execSync24(`python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).trim();
27223
27237
  return `apt-get install -y python3-venv python${pyVer}-venv`;
27224
27238
  } catch {
27225
27239
  return "apt-get install -y python3-venv";
@@ -27247,12 +27261,12 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
27247
27261
  const venvPip = join35(venvBin, "pip");
27248
27262
  log("Installing moondream-station in ~/.open-agents/venv...");
27249
27263
  try {
27250
- execSync23(`"${venvPip}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
27264
+ execSync24(`"${venvPip}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
27251
27265
  if (existsSync25(venvMoondream)) {
27252
27266
  log("moondream-station installed successfully.");
27253
27267
  } else {
27254
27268
  try {
27255
- const check = execSync23(`"${venvPip}" show moondream-station`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 });
27269
+ const check = execSync24(`"${venvPip}" show moondream-station`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 });
27256
27270
  if (check.includes("moondream")) {
27257
27271
  log("moondream-station package installed.");
27258
27272
  }
@@ -27269,7 +27283,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
27269
27283
  const venvPip2 = join35(venvBin, "pip");
27270
27284
  let ocrStackInstalled = false;
27271
27285
  try {
27272
- execSync23(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
27286
+ execSync24(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
27273
27287
  ocrStackInstalled = true;
27274
27288
  } catch {
27275
27289
  }
@@ -27277,9 +27291,9 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
27277
27291
  const ocrPackages = "pytesseract Pillow opencv-python-headless numpy";
27278
27292
  log("Installing OCR Python stack (pytesseract, OpenCV, Pillow, numpy)...");
27279
27293
  try {
27280
- execSync23(`"${venvPip2}" install ${ocrPackages}`, { stdio: "pipe", timeout: 3e5 });
27294
+ execSync24(`"${venvPip2}" install ${ocrPackages}`, { stdio: "pipe", timeout: 3e5 });
27281
27295
  try {
27282
- execSync23(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
27296
+ execSync24(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
27283
27297
  log("OCR Python stack installed successfully.");
27284
27298
  } catch {
27285
27299
  log("OCR Python stack install completed but import verification failed.");
@@ -27313,7 +27327,7 @@ function ensureCloudflaredBackground(onInfo) {
27313
27327
  const archMap = { x64: "amd64", arm64: "arm64", arm: "arm" };
27314
27328
  const cfArch = archMap[arch] ?? "amd64";
27315
27329
  try {
27316
- execSync23(`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 });
27330
+ 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 });
27317
27331
  if (!process.env.PATH?.includes(`${homedir10()}/.local/bin`)) {
27318
27332
  process.env.PATH = `${homedir10()}/.local/bin:${process.env.PATH}`;
27319
27333
  }
@@ -27324,7 +27338,7 @@ function ensureCloudflaredBackground(onInfo) {
27324
27338
  } catch {
27325
27339
  }
27326
27340
  try {
27327
- execSync23(`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 });
27341
+ 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 });
27328
27342
  if (hasCmd("cloudflared")) {
27329
27343
  log("cloudflared installed.");
27330
27344
  return true;
@@ -27333,7 +27347,7 @@ function ensureCloudflaredBackground(onInfo) {
27333
27347
  }
27334
27348
  } else if (os === "darwin") {
27335
27349
  try {
27336
- execSync23("brew install cloudflared", { stdio: "pipe", timeout: 12e4 });
27350
+ execSync24("brew install cloudflared", { stdio: "pipe", timeout: 12e4 });
27337
27351
  if (hasCmd("cloudflared")) {
27338
27352
  log("cloudflared installed via Homebrew.");
27339
27353
  return true;
@@ -27383,7 +27397,7 @@ function createExpandedVariant(baseModel, specs, sizeGB) {
27383
27397
  mkdirSync9(modelDir2, { recursive: true });
27384
27398
  const modelfilePath = join35(modelDir2, `Modelfile.${customName}`);
27385
27399
  writeFileSync9(modelfilePath, modelfileContent + "\n", "utf8");
27386
- execSync23(`ollama create ${customName} -f ${modelfilePath}`, {
27400
+ execSync24(`ollama create ${customName} -f ${modelfilePath}`, {
27387
27401
  stdio: "pipe",
27388
27402
  timeout: 12e4
27389
27403
  });
@@ -28909,7 +28923,7 @@ var init_commands = __esm({
28909
28923
  // packages/cli/dist/tui/project-context.js
28910
28924
  import { existsSync as existsSync26, readFileSync as readFileSync17, readdirSync as readdirSync8 } from "node:fs";
28911
28925
  import { join as join36, basename as basename10 } from "node:path";
28912
- import { execSync as execSync24 } from "node:child_process";
28926
+ import { execSync as execSync25 } from "node:child_process";
28913
28927
  import { homedir as homedir11, platform as platform2, release } from "node:os";
28914
28928
  function getModelTier(modelName) {
28915
28929
  const m = modelName.toLowerCase();
@@ -28955,19 +28969,19 @@ function loadProjectMap(repoRoot) {
28955
28969
  }
28956
28970
  function getGitInfo(repoRoot) {
28957
28971
  try {
28958
- execSync24("git rev-parse --is-inside-work-tree", { cwd: repoRoot, stdio: "pipe" });
28972
+ execSync25("git rev-parse --is-inside-work-tree", { cwd: repoRoot, stdio: "pipe" });
28959
28973
  } catch {
28960
28974
  return "";
28961
28975
  }
28962
28976
  const lines = [];
28963
28977
  try {
28964
- const branch = execSync24("git branch --show-current", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
28978
+ const branch = execSync25("git branch --show-current", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
28965
28979
  if (branch)
28966
28980
  lines.push(`Branch: ${branch}`);
28967
28981
  } catch {
28968
28982
  }
28969
28983
  try {
28970
- const status = execSync24("git status --porcelain", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
28984
+ const status = execSync25("git status --porcelain", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
28971
28985
  if (status) {
28972
28986
  const changed = status.split("\n").length;
28973
28987
  lines.push(`Working tree: ${changed} changed file(s)`);
@@ -28977,7 +28991,7 @@ function getGitInfo(repoRoot) {
28977
28991
  } catch {
28978
28992
  }
28979
28993
  try {
28980
- const log = execSync24("git log --oneline -5 --no-decorate", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
28994
+ const log = execSync25("git log --oneline -5 --no-decorate", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
28981
28995
  if (log)
28982
28996
  lines.push(`Recent commits:
28983
28997
  ${log}`);
@@ -30394,7 +30408,7 @@ var init_carousel_descriptors = __esm({
30394
30408
  import { existsSync as existsSync28, mkdirSync as mkdirSync11, writeFileSync as writeFileSync11, readFileSync as readFileSync19, unlinkSync as unlinkSync4 } from "node:fs";
30395
30409
  import { join as join38 } from "node:path";
30396
30410
  import { homedir as homedir12, tmpdir as tmpdir6, platform as platform3 } from "node:os";
30397
- import { execSync as execSync25, spawn as nodeSpawn } from "node:child_process";
30411
+ import { execSync as execSync26, spawn as nodeSpawn } from "node:child_process";
30398
30412
  import { createRequire } from "node:module";
30399
30413
  function voiceDir() {
30400
30414
  return join38(homedir12(), ".open-agents", "voice");
@@ -31221,7 +31235,7 @@ var init_voice = __esm({
31221
31235
  }
31222
31236
  for (const player of ["paplay", "pw-play", "aplay"]) {
31223
31237
  try {
31224
- execSync25(`which ${player}`, { stdio: "pipe" });
31238
+ execSync26(`which ${player}`, { stdio: "pipe" });
31225
31239
  return [player, path];
31226
31240
  } catch {
31227
31241
  }
@@ -31277,7 +31291,7 @@ var init_voice = __esm({
31277
31291
  }
31278
31292
  renderInfo("Installing ONNX runtime for voice synthesis...");
31279
31293
  try {
31280
- execSync25("npm install --no-audit --no-fund", {
31294
+ execSync26("npm install --no-audit --no-fund", {
31281
31295
  cwd: voiceDir(),
31282
31296
  stdio: "pipe",
31283
31297
  timeout: 12e4
@@ -31298,7 +31312,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
31298
31312
  }
31299
31313
  renderInfo("Installing phonemizer for voice synthesis...");
31300
31314
  try {
31301
- execSync25("npm install --no-audit --no-fund", {
31315
+ execSync26("npm install --no-audit --no-fund", {
31302
31316
  cwd: voiceDir(),
31303
31317
  stdio: "pipe",
31304
31318
  timeout: 12e4
@@ -32352,7 +32366,7 @@ var init_edit_history = __esm({
32352
32366
  // packages/cli/dist/tui/dream-engine.js
32353
32367
  import { mkdirSync as mkdirSync13, writeFileSync as writeFileSync12, readFileSync as readFileSync20, existsSync as existsSync29, cpSync, rmSync, readdirSync as readdirSync10 } from "node:fs";
32354
32368
  import { join as join40, basename as basename12 } from "node:path";
32355
- import { execSync as execSync26 } from "node:child_process";
32369
+ import { execSync as execSync27 } from "node:child_process";
32356
32370
  function loadAutoresearchMemory(repoRoot) {
32357
32371
  const memoryPath = join40(repoRoot, ".oa", "memory", "autoresearch.json");
32358
32372
  if (!existsSync29(memoryPath))
@@ -32746,7 +32760,7 @@ var init_dream_engine = __esm({
32746
32760
  }
32747
32761
  }
32748
32762
  try {
32749
- const output = execSync26(cmd, {
32763
+ const output = execSync27(cmd, {
32750
32764
  cwd: this.repoRoot,
32751
32765
  timeout: 3e4,
32752
32766
  encoding: "utf-8",
@@ -33523,17 +33537,17 @@ ${summaryResult}
33523
33537
  try {
33524
33538
  mkdirSync13(checkpointDir, { recursive: true });
33525
33539
  try {
33526
- const gitStatus = execSync26("git status --porcelain", {
33540
+ const gitStatus = execSync27("git status --porcelain", {
33527
33541
  cwd: this.repoRoot,
33528
33542
  encoding: "utf-8",
33529
33543
  timeout: 1e4
33530
33544
  });
33531
- const gitDiff = execSync26("git diff", {
33545
+ const gitDiff = execSync27("git diff", {
33532
33546
  cwd: this.repoRoot,
33533
33547
  encoding: "utf-8",
33534
33548
  timeout: 1e4
33535
33549
  });
33536
- const gitHash = execSync26("git rev-parse HEAD 2>/dev/null || echo 'no-git'", {
33550
+ const gitHash = execSync27("git rev-parse HEAD 2>/dev/null || echo 'no-git'", {
33537
33551
  cwd: this.repoRoot,
33538
33552
  encoding: "utf-8",
33539
33553
  timeout: 5e3
@@ -38680,6 +38694,26 @@ async function startInteractive(config, repoPath) {
38680
38694
  }
38681
38695
  })).catch(() => {
38682
38696
  });
38697
+ if (!isResumed) {
38698
+ checkForUpdate(version).then((updateInfo) => {
38699
+ if (updateInfo) {
38700
+ const writeMsg = () => {
38701
+ if (statusBar?.isActive)
38702
+ statusBar.beginContentWrite();
38703
+ renderWarning(`Update available: v${updateInfo.currentVersion} \u2192 v${c2.bold(c2.green(updateInfo.latestVersion))}`);
38704
+ renderInfo(`Run /update to install now, or it will auto-install after your next task.`);
38705
+ if (statusBar?.isActive)
38706
+ statusBar.endContentWrite();
38707
+ };
38708
+ writeMsg();
38709
+ const updateMode = savedSettings.updateMode ?? "auto";
38710
+ if (updateMode !== "manual") {
38711
+ performSilentUpdate();
38712
+ }
38713
+ }
38714
+ }).catch(() => {
38715
+ });
38716
+ }
38683
38717
  const voiceEngine = new VoiceEngine();
38684
38718
  let voiceSession = null;
38685
38719
  let exposeGateway = null;