open-agents-ai 0.187.141 → 0.187.143
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.
- package/dist/index.js +713 -482
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -245752,9 +245752,9 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
|
|
|
245752
245752
|
* what was previously computed. */
|
|
245753
245753
|
async loadSessionInfo() {
|
|
245754
245754
|
try {
|
|
245755
|
-
const { readFileSync: readFileSync57, existsSync:
|
|
245755
|
+
const { readFileSync: readFileSync57, existsSync: existsSync73 } = await import("node:fs");
|
|
245756
245756
|
const sessionPath = join24(this.cwd, ".oa", "rlm", "session.json");
|
|
245757
|
-
if (!
|
|
245757
|
+
if (!existsSync73(sessionPath))
|
|
245758
245758
|
return null;
|
|
245759
245759
|
return JSON.parse(readFileSync57(sessionPath, "utf8"));
|
|
245760
245760
|
} catch {
|
|
@@ -246320,10 +246320,10 @@ ${issues.map((i2) => ` - ${i2}`).join("\n")}` : " No issues found."),
|
|
|
246320
246320
|
* Optionally filter by task type for phase-aware context (FSM paper insight).
|
|
246321
246321
|
*/
|
|
246322
246322
|
getTopMemoriesSync(k = 5, taskType) {
|
|
246323
|
-
const { readFileSync: readFileSync57, existsSync:
|
|
246323
|
+
const { readFileSync: readFileSync57, existsSync: existsSync73 } = __require("node:fs");
|
|
246324
246324
|
const metaDir = join25(this.cwd, ".oa", "memory", "metabolism");
|
|
246325
246325
|
const storeFile = join25(metaDir, "store.json");
|
|
246326
|
-
if (!
|
|
246326
|
+
if (!existsSync73(storeFile))
|
|
246327
246327
|
return "";
|
|
246328
246328
|
let store2 = [];
|
|
246329
246329
|
try {
|
|
@@ -246349,10 +246349,10 @@ ${issues.map((i2) => ` - ${i2}`).join("\n")}` : " No issues found."),
|
|
|
246349
246349
|
/** Update memory scores based on task outcome. Called after task completion.
|
|
246350
246350
|
* Memories used in successful tasks get boosted. Memories present during failures get decayed. */
|
|
246351
246351
|
updateFromOutcomeSync(surfacedMemoryText, succeeded) {
|
|
246352
|
-
const { readFileSync: readFileSync57, writeFileSync: writeFileSync38, existsSync:
|
|
246352
|
+
const { readFileSync: readFileSync57, writeFileSync: writeFileSync38, existsSync: existsSync73, mkdirSync: mkdirSync41 } = __require("node:fs");
|
|
246353
246353
|
const metaDir = join25(this.cwd, ".oa", "memory", "metabolism");
|
|
246354
246354
|
const storeFile = join25(metaDir, "store.json");
|
|
246355
|
-
if (!
|
|
246355
|
+
if (!existsSync73(storeFile))
|
|
246356
246356
|
return;
|
|
246357
246357
|
let store2 = [];
|
|
246358
246358
|
try {
|
|
@@ -246803,9 +246803,9 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
246803
246803
|
// Per EvoSkill (arXiv:2603.02766): retrieve relevant strategies from archive.
|
|
246804
246804
|
/** Retrieve top-K strategies for context injection. Returns "" if none. */
|
|
246805
246805
|
getRelevantStrategiesSync(k = 3, taskType) {
|
|
246806
|
-
const { readFileSync: readFileSync57, existsSync:
|
|
246806
|
+
const { readFileSync: readFileSync57, existsSync: existsSync73 } = __require("node:fs");
|
|
246807
246807
|
const archiveFile = join27(this.cwd, ".oa", "arche", "variants.json");
|
|
246808
|
-
if (!
|
|
246808
|
+
if (!existsSync73(archiveFile))
|
|
246809
246809
|
return "";
|
|
246810
246810
|
let variants = [];
|
|
246811
246811
|
try {
|
|
@@ -246827,12 +246827,12 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
246827
246827
|
}
|
|
246828
246828
|
/** Archive a strategy variant synchronously (for task completion path) */
|
|
246829
246829
|
archiveVariantSync(strategy, outcome, tags = []) {
|
|
246830
|
-
const { readFileSync: readFileSync57, writeFileSync: writeFileSync38, existsSync:
|
|
246830
|
+
const { readFileSync: readFileSync57, writeFileSync: writeFileSync38, existsSync: existsSync73, mkdirSync: mkdirSync41 } = __require("node:fs");
|
|
246831
246831
|
const dir = join27(this.cwd, ".oa", "arche");
|
|
246832
246832
|
const archiveFile = join27(dir, "variants.json");
|
|
246833
246833
|
let variants = [];
|
|
246834
246834
|
try {
|
|
246835
|
-
if (
|
|
246835
|
+
if (existsSync73(archiveFile))
|
|
246836
246836
|
variants = JSON.parse(readFileSync57(archiveFile, "utf8"));
|
|
246837
246837
|
} catch {
|
|
246838
246838
|
}
|
|
@@ -247838,9 +247838,9 @@ var init_vision = __esm({
|
|
|
247838
247838
|
if (ollamaResult)
|
|
247839
247839
|
return ollamaResult;
|
|
247840
247840
|
try {
|
|
247841
|
-
const { execSync:
|
|
247841
|
+
const { execSync: execSync51 } = await import("node:child_process");
|
|
247842
247842
|
try {
|
|
247843
|
-
|
|
247843
|
+
execSync51("pip3 install --user moondream 2>/dev/null || pip install --user moondream 2>/dev/null", {
|
|
247844
247844
|
timeout: 12e4,
|
|
247845
247845
|
stdio: "pipe"
|
|
247846
247846
|
});
|
|
@@ -247853,7 +247853,7 @@ var init_vision = __esm({
|
|
|
247853
247853
|
} catch {
|
|
247854
247854
|
}
|
|
247855
247855
|
try {
|
|
247856
|
-
|
|
247856
|
+
execSync51("ollama pull moondream", { timeout: 3e5, stdio: "pipe" });
|
|
247857
247857
|
const retryOllama = await this.tryOllamaVision(buffer2, filename, action, prompt, length4, start2);
|
|
247858
247858
|
if (retryOllama)
|
|
247859
247859
|
return retryOllama;
|
|
@@ -247961,8 +247961,8 @@ Coordinates are normalized (0-1). Multiply by image width/height for pixel value
|
|
|
247961
247961
|
const errText = await res.text().catch(() => "");
|
|
247962
247962
|
if (res.status === 404 || /not found|does not exist/i.test(errText)) {
|
|
247963
247963
|
try {
|
|
247964
|
-
const { execSync:
|
|
247965
|
-
|
|
247964
|
+
const { execSync: execSync51 } = await import("node:child_process");
|
|
247965
|
+
execSync51("ollama pull moondream", { timeout: 3e5, stdio: "pipe" });
|
|
247966
247966
|
res = await fetch(`${ollamaHost}/api/generate`, {
|
|
247967
247967
|
method: "POST",
|
|
247968
247968
|
headers: { "Content-Type": "application/json" },
|
|
@@ -255443,19 +255443,46 @@ var init_sdr_scan = __esm({
|
|
|
255443
255443
|
return { success: false, output: "", error: `sdr_scan error: ${err instanceof Error ? err.message : String(err)}`, durationMs: performance.now() - start2 };
|
|
255444
255444
|
}
|
|
255445
255445
|
}
|
|
255446
|
-
/** Auto-install rtl-sdr tools when hardware is detected
|
|
255446
|
+
/** Auto-install rtl-sdr tools AND configure udev rules when hardware is detected.
|
|
255447
255447
|
* Uses system-native privilege elevation (pkexec/osascript/UAC) to trigger
|
|
255448
|
-
* the OS password dialog — no passwords stored in memory.
|
|
255448
|
+
* the OS password dialog — no passwords stored in memory.
|
|
255449
|
+
*
|
|
255450
|
+
* Full auto-setup sequence:
|
|
255451
|
+
* 1. Install rtl-sdr package (apt)
|
|
255452
|
+
* 2. Add udev rule for RTL-SDR device permissions
|
|
255453
|
+
* 3. Blacklist dvb_usb_rtl28xxu (TV driver that grabs the device)
|
|
255454
|
+
* 4. Reload udev rules and unload conflicting kernel modules
|
|
255455
|
+
*/
|
|
255449
255456
|
async ensureSdrTools() {
|
|
255450
255457
|
try {
|
|
255451
255458
|
execSync32("which rtl_test", { timeout: 3e3, stdio: "pipe" });
|
|
255452
|
-
|
|
255459
|
+
try {
|
|
255460
|
+
execSync32("timeout 2 rtl_test -t 2>&1 | grep -q 'Found'", { timeout: 5e3, stdio: "pipe" });
|
|
255461
|
+
return true;
|
|
255462
|
+
} catch {
|
|
255463
|
+
await this.fixSdrPermissions();
|
|
255464
|
+
return true;
|
|
255465
|
+
}
|
|
255453
255466
|
} catch {
|
|
255454
255467
|
}
|
|
255468
|
+
const setupScript = [
|
|
255469
|
+
// Install rtl-sdr tools
|
|
255470
|
+
"apt-get install -y rtl-sdr",
|
|
255471
|
+
// Add udev rule for device permissions (user-accessible without sudo)
|
|
255472
|
+
`echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="2838", GROUP="plugdev", MODE="0666"' > /etc/udev/rules.d/99-rtlsdr.rules`,
|
|
255473
|
+
// Blacklist the DVB-T TV driver that conflicts with SDR use
|
|
255474
|
+
'echo "blacklist dvb_usb_rtl28xxu" > /etc/modprobe.d/blacklist-rtlsdr.conf',
|
|
255475
|
+
// Reload udev and unload conflicting modules
|
|
255476
|
+
"udevadm control --reload-rules",
|
|
255477
|
+
"udevadm trigger",
|
|
255478
|
+
"rmmod dvb_usb_rtl28xxu 2>/dev/null || true",
|
|
255479
|
+
"rmmod rtl2832 2>/dev/null || true",
|
|
255480
|
+
"rmmod dvb_usb_v2 2>/dev/null || true"
|
|
255481
|
+
].join(" && ");
|
|
255455
255482
|
try {
|
|
255456
|
-
const result = await runElevated(
|
|
255483
|
+
const result = await runElevated(setupScript, {
|
|
255457
255484
|
timeout: 12e4,
|
|
255458
|
-
description: "Open Agents needs to install RTL-SDR tools
|
|
255485
|
+
description: "Open Agents needs to install RTL-SDR radio tools and configure device access"
|
|
255459
255486
|
});
|
|
255460
255487
|
if (result.success)
|
|
255461
255488
|
return true;
|
|
@@ -255468,6 +255495,13 @@ var init_sdr_scan = __esm({
|
|
|
255468
255495
|
}
|
|
255469
255496
|
return false;
|
|
255470
255497
|
}
|
|
255498
|
+
/** Fix SDR device permissions without reinstalling tools */
|
|
255499
|
+
async fixSdrPermissions() {
|
|
255500
|
+
try {
|
|
255501
|
+
await runElevated(`echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="2838", GROUP="plugdev", MODE="0666"' > /etc/udev/rules.d/99-rtlsdr.rules && echo "blacklist dvb_usb_rtl28xxu" > /etc/modprobe.d/blacklist-rtlsdr.conf && udevadm control --reload-rules && udevadm trigger && rmmod dvb_usb_rtl28xxu 2>/dev/null; rmmod rtl2832 2>/dev/null; true`, { timeout: 3e4, description: "Open Agents needs to configure RTL-SDR device permissions" });
|
|
255502
|
+
} catch {
|
|
255503
|
+
}
|
|
255504
|
+
}
|
|
255471
255505
|
async deviceInfo(start2) {
|
|
255472
255506
|
let usbDetected = false;
|
|
255473
255507
|
let usbLine = "";
|
|
@@ -255525,11 +255559,16 @@ Tools installed but rtl_test failed \u2014 device may be in use by another proce
|
|
|
255525
255559
|
mkdirSync12(captureDir, { recursive: true });
|
|
255526
255560
|
const outFile = join46(captureDir, `scan-${Date.now()}.csv`);
|
|
255527
255561
|
const gainArg = gain !== void 0 ? `-g ${gain}` : "";
|
|
255528
|
-
const cmd = `timeout ${duration +
|
|
255562
|
+
const cmd = `timeout ${duration + 15} rtl_power -f ${startFreq}:${endFreq}:10k ${gainArg} -i 1 -e ${duration}s ${outFile} 2>&1`;
|
|
255529
255563
|
try {
|
|
255530
|
-
|
|
255531
|
-
|
|
255532
|
-
|
|
255564
|
+
let output = "";
|
|
255565
|
+
try {
|
|
255566
|
+
output = execSync32(cmd, { encoding: "utf8", timeout: (duration + 20) * 1e3 });
|
|
255567
|
+
} catch (cmdErr) {
|
|
255568
|
+
output = cmdErr.stdout?.toString() || cmdErr.stderr?.toString() || "";
|
|
255569
|
+
}
|
|
255570
|
+
if (!existsSync31(outFile) || statSync13(outFile).size === 0) {
|
|
255571
|
+
return { success: false, output: output.slice(0, 300), error: "Scan produced no data. SDR device may be busy or frequency range unsupported.", durationMs: performance.now() - start2 };
|
|
255533
255572
|
}
|
|
255534
255573
|
const csv = readFileSync23(outFile, "utf8");
|
|
255535
255574
|
const lines = csv.trim().split("\n");
|
|
@@ -255856,6 +255895,195 @@ ${cleanOutput}`, durationMs: performance.now() - start2 };
|
|
|
255856
255895
|
}
|
|
255857
255896
|
});
|
|
255858
255897
|
|
|
255898
|
+
// packages/execution/dist/tools/meshtastic-tool.js
|
|
255899
|
+
import { execSync as execSync34 } from "node:child_process";
|
|
255900
|
+
import { existsSync as existsSync32 } from "node:fs";
|
|
255901
|
+
var MESH_VENV, MESH_CLI, MeshtasticTool;
|
|
255902
|
+
var init_meshtastic_tool = __esm({
|
|
255903
|
+
"packages/execution/dist/tools/meshtastic-tool.js"() {
|
|
255904
|
+
"use strict";
|
|
255905
|
+
init_system_auth();
|
|
255906
|
+
MESH_VENV = "/tmp/mesh-venv";
|
|
255907
|
+
MESH_CLI = `${MESH_VENV}/bin/meshtastic`;
|
|
255908
|
+
MeshtasticTool = class {
|
|
255909
|
+
name = "meshtastic";
|
|
255910
|
+
description = "Interact with a Meshtastic mesh network device. Actions: 'info' for device details, 'nodes' to list mesh nodes, 'send' to send a text message, 'position' for GPS coordinates, 'telemetry' for battery/signal metrics, 'channels' for channel config. Use this to communicate over long-range mesh networks, check device status, or discover other nodes in the mesh. Works with Heltec, T-Beam, RAK devices.";
|
|
255911
|
+
parameters = {
|
|
255912
|
+
type: "object",
|
|
255913
|
+
properties: {
|
|
255914
|
+
action: {
|
|
255915
|
+
type: "string",
|
|
255916
|
+
enum: ["info", "nodes", "send", "position", "telemetry", "channels"],
|
|
255917
|
+
description: "Action to perform"
|
|
255918
|
+
},
|
|
255919
|
+
message: {
|
|
255920
|
+
type: "string",
|
|
255921
|
+
description: "Text message to send (for 'send' action)"
|
|
255922
|
+
},
|
|
255923
|
+
channel: {
|
|
255924
|
+
type: "number",
|
|
255925
|
+
description: "Channel index to send on (default: 0 = primary)"
|
|
255926
|
+
},
|
|
255927
|
+
destination: {
|
|
255928
|
+
type: "string",
|
|
255929
|
+
description: "Destination node ID for direct message (default: broadcast). Use '!hexid' format."
|
|
255930
|
+
},
|
|
255931
|
+
port: {
|
|
255932
|
+
type: "string",
|
|
255933
|
+
description: "Serial port (default: auto-detect /dev/ttyACM0 or /dev/ttyUSB0)"
|
|
255934
|
+
}
|
|
255935
|
+
},
|
|
255936
|
+
required: ["action"]
|
|
255937
|
+
};
|
|
255938
|
+
async execute(args) {
|
|
255939
|
+
const action = args["action"];
|
|
255940
|
+
const start2 = performance.now();
|
|
255941
|
+
const cliReady = await this.ensureMeshtasticCli();
|
|
255942
|
+
if (!cliReady) {
|
|
255943
|
+
return { success: false, output: "", error: "Could not install meshtastic CLI. Run: pip install meshtastic", durationMs: performance.now() - start2 };
|
|
255944
|
+
}
|
|
255945
|
+
const port = args["port"] || this.findMeshtasticPort();
|
|
255946
|
+
if (!port) {
|
|
255947
|
+
return { success: false, output: "", error: "No Meshtastic device found. Connect a Meshtastic device via USB.", durationMs: performance.now() - start2 };
|
|
255948
|
+
}
|
|
255949
|
+
try {
|
|
255950
|
+
switch (action) {
|
|
255951
|
+
case "info":
|
|
255952
|
+
return this.getInfo(port, start2);
|
|
255953
|
+
case "nodes":
|
|
255954
|
+
return this.listNodes(port, start2);
|
|
255955
|
+
case "send":
|
|
255956
|
+
return this.sendMessage(port, args, start2);
|
|
255957
|
+
case "position":
|
|
255958
|
+
return this.getPosition(port, start2);
|
|
255959
|
+
case "telemetry":
|
|
255960
|
+
return this.getTelemetry(port, start2);
|
|
255961
|
+
case "channels":
|
|
255962
|
+
return this.getChannels(port, start2);
|
|
255963
|
+
default:
|
|
255964
|
+
return { success: false, output: "", error: `Unknown action: ${action}`, durationMs: performance.now() - start2 };
|
|
255965
|
+
}
|
|
255966
|
+
} catch (err) {
|
|
255967
|
+
return { success: false, output: "", error: `meshtastic error: ${err instanceof Error ? err.message : String(err)}`, durationMs: performance.now() - start2 };
|
|
255968
|
+
}
|
|
255969
|
+
}
|
|
255970
|
+
async getInfo(port, start2) {
|
|
255971
|
+
return this.runMeshCmd(port, "--info", start2, "Device info");
|
|
255972
|
+
}
|
|
255973
|
+
async listNodes(port, start2) {
|
|
255974
|
+
return this.runMeshCmd(port, "--nodes", start2, "Mesh nodes");
|
|
255975
|
+
}
|
|
255976
|
+
async sendMessage(port, args, start2) {
|
|
255977
|
+
const message2 = args["message"];
|
|
255978
|
+
if (!message2) {
|
|
255979
|
+
return { success: false, output: "", error: "Missing 'message'. Provide text to send.", durationMs: performance.now() - start2 };
|
|
255980
|
+
}
|
|
255981
|
+
const channel = args["channel"] ?? 0;
|
|
255982
|
+
const dest = args["destination"];
|
|
255983
|
+
let cmd = `--sendtext "${message2.replace(/"/g, '\\"')}" --ch-index ${channel}`;
|
|
255984
|
+
if (dest)
|
|
255985
|
+
cmd += ` --dest ${dest}`;
|
|
255986
|
+
return this.runMeshCmd(port, cmd, start2, `Sent: "${message2.slice(0, 50)}"`);
|
|
255987
|
+
}
|
|
255988
|
+
async getPosition(port, start2) {
|
|
255989
|
+
return this.runMeshCmd(port, "--info", start2, "Position", (output) => {
|
|
255990
|
+
const posMatch = output.match(/"position":\s*\{[^}]+\}/s);
|
|
255991
|
+
return posMatch ? `GPS Position:
|
|
255992
|
+
${posMatch[0]}` : "Position data not available (device may not have GPS fix)";
|
|
255993
|
+
});
|
|
255994
|
+
}
|
|
255995
|
+
async getTelemetry(port, start2) {
|
|
255996
|
+
return this.runMeshCmd(port, "--info", start2, "Telemetry", (output) => {
|
|
255997
|
+
const metricMatch = output.match(/"deviceMetrics":\s*\{[^}]+\}/s);
|
|
255998
|
+
return metricMatch ? `Device Telemetry:
|
|
255999
|
+
${metricMatch[0]}` : "Telemetry data not available";
|
|
256000
|
+
});
|
|
256001
|
+
}
|
|
256002
|
+
async getChannels(port, start2) {
|
|
256003
|
+
return this.runMeshCmd(port, "--ch-index 0 --get lora", start2, "Channel config");
|
|
256004
|
+
}
|
|
256005
|
+
// =========================================================================
|
|
256006
|
+
// Helpers
|
|
256007
|
+
// =========================================================================
|
|
256008
|
+
async runMeshCmd(port, cmdArgs, start2, label, transform) {
|
|
256009
|
+
await this.ensureSerialAccess(port);
|
|
256010
|
+
try {
|
|
256011
|
+
const output = execSync34(`${MESH_CLI} --port ${port} ${cmdArgs}`, { encoding: "utf8", timeout: 3e4, stdio: ["pipe", "pipe", "pipe"] });
|
|
256012
|
+
const result = transform ? transform(output) : output;
|
|
256013
|
+
return { success: true, output: `${label}:
|
|
256014
|
+
${result.trim()}`, durationMs: performance.now() - start2 };
|
|
256015
|
+
} catch (err) {
|
|
256016
|
+
const stderr = err.stderr?.toString() || "";
|
|
256017
|
+
const stdout = err.stdout?.toString() || "";
|
|
256018
|
+
if (stderr.includes("Permission") || stderr.includes("denied")) {
|
|
256019
|
+
try {
|
|
256020
|
+
await runElevated(`chmod 666 ${port} && usermod -a -G dialout $(whoami)`, {
|
|
256021
|
+
timeout: 3e4,
|
|
256022
|
+
description: "Open Agents needs serial port access for Meshtastic device"
|
|
256023
|
+
});
|
|
256024
|
+
const output2 = execSync34(`${MESH_CLI} --port ${port} ${cmdArgs}`, { encoding: "utf8", timeout: 3e4, stdio: ["pipe", "pipe", "pipe"] });
|
|
256025
|
+
const result2 = transform ? transform(output2) : output2;
|
|
256026
|
+
return { success: true, output: `${label}:
|
|
256027
|
+
${result2.trim()}`, durationMs: performance.now() - start2 };
|
|
256028
|
+
} catch {
|
|
256029
|
+
return { success: false, output: "", error: `Permission denied on ${port}. Run: sudo chmod 666 ${port}`, durationMs: performance.now() - start2 };
|
|
256030
|
+
}
|
|
256031
|
+
}
|
|
256032
|
+
if (stdout.includes("Connected to radio")) {
|
|
256033
|
+
const result = transform ? transform(stdout) : stdout;
|
|
256034
|
+
return { success: true, output: `${label}:
|
|
256035
|
+
${result.trim()}`, durationMs: performance.now() - start2 };
|
|
256036
|
+
}
|
|
256037
|
+
return { success: false, output: stdout.slice(0, 500), error: `${label} failed: ${stderr.slice(0, 300)}`, durationMs: performance.now() - start2 };
|
|
256038
|
+
}
|
|
256039
|
+
}
|
|
256040
|
+
/** Ensure serial port is accessible without sudo */
|
|
256041
|
+
async ensureSerialAccess(port) {
|
|
256042
|
+
try {
|
|
256043
|
+
execSync34(`test -r ${port} && test -w ${port}`, { timeout: 2e3, stdio: "pipe" });
|
|
256044
|
+
} catch {
|
|
256045
|
+
try {
|
|
256046
|
+
await runElevated(`chmod 666 ${port} && echo 'SUBSYSTEM=="tty", ATTRS{idVendor}=="303a", MODE="0666"' > /etc/udev/rules.d/99-meshtastic.rules && udevadm control --reload-rules`, { timeout: 3e4, description: "Open Agents needs serial port access for Meshtastic" });
|
|
256047
|
+
} catch {
|
|
256048
|
+
}
|
|
256049
|
+
}
|
|
256050
|
+
}
|
|
256051
|
+
findMeshtasticPort() {
|
|
256052
|
+
for (const dev of ["/dev/ttyACM0", "/dev/ttyACM1", "/dev/ttyUSB0", "/dev/ttyUSB1"]) {
|
|
256053
|
+
if (!existsSync32(dev))
|
|
256054
|
+
continue;
|
|
256055
|
+
try {
|
|
256056
|
+
const udev = execSync34(`udevadm info --query=all --name=${dev} 2>/dev/null`, { encoding: "utf8", timeout: 3e3 });
|
|
256057
|
+
if (/heltec|meshtastic|t-beam|espressif|rak|wisblock/i.test(udev)) {
|
|
256058
|
+
return dev;
|
|
256059
|
+
}
|
|
256060
|
+
} catch {
|
|
256061
|
+
}
|
|
256062
|
+
}
|
|
256063
|
+
for (const dev of ["/dev/ttyACM0", "/dev/ttyUSB0"]) {
|
|
256064
|
+
if (existsSync32(dev))
|
|
256065
|
+
return dev;
|
|
256066
|
+
}
|
|
256067
|
+
return null;
|
|
256068
|
+
}
|
|
256069
|
+
/** Auto-install meshtastic CLI into a venv */
|
|
256070
|
+
async ensureMeshtasticCli() {
|
|
256071
|
+
if (existsSync32(MESH_CLI))
|
|
256072
|
+
return true;
|
|
256073
|
+
try {
|
|
256074
|
+
execSync34(`python3 -m venv ${MESH_VENV} && ${MESH_VENV}/bin/pip install meshtastic`, {
|
|
256075
|
+
timeout: 12e4,
|
|
256076
|
+
stdio: "pipe"
|
|
256077
|
+
});
|
|
256078
|
+
return existsSync32(MESH_CLI);
|
|
256079
|
+
} catch {
|
|
256080
|
+
return false;
|
|
256081
|
+
}
|
|
256082
|
+
}
|
|
256083
|
+
};
|
|
256084
|
+
}
|
|
256085
|
+
});
|
|
256086
|
+
|
|
255859
256087
|
// packages/execution/dist/tools/full-sub-agent.js
|
|
255860
256088
|
import { spawn as spawn13, ChildProcess } from "node:child_process";
|
|
255861
256089
|
import { randomBytes as randomBytes13 } from "node:crypto";
|
|
@@ -256300,8 +256528,8 @@ var init_agent_tool = __esm({
|
|
|
256300
256528
|
});
|
|
256301
256529
|
|
|
256302
256530
|
// packages/execution/dist/tools/worktree.js
|
|
256303
|
-
import { execSync as
|
|
256304
|
-
import { existsSync as
|
|
256531
|
+
import { execSync as execSync35 } from "node:child_process";
|
|
256532
|
+
import { existsSync as existsSync33, mkdirSync as mkdirSync13, rmSync } from "node:fs";
|
|
256305
256533
|
import { join as join47, resolve as resolve30 } from "node:path";
|
|
256306
256534
|
function validateSlug(slug) {
|
|
256307
256535
|
if (!slug)
|
|
@@ -256319,7 +256547,7 @@ function flattenSlug(slug) {
|
|
|
256319
256547
|
}
|
|
256320
256548
|
function isGitRepo(cwd4) {
|
|
256321
256549
|
try {
|
|
256322
|
-
|
|
256550
|
+
execSync35("git rev-parse --is-inside-work-tree", { cwd: cwd4, stdio: "pipe" });
|
|
256323
256551
|
return true;
|
|
256324
256552
|
} catch {
|
|
256325
256553
|
return false;
|
|
@@ -256327,14 +256555,14 @@ function isGitRepo(cwd4) {
|
|
|
256327
256555
|
}
|
|
256328
256556
|
function getCurrentBranch(cwd4) {
|
|
256329
256557
|
try {
|
|
256330
|
-
return
|
|
256558
|
+
return execSync35("git rev-parse --abbrev-ref HEAD", { cwd: cwd4, stdio: "pipe" }).toString().trim();
|
|
256331
256559
|
} catch {
|
|
256332
256560
|
return void 0;
|
|
256333
256561
|
}
|
|
256334
256562
|
}
|
|
256335
256563
|
function getCurrentCommit(cwd4) {
|
|
256336
256564
|
try {
|
|
256337
|
-
return
|
|
256565
|
+
return execSync35("git rev-parse --short HEAD", { cwd: cwd4, stdio: "pipe" }).toString().trim();
|
|
256338
256566
|
} catch {
|
|
256339
256567
|
return void 0;
|
|
256340
256568
|
}
|
|
@@ -256350,7 +256578,7 @@ function createWorktree(repoRoot, slug) {
|
|
|
256350
256578
|
const worktreeBase = join47(repoRoot, ".oa", "worktrees");
|
|
256351
256579
|
const worktreePath = join47(worktreeBase, flat);
|
|
256352
256580
|
const branchName = `worktree-${flat}`;
|
|
256353
|
-
if (
|
|
256581
|
+
if (existsSync33(worktreePath)) {
|
|
256354
256582
|
const session2 = {
|
|
256355
256583
|
slug,
|
|
256356
256584
|
worktreePath: resolve30(worktreePath),
|
|
@@ -256365,13 +256593,13 @@ function createWorktree(repoRoot, slug) {
|
|
|
256365
256593
|
}
|
|
256366
256594
|
mkdirSync13(worktreeBase, { recursive: true });
|
|
256367
256595
|
try {
|
|
256368
|
-
|
|
256596
|
+
execSync35(`git worktree add "${worktreePath}" -b "${branchName}"`, {
|
|
256369
256597
|
cwd: repoRoot,
|
|
256370
256598
|
stdio: "pipe"
|
|
256371
256599
|
});
|
|
256372
256600
|
} catch (err) {
|
|
256373
256601
|
try {
|
|
256374
|
-
|
|
256602
|
+
execSync35(`git worktree add "${worktreePath}" "${branchName}"`, {
|
|
256375
256603
|
cwd: repoRoot,
|
|
256376
256604
|
stdio: "pipe"
|
|
256377
256605
|
});
|
|
@@ -256393,7 +256621,7 @@ function createWorktree(repoRoot, slug) {
|
|
|
256393
256621
|
}
|
|
256394
256622
|
function worktreeHasChanges(worktreePath) {
|
|
256395
256623
|
try {
|
|
256396
|
-
const status =
|
|
256624
|
+
const status = execSync35("git status --porcelain", {
|
|
256397
256625
|
cwd: worktreePath,
|
|
256398
256626
|
stdio: "pipe"
|
|
256399
256627
|
}).toString().trim();
|
|
@@ -256406,7 +256634,7 @@ function removeWorktree(repoRoot, slug, force = false) {
|
|
|
256406
256634
|
const flat = flattenSlug(slug);
|
|
256407
256635
|
const worktreePath = join47(repoRoot, ".oa", "worktrees", flat);
|
|
256408
256636
|
const branchName = `worktree-${flat}`;
|
|
256409
|
-
if (!
|
|
256637
|
+
if (!existsSync33(worktreePath)) {
|
|
256410
256638
|
_sessions.delete(slug);
|
|
256411
256639
|
return true;
|
|
256412
256640
|
}
|
|
@@ -256414,20 +256642,20 @@ function removeWorktree(repoRoot, slug, force = false) {
|
|
|
256414
256642
|
return "Worktree has uncommitted changes. Use force=true to discard, or commit/stash first.";
|
|
256415
256643
|
}
|
|
256416
256644
|
try {
|
|
256417
|
-
|
|
256645
|
+
execSync35(`git worktree remove "${worktreePath}" ${force ? "--force" : ""}`, {
|
|
256418
256646
|
cwd: repoRoot,
|
|
256419
256647
|
stdio: "pipe"
|
|
256420
256648
|
});
|
|
256421
256649
|
} catch (err) {
|
|
256422
256650
|
try {
|
|
256423
256651
|
rmSync(worktreePath, { recursive: true, force: true });
|
|
256424
|
-
|
|
256652
|
+
execSync35("git worktree prune", { cwd: repoRoot, stdio: "pipe" });
|
|
256425
256653
|
} catch {
|
|
256426
256654
|
return `Failed to remove worktree: ${err}`;
|
|
256427
256655
|
}
|
|
256428
256656
|
}
|
|
256429
256657
|
try {
|
|
256430
|
-
|
|
256658
|
+
execSync35(`git branch -D "${branchName}"`, { cwd: repoRoot, stdio: "pipe" });
|
|
256431
256659
|
} catch {
|
|
256432
256660
|
}
|
|
256433
256661
|
_sessions.delete(slug);
|
|
@@ -257078,13 +257306,13 @@ var init_client3 = __esm({
|
|
|
257078
257306
|
});
|
|
257079
257307
|
|
|
257080
257308
|
// packages/execution/dist/mcp/manager.js
|
|
257081
|
-
import { existsSync as
|
|
257309
|
+
import { existsSync as existsSync34, readFileSync as readFileSync24 } from "node:fs";
|
|
257082
257310
|
import { join as join48 } from "node:path";
|
|
257083
257311
|
import { homedir as homedir12 } from "node:os";
|
|
257084
257312
|
function loadMcpConfig(repoRoot) {
|
|
257085
257313
|
const servers = {};
|
|
257086
257314
|
const globalPath = join48(homedir12(), ".open-agents", "mcp.json");
|
|
257087
|
-
if (
|
|
257315
|
+
if (existsSync34(globalPath)) {
|
|
257088
257316
|
try {
|
|
257089
257317
|
const global2 = JSON.parse(readFileSync24(globalPath, "utf8"));
|
|
257090
257318
|
Object.assign(servers, global2.mcpServers ?? {});
|
|
@@ -257092,7 +257320,7 @@ function loadMcpConfig(repoRoot) {
|
|
|
257092
257320
|
}
|
|
257093
257321
|
}
|
|
257094
257322
|
const localPath = join48(repoRoot, ".oa", "mcp.json");
|
|
257095
|
-
if (
|
|
257323
|
+
if (existsSync34(localPath)) {
|
|
257096
257324
|
try {
|
|
257097
257325
|
const local = JSON.parse(readFileSync24(localPath, "utf8"));
|
|
257098
257326
|
Object.assign(servers, local.mcpServers ?? {});
|
|
@@ -257100,7 +257328,7 @@ function loadMcpConfig(repoRoot) {
|
|
|
257100
257328
|
}
|
|
257101
257329
|
}
|
|
257102
257330
|
const rootPath = join48(repoRoot, ".mcp.json");
|
|
257103
|
-
if (
|
|
257331
|
+
if (existsSync34(rootPath)) {
|
|
257104
257332
|
try {
|
|
257105
257333
|
const root = JSON.parse(readFileSync24(rootPath, "utf8"));
|
|
257106
257334
|
Object.assign(servers, root.mcpServers ?? {});
|
|
@@ -257385,17 +257613,17 @@ var init_mcp = __esm({
|
|
|
257385
257613
|
});
|
|
257386
257614
|
|
|
257387
257615
|
// packages/execution/dist/plugins/plugin-system.js
|
|
257388
|
-
import { existsSync as
|
|
257616
|
+
import { existsSync as existsSync35, readdirSync as readdirSync7, readFileSync as readFileSync25 } from "node:fs";
|
|
257389
257617
|
import { join as join49 } from "node:path";
|
|
257390
257618
|
import { homedir as homedir13 } from "node:os";
|
|
257391
257619
|
function discoverPlugins(repoRoot) {
|
|
257392
257620
|
const plugins = [];
|
|
257393
257621
|
const globalDir = join49(homedir13(), ".open-agents", "plugins");
|
|
257394
|
-
if (
|
|
257622
|
+
if (existsSync35(globalDir)) {
|
|
257395
257623
|
plugins.push(...loadPluginsFromDir(globalDir));
|
|
257396
257624
|
}
|
|
257397
257625
|
const localDir = join49(repoRoot, ".oa", "plugins");
|
|
257398
|
-
if (
|
|
257626
|
+
if (existsSync35(localDir)) {
|
|
257399
257627
|
plugins.push(...loadPluginsFromDir(localDir));
|
|
257400
257628
|
}
|
|
257401
257629
|
return plugins;
|
|
@@ -257418,7 +257646,7 @@ function loadPluginsFromDir(dir) {
|
|
|
257418
257646
|
}
|
|
257419
257647
|
function loadPlugin(pluginPath) {
|
|
257420
257648
|
const oaManifestPath = join49(pluginPath, "oa-plugin.json");
|
|
257421
|
-
if (
|
|
257649
|
+
if (existsSync35(oaManifestPath)) {
|
|
257422
257650
|
try {
|
|
257423
257651
|
const manifest = JSON.parse(readFileSync25(oaManifestPath, "utf8"));
|
|
257424
257652
|
if (!manifest.name || !manifest.oa) {
|
|
@@ -257430,7 +257658,7 @@ function loadPlugin(pluginPath) {
|
|
|
257430
257658
|
}
|
|
257431
257659
|
}
|
|
257432
257660
|
const pkgPath = join49(pluginPath, "package.json");
|
|
257433
|
-
if (
|
|
257661
|
+
if (existsSync35(pkgPath)) {
|
|
257434
257662
|
try {
|
|
257435
257663
|
const pkg = JSON.parse(readFileSync25(pkgPath, "utf8"));
|
|
257436
257664
|
if (pkg.oa) {
|
|
@@ -257491,7 +257719,7 @@ var init_plugin_system = __esm({
|
|
|
257491
257719
|
if (skills) {
|
|
257492
257720
|
for (const relPath of skills) {
|
|
257493
257721
|
const absPath = join49(plugin.rootPath, relPath);
|
|
257494
|
-
if (
|
|
257722
|
+
if (existsSync35(absPath))
|
|
257495
257723
|
paths.push(absPath);
|
|
257496
257724
|
}
|
|
257497
257725
|
}
|
|
@@ -257545,9 +257773,9 @@ var init_plugin_system = __esm({
|
|
|
257545
257773
|
});
|
|
257546
257774
|
|
|
257547
257775
|
// packages/execution/dist/tools/notebook-edit.js
|
|
257548
|
-
import { readFileSync as readFileSync26, writeFileSync as writeFileSync12, existsSync as
|
|
257776
|
+
import { readFileSync as readFileSync26, writeFileSync as writeFileSync12, existsSync as existsSync36 } from "node:fs";
|
|
257549
257777
|
function readNotebook(path5) {
|
|
257550
|
-
if (!
|
|
257778
|
+
if (!existsSync36(path5))
|
|
257551
257779
|
return `File not found: ${path5}`;
|
|
257552
257780
|
if (!path5.endsWith(".ipynb"))
|
|
257553
257781
|
return `Not a notebook file (must be .ipynb): ${path5}`;
|
|
@@ -257704,7 +257932,7 @@ var init_notebook_edit = __esm({
|
|
|
257704
257932
|
});
|
|
257705
257933
|
|
|
257706
257934
|
// packages/execution/dist/tools/environment-snapshot.js
|
|
257707
|
-
import { execSync as
|
|
257935
|
+
import { execSync as execSync36 } from "node:child_process";
|
|
257708
257936
|
import { cpus, totalmem, freemem, hostname as hostname2, platform, arch, uptime } from "node:os";
|
|
257709
257937
|
import { statfsSync } from "node:fs";
|
|
257710
257938
|
function collectSnapshot(workingDir) {
|
|
@@ -257722,7 +257950,7 @@ function collectSnapshot(workingDir) {
|
|
|
257722
257950
|
}
|
|
257723
257951
|
let gpu = void 0;
|
|
257724
257952
|
try {
|
|
257725
|
-
const nvOut =
|
|
257953
|
+
const nvOut = execSync36("nvidia-smi --query-gpu=name,memory.total,memory.used,temperature.gpu --format=csv,noheader,nounits", { encoding: "utf-8", timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] }).trim().split(",").map((s2) => s2.trim());
|
|
257726
257954
|
if (nvOut.length >= 3) {
|
|
257727
257955
|
gpu = {
|
|
257728
257956
|
name: nvOut[0],
|
|
@@ -257737,12 +257965,12 @@ function collectSnapshot(workingDir) {
|
|
|
257737
257965
|
let battery = void 0;
|
|
257738
257966
|
try {
|
|
257739
257967
|
if (platform() === "linux") {
|
|
257740
|
-
const cap =
|
|
257741
|
-
const status =
|
|
257968
|
+
const cap = execSync36("cat /sys/class/power_supply/BAT0/capacity 2>/dev/null", { encoding: "utf-8", timeout: 1e3 }).trim();
|
|
257969
|
+
const status = execSync36("cat /sys/class/power_supply/BAT0/status 2>/dev/null", { encoding: "utf-8", timeout: 1e3 }).trim();
|
|
257742
257970
|
if (cap)
|
|
257743
257971
|
battery = { percent: parseInt(cap, 10), charging: status === "Charging" || status === "Full" };
|
|
257744
257972
|
} else if (platform() === "darwin") {
|
|
257745
|
-
const pmOut =
|
|
257973
|
+
const pmOut = execSync36("pmset -g batt", { encoding: "utf-8", timeout: 2e3 });
|
|
257746
257974
|
const match = pmOut.match(/(\d+)%;\s*(charging|discharging|charged)/i);
|
|
257747
257975
|
if (match)
|
|
257748
257976
|
battery = { percent: parseInt(match[1], 10), charging: match[2].toLowerCase() !== "discharging" };
|
|
@@ -257763,8 +257991,8 @@ function collectSnapshot(workingDir) {
|
|
|
257763
257991
|
}
|
|
257764
257992
|
let processInfo = { total: 0, nodeCount: 0, oaSpawned: 0, topCpu: [] };
|
|
257765
257993
|
try {
|
|
257766
|
-
const psLines =
|
|
257767
|
-
const total = parseInt(
|
|
257994
|
+
const psLines = execSync36("ps -eo pid,%cpu,args --sort=-%cpu --no-headers 2>/dev/null | head -50", { encoding: "utf-8", timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] }).trim().split("\n");
|
|
257995
|
+
const total = parseInt(execSync36("ps aux | wc -l", { encoding: "utf-8", timeout: 2e3 }).trim(), 10);
|
|
257768
257996
|
let nodeCount = 0;
|
|
257769
257997
|
let oaSpawned = 0;
|
|
257770
257998
|
const topCpu = [];
|
|
@@ -257845,8 +258073,8 @@ var init_environment_snapshot = __esm({
|
|
|
257845
258073
|
});
|
|
257846
258074
|
|
|
257847
258075
|
// packages/execution/dist/tools/video-understand.js
|
|
257848
|
-
import { execSync as
|
|
257849
|
-
import { existsSync as
|
|
258076
|
+
import { execSync as execSync37 } from "node:child_process";
|
|
258077
|
+
import { existsSync as existsSync37, mkdirSync as mkdirSync14, writeFileSync as writeFileSync13, readFileSync as readFileSync27, readdirSync as readdirSync8, unlinkSync as unlinkSync8 } from "node:fs";
|
|
257850
258078
|
import { join as join50, basename as basename11 } from "node:path";
|
|
257851
258079
|
import { createHash as createHash2 } from "node:crypto";
|
|
257852
258080
|
function isYouTubeUrl2(url) {
|
|
@@ -257854,11 +258082,11 @@ function isYouTubeUrl2(url) {
|
|
|
257854
258082
|
}
|
|
257855
258083
|
function ensureYtDlp2() {
|
|
257856
258084
|
try {
|
|
257857
|
-
|
|
258085
|
+
execSync37("yt-dlp --version", { timeout: 5e3, stdio: "pipe" });
|
|
257858
258086
|
return true;
|
|
257859
258087
|
} catch {
|
|
257860
258088
|
try {
|
|
257861
|
-
|
|
258089
|
+
execSync37("pip3 install --break-system-packages yt-dlp 2>/dev/null || pip3 install --user yt-dlp 2>/dev/null", { timeout: 6e4, stdio: "pipe" });
|
|
257862
258090
|
return true;
|
|
257863
258091
|
} catch {
|
|
257864
258092
|
return false;
|
|
@@ -257867,7 +258095,7 @@ function ensureYtDlp2() {
|
|
|
257867
258095
|
}
|
|
257868
258096
|
function ensureFfmpeg() {
|
|
257869
258097
|
try {
|
|
257870
|
-
|
|
258098
|
+
execSync37("ffmpeg -version", { timeout: 3e3, stdio: "pipe" });
|
|
257871
258099
|
return true;
|
|
257872
258100
|
} catch {
|
|
257873
258101
|
return false;
|
|
@@ -257947,32 +258175,32 @@ var init_video_understand = __esm({
|
|
|
257947
258175
|
return { success: false, output: "", error: "yt-dlp required but not available. Install: pip3 install yt-dlp", durationMs: performance.now() - start2 };
|
|
257948
258176
|
}
|
|
257949
258177
|
try {
|
|
257950
|
-
|
|
258178
|
+
execSync37(`yt-dlp -f "worst[ext=mp4]" -o "${join50(tmpDir, "video.%(ext)s")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
|
|
257951
258179
|
} catch {
|
|
257952
|
-
|
|
258180
|
+
execSync37(`yt-dlp -f worst -o "${join50(tmpDir, "video.%(ext)s")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
|
|
257953
258181
|
}
|
|
257954
|
-
|
|
258182
|
+
execSync37(`yt-dlp -x --audio-format mp3 --audio-quality 5 -o "${join50(tmpDir, "audio.%(ext)s")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
|
|
257955
258183
|
try {
|
|
257956
|
-
title =
|
|
258184
|
+
title = execSync37(`yt-dlp --get-title "${url}"`, { encoding: "utf-8", timeout: 15e3, stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
257957
258185
|
} catch {
|
|
257958
258186
|
}
|
|
257959
258187
|
} else {
|
|
257960
|
-
|
|
257961
|
-
|
|
258188
|
+
execSync37(`curl -sL -o "${join50(tmpDir, "video.mp4")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
|
|
258189
|
+
execSync37(`ffmpeg -i "${join50(tmpDir, "video.mp4")}" -vn -acodec libmp3lame -q:a 5 "${join50(tmpDir, "audio.mp3")}" -y`, { timeout: 12e4, stdio: "pipe" });
|
|
257962
258190
|
}
|
|
257963
258191
|
videoPath = readdirSync8(tmpDir).find((f2) => f2.startsWith("video")) ? join50(tmpDir, readdirSync8(tmpDir).find((f2) => f2.startsWith("video"))) : join50(tmpDir, "video.mp4");
|
|
257964
258192
|
audioPath = readdirSync8(tmpDir).find((f2) => f2.startsWith("audio")) ? join50(tmpDir, readdirSync8(tmpDir).find((f2) => f2.startsWith("audio"))) : join50(tmpDir, "audio.mp3");
|
|
257965
258193
|
} else {
|
|
257966
258194
|
videoPath = localPath;
|
|
257967
258195
|
audioPath = join50(tmpDir, "audio.mp3");
|
|
257968
|
-
|
|
258196
|
+
execSync37(`ffmpeg -i "${videoPath}" -vn -acodec libmp3lame -q:a 5 "${audioPath}" -y`, { timeout: 12e4, stdio: "pipe" });
|
|
257969
258197
|
}
|
|
257970
258198
|
let segments = [];
|
|
257971
258199
|
let language = "en";
|
|
257972
258200
|
let duration = 0;
|
|
257973
258201
|
try {
|
|
257974
258202
|
const jsonOut = join50(tmpDir, "transcript.json");
|
|
257975
|
-
|
|
258203
|
+
execSync37(`transcribe-cli transcribe "${audioPath}" --model ${whisperModel} --format json -o "${tmpDir}"`, { timeout: 6e5, stdio: "pipe" });
|
|
257976
258204
|
const jsonFile = readdirSync8(tmpDir).find((f2) => f2.endsWith(".json") && f2 !== "result.json");
|
|
257977
258205
|
if (jsonFile) {
|
|
257978
258206
|
const data = JSON.parse(readFileSync27(join50(tmpDir, jsonFile), "utf-8"));
|
|
@@ -257989,13 +258217,13 @@ var init_video_understand = __esm({
|
|
|
257989
258217
|
segments = [];
|
|
257990
258218
|
}
|
|
257991
258219
|
let frames = [];
|
|
257992
|
-
if (!skipFrames && ensureFfmpeg() &&
|
|
258220
|
+
if (!skipFrames && ensureFfmpeg() && existsSync37(videoPath)) {
|
|
257993
258221
|
const framesDir = join50(tmpDir, "frames");
|
|
257994
258222
|
mkdirSync14(framesDir, { recursive: true });
|
|
257995
258223
|
const fps = 25;
|
|
257996
258224
|
const intervalFrames = Math.max(1, frameInterval * fps);
|
|
257997
258225
|
try {
|
|
257998
|
-
|
|
258226
|
+
execSync37(`ffmpeg -i "${videoPath}" -vf "select='gt(scene\\,${sceneThreshold})+not(mod(n\\,${intervalFrames}))',showinfo" -vsync vfr "${join50(framesDir, "frame_%04d.jpg")}" -y`, { timeout: 3e5, stdio: "pipe" });
|
|
257999
258227
|
} catch {
|
|
258000
258228
|
}
|
|
258001
258229
|
const frameFiles = readdirSync8(framesDir).filter((f2) => f2.endsWith(".jpg")).sort();
|
|
@@ -258128,7 +258356,7 @@ Topic: ${segments.slice(0, 5).map((s2) => s2.text).join(" ").slice(0, 300)}`,
|
|
|
258128
258356
|
}
|
|
258129
258357
|
}
|
|
258130
258358
|
try {
|
|
258131
|
-
|
|
258359
|
+
execSync37(`rm -rf "${tmpDir}"`, { timeout: 1e4, stdio: "pipe" });
|
|
258132
258360
|
} catch {
|
|
258133
258361
|
}
|
|
258134
258362
|
return {
|
|
@@ -258172,11 +258400,11 @@ var init_venv_paths = __esm({
|
|
|
258172
258400
|
});
|
|
258173
258401
|
|
|
258174
258402
|
// packages/execution/dist/tools/fortemi-bridge.js
|
|
258175
|
-
import { existsSync as
|
|
258403
|
+
import { existsSync as existsSync38, readFileSync as readFileSync28 } from "node:fs";
|
|
258176
258404
|
import { join as join52 } from "node:path";
|
|
258177
258405
|
function loadBridgeState(repoRoot) {
|
|
258178
258406
|
const bridgeFile = join52(repoRoot, ".oa", "fortemi-bridge.json");
|
|
258179
|
-
if (!
|
|
258407
|
+
if (!existsSync38(bridgeFile))
|
|
258180
258408
|
return null;
|
|
258181
258409
|
try {
|
|
258182
258410
|
return JSON.parse(readFileSync28(bridgeFile, "utf8"));
|
|
@@ -258427,7 +258655,7 @@ var init_gitWorktree = __esm({
|
|
|
258427
258655
|
});
|
|
258428
258656
|
|
|
258429
258657
|
// packages/execution/dist/patchApplier.js
|
|
258430
|
-
import { readFileSync as readFileSync29, writeFileSync as writeFileSync14, existsSync as
|
|
258658
|
+
import { readFileSync as readFileSync29, writeFileSync as writeFileSync14, existsSync as existsSync39, mkdirSync as mkdirSync15 } from "node:fs";
|
|
258431
258659
|
import { dirname as dirname14 } from "node:path";
|
|
258432
258660
|
import { spawn as spawn16 } from "node:child_process";
|
|
258433
258661
|
async function applyPatch(patch) {
|
|
@@ -258454,7 +258682,7 @@ function applyRewrite(patch) {
|
|
|
258454
258682
|
writeFileSync14(patch.filePath, patch.newContent, "utf-8");
|
|
258455
258683
|
}
|
|
258456
258684
|
function applyNewFile(patch) {
|
|
258457
|
-
if (
|
|
258685
|
+
if (existsSync39(patch.filePath)) {
|
|
258458
258686
|
throw new Error(`Cannot create new file: "${patch.filePath}" already exists.`);
|
|
258459
258687
|
}
|
|
258460
258688
|
mkdirSync15(dirname14(patch.filePath), { recursive: true });
|
|
@@ -258815,7 +259043,7 @@ var init_buildRunner = __esm({
|
|
|
258815
259043
|
});
|
|
258816
259044
|
|
|
258817
259045
|
// packages/execution/dist/constraints.js
|
|
258818
|
-
import { existsSync as
|
|
259046
|
+
import { existsSync as existsSync40, readFileSync as readFileSync30, writeFileSync as writeFileSync15, mkdirSync as mkdirSync16 } from "node:fs";
|
|
258819
259047
|
import { join as join53 } from "node:path";
|
|
258820
259048
|
import { homedir as homedir14 } from "node:os";
|
|
258821
259049
|
function loadConstraints(projectRoot) {
|
|
@@ -258824,7 +259052,7 @@ function loadConstraints(projectRoot) {
|
|
|
258824
259052
|
}
|
|
258825
259053
|
function loadFile(path5) {
|
|
258826
259054
|
try {
|
|
258827
|
-
if (!
|
|
259055
|
+
if (!existsSync40(path5))
|
|
258828
259056
|
return [];
|
|
258829
259057
|
const data = JSON.parse(readFileSync30(path5, "utf-8"));
|
|
258830
259058
|
return data.constraints || [];
|
|
@@ -258841,7 +259069,7 @@ function addProjectConstraint(projectRoot, constraint) {
|
|
|
258841
259069
|
const path5 = join53(projectRoot, ".oa", "constraints.json");
|
|
258842
259070
|
let data = { version: 1, constraints: [] };
|
|
258843
259071
|
try {
|
|
258844
|
-
if (
|
|
259072
|
+
if (existsSync40(path5))
|
|
258845
259073
|
data = JSON.parse(readFileSync30(path5, "utf-8"));
|
|
258846
259074
|
} catch {
|
|
258847
259075
|
}
|
|
@@ -259063,6 +259291,7 @@ __export(dist_exports, {
|
|
|
259063
259291
|
MemoryReadTool: () => MemoryReadTool,
|
|
259064
259292
|
MemorySearchTool: () => MemorySearchTool,
|
|
259065
259293
|
MemoryWriteTool: () => MemoryWriteTool,
|
|
259294
|
+
MeshtasticTool: () => MeshtasticTool,
|
|
259066
259295
|
NexusTool: () => NexusTool,
|
|
259067
259296
|
NotebookEditTool: () => NotebookEditTool,
|
|
259068
259297
|
OCRTool: () => OCRTool,
|
|
@@ -259266,6 +259495,7 @@ var init_dist4 = __esm({
|
|
|
259266
259495
|
init_bluetooth_scan();
|
|
259267
259496
|
init_sdr_scan();
|
|
259268
259497
|
init_flipper_zero();
|
|
259498
|
+
init_meshtastic_tool();
|
|
259269
259499
|
init_system_auth();
|
|
259270
259500
|
init_full_sub_agent();
|
|
259271
259501
|
init_agent_tool();
|
|
@@ -259965,14 +260195,14 @@ var init_dist5 = __esm({
|
|
|
259965
260195
|
});
|
|
259966
260196
|
|
|
259967
260197
|
// packages/orchestrator/dist/promptLoader.js
|
|
259968
|
-
import { readFileSync as readFileSync31, existsSync as
|
|
260198
|
+
import { readFileSync as readFileSync31, existsSync as existsSync41 } from "node:fs";
|
|
259969
260199
|
import { join as join54, dirname as dirname15 } from "node:path";
|
|
259970
260200
|
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
259971
260201
|
function loadPrompt(promptPath, vars) {
|
|
259972
260202
|
let content = cache4.get(promptPath);
|
|
259973
260203
|
if (content === void 0) {
|
|
259974
260204
|
const fullPath = join54(PROMPTS_DIR, promptPath);
|
|
259975
|
-
if (!
|
|
260205
|
+
if (!existsSync41(fullPath)) {
|
|
259976
260206
|
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
259977
260207
|
}
|
|
259978
260208
|
content = readFileSync31(fullPath, "utf-8");
|
|
@@ -262170,12 +262400,12 @@ var init_tool_batching = __esm({
|
|
|
262170
262400
|
});
|
|
262171
262401
|
|
|
262172
262402
|
// packages/orchestrator/dist/hooks.js
|
|
262173
|
-
import { execSync as
|
|
262403
|
+
import { execSync as execSync38 } from "node:child_process";
|
|
262174
262404
|
function executeHook(hook, env2 = {}) {
|
|
262175
262405
|
const start2 = performance.now();
|
|
262176
262406
|
const timeout2 = hook.timeoutMs ?? DEFAULT_HOOK_TIMEOUT;
|
|
262177
262407
|
try {
|
|
262178
|
-
const output =
|
|
262408
|
+
const output = execSync38(hook.command, {
|
|
262179
262409
|
timeout: timeout2,
|
|
262180
262410
|
env: { ...process.env, ...env2 },
|
|
262181
262411
|
encoding: "utf8",
|
|
@@ -266399,7 +266629,7 @@ ${result}`
|
|
|
266399
266629
|
const buffer2 = Buffer.from(rawBase64, "base64");
|
|
266400
266630
|
let resizedBase64 = null;
|
|
266401
266631
|
try {
|
|
266402
|
-
const { execSync:
|
|
266632
|
+
const { execSync: execSync51 } = await import("node:child_process");
|
|
266403
266633
|
const { writeFileSync: writeFileSync38, readFileSync: readFileSync57, unlinkSync: unlinkSync18 } = await import("node:fs");
|
|
266404
266634
|
const { join: join92 } = await import("node:path");
|
|
266405
266635
|
const { tmpdir: tmpdir15 } = await import("node:os");
|
|
@@ -266409,7 +266639,7 @@ ${result}`
|
|
|
266409
266639
|
const pyBin = process.platform === "win32" ? "python" : "python3";
|
|
266410
266640
|
const escapedIn = tmpIn.replace(/\\/g, "\\\\");
|
|
266411
266641
|
const escapedOut = tmpOut.replace(/\\/g, "\\\\");
|
|
266412
|
-
|
|
266642
|
+
execSync51(`${pyBin} -c "from PIL import Image; img = Image.open('${escapedIn}'); img.thumbnail((512, 512), Image.LANCZOS); img = img.convert('RGB'); img.save('${escapedOut}', 'JPEG', quality=75)"`, { timeout: 1e4, stdio: "pipe" });
|
|
266413
266643
|
const resizedBuf = readFileSync57(tmpOut);
|
|
266414
266644
|
resizedBase64 = `data:image/jpeg;base64,${resizedBuf.toString("base64")}`;
|
|
266415
266645
|
try {
|
|
@@ -266463,8 +266693,8 @@ ${result}`
|
|
|
266463
266693
|
if (!res.ok && model === "moondream" && res.status === 404) {
|
|
266464
266694
|
this.emit({ type: "status", content: `Pulling moondream vision model...`, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
266465
266695
|
try {
|
|
266466
|
-
const { execSync:
|
|
266467
|
-
|
|
266696
|
+
const { execSync: execSync51 } = await import("node:child_process");
|
|
266697
|
+
execSync51("ollama pull moondream", { timeout: 3e5, stdio: "pipe" });
|
|
266468
266698
|
res = await fetch(`${ollamaHost}/api/generate`, {
|
|
266469
266699
|
method: "POST",
|
|
266470
266700
|
headers: { "Content-Type": "application/json" },
|
|
@@ -267030,7 +267260,7 @@ var init_constraint_learner = __esm({
|
|
|
267030
267260
|
});
|
|
267031
267261
|
|
|
267032
267262
|
// packages/orchestrator/dist/nexusBackend.js
|
|
267033
|
-
import { existsSync as
|
|
267263
|
+
import { existsSync as existsSync42, statSync as statSync14, openSync, readSync, closeSync, unlinkSync as unlinkSync9, writeFileSync as writeFileSync16 } from "node:fs";
|
|
267034
267264
|
import { watch as fsWatch } from "node:fs";
|
|
267035
267265
|
import { join as join57 } from "node:path";
|
|
267036
267266
|
import { tmpdir as tmpdir11 } from "node:os";
|
|
@@ -268828,8 +269058,8 @@ __export(listen_exports, {
|
|
|
268828
269058
|
isVideoPath: () => isVideoPath,
|
|
268829
269059
|
waitForTranscribeCli: () => waitForTranscribeCli
|
|
268830
269060
|
});
|
|
268831
|
-
import { spawn as spawn17, execSync as
|
|
268832
|
-
import { existsSync as
|
|
269061
|
+
import { spawn as spawn17, execSync as execSync39 } from "node:child_process";
|
|
269062
|
+
import { existsSync as existsSync43, mkdirSync as mkdirSync17, writeFileSync as writeFileSync17, readdirSync as readdirSync9 } from "node:fs";
|
|
268833
269063
|
import { join as join58, dirname as dirname16 } from "node:path";
|
|
268834
269064
|
import { homedir as homedir15 } from "node:os";
|
|
268835
269065
|
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
@@ -268850,7 +269080,7 @@ function findMicCaptureCommand() {
|
|
|
268850
269080
|
const platform6 = process.platform;
|
|
268851
269081
|
if (platform6 === "linux") {
|
|
268852
269082
|
try {
|
|
268853
|
-
|
|
269083
|
+
execSync39("which arecord", { stdio: "pipe" });
|
|
268854
269084
|
return {
|
|
268855
269085
|
cmd: "arecord",
|
|
268856
269086
|
args: ["-f", "S16_LE", "-r", "16000", "-c", "1", "-t", "raw", "-q", "-"]
|
|
@@ -268860,7 +269090,7 @@ function findMicCaptureCommand() {
|
|
|
268860
269090
|
}
|
|
268861
269091
|
if (platform6 === "darwin") {
|
|
268862
269092
|
try {
|
|
268863
|
-
|
|
269093
|
+
execSync39("which sox", { stdio: "pipe" });
|
|
268864
269094
|
return {
|
|
268865
269095
|
cmd: "sox",
|
|
268866
269096
|
args: ["-d", "-t", "raw", "-r", "16000", "-c", "1", "-b", "16", "-e", "signed-integer", "-"]
|
|
@@ -268869,7 +269099,7 @@ function findMicCaptureCommand() {
|
|
|
268869
269099
|
}
|
|
268870
269100
|
}
|
|
268871
269101
|
try {
|
|
268872
|
-
|
|
269102
|
+
execSync39("which ffmpeg", { stdio: "pipe" });
|
|
268873
269103
|
if (platform6 === "linux") {
|
|
268874
269104
|
return {
|
|
268875
269105
|
cmd: "ffmpeg",
|
|
@@ -268924,10 +269154,10 @@ function findLiveWhisperScript() {
|
|
|
268924
269154
|
join58(thisDir, "../../scripts/live-whisper.py")
|
|
268925
269155
|
];
|
|
268926
269156
|
for (const p2 of candidates) {
|
|
268927
|
-
if (
|
|
269157
|
+
if (existsSync43(p2)) return p2;
|
|
268928
269158
|
}
|
|
268929
269159
|
try {
|
|
268930
|
-
const globalRoot =
|
|
269160
|
+
const globalRoot = execSync39("npm root -g", {
|
|
268931
269161
|
encoding: "utf-8",
|
|
268932
269162
|
timeout: 5e3,
|
|
268933
269163
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -268937,16 +269167,16 @@ function findLiveWhisperScript() {
|
|
|
268937
269167
|
join58(globalRoot, "open-agents-ai", "scripts", "live-whisper.py")
|
|
268938
269168
|
];
|
|
268939
269169
|
for (const p2 of candidates2) {
|
|
268940
|
-
if (
|
|
269170
|
+
if (existsSync43(p2)) return p2;
|
|
268941
269171
|
}
|
|
268942
269172
|
} catch {
|
|
268943
269173
|
}
|
|
268944
269174
|
const nvmBase = join58(homedir15(), ".nvm", "versions", "node");
|
|
268945
|
-
if (
|
|
269175
|
+
if (existsSync43(nvmBase)) {
|
|
268946
269176
|
try {
|
|
268947
269177
|
for (const ver of readdirSync9(nvmBase)) {
|
|
268948
269178
|
const p2 = join58(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
|
|
268949
|
-
if (
|
|
269179
|
+
if (existsSync43(p2)) return p2;
|
|
268950
269180
|
}
|
|
268951
269181
|
} catch {
|
|
268952
269182
|
}
|
|
@@ -268957,12 +269187,12 @@ function ensureTranscribeCliBackground() {
|
|
|
268957
269187
|
if (_bgInstallPromise) return;
|
|
268958
269188
|
_bgInstallPromise = (async () => {
|
|
268959
269189
|
try {
|
|
268960
|
-
const globalRoot =
|
|
269190
|
+
const globalRoot = execSync39("npm root -g", {
|
|
268961
269191
|
encoding: "utf-8",
|
|
268962
269192
|
timeout: 5e3,
|
|
268963
269193
|
stdio: ["pipe", "pipe", "pipe"]
|
|
268964
269194
|
}).trim();
|
|
268965
|
-
if (
|
|
269195
|
+
if (existsSync43(join58(globalRoot, "transcribe-cli", "dist", "index.js"))) {
|
|
268966
269196
|
return true;
|
|
268967
269197
|
}
|
|
268968
269198
|
} catch {
|
|
@@ -269159,7 +269389,7 @@ var init_listen = __esm({
|
|
|
269159
269389
|
}
|
|
269160
269390
|
if (!this.transcribeCliAvailable) {
|
|
269161
269391
|
try {
|
|
269162
|
-
|
|
269392
|
+
execSync39("which transcribe-cli", { stdio: "pipe" });
|
|
269163
269393
|
this.transcribeCliAvailable = true;
|
|
269164
269394
|
} catch {
|
|
269165
269395
|
this.transcribeCliAvailable = false;
|
|
@@ -269176,13 +269406,13 @@ var init_listen = __esm({
|
|
|
269176
269406
|
} catch {
|
|
269177
269407
|
}
|
|
269178
269408
|
try {
|
|
269179
|
-
const globalRoot =
|
|
269409
|
+
const globalRoot = execSync39("npm root -g", {
|
|
269180
269410
|
encoding: "utf-8",
|
|
269181
269411
|
timeout: 5e3,
|
|
269182
269412
|
stdio: ["pipe", "pipe", "pipe"]
|
|
269183
269413
|
}).trim();
|
|
269184
269414
|
const tcPath = join58(globalRoot, "transcribe-cli");
|
|
269185
|
-
if (
|
|
269415
|
+
if (existsSync43(join58(tcPath, "dist", "index.js"))) {
|
|
269186
269416
|
const { createRequire: createRequire7 } = await import("node:module");
|
|
269187
269417
|
const req2 = createRequire7(import.meta.url);
|
|
269188
269418
|
return req2(join58(tcPath, "dist", "index.js"));
|
|
@@ -269190,12 +269420,12 @@ var init_listen = __esm({
|
|
|
269190
269420
|
} catch {
|
|
269191
269421
|
}
|
|
269192
269422
|
const nvmBase = join58(homedir15(), ".nvm", "versions", "node");
|
|
269193
|
-
if (
|
|
269423
|
+
if (existsSync43(nvmBase)) {
|
|
269194
269424
|
try {
|
|
269195
269425
|
const { readdirSync: readdirSync26 } = await import("node:fs");
|
|
269196
269426
|
for (const ver of readdirSync26(nvmBase)) {
|
|
269197
269427
|
const tcPath = join58(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
|
|
269198
|
-
if (
|
|
269428
|
+
if (existsSync43(join58(tcPath, "dist", "index.js"))) {
|
|
269199
269429
|
const { createRequire: createRequire7 } = await import("node:module");
|
|
269200
269430
|
const req2 = createRequire7(import.meta.url);
|
|
269201
269431
|
return req2(join58(tcPath, "dist", "index.js"));
|
|
@@ -269225,7 +269455,7 @@ var init_listen = __esm({
|
|
|
269225
269455
|
}
|
|
269226
269456
|
if (!tc) {
|
|
269227
269457
|
try {
|
|
269228
|
-
|
|
269458
|
+
execSync39("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
|
|
269229
269459
|
this.transcribeCliAvailable = null;
|
|
269230
269460
|
tc = await this.loadTranscribeCli();
|
|
269231
269461
|
} catch {
|
|
@@ -269403,7 +269633,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
269403
269633
|
}
|
|
269404
269634
|
if (!tc) {
|
|
269405
269635
|
try {
|
|
269406
|
-
|
|
269636
|
+
execSync39("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
|
|
269407
269637
|
this.transcribeCliAvailable = null;
|
|
269408
269638
|
tc = await this.loadTranscribeCli();
|
|
269409
269639
|
} catch {
|
|
@@ -269456,7 +269686,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
269456
269686
|
}
|
|
269457
269687
|
if (!tc) {
|
|
269458
269688
|
try {
|
|
269459
|
-
|
|
269689
|
+
execSync39("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
|
|
269460
269690
|
this.transcribeCliAvailable = null;
|
|
269461
269691
|
tc = await this.loadTranscribeCli();
|
|
269462
269692
|
} catch {
|
|
@@ -274378,7 +274608,7 @@ var init_render = __esm({
|
|
|
274378
274608
|
|
|
274379
274609
|
// packages/cli/src/tui/voice-session.ts
|
|
274380
274610
|
import { createServer as createServer3 } from "node:http";
|
|
274381
|
-
import { spawn as spawn18, execSync as
|
|
274611
|
+
import { spawn as spawn18, execSync as execSync40 } from "node:child_process";
|
|
274382
274612
|
import { EventEmitter as EventEmitter4 } from "node:events";
|
|
274383
274613
|
function generateFrontendHTML() {
|
|
274384
274614
|
return `<!DOCTYPE html>
|
|
@@ -275501,7 +275731,7 @@ import { EventEmitter as EventEmitter5 } from "node:events";
|
|
|
275501
275731
|
import { randomBytes as randomBytes15 } from "node:crypto";
|
|
275502
275732
|
import { URL as URL2 } from "node:url";
|
|
275503
275733
|
import { loadavg, cpus as cpus2, totalmem as totalmem2, freemem as freemem2 } from "node:os";
|
|
275504
|
-
import { existsSync as
|
|
275734
|
+
import { existsSync as existsSync44, readFileSync as readFileSync32, writeFileSync as writeFileSync18, unlinkSync as unlinkSync10, mkdirSync as mkdirSync18, readdirSync as readdirSync10, statSync as statSync15 } from "node:fs";
|
|
275505
275735
|
import { join as join59 } from "node:path";
|
|
275506
275736
|
function cleanForwardHeaders(raw, targetHost) {
|
|
275507
275737
|
const out = {};
|
|
@@ -275524,7 +275754,7 @@ function fmtTokens(n2) {
|
|
|
275524
275754
|
function readExposeState(stateDir) {
|
|
275525
275755
|
try {
|
|
275526
275756
|
const path5 = join59(stateDir, STATE_FILE_NAME);
|
|
275527
|
-
if (!
|
|
275757
|
+
if (!existsSync44(path5)) return null;
|
|
275528
275758
|
const raw = readFileSync32(path5, "utf8");
|
|
275529
275759
|
const data = JSON.parse(raw);
|
|
275530
275760
|
if (!data.pid || !data.tunnelUrl || !data.authKey || !data.proxyPort) return null;
|
|
@@ -275640,7 +275870,7 @@ async function collectSystemMetricsAsync() {
|
|
|
275640
275870
|
function readP2PExposeState(stateDir) {
|
|
275641
275871
|
try {
|
|
275642
275872
|
const path5 = join59(stateDir, P2P_STATE_FILE_NAME);
|
|
275643
|
-
if (!
|
|
275873
|
+
if (!existsSync44(path5)) return null;
|
|
275644
275874
|
const raw = readFileSync32(path5, "utf8");
|
|
275645
275875
|
const data = JSON.parse(raw);
|
|
275646
275876
|
if (!data.peerId || !data.authKey) return null;
|
|
@@ -276683,7 +276913,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
276683
276913
|
}
|
|
276684
276914
|
try {
|
|
276685
276915
|
const invocDir = join59(nexusDir, "invocations");
|
|
276686
|
-
if (
|
|
276916
|
+
if (existsSync44(invocDir)) {
|
|
276687
276917
|
this._prevInvocCount = readdirSync10(invocDir).filter((f2) => f2.endsWith(".json")).length;
|
|
276688
276918
|
this._stats.totalRequests = this._prevInvocCount;
|
|
276689
276919
|
}
|
|
@@ -276712,7 +276942,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
276712
276942
|
const nexusDir = nexusTool.getNexusDir();
|
|
276713
276943
|
const statusPath = join59(nexusDir, "status.json");
|
|
276714
276944
|
try {
|
|
276715
|
-
if (!
|
|
276945
|
+
if (!existsSync44(statusPath)) {
|
|
276716
276946
|
removeP2PExposeState(stateDir);
|
|
276717
276947
|
return null;
|
|
276718
276948
|
}
|
|
@@ -276770,7 +277000,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
276770
277000
|
this._activityPollTimer = setInterval(() => {
|
|
276771
277001
|
try {
|
|
276772
277002
|
const invocDir = join59(nexusDir, "invocations");
|
|
276773
|
-
if (!
|
|
277003
|
+
if (!existsSync44(invocDir)) return;
|
|
276774
277004
|
const files = readdirSync10(invocDir).filter((f2) => f2.endsWith(".json"));
|
|
276775
277005
|
const invocCount = files.length;
|
|
276776
277006
|
const newRequests = invocCount - this._prevInvocCount;
|
|
@@ -276792,7 +277022,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
276792
277022
|
const meteringFile = join59(nexusDir, "metering.jsonl");
|
|
276793
277023
|
let meteringLines = lastMeteringLineCount;
|
|
276794
277024
|
try {
|
|
276795
|
-
if (
|
|
277025
|
+
if (existsSync44(meteringFile)) {
|
|
276796
277026
|
const content = readFileSync32(meteringFile, "utf8");
|
|
276797
277027
|
meteringLines = content.split("\n").filter((l2) => l2.trim()).length;
|
|
276798
277028
|
}
|
|
@@ -276819,7 +277049,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
276819
277049
|
this._pollTimer = setInterval(() => {
|
|
276820
277050
|
try {
|
|
276821
277051
|
const statusPath = join59(nexusDir, "status.json");
|
|
276822
|
-
if (
|
|
277052
|
+
if (existsSync44(statusPath)) {
|
|
276823
277053
|
const status = JSON.parse(readFileSync32(statusPath, "utf8"));
|
|
276824
277054
|
if (status.peerId && !this._peerId) {
|
|
276825
277055
|
this._peerId = status.peerId;
|
|
@@ -276830,7 +277060,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
276830
277060
|
}
|
|
276831
277061
|
try {
|
|
276832
277062
|
const invocDir = join59(nexusDir, "invocations");
|
|
276833
|
-
if (
|
|
277063
|
+
if (existsSync44(invocDir)) {
|
|
276834
277064
|
const files = readdirSync10(invocDir);
|
|
276835
277065
|
const invocCount = files.filter((f2) => f2.endsWith(".json")).length;
|
|
276836
277066
|
if (invocCount > this._stats.totalRequests) {
|
|
@@ -276842,7 +277072,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
276842
277072
|
}
|
|
276843
277073
|
try {
|
|
276844
277074
|
const meteringFile = join59(nexusDir, "metering.jsonl");
|
|
276845
|
-
if (
|
|
277075
|
+
if (existsSync44(meteringFile)) {
|
|
276846
277076
|
const content = readFileSync32(meteringFile, "utf8");
|
|
276847
277077
|
if (content.length > lastMeteringSize) {
|
|
276848
277078
|
const newContent = content.slice(lastMeteringSize);
|
|
@@ -277054,7 +277284,7 @@ var init_types = __esm({
|
|
|
277054
277284
|
|
|
277055
277285
|
// packages/cli/src/tui/p2p/secret-vault.ts
|
|
277056
277286
|
import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes16, scryptSync as scryptSync2, createHash as createHash3 } from "node:crypto";
|
|
277057
|
-
import { readFileSync as readFileSync33, writeFileSync as writeFileSync19, existsSync as
|
|
277287
|
+
import { readFileSync as readFileSync33, writeFileSync as writeFileSync19, existsSync as existsSync45, mkdirSync as mkdirSync19 } from "node:fs";
|
|
277058
277288
|
import { dirname as dirname17 } from "node:path";
|
|
277059
277289
|
var PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, CIPHER_ALGO, SALT_LEN, IV_LEN, KEY_LEN, SecretVault;
|
|
277060
277290
|
var init_secret_vault = __esm({
|
|
@@ -277262,7 +277492,7 @@ var init_secret_vault = __esm({
|
|
|
277262
277492
|
const tag = cipher.getAuthTag();
|
|
277263
277493
|
const blob = Buffer.concat([salt, iv, tag, encrypted]);
|
|
277264
277494
|
const dir = dirname17(this.storePath);
|
|
277265
|
-
if (!
|
|
277495
|
+
if (!existsSync45(dir)) mkdirSync19(dir, { recursive: true });
|
|
277266
277496
|
writeFileSync19(this.storePath, blob, { mode: 384 });
|
|
277267
277497
|
}
|
|
277268
277498
|
/**
|
|
@@ -277270,7 +277500,7 @@ var init_secret_vault = __esm({
|
|
|
277270
277500
|
* Returns the number of secrets loaded.
|
|
277271
277501
|
*/
|
|
277272
277502
|
load(passphrase) {
|
|
277273
|
-
if (!this.storePath || !
|
|
277503
|
+
if (!this.storePath || !existsSync45(this.storePath)) return 0;
|
|
277274
277504
|
const blob = readFileSync33(this.storePath);
|
|
277275
277505
|
if (blob.length < SALT_LEN + IV_LEN + 16) {
|
|
277276
277506
|
throw new Error("Vault file is corrupted (too small)");
|
|
@@ -278424,7 +278654,7 @@ async function fetchOpenAIModels(baseUrl, apiKey) {
|
|
|
278424
278654
|
async function fetchPeerModels(peerId, authKey) {
|
|
278425
278655
|
try {
|
|
278426
278656
|
const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist4(), dist_exports));
|
|
278427
|
-
const { existsSync:
|
|
278657
|
+
const { existsSync: existsSync73, readFileSync: readFileSync57 } = await import("node:fs");
|
|
278428
278658
|
const { join: join92 } = await import("node:path");
|
|
278429
278659
|
const cwd4 = process.cwd();
|
|
278430
278660
|
const nexusTool = new NexusTool2(cwd4);
|
|
@@ -278432,7 +278662,7 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
278432
278662
|
let isLocalPeer = false;
|
|
278433
278663
|
try {
|
|
278434
278664
|
const statusPath = join92(nexusDir, "status.json");
|
|
278435
|
-
if (
|
|
278665
|
+
if (existsSync73(statusPath)) {
|
|
278436
278666
|
const status = JSON.parse(readFileSync57(statusPath, "utf8"));
|
|
278437
278667
|
if (status.peerId === peerId) isLocalPeer = true;
|
|
278438
278668
|
}
|
|
@@ -278440,7 +278670,7 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
278440
278670
|
}
|
|
278441
278671
|
if (isLocalPeer) {
|
|
278442
278672
|
const pricingPath = join92(nexusDir, "pricing.json");
|
|
278443
|
-
if (
|
|
278673
|
+
if (existsSync73(pricingPath)) {
|
|
278444
278674
|
try {
|
|
278445
278675
|
const pricing = JSON.parse(readFileSync57(pricingPath, "utf8"));
|
|
278446
278676
|
const localModels = (pricing.models || []).map((m2) => ({
|
|
@@ -278456,7 +278686,7 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
278456
278686
|
}
|
|
278457
278687
|
}
|
|
278458
278688
|
const cachePath = join92(nexusDir, "peer-models-cache.json");
|
|
278459
|
-
if (
|
|
278689
|
+
if (existsSync73(cachePath)) {
|
|
278460
278690
|
try {
|
|
278461
278691
|
const cache7 = JSON.parse(readFileSync57(cachePath, "utf8"));
|
|
278462
278692
|
if (cache7.peerId === peerId && cache7.models?.length > 0) {
|
|
@@ -278571,7 +278801,7 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
278571
278801
|
}
|
|
278572
278802
|
if (isLocalPeer) {
|
|
278573
278803
|
const pricingPath = join92(nexusDir, "pricing.json");
|
|
278574
|
-
if (
|
|
278804
|
+
if (existsSync73(pricingPath)) {
|
|
278575
278805
|
try {
|
|
278576
278806
|
const pricing = JSON.parse(readFileSync57(pricingPath, "utf8"));
|
|
278577
278807
|
return (pricing.models || []).map((m2) => ({
|
|
@@ -278829,14 +279059,14 @@ var init_render2 = __esm({
|
|
|
278829
279059
|
});
|
|
278830
279060
|
|
|
278831
279061
|
// packages/prompts/dist/promptLoader.js
|
|
278832
|
-
import { readFileSync as readFileSync34, existsSync as
|
|
279062
|
+
import { readFileSync as readFileSync34, existsSync as existsSync46 } from "node:fs";
|
|
278833
279063
|
import { join as join61, dirname as dirname18 } from "node:path";
|
|
278834
279064
|
import { fileURLToPath as fileURLToPath10 } from "node:url";
|
|
278835
279065
|
function loadPrompt2(promptPath, vars) {
|
|
278836
279066
|
let content = cache5.get(promptPath);
|
|
278837
279067
|
if (content === void 0) {
|
|
278838
279068
|
const fullPath = join61(PROMPTS_DIR2, promptPath);
|
|
278839
|
-
if (!
|
|
279069
|
+
if (!existsSync46(fullPath)) {
|
|
278840
279070
|
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
278841
279071
|
}
|
|
278842
279072
|
content = readFileSync34(fullPath, "utf-8");
|
|
@@ -278854,7 +279084,7 @@ var init_promptLoader2 = __esm({
|
|
|
278854
279084
|
__dirname6 = dirname18(__filename4);
|
|
278855
279085
|
devPath = join61(__dirname6, "..", "templates");
|
|
278856
279086
|
publishedPath = join61(__dirname6, "..", "prompts", "templates");
|
|
278857
|
-
PROMPTS_DIR2 =
|
|
279087
|
+
PROMPTS_DIR2 = existsSync46(devPath) ? devPath : publishedPath;
|
|
278858
279088
|
cache5 = /* @__PURE__ */ new Map();
|
|
278859
279089
|
}
|
|
278860
279090
|
});
|
|
@@ -279013,7 +279243,7 @@ __export(oa_directory_exports, {
|
|
|
279013
279243
|
writeIndexData: () => writeIndexData,
|
|
279014
279244
|
writeIndexMeta: () => writeIndexMeta
|
|
279015
279245
|
});
|
|
279016
|
-
import { existsSync as
|
|
279246
|
+
import { existsSync as existsSync47, mkdirSync as mkdirSync20, readFileSync as readFileSync35, writeFileSync as writeFileSync20, readdirSync as readdirSync11, statSync as statSync16, unlinkSync as unlinkSync11 } from "node:fs";
|
|
279017
279247
|
import { join as join63, relative as relative4, basename as basename12 } from "node:path";
|
|
279018
279248
|
import { homedir as homedir16 } from "node:os";
|
|
279019
279249
|
function initOaDirectory(repoRoot) {
|
|
@@ -279024,7 +279254,7 @@ function initOaDirectory(repoRoot) {
|
|
|
279024
279254
|
try {
|
|
279025
279255
|
const gitignorePath = join63(repoRoot, ".gitignore");
|
|
279026
279256
|
const settingsPattern = ".oa/settings.json";
|
|
279027
|
-
if (
|
|
279257
|
+
if (existsSync47(gitignorePath)) {
|
|
279028
279258
|
const content = readFileSync35(gitignorePath, "utf-8");
|
|
279029
279259
|
if (!content.includes(settingsPattern)) {
|
|
279030
279260
|
writeFileSync20(gitignorePath, content.trimEnd() + "\n" + settingsPattern + "\n", "utf-8");
|
|
@@ -279035,12 +279265,12 @@ function initOaDirectory(repoRoot) {
|
|
|
279035
279265
|
return oaPath;
|
|
279036
279266
|
}
|
|
279037
279267
|
function hasOaDirectory(repoRoot) {
|
|
279038
|
-
return
|
|
279268
|
+
return existsSync47(join63(repoRoot, OA_DIR, "index"));
|
|
279039
279269
|
}
|
|
279040
279270
|
function loadProjectSettings(repoRoot) {
|
|
279041
279271
|
const settingsPath = join63(repoRoot, OA_DIR, "settings.json");
|
|
279042
279272
|
try {
|
|
279043
|
-
if (
|
|
279273
|
+
if (existsSync47(settingsPath)) {
|
|
279044
279274
|
return JSON.parse(readFileSync35(settingsPath, "utf-8"));
|
|
279045
279275
|
}
|
|
279046
279276
|
} catch {
|
|
@@ -279057,7 +279287,7 @@ function saveProjectSettings(repoRoot, settings) {
|
|
|
279057
279287
|
function loadGlobalSettings() {
|
|
279058
279288
|
const settingsPath = join63(homedir16(), ".open-agents", "settings.json");
|
|
279059
279289
|
try {
|
|
279060
|
-
if (
|
|
279290
|
+
if (existsSync47(settingsPath)) {
|
|
279061
279291
|
return JSON.parse(readFileSync35(settingsPath, "utf-8"));
|
|
279062
279292
|
}
|
|
279063
279293
|
} catch {
|
|
@@ -279086,7 +279316,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
279086
279316
|
for (const name10 of CONTEXT_FILES) {
|
|
279087
279317
|
const filePath = join63(dir, name10);
|
|
279088
279318
|
const normalizedName = name10.toLowerCase();
|
|
279089
|
-
if (
|
|
279319
|
+
if (existsSync47(filePath) && !seen.has(filePath)) {
|
|
279090
279320
|
seen.add(filePath);
|
|
279091
279321
|
try {
|
|
279092
279322
|
let content = readFileSync35(filePath, "utf-8");
|
|
@@ -279104,7 +279334,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
279104
279334
|
}
|
|
279105
279335
|
}
|
|
279106
279336
|
const projectMap = join63(dir, OA_DIR, "context", "project-map.md");
|
|
279107
|
-
if (
|
|
279337
|
+
if (existsSync47(projectMap) && !seen.has(projectMap)) {
|
|
279108
279338
|
seen.add(projectMap);
|
|
279109
279339
|
try {
|
|
279110
279340
|
let content = readFileSync35(projectMap, "utf-8");
|
|
@@ -279222,7 +279452,7 @@ function saveSession(repoRoot, session) {
|
|
|
279222
279452
|
}
|
|
279223
279453
|
function loadRecentSessions(repoRoot, limit = 5) {
|
|
279224
279454
|
const historyDir = join63(repoRoot, OA_DIR, "history");
|
|
279225
|
-
if (!
|
|
279455
|
+
if (!existsSync47(historyDir)) return [];
|
|
279226
279456
|
try {
|
|
279227
279457
|
const files = readdirSync11(historyDir).filter((f2) => f2.endsWith(".json") && f2 !== "pending-task.json").map((f2) => {
|
|
279228
279458
|
const stat6 = statSync16(join63(historyDir, f2));
|
|
@@ -279253,7 +279483,7 @@ function savePendingTask(repoRoot, task) {
|
|
|
279253
279483
|
function loadPendingTask(repoRoot) {
|
|
279254
279484
|
const filePath = join63(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
|
|
279255
279485
|
try {
|
|
279256
|
-
if (!
|
|
279486
|
+
if (!existsSync47(filePath)) return null;
|
|
279257
279487
|
const data = JSON.parse(readFileSync35(filePath, "utf-8"));
|
|
279258
279488
|
try {
|
|
279259
279489
|
unlinkSync11(filePath);
|
|
@@ -279270,7 +279500,7 @@ function saveSessionContext(repoRoot, entry) {
|
|
|
279270
279500
|
const filePath = join63(contextDir, CONTEXT_SAVE_FILE);
|
|
279271
279501
|
let ctx3;
|
|
279272
279502
|
try {
|
|
279273
|
-
if (
|
|
279503
|
+
if (existsSync47(filePath)) {
|
|
279274
279504
|
ctx3 = JSON.parse(readFileSync35(filePath, "utf-8"));
|
|
279275
279505
|
} else {
|
|
279276
279506
|
ctx3 = { entries: [], maxEntries: MAX_CONTEXT_ENTRIES, updatedAt: "" };
|
|
@@ -279304,7 +279534,7 @@ function saveSessionContext(repoRoot, entry) {
|
|
|
279304
279534
|
function loadSessionContext(repoRoot) {
|
|
279305
279535
|
const filePath = join63(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
|
|
279306
279536
|
try {
|
|
279307
|
-
if (!
|
|
279537
|
+
if (!existsSync47(filePath)) return null;
|
|
279308
279538
|
return JSON.parse(readFileSync35(filePath, "utf-8"));
|
|
279309
279539
|
} catch {
|
|
279310
279540
|
return null;
|
|
@@ -279344,7 +279574,7 @@ function saveSessionHistory(repoRoot, sessionId, contentLines, meta) {
|
|
|
279344
279574
|
const indexPath = join63(sessDir, SESSIONS_INDEX);
|
|
279345
279575
|
let index = [];
|
|
279346
279576
|
try {
|
|
279347
|
-
if (
|
|
279577
|
+
if (existsSync47(indexPath)) {
|
|
279348
279578
|
index = JSON.parse(readFileSync35(indexPath, "utf-8"));
|
|
279349
279579
|
}
|
|
279350
279580
|
} catch {
|
|
@@ -279376,7 +279606,7 @@ function saveSessionHistory(repoRoot, sessionId, contentLines, meta) {
|
|
|
279376
279606
|
function listSessions(repoRoot) {
|
|
279377
279607
|
const indexPath = join63(repoRoot, OA_DIR, SESSIONS_DIR, SESSIONS_INDEX);
|
|
279378
279608
|
try {
|
|
279379
|
-
if (!
|
|
279609
|
+
if (!existsSync47(indexPath)) return [];
|
|
279380
279610
|
const index = JSON.parse(readFileSync35(indexPath, "utf-8"));
|
|
279381
279611
|
return index.sort((a2, b) => b.updatedAt.localeCompare(a2.updatedAt));
|
|
279382
279612
|
} catch {
|
|
@@ -279386,7 +279616,7 @@ function listSessions(repoRoot) {
|
|
|
279386
279616
|
function loadSessionHistory(repoRoot, sessionId) {
|
|
279387
279617
|
const contentPath = join63(repoRoot, OA_DIR, SESSIONS_DIR, `${sessionId}.jsonl`);
|
|
279388
279618
|
try {
|
|
279389
|
-
if (!
|
|
279619
|
+
if (!existsSync47(contentPath)) return null;
|
|
279390
279620
|
return readFileSync35(contentPath, "utf-8").split("\n");
|
|
279391
279621
|
} catch {
|
|
279392
279622
|
return null;
|
|
@@ -279397,8 +279627,8 @@ function deleteSession(repoRoot, sessionId) {
|
|
|
279397
279627
|
const indexPath = join63(sessDir, SESSIONS_INDEX);
|
|
279398
279628
|
try {
|
|
279399
279629
|
const contentPath = join63(sessDir, `${sessionId}.jsonl`);
|
|
279400
|
-
if (
|
|
279401
|
-
if (
|
|
279630
|
+
if (existsSync47(contentPath)) unlinkSync11(contentPath);
|
|
279631
|
+
if (existsSync47(indexPath)) {
|
|
279402
279632
|
let index = JSON.parse(readFileSync35(indexPath, "utf-8"));
|
|
279403
279633
|
index = index.filter((s2) => s2.id !== sessionId);
|
|
279404
279634
|
writeFileSync20(indexPath, JSON.stringify(index, null, 2), "utf-8");
|
|
@@ -279453,7 +279683,7 @@ function detectManifests(repoRoot) {
|
|
|
279453
279683
|
];
|
|
279454
279684
|
for (const check of checks) {
|
|
279455
279685
|
const filePath = join63(repoRoot, check.file);
|
|
279456
|
-
if (
|
|
279686
|
+
if (existsSync47(filePath)) {
|
|
279457
279687
|
let name10;
|
|
279458
279688
|
if (check.nameField) {
|
|
279459
279689
|
try {
|
|
@@ -279486,7 +279716,7 @@ function findKeyFiles(repoRoot) {
|
|
|
279486
279716
|
{ pattern: "CLAUDE.md", description: "Claude Code context" }
|
|
279487
279717
|
];
|
|
279488
279718
|
for (const check of checks) {
|
|
279489
|
-
if (
|
|
279719
|
+
if (existsSync47(join63(repoRoot, check.pattern))) {
|
|
279490
279720
|
keyFiles.push({ path: check.pattern, description: check.description });
|
|
279491
279721
|
}
|
|
279492
279722
|
}
|
|
@@ -279526,7 +279756,7 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
|
|
|
279526
279756
|
}
|
|
279527
279757
|
function loadUsageFile(filePath) {
|
|
279528
279758
|
try {
|
|
279529
|
-
if (
|
|
279759
|
+
if (existsSync47(filePath)) {
|
|
279530
279760
|
return JSON.parse(readFileSync35(filePath, "utf-8"));
|
|
279531
279761
|
}
|
|
279532
279762
|
} catch {
|
|
@@ -280247,7 +280477,7 @@ __export(text_selection_exports, {
|
|
|
280247
280477
|
stripAnsi: () => stripAnsi,
|
|
280248
280478
|
visibleLength: () => visibleLength
|
|
280249
280479
|
});
|
|
280250
|
-
import { execSync as
|
|
280480
|
+
import { execSync as execSync41 } from "node:child_process";
|
|
280251
280481
|
function stripAnsi(s2) {
|
|
280252
280482
|
return s2.replace(/\x1B\[[0-9;]*[A-Za-z]|\x1B\].*?(?:\x07|\x1B\\)/g, "");
|
|
280253
280483
|
}
|
|
@@ -280258,16 +280488,16 @@ function copyText(text) {
|
|
|
280258
280488
|
try {
|
|
280259
280489
|
const platform6 = process.platform;
|
|
280260
280490
|
if (platform6 === "darwin") {
|
|
280261
|
-
|
|
280491
|
+
execSync41("pbcopy", { input: text, timeout: 3e3 });
|
|
280262
280492
|
return true;
|
|
280263
280493
|
}
|
|
280264
280494
|
if (platform6 === "win32") {
|
|
280265
|
-
|
|
280495
|
+
execSync41("clip", { input: text, timeout: 3e3 });
|
|
280266
280496
|
return true;
|
|
280267
280497
|
}
|
|
280268
280498
|
for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
|
|
280269
280499
|
try {
|
|
280270
|
-
|
|
280500
|
+
execSync41(tool, { input: text, timeout: 3e3 });
|
|
280271
280501
|
return true;
|
|
280272
280502
|
} catch {
|
|
280273
280503
|
continue;
|
|
@@ -280276,10 +280506,10 @@ function copyText(text) {
|
|
|
280276
280506
|
if (!_clipboardAutoInstallAttempted) {
|
|
280277
280507
|
_clipboardAutoInstallAttempted = true;
|
|
280278
280508
|
try {
|
|
280279
|
-
|
|
280509
|
+
execSync41("which apt-get", { timeout: 2e3, stdio: "pipe" });
|
|
280280
280510
|
try {
|
|
280281
|
-
|
|
280282
|
-
|
|
280511
|
+
execSync41("sudo -n apt-get install -y xclip 2>/dev/null", { timeout: 15e3, stdio: "pipe" });
|
|
280512
|
+
execSync41("xclip -selection clipboard", { input: text, timeout: 3e3 });
|
|
280283
280513
|
return true;
|
|
280284
280514
|
} catch {
|
|
280285
280515
|
}
|
|
@@ -284154,10 +284384,10 @@ __export(personaplex_exports, {
|
|
|
284154
284384
|
startPersonaPlexDaemon: () => startPersonaPlexDaemon,
|
|
284155
284385
|
stopPersonaPlex: () => stopPersonaPlex
|
|
284156
284386
|
});
|
|
284157
|
-
import { existsSync as
|
|
284387
|
+
import { existsSync as existsSync48, writeFileSync as writeFileSync21, readFileSync as readFileSync37, mkdirSync as mkdirSync21, copyFileSync as copyFileSync2, readdirSync as readdirSync12, statSync as statSync17 } from "node:fs";
|
|
284158
284388
|
import { join as join64, dirname as dirname20 } from "node:path";
|
|
284159
284389
|
import { homedir as homedir17 } from "node:os";
|
|
284160
|
-
import { execSync as
|
|
284390
|
+
import { execSync as execSync42, spawn as spawn20 } from "node:child_process";
|
|
284161
284391
|
import { fileURLToPath as fileURLToPath12 } from "node:url";
|
|
284162
284392
|
function execAsync(cmd, opts = {}) {
|
|
284163
284393
|
return new Promise((resolve39, reject) => {
|
|
@@ -284190,7 +284420,7 @@ function detectJetson() {
|
|
|
284190
284420
|
try {
|
|
284191
284421
|
const model = readFileSync37("/proc/device-tree/model", "utf8").replace(/\0/g, "").trim();
|
|
284192
284422
|
if (/jetson|orin|tegra/i.test(model)) {
|
|
284193
|
-
const memInfo =
|
|
284423
|
+
const memInfo = execSync42("grep MemTotal /proc/meminfo", { encoding: "utf8", timeout: 3e3, stdio: "pipe" });
|
|
284194
284424
|
const memKB = parseInt(memInfo.match(/(\d+)/)?.[1] ?? "0", 10);
|
|
284195
284425
|
return { isJetson: true, model, totalMemGB: memKB / 1024 / 1024 };
|
|
284196
284426
|
}
|
|
@@ -284224,7 +284454,7 @@ function detectPersonaPlexCapability() {
|
|
|
284224
284454
|
};
|
|
284225
284455
|
}
|
|
284226
284456
|
try {
|
|
284227
|
-
const nvsmi =
|
|
284457
|
+
const nvsmi = execSync42("nvidia-smi --query-gpu=name,memory.total --format=csv,noheader,nounits", {
|
|
284228
284458
|
encoding: "utf8",
|
|
284229
284459
|
timeout: 5e3,
|
|
284230
284460
|
stdio: "pipe"
|
|
@@ -284236,7 +284466,7 @@ function detectPersonaPlexCapability() {
|
|
|
284236
284466
|
return { ...fail2(`GPU has ${vramGB.toFixed(1)}GB VRAM (need \u22658GB)`), gpuName: gpuName ?? "", vramGB };
|
|
284237
284467
|
}
|
|
284238
284468
|
try {
|
|
284239
|
-
|
|
284469
|
+
execSync42('python3 -c "import torch; assert torch.cuda.is_available()"', {
|
|
284240
284470
|
timeout: 1e4,
|
|
284241
284471
|
stdio: "pipe"
|
|
284242
284472
|
});
|
|
@@ -284265,7 +284495,7 @@ function fileLink2(filePath, label) {
|
|
|
284265
284495
|
return `\x1B]8;;${url}\x1B\\${text}\x1B]8;;\x1B\\`;
|
|
284266
284496
|
}
|
|
284267
284497
|
function isPersonaPlexRunning() {
|
|
284268
|
-
if (!
|
|
284498
|
+
if (!existsSync48(PID_FILE)) return false;
|
|
284269
284499
|
const pid = parseInt(readFileSync37(PID_FILE, "utf8").trim(), 10);
|
|
284270
284500
|
if (isNaN(pid) || pid <= 0) return false;
|
|
284271
284501
|
try {
|
|
@@ -284277,17 +284507,17 @@ function isPersonaPlexRunning() {
|
|
|
284277
284507
|
}
|
|
284278
284508
|
function getPersonaPlexWSUrl() {
|
|
284279
284509
|
if (!isPersonaPlexRunning()) return null;
|
|
284280
|
-
if (!
|
|
284510
|
+
if (!existsSync48(PORT_FILE)) return null;
|
|
284281
284511
|
const port = parseInt(readFileSync37(PORT_FILE, "utf8").trim(), 10);
|
|
284282
284512
|
return isNaN(port) ? null : `wss://127.0.0.1:${port}`;
|
|
284283
284513
|
}
|
|
284284
284514
|
function isPersonaPlexInstalled() {
|
|
284285
|
-
return
|
|
284515
|
+
return existsSync48(join64(PERSONAPLEX_DIR, "model_ready"));
|
|
284286
284516
|
}
|
|
284287
284517
|
function getWeightTier() {
|
|
284288
284518
|
const detected = detectPersonaPlexCapability();
|
|
284289
284519
|
const tierFile = join64(PERSONAPLEX_DIR, "weight_tier");
|
|
284290
|
-
if (
|
|
284520
|
+
if (existsSync48(tierFile)) {
|
|
284291
284521
|
const saved = readFileSync37(tierFile, "utf8").trim();
|
|
284292
284522
|
if (saved in WEIGHT_REPOS) {
|
|
284293
284523
|
const vram = detected.vramGB;
|
|
@@ -284309,13 +284539,13 @@ async function installPersonaPlex(onInfo, weightTier) {
|
|
|
284309
284539
|
mkdirSync21(PERSONAPLEX_DIR, { recursive: true });
|
|
284310
284540
|
let arch2 = "";
|
|
284311
284541
|
try {
|
|
284312
|
-
arch2 =
|
|
284542
|
+
arch2 = execSync42("uname -m", { encoding: "utf8", timeout: 3e3, stdio: "pipe" }).trim();
|
|
284313
284543
|
} catch {
|
|
284314
284544
|
}
|
|
284315
284545
|
const isAarch64 = arch2 === "aarch64" || arch2 === "arm64";
|
|
284316
284546
|
if (isAarch64) log22(`Detected ARM64 platform (${arch2}) \u2014 Jetson/ARM install path`);
|
|
284317
284547
|
const venvDir = join64(PERSONAPLEX_DIR, "venv");
|
|
284318
|
-
if (!
|
|
284548
|
+
if (!existsSync48(venvDir)) {
|
|
284319
284549
|
log22("Creating Python virtual environment...");
|
|
284320
284550
|
try {
|
|
284321
284551
|
const ssp = isAarch64 ? " --system-site-packages" : "";
|
|
@@ -284330,16 +284560,16 @@ async function installPersonaPlex(onInfo, weightTier) {
|
|
|
284330
284560
|
log22("Checking system dependencies (libopus)...");
|
|
284331
284561
|
try {
|
|
284332
284562
|
if (process.platform === "linux") {
|
|
284333
|
-
|
|
284563
|
+
execSync42("dpkg -l libopus-dev 2>/dev/null || sudo apt-get install -y libopus-dev", { timeout: 3e4, stdio: "pipe" });
|
|
284334
284564
|
} else if (process.platform === "darwin") {
|
|
284335
|
-
|
|
284565
|
+
execSync42("brew list opus 2>/dev/null || brew install opus", { timeout: 6e4, stdio: "pipe" });
|
|
284336
284566
|
}
|
|
284337
284567
|
} catch {
|
|
284338
284568
|
}
|
|
284339
284569
|
if (isAarch64) {
|
|
284340
284570
|
log22("ARM64: Checking Rust toolchain for sphn build...");
|
|
284341
284571
|
try {
|
|
284342
|
-
|
|
284572
|
+
execSync42("rustc --version", { timeout: 5e3, stdio: "pipe" });
|
|
284343
284573
|
} catch {
|
|
284344
284574
|
log22("ARM64: Installing Rust toolchain (needed for sphn audio codec)...");
|
|
284345
284575
|
try {
|
|
@@ -284358,7 +284588,7 @@ async function installPersonaPlex(onInfo, weightTier) {
|
|
|
284358
284588
|
log22("Installing PersonaPlex (moshi package)...");
|
|
284359
284589
|
const repoDir = join64(PERSONAPLEX_DIR, "personaplex-repo");
|
|
284360
284590
|
try {
|
|
284361
|
-
if (!
|
|
284591
|
+
if (!existsSync48(repoDir)) {
|
|
284362
284592
|
await execAsync(
|
|
284363
284593
|
`git clone https://github.com/NVIDIA/personaplex.git "${repoDir}"`,
|
|
284364
284594
|
{ timeout: 12e4 }
|
|
@@ -284412,13 +284642,13 @@ async function installPersonaPlex(onInfo, weightTier) {
|
|
|
284412
284642
|
}
|
|
284413
284643
|
const serverPy = join64(venvDir, "lib", `python3.${process.versions.node ? "12" : "10"}`, "site-packages", "moshi", "server.py");
|
|
284414
284644
|
try {
|
|
284415
|
-
const sitePackages =
|
|
284645
|
+
const sitePackages = execSync42(`"${python}" -c "import moshi, os; print(os.path.dirname(moshi.__file__))"`, {
|
|
284416
284646
|
encoding: "utf8",
|
|
284417
284647
|
timeout: 5e3,
|
|
284418
284648
|
stdio: "pipe"
|
|
284419
284649
|
}).trim();
|
|
284420
284650
|
const serverFile = join64(sitePackages, "server.py");
|
|
284421
|
-
if (
|
|
284651
|
+
if (existsSync48(serverFile)) {
|
|
284422
284652
|
let src2 = readFileSync37(serverFile, "utf8");
|
|
284423
284653
|
if (src2.includes('int(request["seed"])')) {
|
|
284424
284654
|
src2 = src2.replace('int(request["seed"])', 'int(request.query["seed"])');
|
|
@@ -284429,13 +284659,13 @@ async function installPersonaPlex(onInfo, weightTier) {
|
|
|
284429
284659
|
} catch {
|
|
284430
284660
|
}
|
|
284431
284661
|
try {
|
|
284432
|
-
const sitePackages =
|
|
284662
|
+
const sitePackages = execSync42(`"${python}" -c "import moshi, os; print(os.path.dirname(moshi.__file__))"`, {
|
|
284433
284663
|
encoding: "utf8",
|
|
284434
284664
|
timeout: 5e3,
|
|
284435
284665
|
stdio: "pipe"
|
|
284436
284666
|
}).trim();
|
|
284437
284667
|
const loadersFile = join64(sitePackages, "models", "loaders.py");
|
|
284438
|
-
if (
|
|
284668
|
+
if (existsSync48(loadersFile)) {
|
|
284439
284669
|
let src2 = readFileSync37(loadersFile, "utf8");
|
|
284440
284670
|
if (!src2.includes("_dequantize_2bit_state_dict")) {
|
|
284441
284671
|
const dequantPatch = `
|
|
@@ -284533,21 +284763,21 @@ $2if filename.endswith(".safetensors"):`
|
|
|
284533
284763
|
} catch {
|
|
284534
284764
|
}
|
|
284535
284765
|
try {
|
|
284536
|
-
const sitePackages2 =
|
|
284766
|
+
const sitePackages2 = execSync42(`"${python}" -c "import moshi, os; print(os.path.dirname(moshi.__file__))"`, {
|
|
284537
284767
|
encoding: "utf8",
|
|
284538
284768
|
timeout: 5e3,
|
|
284539
284769
|
stdio: "pipe"
|
|
284540
284770
|
}).trim();
|
|
284541
284771
|
const hybridDest = join64(sitePackages2, "hybrid_agent.py");
|
|
284542
284772
|
const serverDest = join64(sitePackages2, "server.py");
|
|
284543
|
-
if (!
|
|
284773
|
+
if (!existsSync48(hybridDest) || !readFileSync37(hybridDest, "utf8").includes("OA_API_BASE")) {
|
|
284544
284774
|
log22("Deploying hybrid_agent.py (OA API integration)...");
|
|
284545
284775
|
try {
|
|
284546
284776
|
await execAsync(
|
|
284547
284777
|
`curl -sL "https://raw.githubusercontent.com/robit-man/personaplex/main/personaplex-setup/moshi/moshi/hybrid_agent.py" -o "${hybridDest}"`,
|
|
284548
284778
|
{ timeout: 3e4 }
|
|
284549
284779
|
);
|
|
284550
|
-
if (
|
|
284780
|
+
if (existsSync48(hybridDest) && readFileSync37(hybridDest, "utf8").includes("OA_API_BASE")) {
|
|
284551
284781
|
log22("hybrid_agent.py deployed (OA API + Ollama fallback).");
|
|
284552
284782
|
}
|
|
284553
284783
|
} catch {
|
|
@@ -284668,14 +284898,14 @@ async function startPersonaPlexDaemon(onInfo) {
|
|
|
284668
284898
|
if (tier === "nf4-distilled") {
|
|
284669
284899
|
log22(`Weight tier: ${tier} \u2014 distilled NF4 (90% token match, ${repoInfo.sizeGB}GB)...`);
|
|
284670
284900
|
try {
|
|
284671
|
-
const weightPath =
|
|
284901
|
+
const weightPath = execSync42(
|
|
284672
284902
|
`"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', '${repoInfo.file}', token=False))"`,
|
|
284673
284903
|
{ encoding: "utf8", timeout: 6e4, stdio: "pipe" }
|
|
284674
284904
|
).trim();
|
|
284675
|
-
if (
|
|
284676
|
-
if (!
|
|
284905
|
+
if (existsSync48(weightPath)) {
|
|
284906
|
+
if (!existsSync48(cachedBf16)) {
|
|
284677
284907
|
log22("Converting .pt checkpoint to safetensors (one-time)...");
|
|
284678
|
-
|
|
284908
|
+
execSync42(
|
|
284679
284909
|
`"${venvPython2}" -c "
|
|
284680
284910
|
import torch; from safetensors.torch import save_file
|
|
284681
284911
|
state = torch.load('${weightPath}', map_location='cpu', weights_only=True)
|
|
@@ -284686,7 +284916,7 @@ print('Converted')
|
|
|
284686
284916
|
{ timeout: 18e4, stdio: "pipe" }
|
|
284687
284917
|
);
|
|
284688
284918
|
}
|
|
284689
|
-
if (
|
|
284919
|
+
if (existsSync48(cachedBf16)) {
|
|
284690
284920
|
extraArgs.push("--moshi-weight", cachedBf16);
|
|
284691
284921
|
log22(`Using distilled weights: ${(statSync17(cachedBf16).size / 1024 ** 3).toFixed(1)}GB`);
|
|
284692
284922
|
} else {
|
|
@@ -284699,25 +284929,25 @@ print('Converted')
|
|
|
284699
284929
|
} else {
|
|
284700
284930
|
log22(`Weight tier: ${tier} (${repoInfo.sizeGB}GB) \u2014 dequantizing to bf16 cache...`);
|
|
284701
284931
|
const dequantScript = join64(PERSONAPLEX_DIR, "dequant-loader.py");
|
|
284702
|
-
if (!
|
|
284932
|
+
if (!existsSync48(dequantScript)) {
|
|
284703
284933
|
const shipped = getShippedVoicesDir();
|
|
284704
284934
|
if (shipped) {
|
|
284705
284935
|
const src2 = join64(shipped, "dequant-loader.py");
|
|
284706
|
-
if (
|
|
284936
|
+
if (existsSync48(src2)) copyFileSync2(src2, dequantScript);
|
|
284707
284937
|
}
|
|
284708
284938
|
}
|
|
284709
284939
|
try {
|
|
284710
|
-
const weightPath =
|
|
284940
|
+
const weightPath = execSync42(
|
|
284711
284941
|
`"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', '${repoInfo.file}'${repoInfo.needsToken ? "" : ", token=False"}))"`,
|
|
284712
284942
|
{ encoding: "utf8", timeout: 3e4, stdio: "pipe" }
|
|
284713
284943
|
).trim();
|
|
284714
|
-
if (
|
|
284944
|
+
if (existsSync48(dequantScript) && existsSync48(weightPath)) {
|
|
284715
284945
|
try {
|
|
284716
|
-
|
|
284946
|
+
execSync42(
|
|
284717
284947
|
`"${venvPython2}" "${dequantScript}" --input "${weightPath}" --output "${cachedBf16}"`,
|
|
284718
284948
|
{ timeout: 3e5, stdio: "pipe" }
|
|
284719
284949
|
);
|
|
284720
|
-
if (
|
|
284950
|
+
if (existsSync48(cachedBf16)) {
|
|
284721
284951
|
extraArgs.push("--moshi-weight", cachedBf16);
|
|
284722
284952
|
log22(`Using dequantized cache: ${(statSync17(cachedBf16).size / 1024 ** 3).toFixed(1)}GB`);
|
|
284723
284953
|
}
|
|
@@ -284726,19 +284956,19 @@ print('Converted')
|
|
|
284726
284956
|
}
|
|
284727
284957
|
}
|
|
284728
284958
|
try {
|
|
284729
|
-
const mimiPath =
|
|
284959
|
+
const mimiPath = execSync42(
|
|
284730
284960
|
`"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', 'tokenizer-e351c8d8-checkpoint125.safetensors', token=False))"`,
|
|
284731
284961
|
{ encoding: "utf8", timeout: 3e4, stdio: "pipe" }
|
|
284732
284962
|
).trim();
|
|
284733
|
-
if (
|
|
284963
|
+
if (existsSync48(mimiPath)) extraArgs.push("--mimi-weight", mimiPath);
|
|
284734
284964
|
} catch {
|
|
284735
284965
|
}
|
|
284736
284966
|
try {
|
|
284737
|
-
const tokPath =
|
|
284967
|
+
const tokPath = execSync42(
|
|
284738
284968
|
`"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', 'tokenizer_spm_32k_3.model', token=False))"`,
|
|
284739
284969
|
{ encoding: "utf8", timeout: 3e4, stdio: "pipe" }
|
|
284740
284970
|
).trim();
|
|
284741
|
-
if (
|
|
284971
|
+
if (existsSync48(tokPath)) extraArgs.push("--tokenizer", tokPath);
|
|
284742
284972
|
} catch {
|
|
284743
284973
|
}
|
|
284744
284974
|
} catch {
|
|
@@ -284758,7 +284988,7 @@ print('Converted')
|
|
|
284758
284988
|
}
|
|
284759
284989
|
if (!ollamaModel) ollamaModel = "qwen3.5:4b";
|
|
284760
284990
|
try {
|
|
284761
|
-
const ollamaCheck =
|
|
284991
|
+
const ollamaCheck = execSync42("curl -s http://localhost:11434/api/tags", {
|
|
284762
284992
|
timeout: 3e3,
|
|
284763
284993
|
stdio: "pipe",
|
|
284764
284994
|
encoding: "utf8"
|
|
@@ -284832,7 +285062,7 @@ print('Converted')
|
|
|
284832
285062
|
return null;
|
|
284833
285063
|
}
|
|
284834
285064
|
try {
|
|
284835
|
-
|
|
285065
|
+
execSync42(`curl -sk -o /dev/null -w "%{http_code}" https://127.0.0.1:${PORT}/`, {
|
|
284836
285066
|
timeout: 3e3,
|
|
284837
285067
|
stdio: "pipe",
|
|
284838
285068
|
encoding: "utf8"
|
|
@@ -284850,12 +285080,12 @@ print('Converted')
|
|
|
284850
285080
|
return null;
|
|
284851
285081
|
}
|
|
284852
285082
|
function stopPersonaPlex() {
|
|
284853
|
-
if (!
|
|
285083
|
+
if (!existsSync48(PID_FILE)) return;
|
|
284854
285084
|
const pid = parseInt(readFileSync37(PID_FILE, "utf8").trim(), 10);
|
|
284855
285085
|
if (isNaN(pid) || pid <= 0) return;
|
|
284856
285086
|
try {
|
|
284857
285087
|
if (process.platform === "win32") {
|
|
284858
|
-
|
|
285088
|
+
execSync42(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
|
|
284859
285089
|
} else {
|
|
284860
285090
|
process.kill(pid, "SIGTERM");
|
|
284861
285091
|
}
|
|
@@ -284887,7 +285117,7 @@ function listPersonaPlexVoices() {
|
|
|
284887
285117
|
for (const name10 of builtins) {
|
|
284888
285118
|
voices.push({ name: name10, type: "builtin", path: `${name10}.pt` });
|
|
284889
285119
|
}
|
|
284890
|
-
if (
|
|
285120
|
+
if (existsSync48(CUSTOM_VOICES_DIR)) {
|
|
284891
285121
|
try {
|
|
284892
285122
|
for (const f2 of readdirSync12(CUSTOM_VOICES_DIR)) {
|
|
284893
285123
|
if (f2.endsWith(".pt")) {
|
|
@@ -284907,19 +285137,19 @@ async function clonePersonaPlexVoice(inputWav, voiceName, onInfo) {
|
|
|
284907
285137
|
log22("PersonaPlex not installed. Run /voice personaplex first.");
|
|
284908
285138
|
return null;
|
|
284909
285139
|
}
|
|
284910
|
-
if (!
|
|
285140
|
+
if (!existsSync48(inputWav)) {
|
|
284911
285141
|
log22(`Input WAV not found: ${inputWav}`);
|
|
284912
285142
|
return null;
|
|
284913
285143
|
}
|
|
284914
285144
|
mkdirSync21(CUSTOM_VOICES_DIR, { recursive: true });
|
|
284915
285145
|
const outputPt = join64(CUSTOM_VOICES_DIR, `${voiceName}.pt`);
|
|
284916
|
-
if (
|
|
285146
|
+
if (existsSync48(outputPt)) {
|
|
284917
285147
|
log22(`Voice "${voiceName}" already exists. Delete ${outputPt} to re-clone.`);
|
|
284918
285148
|
return outputPt;
|
|
284919
285149
|
}
|
|
284920
285150
|
const venvPython2 = process.platform === "win32" ? join64(PERSONAPLEX_DIR, "venv", "Scripts", "python.exe") : join64(PERSONAPLEX_DIR, "venv", "bin", "python3");
|
|
284921
285151
|
const cloneScript = join64(PERSONAPLEX_DIR, "clone-voice.py");
|
|
284922
|
-
if (!
|
|
285152
|
+
if (!existsSync48(cloneScript)) {
|
|
284923
285153
|
log22("clone-voice.py not found. Reinstall PersonaPlex.");
|
|
284924
285154
|
return null;
|
|
284925
285155
|
}
|
|
@@ -284951,7 +285181,7 @@ async function clonePersonaPlexVoice(inputWav, voiceName, onInfo) {
|
|
|
284951
285181
|
output += d2.toString();
|
|
284952
285182
|
});
|
|
284953
285183
|
child.on("close", (code8) => {
|
|
284954
|
-
if (code8 === 0 &&
|
|
285184
|
+
if (code8 === 0 && existsSync48(outputPt)) {
|
|
284955
285185
|
log22(`Voice "${voiceName}" cloned successfully.`);
|
|
284956
285186
|
resolve39(outputPt);
|
|
284957
285187
|
} else {
|
|
@@ -284975,7 +285205,7 @@ function getShippedVoicesDir() {
|
|
|
284975
285205
|
} catch {
|
|
284976
285206
|
}
|
|
284977
285207
|
for (const dir of candidates) {
|
|
284978
|
-
if (
|
|
285208
|
+
if (existsSync48(dir)) {
|
|
284979
285209
|
try {
|
|
284980
285210
|
const files = readdirSync12(dir);
|
|
284981
285211
|
if (files.some((f2) => f2.endsWith(".pt"))) return dir;
|
|
@@ -284997,12 +285227,12 @@ function provisionShippedVoices(onInfo) {
|
|
|
284997
285227
|
for (const f2 of readdirSync12(shippedDir)) {
|
|
284998
285228
|
if (!f2.endsWith(".pt")) continue;
|
|
284999
285229
|
const customDst = join64(CUSTOM_VOICES_DIR, f2);
|
|
285000
|
-
if (!
|
|
285230
|
+
if (!existsSync48(customDst)) {
|
|
285001
285231
|
copyFileSync2(join64(shippedDir, f2), customDst);
|
|
285002
285232
|
}
|
|
285003
285233
|
if (hfVoicesDir) {
|
|
285004
285234
|
const hfDst = join64(hfVoicesDir, f2);
|
|
285005
|
-
if (!
|
|
285235
|
+
if (!existsSync48(hfDst)) {
|
|
285006
285236
|
copyFileSync2(join64(shippedDir, f2), hfDst);
|
|
285007
285237
|
log22(`Deployed voice: ${f2.replace(".pt", "")}`);
|
|
285008
285238
|
deployed++;
|
|
@@ -285013,7 +285243,7 @@ function provisionShippedVoices(onInfo) {
|
|
|
285013
285243
|
}
|
|
285014
285244
|
const shippedScript = join64(shippedDir, "clone-voice.py");
|
|
285015
285245
|
const targetScript = join64(PERSONAPLEX_DIR, "clone-voice.py");
|
|
285016
|
-
if (
|
|
285246
|
+
if (existsSync48(shippedScript) && !existsSync48(targetScript)) {
|
|
285017
285247
|
try {
|
|
285018
285248
|
copyFileSync2(shippedScript, targetScript);
|
|
285019
285249
|
} catch {
|
|
@@ -285023,13 +285253,13 @@ function provisionShippedVoices(onInfo) {
|
|
|
285023
285253
|
}
|
|
285024
285254
|
function getHFVoicesDir() {
|
|
285025
285255
|
const hfBase = join64(homedir17(), ".cache", "huggingface", "hub", "models--nvidia--personaplex-7b-v1");
|
|
285026
|
-
if (!
|
|
285256
|
+
if (!existsSync48(hfBase)) return null;
|
|
285027
285257
|
try {
|
|
285028
285258
|
const snapshots = join64(hfBase, "snapshots");
|
|
285029
|
-
if (!
|
|
285259
|
+
if (!existsSync48(snapshots)) return null;
|
|
285030
285260
|
for (const snap of readdirSync12(snapshots)) {
|
|
285031
285261
|
const voicesDir = join64(snapshots, snap, "voices");
|
|
285032
|
-
if (
|
|
285262
|
+
if (existsSync48(voicesDir)) return voicesDir;
|
|
285033
285263
|
}
|
|
285034
285264
|
} catch {
|
|
285035
285265
|
}
|
|
@@ -285039,18 +285269,18 @@ function patchFrontendVoiceList(onInfo) {
|
|
|
285039
285269
|
const log22 = onInfo ?? (() => {
|
|
285040
285270
|
});
|
|
285041
285271
|
const hfBase = join64(homedir17(), ".cache", "huggingface", "hub", "models--nvidia--personaplex-7b-v1");
|
|
285042
|
-
if (!
|
|
285272
|
+
if (!existsSync48(hfBase)) return;
|
|
285043
285273
|
try {
|
|
285044
285274
|
const snapshots = join64(hfBase, "snapshots");
|
|
285045
285275
|
for (const snap of readdirSync12(snapshots)) {
|
|
285046
285276
|
const distDir = join64(snapshots, snap, "dist", "assets");
|
|
285047
|
-
if (!
|
|
285277
|
+
if (!existsSync48(distDir)) continue;
|
|
285048
285278
|
for (const f2 of readdirSync12(distDir)) {
|
|
285049
285279
|
if (!f2.startsWith("index-") || !f2.endsWith(".js")) continue;
|
|
285050
285280
|
const jsPath = join64(distDir, f2);
|
|
285051
285281
|
let js = readFileSync37(jsPath, "utf8");
|
|
285052
285282
|
const customVoices = [];
|
|
285053
|
-
if (
|
|
285283
|
+
if (existsSync48(CUSTOM_VOICES_DIR)) {
|
|
285054
285284
|
for (const vf of readdirSync12(CUSTOM_VOICES_DIR)) {
|
|
285055
285285
|
if (vf.endsWith(".pt")) {
|
|
285056
285286
|
const name10 = vf.replace(".pt", "");
|
|
@@ -285159,9 +285389,9 @@ __export(setup_exports, {
|
|
|
285159
285389
|
updateOllama: () => updateOllama
|
|
285160
285390
|
});
|
|
285161
285391
|
import * as readline from "node:readline";
|
|
285162
|
-
import { execSync as
|
|
285392
|
+
import { execSync as execSync43, spawn as spawn21, exec as exec4 } from "node:child_process";
|
|
285163
285393
|
import { promisify as promisify7 } from "node:util";
|
|
285164
|
-
import { existsSync as
|
|
285394
|
+
import { existsSync as existsSync49, writeFileSync as writeFileSync22, readFileSync as readFileSync38, appendFileSync as appendFileSync2, mkdirSync as mkdirSync22 } from "node:fs";
|
|
285165
285395
|
import { join as join65 } from "node:path";
|
|
285166
285396
|
import { homedir as homedir18, platform as platform3 } from "node:os";
|
|
285167
285397
|
async function checkToolSupport(modelName, backendUrl = "http://localhost:11434") {
|
|
@@ -285197,7 +285427,7 @@ function detectSystemSpecs() {
|
|
|
285197
285427
|
let gpuVramGB = 0;
|
|
285198
285428
|
let gpuName = "";
|
|
285199
285429
|
try {
|
|
285200
|
-
const memInfo =
|
|
285430
|
+
const memInfo = execSync43("free -b 2>/dev/null || sysctl -n hw.memsize 2>/dev/null", {
|
|
285201
285431
|
encoding: "utf8",
|
|
285202
285432
|
timeout: 5e3
|
|
285203
285433
|
});
|
|
@@ -285217,7 +285447,7 @@ function detectSystemSpecs() {
|
|
|
285217
285447
|
} catch {
|
|
285218
285448
|
}
|
|
285219
285449
|
try {
|
|
285220
|
-
const nvidiaSmi =
|
|
285450
|
+
const nvidiaSmi = execSync43(
|
|
285221
285451
|
"nvidia-smi --query-gpu=memory.total,name --format=csv,noheader,nounits 2>/dev/null",
|
|
285222
285452
|
{ encoding: "utf8", timeout: 5e3 }
|
|
285223
285453
|
);
|
|
@@ -285391,7 +285621,7 @@ function ensureCurl() {
|
|
|
285391
285621
|
for (const s2 of strategies) {
|
|
285392
285622
|
if (hasCmd(s2.check)) {
|
|
285393
285623
|
try {
|
|
285394
|
-
|
|
285624
|
+
execSync43(s2.install, { stdio: "inherit", timeout: 12e4 });
|
|
285395
285625
|
if (hasCmd("curl")) {
|
|
285396
285626
|
process.stdout.write(` ${c3.green("\u2714")} curl installed via ${s2.label}.
|
|
285397
285627
|
`);
|
|
@@ -285405,7 +285635,7 @@ function ensureCurl() {
|
|
|
285405
285635
|
}
|
|
285406
285636
|
if (plat === "darwin") {
|
|
285407
285637
|
try {
|
|
285408
|
-
|
|
285638
|
+
execSync43("xcode-select --install", { stdio: "inherit", timeout: 3e5 });
|
|
285409
285639
|
if (hasCmd("curl")) return true;
|
|
285410
285640
|
} catch {
|
|
285411
285641
|
}
|
|
@@ -285439,7 +285669,7 @@ function installOllamaLinux() {
|
|
|
285439
285669
|
|
|
285440
285670
|
`);
|
|
285441
285671
|
try {
|
|
285442
|
-
|
|
285672
|
+
execSync43("curl -fsSL https://ollama.com/install.sh | sh", {
|
|
285443
285673
|
stdio: "inherit",
|
|
285444
285674
|
timeout: 3e5
|
|
285445
285675
|
});
|
|
@@ -285467,13 +285697,13 @@ async function installOllamaMac(_rl) {
|
|
|
285467
285697
|
|
|
285468
285698
|
`);
|
|
285469
285699
|
try {
|
|
285470
|
-
|
|
285700
|
+
execSync43(
|
|
285471
285701
|
'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"',
|
|
285472
285702
|
{ stdio: "inherit", timeout: 6e5 }
|
|
285473
285703
|
);
|
|
285474
285704
|
if (!hasCmd("brew")) {
|
|
285475
285705
|
try {
|
|
285476
|
-
const brewPrefix =
|
|
285706
|
+
const brewPrefix = existsSync49("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
|
|
285477
285707
|
process.env["PATH"] = `${brewPrefix}/bin:${process.env["PATH"]}`;
|
|
285478
285708
|
} catch {
|
|
285479
285709
|
}
|
|
@@ -285503,7 +285733,7 @@ async function installOllamaMac(_rl) {
|
|
|
285503
285733
|
|
|
285504
285734
|
`);
|
|
285505
285735
|
try {
|
|
285506
|
-
|
|
285736
|
+
execSync43("brew install ollama", {
|
|
285507
285737
|
stdio: "inherit",
|
|
285508
285738
|
timeout: 3e5
|
|
285509
285739
|
});
|
|
@@ -285530,7 +285760,7 @@ function installOllamaWindows() {
|
|
|
285530
285760
|
|
|
285531
285761
|
`);
|
|
285532
285762
|
try {
|
|
285533
|
-
|
|
285763
|
+
execSync43('powershell -Command "irm https://ollama.com/install.ps1 | iex"', {
|
|
285534
285764
|
stdio: "inherit",
|
|
285535
285765
|
timeout: 3e5
|
|
285536
285766
|
});
|
|
@@ -285610,7 +285840,7 @@ async function ensureOllamaRunning(backendUrl, rl) {
|
|
|
285610
285840
|
}
|
|
285611
285841
|
function getOllamaVersion() {
|
|
285612
285842
|
try {
|
|
285613
|
-
const out =
|
|
285843
|
+
const out = execSync43("ollama --version", { encoding: "utf8", timeout: 5e3 });
|
|
285614
285844
|
const match = out.match(/(\d+\.\d+\.\d+)/);
|
|
285615
285845
|
return match ? match[1] : null;
|
|
285616
285846
|
} catch {
|
|
@@ -285656,7 +285886,7 @@ function updateOllama() {
|
|
|
285656
285886
|
return false;
|
|
285657
285887
|
}
|
|
285658
285888
|
try {
|
|
285659
|
-
|
|
285889
|
+
execSync43("curl -fsSL https://ollama.com/install.sh | sh", {
|
|
285660
285890
|
stdio: "inherit",
|
|
285661
285891
|
timeout: 3e5
|
|
285662
285892
|
});
|
|
@@ -285667,7 +285897,7 @@ function updateOllama() {
|
|
|
285667
285897
|
}
|
|
285668
285898
|
function pullModelWithAutoUpdate(tag) {
|
|
285669
285899
|
try {
|
|
285670
|
-
|
|
285900
|
+
execSync43(`ollama pull ${tag}`, {
|
|
285671
285901
|
stdio: "inherit",
|
|
285672
285902
|
timeout: 36e5
|
|
285673
285903
|
// 1 hour max
|
|
@@ -285687,7 +285917,7 @@ function pullModelWithAutoUpdate(tag) {
|
|
|
285687
285917
|
|
|
285688
285918
|
`);
|
|
285689
285919
|
try {
|
|
285690
|
-
|
|
285920
|
+
execSync43("curl -fsSL https://ollama.com/install.sh | sh", {
|
|
285691
285921
|
stdio: "inherit",
|
|
285692
285922
|
timeout: 3e5
|
|
285693
285923
|
// 5 min max for install
|
|
@@ -285698,7 +285928,7 @@ function pullModelWithAutoUpdate(tag) {
|
|
|
285698
285928
|
process.stdout.write(` ${c3.cyan("\u25CF")} Retrying pull of ${c3.bold(tag)}...
|
|
285699
285929
|
|
|
285700
285930
|
`);
|
|
285701
|
-
|
|
285931
|
+
execSync43(`ollama pull ${tag}`, {
|
|
285702
285932
|
stdio: "inherit",
|
|
285703
285933
|
timeout: 36e5
|
|
285704
285934
|
});
|
|
@@ -285787,7 +286017,7 @@ function ensurePython3() {
|
|
|
285787
286017
|
if (plat === "darwin") {
|
|
285788
286018
|
if (hasCmd("brew")) {
|
|
285789
286019
|
try {
|
|
285790
|
-
|
|
286020
|
+
execSync43("brew install python3", { stdio: "inherit", timeout: 3e5 });
|
|
285791
286021
|
if (hasCmd("python3")) {
|
|
285792
286022
|
process.stdout.write(` ${c3.green("\u2714")} Python3 installed via Homebrew.
|
|
285793
286023
|
`);
|
|
@@ -285800,7 +286030,7 @@ function ensurePython3() {
|
|
|
285800
286030
|
for (const s2 of strategies) {
|
|
285801
286031
|
if (hasCmd(s2.check)) {
|
|
285802
286032
|
try {
|
|
285803
|
-
|
|
286033
|
+
execSync43(s2.install, { stdio: "inherit", timeout: 12e4 });
|
|
285804
286034
|
if (hasCmd("python3") || hasCmd("python")) {
|
|
285805
286035
|
process.stdout.write(` ${c3.green("\u2714")} Python3 installed via ${s2.label}.
|
|
285806
286036
|
`);
|
|
@@ -285816,11 +286046,11 @@ function ensurePython3() {
|
|
|
285816
286046
|
}
|
|
285817
286047
|
function checkPythonVenv() {
|
|
285818
286048
|
try {
|
|
285819
|
-
|
|
286049
|
+
execSync43("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
|
|
285820
286050
|
return true;
|
|
285821
286051
|
} catch {
|
|
285822
286052
|
try {
|
|
285823
|
-
|
|
286053
|
+
execSync43("python -m venv --help", { stdio: "pipe", timeout: 5e3 });
|
|
285824
286054
|
return true;
|
|
285825
286055
|
} catch {
|
|
285826
286056
|
return false;
|
|
@@ -285839,7 +286069,7 @@ function ensurePythonVenv() {
|
|
|
285839
286069
|
for (const s2 of strategies) {
|
|
285840
286070
|
if (hasCmd(s2.check)) {
|
|
285841
286071
|
try {
|
|
285842
|
-
|
|
286072
|
+
execSync43(s2.install, { stdio: "inherit", timeout: 12e4 });
|
|
285843
286073
|
if (checkPythonVenv()) {
|
|
285844
286074
|
process.stdout.write(` ${c3.green("\u2714")} python3-venv installed via ${s2.label}.
|
|
285845
286075
|
`);
|
|
@@ -286267,7 +286497,7 @@ async function doSetup(config, rl) {
|
|
|
286267
286497
|
const modelfilePath = join65(modelDir2, `Modelfile.${customName}`);
|
|
286268
286498
|
writeFileSync22(modelfilePath, modelfileContent + "\n", "utf8");
|
|
286269
286499
|
process.stdout.write(` ${c3.dim("Creating model...")} `);
|
|
286270
|
-
|
|
286500
|
+
execSync43(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
286271
286501
|
stdio: "pipe",
|
|
286272
286502
|
timeout: 12e4
|
|
286273
286503
|
});
|
|
@@ -286310,7 +286540,7 @@ async function isModelAvailable(config) {
|
|
|
286310
286540
|
}
|
|
286311
286541
|
function isFirstRun() {
|
|
286312
286542
|
try {
|
|
286313
|
-
return !
|
|
286543
|
+
return !existsSync49(join65(homedir18(), ".open-agents", "config.json"));
|
|
286314
286544
|
} catch {
|
|
286315
286545
|
return true;
|
|
286316
286546
|
}
|
|
@@ -286318,7 +286548,7 @@ function isFirstRun() {
|
|
|
286318
286548
|
function hasCmd(cmd) {
|
|
286319
286549
|
try {
|
|
286320
286550
|
const whichCmd = process.platform === "win32" ? `where ${cmd}` : `which ${cmd}`;
|
|
286321
|
-
|
|
286551
|
+
execSync43(whichCmd, { stdio: "pipe", timeout: 3e3 });
|
|
286322
286552
|
return true;
|
|
286323
286553
|
} catch {
|
|
286324
286554
|
return false;
|
|
@@ -286330,7 +286560,7 @@ function detectPkgManager() {
|
|
|
286330
286560
|
if (hasCmd("choco")) return "choco";
|
|
286331
286561
|
if (hasCmd("winget")) return "winget";
|
|
286332
286562
|
try {
|
|
286333
|
-
|
|
286563
|
+
execSync43(
|
|
286334
286564
|
`powershell -NoProfile -Command "Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))"`,
|
|
286335
286565
|
{ stdio: "pipe", timeout: 12e4 }
|
|
286336
286566
|
);
|
|
@@ -286342,7 +286572,7 @@ function detectPkgManager() {
|
|
|
286342
286572
|
if (plat === "darwin") {
|
|
286343
286573
|
if (hasCmd("brew")) return "brew";
|
|
286344
286574
|
try {
|
|
286345
|
-
|
|
286575
|
+
execSync43(
|
|
286346
286576
|
'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"',
|
|
286347
286577
|
{ stdio: "pipe", timeout: 3e5, env: { ...process.env, NONINTERACTIVE: "1" } }
|
|
286348
286578
|
);
|
|
@@ -286362,7 +286592,7 @@ function getVenvDir() {
|
|
|
286362
286592
|
}
|
|
286363
286593
|
function hasVenvModule() {
|
|
286364
286594
|
try {
|
|
286365
|
-
|
|
286595
|
+
execSync43("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
|
|
286366
286596
|
return true;
|
|
286367
286597
|
} catch {
|
|
286368
286598
|
return false;
|
|
@@ -286373,7 +286603,7 @@ function ensureVenv(log22) {
|
|
|
286373
286603
|
const isWin2 = process.platform === "win32";
|
|
286374
286604
|
const pipPath = isWin2 ? join65(venvDir, "Scripts", "pip.exe") : join65(venvDir, "bin", "pip");
|
|
286375
286605
|
const pythonCmd = isWin2 ? "python" : "python3";
|
|
286376
|
-
if (
|
|
286606
|
+
if (existsSync49(pipPath)) return venvDir;
|
|
286377
286607
|
log22("Creating Python venv for vision deps...");
|
|
286378
286608
|
if (!hasCmd(pythonCmd) && !hasCmd("python3")) {
|
|
286379
286609
|
log22(`${pythonCmd} not found \u2014 cannot create venv.`);
|
|
@@ -286386,8 +286616,8 @@ function ensureVenv(log22) {
|
|
|
286386
286616
|
try {
|
|
286387
286617
|
mkdirSync22(join65(homedir18(), ".open-agents"), { recursive: true });
|
|
286388
286618
|
const pyCmd = hasCmd(pythonCmd) ? pythonCmd : "python3";
|
|
286389
|
-
|
|
286390
|
-
|
|
286619
|
+
execSync43(`${pyCmd} -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
|
|
286620
|
+
execSync43(`"${pipPath}" install --upgrade pip`, {
|
|
286391
286621
|
stdio: "pipe",
|
|
286392
286622
|
timeout: 6e4
|
|
286393
286623
|
});
|
|
@@ -286400,7 +286630,7 @@ function ensureVenv(log22) {
|
|
|
286400
286630
|
}
|
|
286401
286631
|
function trySudoPasswordless(cmd, timeoutMs = 12e4) {
|
|
286402
286632
|
try {
|
|
286403
|
-
|
|
286633
|
+
execSync43(`sudo -n ${cmd}`, {
|
|
286404
286634
|
stdio: "pipe",
|
|
286405
286635
|
timeout: timeoutMs,
|
|
286406
286636
|
env: { ...process.env, DEBIAN_FRONTEND: "noninteractive" }
|
|
@@ -286413,7 +286643,7 @@ function trySudoPasswordless(cmd, timeoutMs = 12e4) {
|
|
|
286413
286643
|
function runWithSudo(cmd, password, timeoutMs = 12e4) {
|
|
286414
286644
|
try {
|
|
286415
286645
|
const escaped = cmd.replace(/'/g, "'\\''");
|
|
286416
|
-
|
|
286646
|
+
execSync43(`sudo -S bash -c '${escaped}'`, {
|
|
286417
286647
|
input: password + "\n",
|
|
286418
286648
|
stdio: ["pipe", "pipe", "pipe"],
|
|
286419
286649
|
timeout: timeoutMs,
|
|
@@ -286488,7 +286718,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
286488
286718
|
const _visionMarkerFile = join65(_visionMarkerDir, "vision-deps-installed.json");
|
|
286489
286719
|
let _visionPreviouslyInstalled = /* @__PURE__ */ new Set();
|
|
286490
286720
|
try {
|
|
286491
|
-
if (
|
|
286721
|
+
if (existsSync49(_visionMarkerFile)) {
|
|
286492
286722
|
const _vm = JSON.parse(readFileSync38(_visionMarkerFile, "utf8"));
|
|
286493
286723
|
_visionPreviouslyInstalled = new Set(_vm.installed || []);
|
|
286494
286724
|
}
|
|
@@ -286507,7 +286737,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
286507
286737
|
let winNeedsElevation = false;
|
|
286508
286738
|
if (process.platform === "win32") {
|
|
286509
286739
|
try {
|
|
286510
|
-
|
|
286740
|
+
execSync43("net session", { stdio: "pipe", timeout: 3e3 });
|
|
286511
286741
|
} catch {
|
|
286512
286742
|
winNeedsElevation = true;
|
|
286513
286743
|
log22(`Installing ${labels} via ${pm2} (requires admin \u2014 UAC prompt will appear)...`);
|
|
@@ -286554,12 +286784,12 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
286554
286784
|
if (needsSudo) {
|
|
286555
286785
|
await sudoInstall(installCmd, getPassword, log22, cachedPasswordRef, 18e4);
|
|
286556
286786
|
} else if (winNeedsElevation) {
|
|
286557
|
-
|
|
286787
|
+
execSync43(
|
|
286558
286788
|
`powershell -NoProfile -Command "Start-Process -FilePath 'cmd.exe' -ArgumentList '/c ${installCmd.replace(/'/g, "''")}' -Verb RunAs -Wait"`,
|
|
286559
286789
|
{ stdio: "pipe", timeout: 18e4 }
|
|
286560
286790
|
);
|
|
286561
286791
|
} else {
|
|
286562
|
-
|
|
286792
|
+
execSync43(installCmd, { stdio: "pipe", timeout: 18e4 });
|
|
286563
286793
|
}
|
|
286564
286794
|
} catch (e2) {
|
|
286565
286795
|
const stderr = e2.stderr?.toString?.()?.trim?.() ?? "";
|
|
@@ -286572,7 +286802,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
286572
286802
|
if (!hasCmd(d2.binary) && pipPkg) {
|
|
286573
286803
|
try {
|
|
286574
286804
|
const pipCmd = process.platform === "win32" ? `pip install ${pipPkg}` : `pip3 install ${pipPkg}`;
|
|
286575
|
-
|
|
286805
|
+
execSync43(pipCmd, { stdio: "pipe", timeout: 12e4 });
|
|
286576
286806
|
lastError = "";
|
|
286577
286807
|
} catch (e2) {
|
|
286578
286808
|
const stderr = e2.stderr?.toString?.()?.trim?.() ?? "";
|
|
@@ -286584,7 +286814,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
286584
286814
|
}
|
|
286585
286815
|
if (process.platform === "win32" && !hasCmd(d2.binary)) {
|
|
286586
286816
|
try {
|
|
286587
|
-
const freshPath =
|
|
286817
|
+
const freshPath = execSync43(
|
|
286588
286818
|
`powershell -NoProfile -Command "[System.Environment]::GetEnvironmentVariable('Path','Machine') + ';' + [System.Environment]::GetEnvironmentVariable('Path','User')"`,
|
|
286589
286819
|
{ encoding: "utf8", timeout: 5e3, stdio: "pipe" }
|
|
286590
286820
|
).trim();
|
|
@@ -286630,7 +286860,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
286630
286860
|
const venvCmds = {
|
|
286631
286861
|
apt: () => {
|
|
286632
286862
|
try {
|
|
286633
|
-
const pyVer =
|
|
286863
|
+
const pyVer = execSync43(
|
|
286634
286864
|
`python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"`,
|
|
286635
286865
|
{ encoding: "utf8", stdio: "pipe", timeout: 5e3 }
|
|
286636
286866
|
).trim();
|
|
@@ -286658,16 +286888,16 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
286658
286888
|
const venvBin = join65(venvDir, isWin2 ? "Scripts" : "bin");
|
|
286659
286889
|
const venvMoondream = join65(venvBin, isWin2 ? "moondream-station.exe" : "moondream-station");
|
|
286660
286890
|
const venv = ensureVenv(log22);
|
|
286661
|
-
if (venv && !hasCmd("moondream-station") && !
|
|
286891
|
+
if (venv && !hasCmd("moondream-station") && !existsSync49(venvMoondream)) {
|
|
286662
286892
|
const venvPip2 = join65(venvBin, "pip");
|
|
286663
286893
|
log22("Installing moondream-station in ~/.open-agents/venv...");
|
|
286664
286894
|
try {
|
|
286665
|
-
|
|
286666
|
-
if (
|
|
286895
|
+
execSync43(`"${venvPip2}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
|
|
286896
|
+
if (existsSync49(venvMoondream)) {
|
|
286667
286897
|
log22("moondream-station installed successfully.");
|
|
286668
286898
|
} else {
|
|
286669
286899
|
try {
|
|
286670
|
-
const check =
|
|
286900
|
+
const check = execSync43(`"${venvPip2}" show moondream-station`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 });
|
|
286671
286901
|
if (check.includes("moondream")) {
|
|
286672
286902
|
log22("moondream-station package installed.");
|
|
286673
286903
|
}
|
|
@@ -286684,7 +286914,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
286684
286914
|
const venvPip2 = join65(venvBin, isWin2 ? "pip.exe" : "pip");
|
|
286685
286915
|
let ocrStackInstalled = false;
|
|
286686
286916
|
try {
|
|
286687
|
-
|
|
286917
|
+
execSync43(
|
|
286688
286918
|
`"${venvPython2}" -c "import cv2, pytesseract, numpy, PIL"`,
|
|
286689
286919
|
{ stdio: "pipe", timeout: 1e4 }
|
|
286690
286920
|
);
|
|
@@ -286695,12 +286925,12 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
286695
286925
|
const ocrPackages = "pytesseract Pillow opencv-python-headless numpy";
|
|
286696
286926
|
log22("Installing OCR Python stack (pytesseract, OpenCV, Pillow, numpy)...");
|
|
286697
286927
|
try {
|
|
286698
|
-
|
|
286928
|
+
execSync43(
|
|
286699
286929
|
`"${venvPip2}" install ${ocrPackages}`,
|
|
286700
286930
|
{ stdio: "pipe", timeout: 3e5 }
|
|
286701
286931
|
);
|
|
286702
286932
|
try {
|
|
286703
|
-
|
|
286933
|
+
execSync43(
|
|
286704
286934
|
`"${venvPython2}" -c "import cv2, pytesseract, numpy, PIL"`,
|
|
286705
286935
|
{ stdio: "pipe", timeout: 1e4 }
|
|
286706
286936
|
);
|
|
@@ -286736,7 +286966,7 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
286736
286966
|
const archMap = { x64: "amd64", arm64: "arm64", arm: "arm" };
|
|
286737
286967
|
const cfArch = archMap[arch2] ?? "amd64";
|
|
286738
286968
|
try {
|
|
286739
|
-
|
|
286969
|
+
execSync43(
|
|
286740
286970
|
`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && mkdir -p "${homedir18()}/.local/bin" && mv /tmp/cloudflared "${homedir18()}/.local/bin/cloudflared"`,
|
|
286741
286971
|
{ stdio: "pipe", timeout: 6e4 }
|
|
286742
286972
|
);
|
|
@@ -286750,7 +286980,7 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
286750
286980
|
} catch {
|
|
286751
286981
|
}
|
|
286752
286982
|
try {
|
|
286753
|
-
|
|
286983
|
+
execSync43(
|
|
286754
286984
|
`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`,
|
|
286755
286985
|
{ stdio: "pipe", timeout: 6e4 }
|
|
286756
286986
|
);
|
|
@@ -286762,7 +286992,7 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
286762
286992
|
}
|
|
286763
286993
|
} else if (os8 === "darwin") {
|
|
286764
286994
|
try {
|
|
286765
|
-
|
|
286995
|
+
execSync43("brew install cloudflared", { stdio: "pipe", timeout: 12e4 });
|
|
286766
286996
|
if (hasCmd("cloudflared")) {
|
|
286767
286997
|
log22("cloudflared installed via Homebrew.");
|
|
286768
286998
|
return true;
|
|
@@ -286842,7 +287072,7 @@ function createExpandedVariant(baseModel, specs, sizeGB, kvBytesPerToken, archMa
|
|
|
286842
287072
|
mkdirSync22(modelDir2, { recursive: true });
|
|
286843
287073
|
const modelfilePath = join65(modelDir2, `Modelfile.${customName}`);
|
|
286844
287074
|
writeFileSync22(modelfilePath, modelfileContent + "\n", "utf8");
|
|
286845
|
-
|
|
287075
|
+
execSync43(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
286846
287076
|
stdio: "pipe",
|
|
286847
287077
|
timeout: 12e4
|
|
286848
287078
|
});
|
|
@@ -286928,7 +287158,7 @@ async function ensureExpandedContext(modelName, backendUrl) {
|
|
|
286928
287158
|
}
|
|
286929
287159
|
async function ensureNeovim() {
|
|
286930
287160
|
try {
|
|
286931
|
-
const nvimPath =
|
|
287161
|
+
const nvimPath = execSync43("which nvim 2>/dev/null || where nvim 2>nul", {
|
|
286932
287162
|
encoding: "utf8",
|
|
286933
287163
|
stdio: "pipe",
|
|
286934
287164
|
timeout: 5e3
|
|
@@ -286949,14 +287179,14 @@ async function ensureNeovim() {
|
|
|
286949
287179
|
const url = `https://github.com/neovim/neovim/releases/latest/download/${appImageName}`;
|
|
286950
287180
|
console.log(` Downloading Neovim (${appImageName})...`);
|
|
286951
287181
|
try {
|
|
286952
|
-
|
|
286953
|
-
|
|
287182
|
+
execSync43(`curl -fsSL "${url}" -o "${nvimDest}"`, { stdio: "pipe", timeout: 6e4 });
|
|
287183
|
+
execSync43(`chmod +x "${nvimDest}"`, { stdio: "pipe", timeout: 3e3 });
|
|
286954
287184
|
} catch (err) {
|
|
286955
287185
|
console.log(` Failed to download Neovim: ${err instanceof Error ? err.message : String(err)}`);
|
|
286956
287186
|
return null;
|
|
286957
287187
|
}
|
|
286958
287188
|
try {
|
|
286959
|
-
const ver =
|
|
287189
|
+
const ver = execSync43(`"${nvimDest}" --version`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).split("\n")[0];
|
|
286960
287190
|
console.log(` Installed: ${ver}`);
|
|
286961
287191
|
} catch {
|
|
286962
287192
|
console.log(" Warning: nvim binary downloaded but may not work (missing FUSE? Try: nvim --appimage-extract)");
|
|
@@ -286971,8 +287201,8 @@ async function ensureNeovim() {
|
|
|
286971
287201
|
if (hasCmd("brew")) {
|
|
286972
287202
|
console.log(" Installing Neovim via Homebrew...");
|
|
286973
287203
|
try {
|
|
286974
|
-
|
|
286975
|
-
const nvimPath =
|
|
287204
|
+
execSync43("brew install neovim", { stdio: "inherit", timeout: 12e4 });
|
|
287205
|
+
const nvimPath = execSync43("which nvim", { encoding: "utf8", stdio: "pipe", timeout: 3e3 }).trim();
|
|
286976
287206
|
return nvimPath || null;
|
|
286977
287207
|
} catch {
|
|
286978
287208
|
console.log(" brew install neovim failed.");
|
|
@@ -286986,7 +287216,7 @@ async function ensureNeovim() {
|
|
|
286986
287216
|
if (hasCmd("choco")) {
|
|
286987
287217
|
console.log(" Installing Neovim via Chocolatey...");
|
|
286988
287218
|
try {
|
|
286989
|
-
|
|
287219
|
+
execSync43("choco install neovim -y", { stdio: "inherit", timeout: 12e4 });
|
|
286990
287220
|
return "nvim";
|
|
286991
287221
|
} catch {
|
|
286992
287222
|
console.log(" choco install neovim failed.");
|
|
@@ -286995,7 +287225,7 @@ async function ensureNeovim() {
|
|
|
286995
287225
|
if (hasCmd("winget")) {
|
|
286996
287226
|
console.log(" Installing Neovim via winget...");
|
|
286997
287227
|
try {
|
|
286998
|
-
|
|
287228
|
+
execSync43("winget install Neovim.Neovim --accept-source-agreements --accept-package-agreements", {
|
|
286999
287229
|
stdio: "inherit",
|
|
287000
287230
|
timeout: 12e4
|
|
287001
287231
|
});
|
|
@@ -287013,7 +287243,7 @@ function ensurePathInShellRc(binDir) {
|
|
|
287013
287243
|
const shell = process.env.SHELL ?? "";
|
|
287014
287244
|
const rcFile = shell.includes("zsh") ? join65(homedir18(), ".zshrc") : join65(homedir18(), ".bashrc");
|
|
287015
287245
|
try {
|
|
287016
|
-
const rcContent =
|
|
287246
|
+
const rcContent = existsSync49(rcFile) ? readFileSync38(rcFile, "utf8") : "";
|
|
287017
287247
|
if (rcContent.includes(binDir)) return;
|
|
287018
287248
|
const exportLine = `
|
|
287019
287249
|
export PATH="${binDir}:$PATH" # Added by open-agents for nvim
|
|
@@ -287050,7 +287280,7 @@ var init_setup = __esm({
|
|
|
287050
287280
|
});
|
|
287051
287281
|
|
|
287052
287282
|
// packages/cli/src/tui/drop-panel.ts
|
|
287053
|
-
import { existsSync as
|
|
287283
|
+
import { existsSync as existsSync50 } from "node:fs";
|
|
287054
287284
|
import { extname as extname10, resolve as resolve31 } from "node:path";
|
|
287055
287285
|
function ansi4(code8, text) {
|
|
287056
287286
|
return isTTY4 ? `\x1B[${code8}m${text}\x1B[0m` : text;
|
|
@@ -287171,7 +287401,7 @@ function showDropPanel(opts) {
|
|
|
287171
287401
|
filePath = decodeURIComponent(filePath.slice(7));
|
|
287172
287402
|
}
|
|
287173
287403
|
filePath = resolve31(filePath);
|
|
287174
|
-
if (!
|
|
287404
|
+
if (!existsSync50(filePath)) {
|
|
287175
287405
|
errorMsg = `File not found: ${filePath}`;
|
|
287176
287406
|
render();
|
|
287177
287407
|
return;
|
|
@@ -287243,10 +287473,10 @@ var init_drop_panel = __esm({
|
|
|
287243
287473
|
});
|
|
287244
287474
|
|
|
287245
287475
|
// packages/cli/src/tui/neovim-mode.ts
|
|
287246
|
-
import { existsSync as
|
|
287476
|
+
import { existsSync as existsSync51, unlinkSync as unlinkSync12 } from "node:fs";
|
|
287247
287477
|
import { tmpdir as tmpdir12 } from "node:os";
|
|
287248
287478
|
import { join as join66 } from "node:path";
|
|
287249
|
-
import { execSync as
|
|
287479
|
+
import { execSync as execSync44 } from "node:child_process";
|
|
287250
287480
|
function isNeovimActive() {
|
|
287251
287481
|
return _state !== null && !_state.cleanedUp;
|
|
287252
287482
|
}
|
|
@@ -287263,7 +287493,7 @@ async function startNeovimMode(opts) {
|
|
|
287263
287493
|
}
|
|
287264
287494
|
let nvimPath;
|
|
287265
287495
|
try {
|
|
287266
|
-
nvimPath =
|
|
287496
|
+
nvimPath = execSync44("which nvim 2>/dev/null", { encoding: "utf8" }).trim();
|
|
287267
287497
|
if (!nvimPath) throw new Error();
|
|
287268
287498
|
} catch {
|
|
287269
287499
|
const installed = await ensureNeovim();
|
|
@@ -287293,7 +287523,7 @@ async function startNeovimMode(opts) {
|
|
|
287293
287523
|
}
|
|
287294
287524
|
const socketPath = join66(tmpdir12(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
|
|
287295
287525
|
try {
|
|
287296
|
-
if (
|
|
287526
|
+
if (existsSync51(socketPath)) unlinkSync12(socketPath);
|
|
287297
287527
|
} catch {
|
|
287298
287528
|
}
|
|
287299
287529
|
const ptyCols = opts.cols;
|
|
@@ -287540,12 +287770,12 @@ function resizeNeovim(cols, contentRows) {
|
|
|
287540
287770
|
}
|
|
287541
287771
|
async function connectRPC(state, neovimPkg, cols) {
|
|
287542
287772
|
let attempts = 0;
|
|
287543
|
-
while (!
|
|
287773
|
+
while (!existsSync51(state.socketPath) && attempts < 30) {
|
|
287544
287774
|
await new Promise((r2) => setTimeout(r2, 200));
|
|
287545
287775
|
attempts++;
|
|
287546
287776
|
if (state.cleanedUp) return;
|
|
287547
287777
|
}
|
|
287548
|
-
if (!
|
|
287778
|
+
if (!existsSync51(state.socketPath)) return;
|
|
287549
287779
|
const nvim = neovimPkg.attach({ socket: state.socketPath });
|
|
287550
287780
|
state.nvim = nvim;
|
|
287551
287781
|
await new Promise((r2) => setTimeout(r2, 300));
|
|
@@ -287682,7 +287912,7 @@ function doCleanup(state) {
|
|
|
287682
287912
|
state.pty = null;
|
|
287683
287913
|
}
|
|
287684
287914
|
try {
|
|
287685
|
-
if (
|
|
287915
|
+
if (existsSync51(state.socketPath)) unlinkSync12(state.socketPath);
|
|
287686
287916
|
} catch {
|
|
287687
287917
|
}
|
|
287688
287918
|
if (state.stdinHandler) {
|
|
@@ -287752,7 +287982,7 @@ __export(daemon_exports, {
|
|
|
287752
287982
|
stopDaemon: () => stopDaemon
|
|
287753
287983
|
});
|
|
287754
287984
|
import { spawn as spawn22 } from "node:child_process";
|
|
287755
|
-
import { existsSync as
|
|
287985
|
+
import { existsSync as existsSync52, readFileSync as readFileSync39, writeFileSync as writeFileSync23, mkdirSync as mkdirSync23, unlinkSync as unlinkSync13 } from "node:fs";
|
|
287756
287986
|
import { join as join67 } from "node:path";
|
|
287757
287987
|
import { homedir as homedir19 } from "node:os";
|
|
287758
287988
|
import { fileURLToPath as fileURLToPath13 } from "node:url";
|
|
@@ -287778,7 +288008,7 @@ async function isDaemonRunning(port) {
|
|
|
287778
288008
|
}
|
|
287779
288009
|
}
|
|
287780
288010
|
function getDaemonPid() {
|
|
287781
|
-
if (!
|
|
288011
|
+
if (!existsSync52(PID_FILE2)) return null;
|
|
287782
288012
|
try {
|
|
287783
288013
|
const pid = parseInt(readFileSync39(PID_FILE2, "utf8").trim(), 10);
|
|
287784
288014
|
if (!pid || pid <= 0) return null;
|
|
@@ -287798,8 +288028,8 @@ async function startDaemon() {
|
|
|
287798
288028
|
let oaScript = process.argv[1];
|
|
287799
288029
|
if (!oaScript) {
|
|
287800
288030
|
try {
|
|
287801
|
-
const { execSync:
|
|
287802
|
-
const whichOa =
|
|
288031
|
+
const { execSync: execSync51 } = await import("node:child_process");
|
|
288032
|
+
const whichOa = execSync51("which oa 2>/dev/null || where oa 2>nul", { encoding: "utf8" }).trim();
|
|
287803
288033
|
if (whichOa) oaScript = whichOa;
|
|
287804
288034
|
} catch {
|
|
287805
288035
|
}
|
|
@@ -287807,7 +288037,7 @@ async function startDaemon() {
|
|
|
287807
288037
|
if (!oaScript) {
|
|
287808
288038
|
const thisDir = dirname21(fileURLToPath13(import.meta.url));
|
|
287809
288039
|
const indexJs = join67(thisDir, "index.js");
|
|
287810
|
-
if (
|
|
288040
|
+
if (existsSync52(indexJs)) oaScript = indexJs;
|
|
287811
288041
|
}
|
|
287812
288042
|
if (!oaScript) return null;
|
|
287813
288043
|
try {
|
|
@@ -288291,7 +288521,7 @@ __export(sponsor_wizard_exports, {
|
|
|
288291
288521
|
saveSponsorConfig: () => saveSponsorConfig,
|
|
288292
288522
|
showSponsorDashboard: () => showSponsorDashboard
|
|
288293
288523
|
});
|
|
288294
|
-
import { existsSync as
|
|
288524
|
+
import { existsSync as existsSync53, readFileSync as readFileSync40, writeFileSync as writeFileSync24, mkdirSync as mkdirSync24 } from "node:fs";
|
|
288295
288525
|
import { join as join68 } from "node:path";
|
|
288296
288526
|
function colorPreview(code8) {
|
|
288297
288527
|
return `\x1B[38;5;${code8}m\u2588\u2588\u2588\u2588\x1B[0m (${code8})`;
|
|
@@ -288312,7 +288542,7 @@ function configPath(projectDir) {
|
|
|
288312
288542
|
}
|
|
288313
288543
|
function loadSponsorConfig(projectDir) {
|
|
288314
288544
|
const p2 = configPath(projectDir);
|
|
288315
|
-
if (!
|
|
288545
|
+
if (!existsSync53(p2)) return null;
|
|
288316
288546
|
try {
|
|
288317
288547
|
return JSON.parse(readFileSync40(p2, "utf8"));
|
|
288318
288548
|
} catch {
|
|
@@ -289203,10 +289433,10 @@ __export(voice_exports, {
|
|
|
289203
289433
|
registerCustomOnnxModel: () => registerCustomOnnxModel,
|
|
289204
289434
|
resetNarrationContext: () => resetNarrationContext
|
|
289205
289435
|
});
|
|
289206
|
-
import { existsSync as
|
|
289436
|
+
import { existsSync as existsSync54, mkdirSync as mkdirSync25, writeFileSync as writeFileSync25, readFileSync as readFileSync41, unlinkSync as unlinkSync14, readdirSync as readdirSync13, statSync as statSync18 } from "node:fs";
|
|
289207
289437
|
import { join as join69, dirname as dirname22 } from "node:path";
|
|
289208
289438
|
import { homedir as homedir20, tmpdir as tmpdir13, platform as platform4 } from "node:os";
|
|
289209
|
-
import { execSync as
|
|
289439
|
+
import { execSync as execSync45, spawn as nodeSpawn } from "node:child_process";
|
|
289210
289440
|
import { createRequire as createRequire2 } from "node:module";
|
|
289211
289441
|
function sanitizeForTTS(text) {
|
|
289212
289442
|
return text.replace(/^#{1,6}\s+/gm, "").replace(/\*{1,3}([^*]+)\*{1,3}/g, "$1").replace(/_{1,3}([^_]+)_{1,3}/g, "$1").replace(/~~([^~]+)~~/g, "$1").replace(/`([^`]+)`/g, "$1").replace(/```[\s\S]*?```/g, "").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/!\[([^\]]*)\]\([^)]+\)/g, "$1").replace(/^[\s]*[-*+]\s+/gm, "").replace(/^[\s]*\d+\.\s+/gm, "").replace(/^>\s+/gm, "").replace(/^[-*_]{3,}$/gm, "").replace(/\[[ xX]\]\s*/g, "").replace(/[\u{1F600}-\u{1F64F}]/gu, "").replace(/[\u{1F300}-\u{1F5FF}]/gu, "").replace(/[\u{1F680}-\u{1F6FF}]/gu, "").replace(/[\u{1F1E0}-\u{1F1FF}]/gu, "").replace(/[\u{2600}-\u{26FF}]/gu, "").replace(/[\u{2700}-\u{27BF}]/gu, "").replace(/[\u{FE00}-\u{FE0F}]/gu, "").replace(/[\u{1F900}-\u{1F9FF}]/gu, "").replace(/[\u{1FA00}-\u{1FA6F}]/gu, "").replace(/[\u{1FA70}-\u{1FAFF}]/gu, "").replace(/[\u{200D}]/gu, "").replace(/[\u{20E3}]/gu, "").replace(/[✓✔✗✘✕✖⚠️⏸⏹⏵●○◆◇■□▪▫►▼▲◀⬆⬇⬅➡↑↓←→⇐⇒⇑⇓]/g, "").replace(/[─━│┃┌┐└┘├┤┬┴┼╔╗╚╝╠╣╦╩╬⎿⎾▕▏⏐░▒▓█⠀-⣿]/g, "").replace(/\s{2,}/g, " ").trim();
|
|
@@ -289259,7 +289489,7 @@ function luxttsInferScript() {
|
|
|
289259
289489
|
return join69(voiceDir(), "luxtts-infer.py");
|
|
289260
289490
|
}
|
|
289261
289491
|
function writeDetectTorchScript(targetPath) {
|
|
289262
|
-
if (
|
|
289492
|
+
if (existsSync54(targetPath)) return;
|
|
289263
289493
|
try {
|
|
289264
289494
|
mkdirSync25(dirname22(targetPath), { recursive: true });
|
|
289265
289495
|
} catch {
|
|
@@ -290085,7 +290315,7 @@ var init_voice = __esm({
|
|
|
290085
290315
|
const targets = ["glados", "overwatch"];
|
|
290086
290316
|
for (const modelId of targets) {
|
|
290087
290317
|
const refFile = join69(refsDir, `${modelId}-ref.wav`);
|
|
290088
|
-
if (
|
|
290318
|
+
if (existsSync54(refFile)) continue;
|
|
290089
290319
|
try {
|
|
290090
290320
|
await this.generateCloneRef(modelId);
|
|
290091
290321
|
const meta = this.loadCloneMeta();
|
|
@@ -290163,13 +290393,13 @@ var init_voice = __esm({
|
|
|
290163
290393
|
if (p2.startsWith("~/") || p2 === "~") {
|
|
290164
290394
|
p2 = join69(homedir20(), p2.slice(1));
|
|
290165
290395
|
}
|
|
290166
|
-
if (!
|
|
290396
|
+
if (!existsSync54(p2)) {
|
|
290167
290397
|
return `File not found: ${p2}
|
|
290168
290398
|
(original input: ${audioPath})`;
|
|
290169
290399
|
}
|
|
290170
290400
|
audioPath = p2;
|
|
290171
290401
|
const refsDir = luxttsCloneRefsDir();
|
|
290172
|
-
if (!
|
|
290402
|
+
if (!existsSync54(refsDir)) mkdirSync25(refsDir, { recursive: true });
|
|
290173
290403
|
const ext = audioPath.split(".").pop() || "wav";
|
|
290174
290404
|
const srcName = (audioPath.split("/").pop() ?? "clone").replace(/\.[^.]+$/, "").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
290175
290405
|
const ts = Date.now().toString(36);
|
|
@@ -290217,7 +290447,7 @@ var init_voice = __esm({
|
|
|
290217
290447
|
return `Failed to synthesize reference audio from ${source.label}.`;
|
|
290218
290448
|
}
|
|
290219
290449
|
const refsDir = luxttsCloneRefsDir();
|
|
290220
|
-
if (!
|
|
290450
|
+
if (!existsSync54(refsDir)) mkdirSync25(refsDir, { recursive: true });
|
|
290221
290451
|
const destPath = join69(refsDir, `${sourceModelId}-ref.wav`);
|
|
290222
290452
|
const sampleRate = this.config?.audio?.sample_rate ?? 22050;
|
|
290223
290453
|
this.writeWav(audioData, sampleRate, destPath);
|
|
@@ -290238,7 +290468,7 @@ var init_voice = __esm({
|
|
|
290238
290468
|
}
|
|
290239
290469
|
loadCloneMeta() {
|
|
290240
290470
|
const p2 = _VoiceEngine.cloneMetaFile();
|
|
290241
|
-
if (!
|
|
290471
|
+
if (!existsSync54(p2)) return {};
|
|
290242
290472
|
try {
|
|
290243
290473
|
return JSON.parse(readFileSync41(p2, "utf8"));
|
|
290244
290474
|
} catch {
|
|
@@ -290247,7 +290477,7 @@ var init_voice = __esm({
|
|
|
290247
290477
|
}
|
|
290248
290478
|
saveCloneMeta(meta) {
|
|
290249
290479
|
const dir = luxttsCloneRefsDir();
|
|
290250
|
-
if (!
|
|
290480
|
+
if (!existsSync54(dir)) mkdirSync25(dir, { recursive: true });
|
|
290251
290481
|
writeFileSync25(_VoiceEngine.cloneMetaFile(), JSON.stringify(meta, null, 2));
|
|
290252
290482
|
}
|
|
290253
290483
|
/** Audio file extensions recognized as clone references */
|
|
@@ -290258,7 +290488,7 @@ var init_voice = __esm({
|
|
|
290258
290488
|
*/
|
|
290259
290489
|
listCloneRefs() {
|
|
290260
290490
|
const dir = luxttsCloneRefsDir();
|
|
290261
|
-
if (!
|
|
290491
|
+
if (!existsSync54(dir)) return [];
|
|
290262
290492
|
const meta = this.loadCloneMeta();
|
|
290263
290493
|
const files = readdirSync13(dir).filter((f2) => {
|
|
290264
290494
|
const ext = f2.split(".").pop()?.toLowerCase() ?? "";
|
|
@@ -290283,7 +290513,7 @@ var init_voice = __esm({
|
|
|
290283
290513
|
/** Delete a clone reference file by filename. Returns true if deleted. */
|
|
290284
290514
|
deleteCloneRef(filename) {
|
|
290285
290515
|
const p2 = join69(luxttsCloneRefsDir(), filename);
|
|
290286
|
-
if (!
|
|
290516
|
+
if (!existsSync54(p2)) return false;
|
|
290287
290517
|
try {
|
|
290288
290518
|
unlinkSync14(p2);
|
|
290289
290519
|
const meta = this.loadCloneMeta();
|
|
@@ -290307,7 +290537,7 @@ var init_voice = __esm({
|
|
|
290307
290537
|
/** Set the active clone reference by filename. */
|
|
290308
290538
|
setActiveCloneRef(filename) {
|
|
290309
290539
|
const p2 = join69(luxttsCloneRefsDir(), filename);
|
|
290310
|
-
if (!
|
|
290540
|
+
if (!existsSync54(p2)) return `File not found: ${filename}`;
|
|
290311
290541
|
this.luxttsCloneRef = p2;
|
|
290312
290542
|
return `Active clone voice set to: ${filename}`;
|
|
290313
290543
|
}
|
|
@@ -290894,7 +291124,7 @@ var init_voice = __esm({
|
|
|
290894
291124
|
}
|
|
290895
291125
|
for (const player of ["paplay", "pw-play", "aplay"]) {
|
|
290896
291126
|
try {
|
|
290897
|
-
|
|
291127
|
+
execSync45(`which ${player}`, { stdio: "pipe" });
|
|
290898
291128
|
return [player, path5];
|
|
290899
291129
|
} catch {
|
|
290900
291130
|
}
|
|
@@ -290922,7 +291152,7 @@ var init_voice = __esm({
|
|
|
290922
291152
|
if (this.python3Path) return this.python3Path;
|
|
290923
291153
|
for (const bin of ["python3", "python"]) {
|
|
290924
291154
|
try {
|
|
290925
|
-
const path5 =
|
|
291155
|
+
const path5 = execSync45(`which ${bin}`, { stdio: "pipe", timeout: 5e3 }).toString().trim();
|
|
290926
291156
|
if (path5) {
|
|
290927
291157
|
this.python3Path = path5;
|
|
290928
291158
|
return path5;
|
|
@@ -290984,7 +291214,7 @@ var init_voice = __esm({
|
|
|
290984
291214
|
return false;
|
|
290985
291215
|
}
|
|
290986
291216
|
try {
|
|
290987
|
-
|
|
291217
|
+
execSync45(`${py} -c "import mlx_audio"`, { stdio: "pipe", timeout: 1e4 });
|
|
290988
291218
|
this.mlxInstalled = true;
|
|
290989
291219
|
return true;
|
|
290990
291220
|
} catch {
|
|
@@ -291047,14 +291277,14 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
291047
291277
|
`tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
|
|
291048
291278
|
].join("; ");
|
|
291049
291279
|
try {
|
|
291050
|
-
|
|
291280
|
+
execSync45(
|
|
291051
291281
|
`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`,
|
|
291052
291282
|
{ stdio: "pipe", timeout: 6e4, cwd: tmpdir13() }
|
|
291053
291283
|
);
|
|
291054
291284
|
} catch (err) {
|
|
291055
291285
|
try {
|
|
291056
291286
|
const safeText = cleaned.replace(/'/g, "'\\''");
|
|
291057
|
-
|
|
291287
|
+
execSync45(
|
|
291058
291288
|
`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`,
|
|
291059
291289
|
{ stdio: "pipe", timeout: 6e4, cwd: tmpdir13() }
|
|
291060
291290
|
);
|
|
@@ -291062,7 +291292,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
291062
291292
|
return;
|
|
291063
291293
|
}
|
|
291064
291294
|
}
|
|
291065
|
-
if (!
|
|
291295
|
+
if (!existsSync54(wavPath)) return;
|
|
291066
291296
|
if (volume !== 1) {
|
|
291067
291297
|
try {
|
|
291068
291298
|
const wavData = readFileSync41(wavPath);
|
|
@@ -291121,14 +291351,14 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
291121
291351
|
`tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
|
|
291122
291352
|
].join("; ");
|
|
291123
291353
|
try {
|
|
291124
|
-
|
|
291354
|
+
execSync45(
|
|
291125
291355
|
`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`,
|
|
291126
291356
|
{ stdio: "pipe", timeout: 6e4, cwd: tmpdir13() }
|
|
291127
291357
|
);
|
|
291128
291358
|
} catch {
|
|
291129
291359
|
try {
|
|
291130
291360
|
const safeText = cleaned.replace(/'/g, "'\\''");
|
|
291131
|
-
|
|
291361
|
+
execSync45(
|
|
291132
291362
|
`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`,
|
|
291133
291363
|
{ stdio: "pipe", timeout: 6e4, cwd: tmpdir13() }
|
|
291134
291364
|
);
|
|
@@ -291136,7 +291366,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
291136
291366
|
return null;
|
|
291137
291367
|
}
|
|
291138
291368
|
}
|
|
291139
|
-
if (!
|
|
291369
|
+
if (!existsSync54(wavPath)) return null;
|
|
291140
291370
|
try {
|
|
291141
291371
|
const data = readFileSync41(wavPath);
|
|
291142
291372
|
unlinkSync14(wavPath);
|
|
@@ -291163,7 +291393,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
291163
291393
|
}
|
|
291164
291394
|
const venvDir = luxttsVenvDir();
|
|
291165
291395
|
const venvPy = luxttsVenvPy();
|
|
291166
|
-
if (
|
|
291396
|
+
if (existsSync54(venvPy)) {
|
|
291167
291397
|
try {
|
|
291168
291398
|
const quotedPy = `"${venvPy}"`;
|
|
291169
291399
|
const repoPath = luxttsRepoDir().replace(/\\/g, "/");
|
|
@@ -291212,7 +291442,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
291212
291442
|
}
|
|
291213
291443
|
}
|
|
291214
291444
|
renderInfo("Setting up LuxTTS voice cloning (first-time setup, this takes several minutes)...");
|
|
291215
|
-
if (!
|
|
291445
|
+
if (!existsSync54(venvDir)) {
|
|
291216
291446
|
renderInfo(" Creating Python virtual environment...");
|
|
291217
291447
|
try {
|
|
291218
291448
|
await this.asyncShell(`${py} -m venv ${JSON.stringify(venvDir)}`, 6e4);
|
|
@@ -291268,10 +291498,10 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
291268
291498
|
}
|
|
291269
291499
|
}
|
|
291270
291500
|
const repoDir = luxttsRepoDir();
|
|
291271
|
-
if (!
|
|
291501
|
+
if (!existsSync54(join69(repoDir, "zipvoice", "luxvoice.py"))) {
|
|
291272
291502
|
renderInfo(" Cloning LuxTTS repository...");
|
|
291273
291503
|
try {
|
|
291274
|
-
if (
|
|
291504
|
+
if (existsSync54(repoDir)) {
|
|
291275
291505
|
const rmCmd = process.platform === "win32" ? `rmdir /s /q ${JSON.stringify(repoDir)}` : `rm -rf ${JSON.stringify(repoDir)}`;
|
|
291276
291506
|
await this.asyncShell(rmCmd, 3e4);
|
|
291277
291507
|
}
|
|
@@ -291360,7 +291590,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
291360
291590
|
renderWarning(` Could not install system build deps: ${err instanceof Error ? err.message : String(err)}`);
|
|
291361
291591
|
}
|
|
291362
291592
|
}
|
|
291363
|
-
const isJetson = isArm && (
|
|
291593
|
+
const isJetson = isArm && (existsSync54("/etc/nv_tegra_release") || existsSync54("/usr/local/cuda/targets/aarch64-linux") || (process.env.JETSON_L4T_VERSION ?? "") !== "");
|
|
291364
291594
|
const installSteps = isArm ? [
|
|
291365
291595
|
// ARM: install individually so we get clear error messages per package.
|
|
291366
291596
|
// ALL are fatal because LuxTTS hard-imports them (no lazy/optional imports).
|
|
@@ -291435,12 +291665,12 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
291435
291665
|
}
|
|
291436
291666
|
/** Auto-detect an existing clone reference in the refs directory */
|
|
291437
291667
|
autoDetectCloneRef() {
|
|
291438
|
-
if (this.luxttsCloneRef &&
|
|
291668
|
+
if (this.luxttsCloneRef && existsSync54(this.luxttsCloneRef)) return;
|
|
291439
291669
|
const refsDir = luxttsCloneRefsDir();
|
|
291440
|
-
if (!
|
|
291670
|
+
if (!existsSync54(refsDir)) return;
|
|
291441
291671
|
for (const name10 of ["custom-clone.wav", "custom-clone.mp3", "glados-ref.wav", "overwatch-ref.wav"]) {
|
|
291442
291672
|
const p2 = join69(refsDir, name10);
|
|
291443
|
-
if (
|
|
291673
|
+
if (existsSync54(p2)) {
|
|
291444
291674
|
this.luxttsCloneRef = p2;
|
|
291445
291675
|
return;
|
|
291446
291676
|
}
|
|
@@ -291547,7 +291777,7 @@ if __name__ == '__main__':
|
|
|
291547
291777
|
async ensureLuxttsDaemon() {
|
|
291548
291778
|
if (this._luxttsDaemon && !this._luxttsDaemon.killed) return true;
|
|
291549
291779
|
const venvPy = luxttsVenvPy();
|
|
291550
|
-
if (!
|
|
291780
|
+
if (!existsSync54(venvPy)) return false;
|
|
291551
291781
|
return new Promise((resolve39) => {
|
|
291552
291782
|
const env2 = { ...process.env, LUXTTS_REPO_PATH: luxttsRepoDir() };
|
|
291553
291783
|
const daemon = nodeSpawn(venvPy, [luxttsInferScript()], {
|
|
@@ -291636,7 +291866,7 @@ if __name__ == '__main__':
|
|
|
291636
291866
|
* Used by drainQueue's pre-fetch pipeline for gapless back-to-back playback.
|
|
291637
291867
|
*/
|
|
291638
291868
|
async synthesizeLuxttsWav(text, speedFactor = 1) {
|
|
291639
|
-
if (!this.luxttsCloneRef || !
|
|
291869
|
+
if (!this.luxttsCloneRef || !existsSync54(this.luxttsCloneRef)) return null;
|
|
291640
291870
|
const cleaned = text.replace(/\*/g, "").trim();
|
|
291641
291871
|
if (!cleaned) return null;
|
|
291642
291872
|
const ready = await this.ensureLuxttsDaemon();
|
|
@@ -291653,14 +291883,14 @@ if __name__ == '__main__':
|
|
|
291653
291883
|
} catch {
|
|
291654
291884
|
return null;
|
|
291655
291885
|
}
|
|
291656
|
-
return
|
|
291886
|
+
return existsSync54(wavPath) ? wavPath : null;
|
|
291657
291887
|
}
|
|
291658
291888
|
/**
|
|
291659
291889
|
* Post-process (fade-in, volume, pitch, stereo) and play a LuxTTS WAV file.
|
|
291660
291890
|
* Cleans up the WAV file after playback.
|
|
291661
291891
|
*/
|
|
291662
291892
|
async postProcessAndPlayLuxtts(wavPath, volume = 1, pitchFactor = 1, stereoDelayMs = 0.6) {
|
|
291663
|
-
if (!
|
|
291893
|
+
if (!existsSync54(wavPath)) return;
|
|
291664
291894
|
try {
|
|
291665
291895
|
const wavData = readFileSync41(wavPath);
|
|
291666
291896
|
if (wavData.length > 44) {
|
|
@@ -291756,7 +291986,7 @@ if __name__ == '__main__':
|
|
|
291756
291986
|
* Used for Telegram voice messages and WebSocket streaming.
|
|
291757
291987
|
*/
|
|
291758
291988
|
async synthesizeLuxttsToBuffer(text) {
|
|
291759
|
-
if (!this.luxttsCloneRef || !
|
|
291989
|
+
if (!this.luxttsCloneRef || !existsSync54(this.luxttsCloneRef)) return null;
|
|
291760
291990
|
const cleaned = text.replace(/\*/g, "").trim();
|
|
291761
291991
|
if (!cleaned) return null;
|
|
291762
291992
|
const ready = await this.ensureLuxttsDaemon();
|
|
@@ -291773,7 +292003,7 @@ if __name__ == '__main__':
|
|
|
291773
292003
|
} catch {
|
|
291774
292004
|
return null;
|
|
291775
292005
|
}
|
|
291776
|
-
if (!
|
|
292006
|
+
if (!existsSync54(wavPath)) return null;
|
|
291777
292007
|
try {
|
|
291778
292008
|
const data = readFileSync41(wavPath);
|
|
291779
292009
|
unlinkSync14(wavPath);
|
|
@@ -291794,7 +292024,7 @@ if __name__ == '__main__':
|
|
|
291794
292024
|
"onnxruntime-node": "^1.21.0",
|
|
291795
292025
|
"phonemizer": "^1.2.1"
|
|
291796
292026
|
};
|
|
291797
|
-
if (
|
|
292027
|
+
if (existsSync54(pkgPath)) {
|
|
291798
292028
|
try {
|
|
291799
292029
|
const existing = JSON.parse(readFileSync41(pkgPath, "utf8"));
|
|
291800
292030
|
if (!existing.dependencies?.["phonemizer"]) {
|
|
@@ -291804,7 +292034,7 @@ if __name__ == '__main__':
|
|
|
291804
292034
|
} catch {
|
|
291805
292035
|
}
|
|
291806
292036
|
}
|
|
291807
|
-
if (!
|
|
292037
|
+
if (!existsSync54(pkgPath)) {
|
|
291808
292038
|
writeFileSync25(pkgPath, JSON.stringify({
|
|
291809
292039
|
name: "open-agents-voice",
|
|
291810
292040
|
private: true,
|
|
@@ -291824,7 +292054,7 @@ if __name__ == '__main__':
|
|
|
291824
292054
|
}
|
|
291825
292055
|
};
|
|
291826
292056
|
const onnxNodeModules = join69(voiceDir(), "node_modules", "onnxruntime-node");
|
|
291827
|
-
const onnxInstalled =
|
|
292057
|
+
const onnxInstalled = existsSync54(onnxNodeModules);
|
|
291828
292058
|
if (onnxInstalled && !await probeOnnx()) {
|
|
291829
292059
|
throw new Error(
|
|
291830
292060
|
`Voice synthesis unavailable: ONNX runtime crashes on this CPU (${process.platform}-${arch2}). 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.`
|
|
@@ -291883,16 +292113,16 @@ Error: ${err instanceof Error ? err.message : String(err)}`
|
|
|
291883
292113
|
const dir = modelDir(id);
|
|
291884
292114
|
const onnxPath = modelOnnxPath(id);
|
|
291885
292115
|
const configPath2 = modelConfigPath(id);
|
|
291886
|
-
if (
|
|
292116
|
+
if (existsSync54(onnxPath) && existsSync54(configPath2)) return;
|
|
291887
292117
|
mkdirSync25(dir, { recursive: true });
|
|
291888
|
-
if (!
|
|
292118
|
+
if (!existsSync54(configPath2)) {
|
|
291889
292119
|
renderInfo(`Downloading ${model.label} voice config...`);
|
|
291890
292120
|
const configResp = await fetch(model.configUrl);
|
|
291891
292121
|
if (!configResp.ok) throw new Error(`Failed to download config: HTTP ${configResp.status}`);
|
|
291892
292122
|
const configText = await configResp.text();
|
|
291893
292123
|
writeFileSync25(configPath2, configText);
|
|
291894
292124
|
}
|
|
291895
|
-
if (!
|
|
292125
|
+
if (!existsSync54(onnxPath)) {
|
|
291896
292126
|
renderInfo(`Downloading ${model.label} voice model (this may take a minute)...`);
|
|
291897
292127
|
const onnxResp = await fetch(model.onnxUrl);
|
|
291898
292128
|
if (!onnxResp.ok) throw new Error(`Failed to download model: HTTP ${onnxResp.status}`);
|
|
@@ -291925,7 +292155,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`
|
|
|
291925
292155
|
if (!this.ort) throw new Error("ONNX runtime not loaded");
|
|
291926
292156
|
const onnxPath = modelOnnxPath(this.modelId);
|
|
291927
292157
|
const configPath2 = modelConfigPath(this.modelId);
|
|
291928
|
-
if (!
|
|
292158
|
+
if (!existsSync54(onnxPath) || !existsSync54(configPath2)) {
|
|
291929
292159
|
throw new Error(`Model files not found for ${this.modelId}`);
|
|
291930
292160
|
}
|
|
291931
292161
|
this.config = JSON.parse(readFileSync41(configPath2, "utf8"));
|
|
@@ -291955,7 +292185,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`
|
|
|
291955
292185
|
// packages/cli/src/tui/commands.ts
|
|
291956
292186
|
import * as nodeOs from "node:os";
|
|
291957
292187
|
import { execSync as nodeExecSync } from "node:child_process";
|
|
291958
|
-
import { existsSync as
|
|
292188
|
+
import { existsSync as existsSync55, readFileSync as readFileSync42, writeFileSync as writeFileSync26, mkdirSync as mkdirSync26, readdirSync as readdirSync14, statSync as statSync19, rmSync as rmSync2, appendFileSync as appendFileSync3 } from "node:fs";
|
|
291959
292189
|
import { join as join70 } from "node:path";
|
|
291960
292190
|
async function _immediateReregister(newUrl) {
|
|
291961
292191
|
if (!_lastRegisteredSponsorPayload) return;
|
|
@@ -292470,7 +292700,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
292470
292700
|
renderInfo(out.split("\n").slice(0, 4).join("\n"));
|
|
292471
292701
|
try {
|
|
292472
292702
|
const pidFile = join70(ctx3.repoRoot ?? process.cwd(), ".oa", "nexus", "daemon.pid");
|
|
292473
|
-
if (
|
|
292703
|
+
if (existsSync55(pidFile)) {
|
|
292474
292704
|
const pid = parseInt(readFileSync42(pidFile, "utf8").trim(), 10);
|
|
292475
292705
|
if (pid > 0 && !registry2.daemons.has("Nexus")) {
|
|
292476
292706
|
registry2.register({ name: "Nexus", pid, startedAt: Date.now(), status: "running" });
|
|
@@ -292777,7 +293007,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
292777
293007
|
if (shareType === "tool") {
|
|
292778
293008
|
const toolDir = join70(ctx3.repoRoot, ".oa", "tools");
|
|
292779
293009
|
const toolFile = join70(toolDir, shareName.endsWith(".json") ? shareName : `${shareName}.json`);
|
|
292780
|
-
if (!
|
|
293010
|
+
if (!existsSync55(toolFile)) {
|
|
292781
293011
|
renderWarning(`Tool not found: ${toolFile}`);
|
|
292782
293012
|
return "handled";
|
|
292783
293013
|
}
|
|
@@ -292786,7 +293016,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
292786
293016
|
} else if (shareType === "skill") {
|
|
292787
293017
|
const skillDir = join70(ctx3.repoRoot, ".oa", "skills", shareName);
|
|
292788
293018
|
const skillFile = join70(skillDir, "SKILL.md");
|
|
292789
|
-
if (!
|
|
293019
|
+
if (!existsSync55(skillFile)) {
|
|
292790
293020
|
renderWarning(`Skill not found: ${skillFile}`);
|
|
292791
293021
|
return "handled";
|
|
292792
293022
|
}
|
|
@@ -292828,7 +293058,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
292828
293058
|
const nexus = new NexusTool(ctx3.repoRoot);
|
|
292829
293059
|
await nexus.execute({ action: "ipfs_pin", cid: importCid, source: "import" });
|
|
292830
293060
|
const regFile = join70(ctx3.repoRoot, ".oa", "nexus", "ipfs", "cid-registry", "learning-cids.json");
|
|
292831
|
-
if (
|
|
293061
|
+
if (existsSync55(regFile)) {
|
|
292832
293062
|
const reg = JSON.parse(readFileSync42(regFile, "utf8"));
|
|
292833
293063
|
const pinned = Object.values(reg).some((e2) => e2.cid === importCid && e2.pinned);
|
|
292834
293064
|
if (pinned) {
|
|
@@ -292887,7 +293117,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
292887
293117
|
let heliaBlocks = 0;
|
|
292888
293118
|
let heliaBytes = 0;
|
|
292889
293119
|
try {
|
|
292890
|
-
if (
|
|
293120
|
+
if (existsSync55(ipfsLocalDir)) {
|
|
292891
293121
|
const files = readdirSync14(ipfsLocalDir).filter((f2) => f2.endsWith(".json"));
|
|
292892
293122
|
ipfsFiles = files.length;
|
|
292893
293123
|
for (const f2 of files) {
|
|
@@ -292898,7 +293128,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
292898
293128
|
}
|
|
292899
293129
|
}
|
|
292900
293130
|
const heliaBlockDir = join70(ipfsDir, "blocks");
|
|
292901
|
-
if (
|
|
293131
|
+
if (existsSync55(heliaBlockDir)) {
|
|
292902
293132
|
const walkDir = (dir) => {
|
|
292903
293133
|
for (const entry of readdirSync14(dir, { withFileTypes: true })) {
|
|
292904
293134
|
if (entry.isDirectory()) walkDir(join70(dir, entry.name));
|
|
@@ -292922,7 +293152,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
292922
293152
|
lines.push(` Backend: ${heliaBlocks > 0 ? c3.green("helia-ipfs") : c3.yellow("sha256-local (Helia not initialized)")}`);
|
|
292923
293153
|
try {
|
|
292924
293154
|
const statusFile = join70(ctx3.repoRoot, ".oa", "nexus", "status.json");
|
|
292925
|
-
if (
|
|
293155
|
+
if (existsSync55(statusFile)) {
|
|
292926
293156
|
const status = JSON.parse(readFileSync42(statusFile, "utf8"));
|
|
292927
293157
|
if (status.peerId) {
|
|
292928
293158
|
lines.push(`
|
|
@@ -292945,7 +293175,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
292945
293175
|
const idDir = join70(ctx3.repoRoot, ".oa", "identity");
|
|
292946
293176
|
try {
|
|
292947
293177
|
const stateFile = join70(idDir, "self-state.json");
|
|
292948
|
-
if (
|
|
293178
|
+
if (existsSync55(stateFile)) {
|
|
292949
293179
|
const state = JSON.parse(readFileSync42(stateFile, "utf8"));
|
|
292950
293180
|
lines.push(` Version: ${c3.bold("v" + (state.version ?? "?"))} Sessions: ${c3.bold(String(state.session_count ?? 0))}`);
|
|
292951
293181
|
if (state.narrative_summary) {
|
|
@@ -292956,7 +293186,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
292956
293186
|
lines.push(` Traits: ${c3.dim(traits.slice(0, 60))}`);
|
|
292957
293187
|
}
|
|
292958
293188
|
const cidFile = join70(idDir, "cids.json");
|
|
292959
|
-
if (
|
|
293189
|
+
if (existsSync55(cidFile)) {
|
|
292960
293190
|
const cids = JSON.parse(readFileSync42(cidFile, "utf8"));
|
|
292961
293191
|
const lastCid = Array.isArray(cids) ? cids[cids.length - 1] : cids.latest;
|
|
292962
293192
|
if (lastCid) lines.push(` Last CID: ${c3.dim(String(lastCid).slice(0, 50))}`);
|
|
@@ -292970,7 +293200,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
292970
293200
|
${c3.bold("Memory Sentiment")}`);
|
|
292971
293201
|
try {
|
|
292972
293202
|
const metaFile = join70(ctx3.repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
292973
|
-
if (
|
|
293203
|
+
if (existsSync55(metaFile)) {
|
|
292974
293204
|
const store2 = JSON.parse(readFileSync42(metaFile, "utf8"));
|
|
292975
293205
|
const active = store2.filter((m2) => m2.type !== "quarantine");
|
|
292976
293206
|
const recoveries = active.filter((m2) => m2.content?.startsWith("[recovery]")).length;
|
|
@@ -292990,7 +293220,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
292990
293220
|
}
|
|
292991
293221
|
try {
|
|
292992
293222
|
const dbPath = join70(ctx3.repoRoot, ".oa", "memory", "structured.db");
|
|
292993
|
-
if (
|
|
293223
|
+
if (existsSync55(dbPath)) {
|
|
292994
293224
|
const { initDb: initDb2, closeDb: cDb, ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
|
|
292995
293225
|
const db = initDb2(dbPath);
|
|
292996
293226
|
const memStore = new ProceduralMemoryStore2(db);
|
|
@@ -293012,7 +293242,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
293012
293242
|
${c3.bold("Storage Overview")}
|
|
293013
293243
|
`);
|
|
293014
293244
|
const oaDir = join70(ctx3.repoRoot, ".oa");
|
|
293015
|
-
if (!
|
|
293245
|
+
if (!existsSync55(oaDir)) {
|
|
293016
293246
|
lines.push(` ${c3.dim("No .oa/ directory found.")}`);
|
|
293017
293247
|
safeLog(lines.join("\n") + "\n");
|
|
293018
293248
|
return "handled";
|
|
@@ -293088,7 +293318,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
293088
293318
|
return "handled";
|
|
293089
293319
|
}
|
|
293090
293320
|
const resolvedPath = join70(ctx3.repoRoot, filePath);
|
|
293091
|
-
if (!
|
|
293321
|
+
if (!existsSync55(resolvedPath)) {
|
|
293092
293322
|
renderWarning(`File not found: ${resolvedPath}`);
|
|
293093
293323
|
return "handled";
|
|
293094
293324
|
}
|
|
@@ -293190,7 +293420,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
293190
293420
|
const fortemiSubCmd = (arg || "").trim().toLowerCase();
|
|
293191
293421
|
const fortemiDir = join70(ctx3.repoRoot, "..", "fortemi-react");
|
|
293192
293422
|
const altFortemiDir = join70(nodeOs.homedir(), "fortemi-react");
|
|
293193
|
-
const fDir =
|
|
293423
|
+
const fDir = existsSync55(fortemiDir) ? fortemiDir : existsSync55(altFortemiDir) ? altFortemiDir : null;
|
|
293194
293424
|
if (fortemiSubCmd === "start" || fortemiSubCmd === "") {
|
|
293195
293425
|
if (!fDir) {
|
|
293196
293426
|
renderWarning("fortemi-react not found adjacent or in home directory.");
|
|
@@ -293235,7 +293465,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
293235
293465
|
}
|
|
293236
293466
|
if (fortemiSubCmd === "status") {
|
|
293237
293467
|
const bridgeFile = join70(ctx3.repoRoot, ".oa", "fortemi-bridge.json");
|
|
293238
|
-
if (!
|
|
293468
|
+
if (!existsSync55(bridgeFile)) {
|
|
293239
293469
|
renderInfo("Fortemi bridge: not connected. Run /fortemi start");
|
|
293240
293470
|
return "handled";
|
|
293241
293471
|
}
|
|
@@ -293259,14 +293489,14 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
293259
293489
|
lines.push(` Process: ${alive ? c3.green("running") : c3.yellow("not running")} (PID ${bridge.pid})`);
|
|
293260
293490
|
lines.push(` HTTP: ${httpOk ? c3.green("connected") : c3.yellow("unreachable")}`);
|
|
293261
293491
|
lines.push(` Started: ${bridge.startedAt}`);
|
|
293262
|
-
lines.push(` JWT: ${
|
|
293492
|
+
lines.push(` JWT: ${existsSync55(bridge.jwtFile) ? c3.green("valid") : c3.yellow("missing")}`);
|
|
293263
293493
|
lines.push("");
|
|
293264
293494
|
safeLog(lines.join("\n"));
|
|
293265
293495
|
return "handled";
|
|
293266
293496
|
}
|
|
293267
293497
|
if (fortemiSubCmd === "stop") {
|
|
293268
293498
|
const bridgeFile = join70(ctx3.repoRoot, ".oa", "fortemi-bridge.json");
|
|
293269
|
-
if (
|
|
293499
|
+
if (existsSync55(bridgeFile)) {
|
|
293270
293500
|
const bridge = JSON.parse(readFileSync42(bridgeFile, "utf8"));
|
|
293271
293501
|
try {
|
|
293272
293502
|
process.kill(bridge.pid, "SIGTERM");
|
|
@@ -294186,8 +294416,8 @@ The session corrections MUST become hard rules in the SKILL.md Rules section.`;
|
|
|
294186
294416
|
if (!sponsorUrl && !sponsorPeerId) {
|
|
294187
294417
|
_spLog("FAILED \u2014 no tunnelUrl and no peerId");
|
|
294188
294418
|
_spLog(`nexusDir checked: ${join70(projectDir, ".oa", "nexus")}`);
|
|
294189
|
-
_spLog(`status.json exists: ${
|
|
294190
|
-
_spLog(`daemon.pid exists: ${
|
|
294419
|
+
_spLog(`status.json exists: ${existsSync55(join70(projectDir, ".oa", "nexus", "status.json"))}`);
|
|
294420
|
+
_spLog(`daemon.pid exists: ${existsSync55(join70(projectDir, ".oa", "nexus", "daemon.pid"))}`);
|
|
294191
294421
|
try {
|
|
294192
294422
|
const _statusRaw = readFileSync42(join70(projectDir, ".oa", "nexus", "status.json"), "utf8");
|
|
294193
294423
|
_spLog(`status.json content: ${_statusRaw.slice(0, 300)}`);
|
|
@@ -294214,7 +294444,7 @@ The session corrections MUST become hard rules in the SKILL.md Rules section.`;
|
|
|
294214
294444
|
try {
|
|
294215
294445
|
const { homedir: homedir27 } = __require("os");
|
|
294216
294446
|
const namePath = __require("path").join(homedir27(), ".open-agents", "agent-name");
|
|
294217
|
-
if (
|
|
294447
|
+
if (existsSync55(namePath)) sponsorName = readFileSync42(namePath, "utf8").trim();
|
|
294218
294448
|
} catch {
|
|
294219
294449
|
}
|
|
294220
294450
|
if (!sponsorName) sponsorName = "OA Sponsor";
|
|
@@ -294290,7 +294520,7 @@ The session corrections MUST become hard rules in the SKILL.md Rules section.`;
|
|
|
294290
294520
|
renderInfo("Sponsor wizard completed.");
|
|
294291
294521
|
try {
|
|
294292
294522
|
const nexusPidFile = join70(projectDir, ".oa", "nexus", "daemon.pid");
|
|
294293
|
-
if (
|
|
294523
|
+
if (existsSync55(nexusPidFile)) {
|
|
294294
294524
|
const nPid = parseInt(readFileSync42(nexusPidFile, "utf8").trim(), 10);
|
|
294295
294525
|
if (nPid > 0) {
|
|
294296
294526
|
registry2.register({ name: "Nexus", pid: nPid, startedAt: Date.now(), status: "running" });
|
|
@@ -295356,7 +295586,7 @@ async function showCohereDashboard(ctx3) {
|
|
|
295356
295586
|
await ik.execute({ operation: "hydrate" });
|
|
295357
295587
|
} else if (idResult.key === "history") {
|
|
295358
295588
|
const snapDir = join70(ctx3.repoRoot, ".oa", "identity", "snapshots");
|
|
295359
|
-
if (
|
|
295589
|
+
if (existsSync55(snapDir)) {
|
|
295360
295590
|
const snaps = readdirSync14(snapDir).filter((f2) => f2.endsWith(".json")).sort().reverse();
|
|
295361
295591
|
const snapItems = snaps.slice(0, 20).map((f2) => ({
|
|
295362
295592
|
key: f2,
|
|
@@ -296367,7 +296597,7 @@ async function handleSponsoredEndpoint(ctx3, local) {
|
|
|
296367
296597
|
const sponsorDir2 = join70(ctx3.repoRoot ?? process.cwd(), ".oa", "sponsor");
|
|
296368
296598
|
const knownFile = join70(sponsorDir2, "known-sponsors.json");
|
|
296369
296599
|
try {
|
|
296370
|
-
if (
|
|
296600
|
+
if (existsSync55(knownFile)) {
|
|
296371
296601
|
const saved = JSON.parse(readFileSync42(knownFile, "utf8"));
|
|
296372
296602
|
for (const s2 of saved) {
|
|
296373
296603
|
if (!sponsors.some((sp) => sp.url === s2.url)) {
|
|
@@ -296519,7 +296749,7 @@ async function handleSponsoredEndpoint(ctx3, local) {
|
|
|
296519
296749
|
const saveKey = selected.url || selected.peerId || selected.name;
|
|
296520
296750
|
try {
|
|
296521
296751
|
mkdirSync26(sponsorDir2, { recursive: true });
|
|
296522
|
-
const existing =
|
|
296752
|
+
const existing = existsSync55(knownFile) ? JSON.parse(readFileSync42(knownFile, "utf8")) : [];
|
|
296523
296753
|
const updated = existing.filter((s2) => (s2.url || s2.peerId || s2.name) !== saveKey);
|
|
296524
296754
|
updated.push(selected);
|
|
296525
296755
|
writeFileSync26(knownFile, JSON.stringify(updated, null, 2), "utf8");
|
|
@@ -296643,7 +296873,7 @@ async function handlePeerEndpoint(peerId, authKey, ctx3, local) {
|
|
|
296643
296873
|
}
|
|
296644
296874
|
}
|
|
296645
296875
|
async function handleParallel(arg, ctx3) {
|
|
296646
|
-
const { execSync:
|
|
296876
|
+
const { execSync: execSync51 } = await import("node:child_process");
|
|
296647
296877
|
const baseUrl = ctx3.config.backendUrl || "http://localhost:11434";
|
|
296648
296878
|
const isRemote = ctx3.config.backendType === "nexus";
|
|
296649
296879
|
if (isRemote) {
|
|
@@ -296667,7 +296897,7 @@ async function handleParallel(arg, ctx3) {
|
|
|
296667
296897
|
}
|
|
296668
296898
|
let systemdVal = "";
|
|
296669
296899
|
try {
|
|
296670
|
-
const out =
|
|
296900
|
+
const out = execSync51("systemctl show ollama.service -p Environment 2>/dev/null || true", { encoding: "utf8" });
|
|
296671
296901
|
const match = out.match(/OLLAMA_NUM_PARALLEL=(\d+)/);
|
|
296672
296902
|
if (match) systemdVal = match[1];
|
|
296673
296903
|
} catch {
|
|
@@ -296695,7 +296925,7 @@ async function handleParallel(arg, ctx3) {
|
|
|
296695
296925
|
}
|
|
296696
296926
|
const isSystemd = (() => {
|
|
296697
296927
|
try {
|
|
296698
|
-
const out =
|
|
296928
|
+
const out = execSync51("systemctl is-active ollama.service 2>/dev/null", { encoding: "utf8" }).trim();
|
|
296699
296929
|
return out === "active" || out === "inactive";
|
|
296700
296930
|
} catch {
|
|
296701
296931
|
return false;
|
|
@@ -296709,10 +296939,10 @@ async function handleParallel(arg, ctx3) {
|
|
|
296709
296939
|
const overrideContent = `[Service]
|
|
296710
296940
|
Environment="OLLAMA_NUM_PARALLEL=${n2}"
|
|
296711
296941
|
`;
|
|
296712
|
-
|
|
296713
|
-
|
|
296714
|
-
|
|
296715
|
-
|
|
296942
|
+
execSync51(`sudo mkdir -p ${overrideDir}`, { stdio: "pipe" });
|
|
296943
|
+
execSync51(`echo '${overrideContent}' | sudo tee ${overrideFile} > /dev/null`, { stdio: "pipe" });
|
|
296944
|
+
execSync51("sudo systemctl daemon-reload", { stdio: "pipe" });
|
|
296945
|
+
execSync51("sudo systemctl restart ollama.service", { stdio: "pipe" });
|
|
296716
296946
|
let ready = false;
|
|
296717
296947
|
for (let i2 = 0; i2 < 30 && !ready; i2++) {
|
|
296718
296948
|
await new Promise((r2) => setTimeout(r2, 500));
|
|
@@ -296738,7 +296968,7 @@ Environment="OLLAMA_NUM_PARALLEL=${n2}"
|
|
|
296738
296968
|
renderInfo(`Setting OLLAMA_NUM_PARALLEL=${n2}...`);
|
|
296739
296969
|
try {
|
|
296740
296970
|
try {
|
|
296741
|
-
|
|
296971
|
+
execSync51("pkill -f 'ollama serve' 2>/dev/null || true", { stdio: "pipe" });
|
|
296742
296972
|
} catch {
|
|
296743
296973
|
}
|
|
296744
296974
|
await new Promise((r2) => setTimeout(r2, 1e3));
|
|
@@ -296791,7 +297021,7 @@ async function handleUpdate(subcommand, ctx3) {
|
|
|
296791
297021
|
const { createRequire: createRequire7 } = await import("node:module");
|
|
296792
297022
|
const { fileURLToPath: fileURLToPath19 } = await import("node:url");
|
|
296793
297023
|
const { dirname: dirname28, join: join92 } = await import("node:path");
|
|
296794
|
-
const { existsSync:
|
|
297024
|
+
const { existsSync: existsSync73 } = await import("node:fs");
|
|
296795
297025
|
const req2 = createRequire7(import.meta.url);
|
|
296796
297026
|
const thisDir = dirname28(fileURLToPath19(import.meta.url));
|
|
296797
297027
|
const candidates = [
|
|
@@ -296800,7 +297030,7 @@ async function handleUpdate(subcommand, ctx3) {
|
|
|
296800
297030
|
join92(thisDir, "..", "..", "..", "package.json")
|
|
296801
297031
|
];
|
|
296802
297032
|
for (const pkgPath of candidates) {
|
|
296803
|
-
if (
|
|
297033
|
+
if (existsSync73(pkgPath)) {
|
|
296804
297034
|
const pkg = req2(pkgPath);
|
|
296805
297035
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
|
|
296806
297036
|
currentVersion = pkg.version ?? "0.0.0";
|
|
@@ -297790,18 +298020,18 @@ async function showExposeDashboard(gateway, rl, ctx3) {
|
|
|
297790
298020
|
const cmd = `/endpoint ${id} --auth ${gateway.authKey ?? ""}`;
|
|
297791
298021
|
let copied = false;
|
|
297792
298022
|
try {
|
|
297793
|
-
const { execSync:
|
|
298023
|
+
const { execSync: execSync51 } = __require("node:child_process");
|
|
297794
298024
|
const platform6 = process.platform;
|
|
297795
298025
|
if (platform6 === "darwin") {
|
|
297796
|
-
|
|
298026
|
+
execSync51("pbcopy", { input: cmd, timeout: 3e3 });
|
|
297797
298027
|
copied = true;
|
|
297798
298028
|
} else if (platform6 === "win32") {
|
|
297799
|
-
|
|
298029
|
+
execSync51("clip", { input: cmd, timeout: 3e3 });
|
|
297800
298030
|
copied = true;
|
|
297801
298031
|
} else {
|
|
297802
298032
|
for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
|
|
297803
298033
|
try {
|
|
297804
|
-
|
|
298034
|
+
execSync51(tool, { input: cmd, timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] });
|
|
297805
298035
|
copied = true;
|
|
297806
298036
|
break;
|
|
297807
298037
|
} catch {
|
|
@@ -297894,9 +298124,9 @@ var init_commands = __esm({
|
|
|
297894
298124
|
});
|
|
297895
298125
|
|
|
297896
298126
|
// packages/cli/src/tui/project-context.ts
|
|
297897
|
-
import { existsSync as
|
|
298127
|
+
import { existsSync as existsSync56, readFileSync as readFileSync43, readdirSync as readdirSync15 } from "node:fs";
|
|
297898
298128
|
import { join as join71, basename as basename13 } from "node:path";
|
|
297899
|
-
import { execSync as
|
|
298129
|
+
import { execSync as execSync46 } from "node:child_process";
|
|
297900
298130
|
import { homedir as homedir22, platform as platform5, release } from "node:os";
|
|
297901
298131
|
function getModelTier(modelName) {
|
|
297902
298132
|
const m2 = modelName.toLowerCase();
|
|
@@ -297927,7 +298157,7 @@ function loadProjectMap(repoRoot) {
|
|
|
297927
298157
|
initOaDirectory(repoRoot);
|
|
297928
298158
|
}
|
|
297929
298159
|
const mapPath2 = join71(repoRoot, OA_DIR, "context", "project-map.md");
|
|
297930
|
-
if (
|
|
298160
|
+
if (existsSync56(mapPath2)) {
|
|
297931
298161
|
try {
|
|
297932
298162
|
const content = readFileSync43(mapPath2, "utf-8");
|
|
297933
298163
|
return content;
|
|
@@ -297938,18 +298168,18 @@ function loadProjectMap(repoRoot) {
|
|
|
297938
298168
|
}
|
|
297939
298169
|
function getGitInfo(repoRoot) {
|
|
297940
298170
|
try {
|
|
297941
|
-
|
|
298171
|
+
execSync46("git rev-parse --is-inside-work-tree", { cwd: repoRoot, stdio: "pipe" });
|
|
297942
298172
|
} catch {
|
|
297943
298173
|
return "";
|
|
297944
298174
|
}
|
|
297945
298175
|
const lines = [];
|
|
297946
298176
|
try {
|
|
297947
|
-
const branch =
|
|
298177
|
+
const branch = execSync46("git branch --show-current", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
297948
298178
|
if (branch) lines.push(`Branch: ${branch}`);
|
|
297949
298179
|
} catch {
|
|
297950
298180
|
}
|
|
297951
298181
|
try {
|
|
297952
|
-
const status =
|
|
298182
|
+
const status = execSync46("git status --porcelain", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
297953
298183
|
if (status) {
|
|
297954
298184
|
const changed = status.split("\n").length;
|
|
297955
298185
|
lines.push(`Working tree: ${changed} changed file(s)`);
|
|
@@ -297959,7 +298189,7 @@ function getGitInfo(repoRoot) {
|
|
|
297959
298189
|
} catch {
|
|
297960
298190
|
}
|
|
297961
298191
|
try {
|
|
297962
|
-
const log22 =
|
|
298192
|
+
const log22 = execSync46("git log --oneline -5 --no-decorate", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
297963
298193
|
if (log22) lines.push(`Recent commits:
|
|
297964
298194
|
${log22}`);
|
|
297965
298195
|
} catch {
|
|
@@ -297972,7 +298202,7 @@ function loadMemoryContext(repoRoot) {
|
|
|
297972
298202
|
const oaEntries = loadMemoryDir(oaMemDir, "project");
|
|
297973
298203
|
if (oaEntries) sections.push(oaEntries);
|
|
297974
298204
|
const legacyMemDir = join71(repoRoot, ".open-agents", "memory");
|
|
297975
|
-
if (legacyMemDir !== oaMemDir &&
|
|
298205
|
+
if (legacyMemDir !== oaMemDir && existsSync56(legacyMemDir)) {
|
|
297976
298206
|
const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
|
|
297977
298207
|
if (legacyEntries) sections.push(legacyEntries);
|
|
297978
298208
|
}
|
|
@@ -297982,7 +298212,7 @@ function loadMemoryContext(repoRoot) {
|
|
|
297982
298212
|
return sections.join("\n\n");
|
|
297983
298213
|
}
|
|
297984
298214
|
function loadMemoryDir(memDir, scope) {
|
|
297985
|
-
if (!
|
|
298215
|
+
if (!existsSync56(memDir)) return "";
|
|
297986
298216
|
const lines = [];
|
|
297987
298217
|
try {
|
|
297988
298218
|
const files = readdirSync15(memDir).filter((f2) => f2.endsWith(".json"));
|
|
@@ -299123,7 +299353,7 @@ __export(banner_exports, {
|
|
|
299123
299353
|
saveBannerDesign: () => saveBannerDesign,
|
|
299124
299354
|
setGridText: () => setGridText
|
|
299125
299355
|
});
|
|
299126
|
-
import { existsSync as
|
|
299356
|
+
import { existsSync as existsSync57, readFileSync as readFileSync44, writeFileSync as writeFileSync27, mkdirSync as mkdirSync27 } from "node:fs";
|
|
299127
299357
|
import { join as join72 } from "node:path";
|
|
299128
299358
|
function generateMnemonic(seed) {
|
|
299129
299359
|
let h = 2166136261;
|
|
@@ -299260,7 +299490,7 @@ function saveBannerDesign(workDir, design) {
|
|
|
299260
299490
|
}
|
|
299261
299491
|
function loadBannerDesign(workDir, id) {
|
|
299262
299492
|
const file = join72(workDir, ".oa", "banners", `${id}.json`);
|
|
299263
|
-
if (!
|
|
299493
|
+
if (!existsSync57(file)) return null;
|
|
299264
299494
|
try {
|
|
299265
299495
|
return JSON.parse(readFileSync44(file, "utf8"));
|
|
299266
299496
|
} catch {
|
|
@@ -299269,7 +299499,7 @@ function loadBannerDesign(workDir, id) {
|
|
|
299269
299499
|
}
|
|
299270
299500
|
function listBannerDesigns(workDir) {
|
|
299271
299501
|
const dir = join72(workDir, ".oa", "banners");
|
|
299272
|
-
if (!
|
|
299502
|
+
if (!existsSync57(dir)) return [];
|
|
299273
299503
|
try {
|
|
299274
299504
|
const { readdirSync: readdirSync26 } = __require("node:fs");
|
|
299275
299505
|
return readdirSync26(dir).filter((f2) => f2.endsWith(".json")).map((f2) => f2.replace(".json", ""));
|
|
@@ -299576,12 +299806,12 @@ var init_banner = __esm({
|
|
|
299576
299806
|
});
|
|
299577
299807
|
|
|
299578
299808
|
// packages/cli/src/tui/carousel-descriptors.ts
|
|
299579
|
-
import { existsSync as
|
|
299809
|
+
import { existsSync as existsSync58, readFileSync as readFileSync45, writeFileSync as writeFileSync28, mkdirSync as mkdirSync28, readdirSync as readdirSync16 } from "node:fs";
|
|
299580
299810
|
import { join as join73, basename as basename14 } from "node:path";
|
|
299581
299811
|
function loadToolProfile(repoRoot) {
|
|
299582
299812
|
const filePath = join73(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
|
|
299583
299813
|
try {
|
|
299584
|
-
if (!
|
|
299814
|
+
if (!existsSync58(filePath)) return null;
|
|
299585
299815
|
return JSON.parse(readFileSync45(filePath, "utf-8"));
|
|
299586
299816
|
} catch {
|
|
299587
299817
|
return null;
|
|
@@ -299647,7 +299877,7 @@ function weightedColor(profile) {
|
|
|
299647
299877
|
function loadCachedDescriptors(repoRoot) {
|
|
299648
299878
|
const filePath = join73(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
|
|
299649
299879
|
try {
|
|
299650
|
-
if (!
|
|
299880
|
+
if (!existsSync58(filePath)) return null;
|
|
299651
299881
|
const cached = JSON.parse(readFileSync45(filePath, "utf-8"));
|
|
299652
299882
|
return cached.phrases.length > 0 ? cached.phrases : null;
|
|
299653
299883
|
} catch {
|
|
@@ -299711,7 +299941,7 @@ function generateDescriptors(repoRoot) {
|
|
|
299711
299941
|
function extractFromPackageJson(repoRoot, tags) {
|
|
299712
299942
|
const pkgPath = join73(repoRoot, "package.json");
|
|
299713
299943
|
try {
|
|
299714
|
-
if (!
|
|
299944
|
+
if (!existsSync58(pkgPath)) return;
|
|
299715
299945
|
const pkg = JSON.parse(readFileSync45(pkgPath, "utf-8"));
|
|
299716
299946
|
if (pkg.name && typeof pkg.name === "string") {
|
|
299717
299947
|
const parts = pkg.name.replace(/^@/, "").split("/");
|
|
@@ -299753,7 +299983,7 @@ function extractFromManifests(repoRoot, tags) {
|
|
|
299753
299983
|
{ file: ".github/workflows", tag: "ci/cd" }
|
|
299754
299984
|
];
|
|
299755
299985
|
for (const check of manifestChecks) {
|
|
299756
|
-
if (
|
|
299986
|
+
if (existsSync58(join73(repoRoot, check.file))) {
|
|
299757
299987
|
tags.push(check.tag);
|
|
299758
299988
|
}
|
|
299759
299989
|
}
|
|
@@ -299777,7 +300007,7 @@ function extractFromSessions(repoRoot, tags) {
|
|
|
299777
300007
|
function extractFromMemory(repoRoot, tags) {
|
|
299778
300008
|
const memoryDir = join73(repoRoot, OA_DIR, "memory");
|
|
299779
300009
|
try {
|
|
299780
|
-
if (!
|
|
300010
|
+
if (!existsSync58(memoryDir)) return;
|
|
299781
300011
|
const files = readdirSync16(memoryDir).filter((f2) => f2.endsWith(".json"));
|
|
299782
300012
|
for (const file of files) {
|
|
299783
300013
|
const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
|
|
@@ -300591,14 +300821,14 @@ var init_edit_history = __esm({
|
|
|
300591
300821
|
});
|
|
300592
300822
|
|
|
300593
300823
|
// packages/cli/src/tui/promptLoader.ts
|
|
300594
|
-
import { readFileSync as readFileSync46, existsSync as
|
|
300824
|
+
import { readFileSync as readFileSync46, existsSync as existsSync59 } from "node:fs";
|
|
300595
300825
|
import { join as join75, dirname as dirname23 } from "node:path";
|
|
300596
300826
|
import { fileURLToPath as fileURLToPath14 } from "node:url";
|
|
300597
300827
|
function loadPrompt3(promptPath, vars) {
|
|
300598
300828
|
let content = cache6.get(promptPath);
|
|
300599
300829
|
if (content === void 0) {
|
|
300600
300830
|
const fullPath = join75(PROMPTS_DIR3, promptPath);
|
|
300601
|
-
if (!
|
|
300831
|
+
if (!existsSync59(fullPath)) {
|
|
300602
300832
|
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
300603
300833
|
}
|
|
300604
300834
|
content = readFileSync46(fullPath, "utf-8");
|
|
@@ -300615,15 +300845,15 @@ var init_promptLoader3 = __esm({
|
|
|
300615
300845
|
__dirname7 = dirname23(__filename5);
|
|
300616
300846
|
devPath2 = join75(__dirname7, "..", "..", "prompts");
|
|
300617
300847
|
publishedPath2 = join75(__dirname7, "..", "prompts");
|
|
300618
|
-
PROMPTS_DIR3 =
|
|
300848
|
+
PROMPTS_DIR3 = existsSync59(devPath2) ? devPath2 : publishedPath2;
|
|
300619
300849
|
cache6 = /* @__PURE__ */ new Map();
|
|
300620
300850
|
}
|
|
300621
300851
|
});
|
|
300622
300852
|
|
|
300623
300853
|
// packages/cli/src/tui/dream-engine.ts
|
|
300624
|
-
import { mkdirSync as mkdirSync30, writeFileSync as writeFileSync29, readFileSync as readFileSync47, existsSync as
|
|
300854
|
+
import { mkdirSync as mkdirSync30, writeFileSync as writeFileSync29, readFileSync as readFileSync47, existsSync as existsSync60, readdirSync as readdirSync17 } from "node:fs";
|
|
300625
300855
|
import { join as join76, basename as basename15 } from "node:path";
|
|
300626
|
-
import { execSync as
|
|
300856
|
+
import { execSync as execSync47 } from "node:child_process";
|
|
300627
300857
|
function setDreamWriteContent(fn) {
|
|
300628
300858
|
_dreamWriteContent = fn;
|
|
300629
300859
|
}
|
|
@@ -300636,7 +300866,7 @@ function dreamWrite(fn) {
|
|
|
300636
300866
|
}
|
|
300637
300867
|
function loadAutoresearchMemory(repoRoot) {
|
|
300638
300868
|
const memoryPath = join76(repoRoot, ".oa", "memory", "autoresearch.json");
|
|
300639
|
-
if (!
|
|
300869
|
+
if (!existsSync60(memoryPath)) return "";
|
|
300640
300870
|
try {
|
|
300641
300871
|
const raw = readFileSync47(memoryPath, "utf-8");
|
|
300642
300872
|
const data = JSON.parse(raw);
|
|
@@ -300873,7 +301103,7 @@ var init_dream_engine = __esm({
|
|
|
300873
301103
|
return { success: false, output: "", error: "Autoresearch mode: edits are confined to .oa/autoresearch/", durationMs: Date.now() - start2 };
|
|
300874
301104
|
}
|
|
300875
301105
|
try {
|
|
300876
|
-
if (!
|
|
301106
|
+
if (!existsSync60(targetPath)) {
|
|
300877
301107
|
return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start2 };
|
|
300878
301108
|
}
|
|
300879
301109
|
let content = readFileSync47(targetPath, "utf-8");
|
|
@@ -300959,7 +301189,7 @@ var init_dream_engine = __esm({
|
|
|
300959
301189
|
return { success: false, output: "", error: "Dream mode: edits are confined to .oa/dreams/", durationMs: Date.now() - start2 };
|
|
300960
301190
|
}
|
|
300961
301191
|
try {
|
|
300962
|
-
if (!
|
|
301192
|
+
if (!existsSync60(targetPath)) {
|
|
300963
301193
|
return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start2 };
|
|
300964
301194
|
}
|
|
300965
301195
|
let content = readFileSync47(targetPath, "utf-8");
|
|
@@ -300997,7 +301227,7 @@ var init_dream_engine = __esm({
|
|
|
300997
301227
|
}
|
|
300998
301228
|
}
|
|
300999
301229
|
try {
|
|
301000
|
-
const output =
|
|
301230
|
+
const output = execSync47(cmd, {
|
|
301001
301231
|
cwd: this.repoRoot,
|
|
301002
301232
|
timeout: 3e4,
|
|
301003
301233
|
encoding: "utf-8",
|
|
@@ -301856,17 +302086,17 @@ ${summaryResult}
|
|
|
301856
302086
|
try {
|
|
301857
302087
|
mkdirSync30(checkpointDir, { recursive: true });
|
|
301858
302088
|
try {
|
|
301859
|
-
const gitStatus =
|
|
302089
|
+
const gitStatus = execSync47("git status --porcelain", {
|
|
301860
302090
|
cwd: this.repoRoot,
|
|
301861
302091
|
encoding: "utf-8",
|
|
301862
302092
|
timeout: 1e4
|
|
301863
302093
|
});
|
|
301864
|
-
const gitDiff =
|
|
302094
|
+
const gitDiff = execSync47("git diff", {
|
|
301865
302095
|
cwd: this.repoRoot,
|
|
301866
302096
|
encoding: "utf-8",
|
|
301867
302097
|
timeout: 1e4
|
|
301868
302098
|
});
|
|
301869
|
-
const gitHash =
|
|
302099
|
+
const gitHash = execSync47("git rev-parse HEAD 2>/dev/null || echo 'no-git'", {
|
|
301870
302100
|
cwd: this.repoRoot,
|
|
301871
302101
|
encoding: "utf-8",
|
|
301872
302102
|
timeout: 5e3
|
|
@@ -302423,7 +302653,7 @@ var init_bless_engine = __esm({
|
|
|
302423
302653
|
});
|
|
302424
302654
|
|
|
302425
302655
|
// packages/cli/src/tui/dmn-engine.ts
|
|
302426
|
-
import { existsSync as
|
|
302656
|
+
import { existsSync as existsSync61, readFileSync as readFileSync48, writeFileSync as writeFileSync30, mkdirSync as mkdirSync31, readdirSync as readdirSync18, unlinkSync as unlinkSync15 } from "node:fs";
|
|
302427
302657
|
import { join as join77, basename as basename16 } from "node:path";
|
|
302428
302658
|
function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
|
|
302429
302659
|
const competenceReport = competence.length > 0 ? competence.map((c7) => {
|
|
@@ -303166,7 +303396,7 @@ OUTPUT: Call task_complete with JSON:
|
|
|
303166
303396
|
join77(this.repoRoot, ".open-agents", "memory")
|
|
303167
303397
|
];
|
|
303168
303398
|
for (const dir of dirs) {
|
|
303169
|
-
if (!
|
|
303399
|
+
if (!existsSync61(dir)) continue;
|
|
303170
303400
|
try {
|
|
303171
303401
|
const files = readdirSync18(dir).filter((f2) => f2.endsWith(".json"));
|
|
303172
303402
|
for (const f2 of files) {
|
|
@@ -303181,7 +303411,7 @@ OUTPUT: Call task_complete with JSON:
|
|
|
303181
303411
|
// ── State persistence ─────────────────────────────────────────────────
|
|
303182
303412
|
loadState() {
|
|
303183
303413
|
const path5 = join77(this.stateDir, "state.json");
|
|
303184
|
-
if (
|
|
303414
|
+
if (existsSync61(path5)) {
|
|
303185
303415
|
try {
|
|
303186
303416
|
this.state = JSON.parse(readFileSync48(path5, "utf-8"));
|
|
303187
303417
|
} catch {
|
|
@@ -303223,7 +303453,7 @@ OUTPUT: Call task_complete with JSON:
|
|
|
303223
303453
|
});
|
|
303224
303454
|
|
|
303225
303455
|
// packages/cli/src/tui/snr-engine.ts
|
|
303226
|
-
import { existsSync as
|
|
303456
|
+
import { existsSync as existsSync62, readdirSync as readdirSync19, readFileSync as readFileSync49 } from "node:fs";
|
|
303227
303457
|
import { join as join78, basename as basename17 } from "node:path";
|
|
303228
303458
|
function computeDPrime(signalScores, noiseScores) {
|
|
303229
303459
|
if (signalScores.length === 0 || noiseScores.length === 0) return 0;
|
|
@@ -303512,7 +303742,7 @@ Call task_complete with the JSON array when done.`,
|
|
|
303512
303742
|
join78(this.repoRoot, ".open-agents", "memory")
|
|
303513
303743
|
];
|
|
303514
303744
|
for (const dir of dirs) {
|
|
303515
|
-
if (!
|
|
303745
|
+
if (!existsSync62(dir)) continue;
|
|
303516
303746
|
try {
|
|
303517
303747
|
const files = readdirSync19(dir).filter((f2) => f2.endsWith(".json"));
|
|
303518
303748
|
for (const f2 of files) {
|
|
@@ -305735,7 +305965,7 @@ var init_direct_input = __esm({
|
|
|
305735
305965
|
});
|
|
305736
305966
|
|
|
305737
305967
|
// packages/cli/src/api/audit-log.ts
|
|
305738
|
-
import { mkdirSync as mkdirSync33, appendFileSync as appendFileSync5, readFileSync as readFileSync50, existsSync as
|
|
305968
|
+
import { mkdirSync as mkdirSync33, appendFileSync as appendFileSync5, readFileSync as readFileSync50, existsSync as existsSync64 } from "node:fs";
|
|
305739
305969
|
import { join as join80 } from "node:path";
|
|
305740
305970
|
function initAuditLog(oaDir) {
|
|
305741
305971
|
auditDir = join80(oaDir, "audit");
|
|
@@ -305755,7 +305985,7 @@ function recordAudit(record) {
|
|
|
305755
305985
|
}
|
|
305756
305986
|
}
|
|
305757
305987
|
function queryAudit(opts) {
|
|
305758
|
-
if (!initialized || !
|
|
305988
|
+
if (!initialized || !existsSync64(auditFile)) return [];
|
|
305759
305989
|
try {
|
|
305760
305990
|
const raw = readFileSync50(auditFile, "utf-8");
|
|
305761
305991
|
const lines = raw.split("\n").filter(Boolean);
|
|
@@ -307077,7 +307307,7 @@ var init_auth_oidc = __esm({
|
|
|
307077
307307
|
|
|
307078
307308
|
// packages/cli/src/api/chat-session.ts
|
|
307079
307309
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
307080
|
-
import { existsSync as
|
|
307310
|
+
import { existsSync as existsSync65, readFileSync as readFileSync51, readdirSync as readdirSync21 } from "node:fs";
|
|
307081
307311
|
import { join as join81 } from "node:path";
|
|
307082
307312
|
function buildSystemPrompt(cwd4) {
|
|
307083
307313
|
const parts = [];
|
|
@@ -307086,7 +307316,7 @@ function buildSystemPrompt(cwd4) {
|
|
|
307086
307316
|
);
|
|
307087
307317
|
parts.push(`\\nEnvironment: ${process.platform}, Node ${process.version}, CWD: ${cwd4}`);
|
|
307088
307318
|
const diaryPath = join81(cwd4, ".oa", "context", "session-diary.md");
|
|
307089
|
-
if (
|
|
307319
|
+
if (existsSync65(diaryPath)) {
|
|
307090
307320
|
try {
|
|
307091
307321
|
const diary = readFileSync51(diaryPath, "utf-8").slice(0, 1e3);
|
|
307092
307322
|
parts.push(`\\nPrevious session history:\\n${diary}`);
|
|
@@ -307094,7 +307324,7 @@ function buildSystemPrompt(cwd4) {
|
|
|
307094
307324
|
}
|
|
307095
307325
|
}
|
|
307096
307326
|
const memDir = join81(cwd4, ".oa", "memory");
|
|
307097
|
-
if (
|
|
307327
|
+
if (existsSync65(memDir)) {
|
|
307098
307328
|
try {
|
|
307099
307329
|
const files = readdirSync21(memDir).filter((f2) => f2.endsWith(".json")).slice(0, 5);
|
|
307100
307330
|
if (files.length > 0) {
|
|
@@ -307115,7 +307345,7 @@ function buildSystemPrompt(cwd4) {
|
|
|
307115
307345
|
}
|
|
307116
307346
|
for (const name10 of ["AGENTS.md", "OA.md", ".open-agents.md"]) {
|
|
307117
307347
|
const p2 = join81(cwd4, name10);
|
|
307118
|
-
if (
|
|
307348
|
+
if (existsSync65(p2)) {
|
|
307119
307349
|
try {
|
|
307120
307350
|
const content = readFileSync51(p2, "utf-8").slice(0, 500);
|
|
307121
307351
|
parts.push(`\\nProject instructions (${name10}):\\n${content}`);
|
|
@@ -307193,14 +307423,14 @@ var init_chat_session = __esm({
|
|
|
307193
307423
|
});
|
|
307194
307424
|
|
|
307195
307425
|
// packages/cli/src/api/usage-tracker.ts
|
|
307196
|
-
import { mkdirSync as mkdirSync34, readFileSync as readFileSync52, writeFileSync as writeFileSync31, existsSync as
|
|
307426
|
+
import { mkdirSync as mkdirSync34, readFileSync as readFileSync52, writeFileSync as writeFileSync31, existsSync as existsSync66 } from "node:fs";
|
|
307197
307427
|
import { join as join82 } from "node:path";
|
|
307198
307428
|
function initUsageTracker(oaDir) {
|
|
307199
307429
|
const dir = join82(oaDir, "usage");
|
|
307200
307430
|
mkdirSync34(dir, { recursive: true });
|
|
307201
307431
|
usageFile = join82(dir, "token-usage.json");
|
|
307202
307432
|
try {
|
|
307203
|
-
if (
|
|
307433
|
+
if (existsSync66(usageFile)) {
|
|
307204
307434
|
store = JSON.parse(readFileSync52(usageFile, "utf-8"));
|
|
307205
307435
|
}
|
|
307206
307436
|
} catch {
|
|
@@ -307265,7 +307495,7 @@ var init_usage_tracker = __esm({
|
|
|
307265
307495
|
});
|
|
307266
307496
|
|
|
307267
307497
|
// packages/cli/src/api/profiles.ts
|
|
307268
|
-
import { existsSync as
|
|
307498
|
+
import { existsSync as existsSync67, readFileSync as readFileSync53, writeFileSync as writeFileSync32, mkdirSync as mkdirSync35, readdirSync as readdirSync22, unlinkSync as unlinkSync17 } from "node:fs";
|
|
307269
307499
|
import { join as join83 } from "node:path";
|
|
307270
307500
|
import { homedir as homedir23 } from "node:os";
|
|
307271
307501
|
import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, randomBytes as randomBytes18, scryptSync as scryptSync3 } from "node:crypto";
|
|
@@ -307279,7 +307509,7 @@ function listProfiles(projectDir) {
|
|
|
307279
307509
|
const result = [];
|
|
307280
307510
|
const seen = /* @__PURE__ */ new Set();
|
|
307281
307511
|
const projDir = projectProfileDir(projectDir);
|
|
307282
|
-
if (
|
|
307512
|
+
if (existsSync67(projDir)) {
|
|
307283
307513
|
for (const f2 of readdirSync22(projDir).filter((f3) => f3.endsWith(".json"))) {
|
|
307284
307514
|
try {
|
|
307285
307515
|
const raw = JSON.parse(readFileSync53(join83(projDir, f2), "utf8"));
|
|
@@ -307296,7 +307526,7 @@ function listProfiles(projectDir) {
|
|
|
307296
307526
|
}
|
|
307297
307527
|
}
|
|
307298
307528
|
const globDir = globalProfileDir();
|
|
307299
|
-
if (
|
|
307529
|
+
if (existsSync67(globDir)) {
|
|
307300
307530
|
for (const f2 of readdirSync22(globDir).filter((f3) => f3.endsWith(".json"))) {
|
|
307301
307531
|
const name10 = f2.replace(".json", "");
|
|
307302
307532
|
if (seen.has(name10)) continue;
|
|
@@ -307318,7 +307548,7 @@ function loadProfile(name10, password, projectDir) {
|
|
|
307318
307548
|
const sanitized = name10.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
307319
307549
|
const projPath = join83(projectProfileDir(projectDir), `${sanitized}.json`);
|
|
307320
307550
|
const globPath = join83(globalProfileDir(), `${sanitized}.json`);
|
|
307321
|
-
const filePath =
|
|
307551
|
+
const filePath = existsSync67(projPath) ? projPath : existsSync67(globPath) ? globPath : null;
|
|
307322
307552
|
if (!filePath) return null;
|
|
307323
307553
|
const raw = JSON.parse(readFileSync53(filePath, "utf8"));
|
|
307324
307554
|
if (raw.encrypted === true) {
|
|
@@ -307345,7 +307575,7 @@ function deleteProfile(name10, scope = "global", projectDir) {
|
|
|
307345
307575
|
const sanitized = name10.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
307346
307576
|
const dir = scope === "project" ? projectProfileDir(projectDir) : globalProfileDir();
|
|
307347
307577
|
const filePath = join83(dir, `${sanitized}.json`);
|
|
307348
|
-
if (
|
|
307578
|
+
if (existsSync67(filePath)) {
|
|
307349
307579
|
unlinkSync17(filePath);
|
|
307350
307580
|
return true;
|
|
307351
307581
|
}
|
|
@@ -307459,8 +307689,8 @@ var init_profiles = __esm({
|
|
|
307459
307689
|
});
|
|
307460
307690
|
|
|
307461
307691
|
// packages/cli/src/docker.ts
|
|
307462
|
-
import { execSync as
|
|
307463
|
-
import { existsSync as
|
|
307692
|
+
import { execSync as execSync48, spawn as spawn23 } from "node:child_process";
|
|
307693
|
+
import { existsSync as existsSync68, mkdirSync as mkdirSync36, writeFileSync as writeFileSync33 } from "node:fs";
|
|
307464
307694
|
import { join as join84, resolve as resolve33, dirname as dirname24 } from "node:path";
|
|
307465
307695
|
import { homedir as homedir24 } from "node:os";
|
|
307466
307696
|
import { fileURLToPath as fileURLToPath15 } from "node:url";
|
|
@@ -307480,7 +307710,7 @@ function getDockerDir() {
|
|
|
307480
307710
|
}
|
|
307481
307711
|
function isDockerAvailable() {
|
|
307482
307712
|
try {
|
|
307483
|
-
|
|
307713
|
+
execSync48("docker info", { stdio: "pipe", timeout: 1e4 });
|
|
307484
307714
|
return true;
|
|
307485
307715
|
} catch {
|
|
307486
307716
|
return false;
|
|
@@ -307488,7 +307718,7 @@ function isDockerAvailable() {
|
|
|
307488
307718
|
}
|
|
307489
307719
|
function isDockerInstalled() {
|
|
307490
307720
|
try {
|
|
307491
|
-
|
|
307721
|
+
execSync48("docker --version", { stdio: "pipe", timeout: 5e3 });
|
|
307492
307722
|
return true;
|
|
307493
307723
|
} catch {
|
|
307494
307724
|
return false;
|
|
@@ -307513,31 +307743,31 @@ async function ensureDocker() {
|
|
|
307513
307743
|
}
|
|
307514
307744
|
try {
|
|
307515
307745
|
console.log("[oa-docker] Docker not found. Installing via get.docker.com...");
|
|
307516
|
-
|
|
307746
|
+
execSync48("curl -fsSL https://get.docker.com | sh", {
|
|
307517
307747
|
stdio: "inherit",
|
|
307518
307748
|
timeout: 3e5
|
|
307519
307749
|
});
|
|
307520
307750
|
const user = process.env["USER"] || process.env["LOGNAME"];
|
|
307521
307751
|
if (user) {
|
|
307522
307752
|
try {
|
|
307523
|
-
|
|
307753
|
+
execSync48(`sudo usermod -aG docker ${user}`, { stdio: "pipe" });
|
|
307524
307754
|
} catch {
|
|
307525
307755
|
}
|
|
307526
307756
|
}
|
|
307527
307757
|
try {
|
|
307528
|
-
|
|
307758
|
+
execSync48("sudo systemctl start docker", { stdio: "pipe", timeout: 15e3 });
|
|
307529
307759
|
} catch {
|
|
307530
307760
|
}
|
|
307531
307761
|
try {
|
|
307532
|
-
|
|
307533
|
-
const runtimes =
|
|
307762
|
+
execSync48("nvidia-smi", { stdio: "pipe", timeout: 5e3 });
|
|
307763
|
+
const runtimes = execSync48("docker info --format '{{json .Runtimes}}'", {
|
|
307534
307764
|
stdio: "pipe",
|
|
307535
307765
|
timeout: 5e3
|
|
307536
307766
|
}).toString();
|
|
307537
307767
|
if (!runtimes.includes("nvidia")) {
|
|
307538
307768
|
console.log("[oa-docker] NVIDIA GPU detected. Installing nvidia-container-toolkit...");
|
|
307539
307769
|
try {
|
|
307540
|
-
|
|
307770
|
+
execSync48(`
|
|
307541
307771
|
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg 2>/dev/null
|
|
307542
307772
|
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list > /dev/null 2>&1
|
|
307543
307773
|
sudo apt-get update -qq 2>/dev/null && sudo apt-get install -y -qq nvidia-container-toolkit 2>/dev/null || ( sudo dnf install -y nvidia-container-toolkit 2>/dev/null || sudo yum install -y nvidia-container-toolkit 2>/dev/null || true )
|
|
@@ -307567,7 +307797,7 @@ async function ensureDocker() {
|
|
|
307567
307797
|
}
|
|
307568
307798
|
async function ensureNvidiaToolkit() {
|
|
307569
307799
|
try {
|
|
307570
|
-
|
|
307800
|
+
execSync48("nvidia-smi --query-gpu=name --format=csv,noheader", { stdio: "pipe", timeout: 5e3 });
|
|
307571
307801
|
} catch {
|
|
307572
307802
|
return { ok: false, message: "No NVIDIA GPU detected (nvidia-smi not found)" };
|
|
307573
307803
|
}
|
|
@@ -307578,7 +307808,7 @@ async function ensureNvidiaToolkit() {
|
|
|
307578
307808
|
return { ok: false, message: "Auto-install only supported on Linux. Install manually: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html" };
|
|
307579
307809
|
}
|
|
307580
307810
|
try {
|
|
307581
|
-
|
|
307811
|
+
execSync48(`
|
|
307582
307812
|
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg 2>/dev/null
|
|
307583
307813
|
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list > /dev/null 2>&1
|
|
307584
307814
|
sudo apt-get update -qq 2>/dev/null && sudo apt-get install -y -qq nvidia-container-toolkit 2>/dev/null || ( sudo dnf install -y nvidia-container-toolkit 2>/dev/null || sudo yum install -y nvidia-container-toolkit 2>/dev/null || true )
|
|
@@ -307592,7 +307822,7 @@ async function ensureNvidiaToolkit() {
|
|
|
307592
307822
|
}
|
|
307593
307823
|
function isOaImageBuilt() {
|
|
307594
307824
|
try {
|
|
307595
|
-
const out =
|
|
307825
|
+
const out = execSync48(`docker images -q ${OA_IMAGE}:${OA_IMAGE_TAG}`, {
|
|
307596
307826
|
stdio: "pipe",
|
|
307597
307827
|
timeout: 5e3
|
|
307598
307828
|
}).toString().trim();
|
|
@@ -307607,7 +307837,7 @@ async function ensureOaImage(force = false) {
|
|
|
307607
307837
|
}
|
|
307608
307838
|
let buildContext;
|
|
307609
307839
|
const dockerDir = getDockerDir();
|
|
307610
|
-
if (
|
|
307840
|
+
if (existsSync68(join84(dockerDir, "Dockerfile"))) {
|
|
307611
307841
|
buildContext = dockerDir;
|
|
307612
307842
|
} else {
|
|
307613
307843
|
buildContext = join84(homedir24(), ".oa", "docker-build");
|
|
@@ -307616,7 +307846,7 @@ async function ensureOaImage(force = false) {
|
|
|
307616
307846
|
}
|
|
307617
307847
|
try {
|
|
307618
307848
|
console.log(`[oa-docker] Building image ${OA_IMAGE}:${OA_IMAGE_TAG}...`);
|
|
307619
|
-
|
|
307849
|
+
execSync48(`docker build -t ${OA_IMAGE}:${OA_IMAGE_TAG} ${buildContext}`, {
|
|
307620
307850
|
stdio: "inherit",
|
|
307621
307851
|
timeout: 6e5
|
|
307622
307852
|
// 10 min
|
|
@@ -307690,11 +307920,11 @@ exec "$@"
|
|
|
307690
307920
|
}
|
|
307691
307921
|
function hasNvidiaGpu() {
|
|
307692
307922
|
try {
|
|
307693
|
-
|
|
307923
|
+
execSync48("nvidia-smi --query-gpu=name --format=csv,noheader", {
|
|
307694
307924
|
stdio: "pipe",
|
|
307695
307925
|
timeout: 5e3
|
|
307696
307926
|
});
|
|
307697
|
-
const runtimes =
|
|
307927
|
+
const runtimes = execSync48("docker info --format '{{json .Runtimes}}'", {
|
|
307698
307928
|
stdio: "pipe",
|
|
307699
307929
|
timeout: 5e3
|
|
307700
307930
|
}).toString();
|
|
@@ -307764,8 +307994,8 @@ import * as https3 from "node:https";
|
|
|
307764
307994
|
import { createRequire as createRequire4 } from "node:module";
|
|
307765
307995
|
import { fileURLToPath as fileURLToPath16 } from "node:url";
|
|
307766
307996
|
import { dirname as dirname25, join as join85, resolve as resolve34 } from "node:path";
|
|
307767
|
-
import { spawn as spawn24, execSync as
|
|
307768
|
-
import { mkdirSync as mkdirSync37, writeFileSync as writeFileSync34, readFileSync as readFileSync54, readdirSync as readdirSync23, existsSync as
|
|
307997
|
+
import { spawn as spawn24, execSync as execSync49 } from "node:child_process";
|
|
307998
|
+
import { mkdirSync as mkdirSync37, writeFileSync as writeFileSync34, readFileSync as readFileSync54, readdirSync as readdirSync23, existsSync as existsSync69 } from "node:fs";
|
|
307769
307999
|
import { randomBytes as randomBytes19, randomUUID as randomUUID5 } from "node:crypto";
|
|
307770
308000
|
function getVersion3() {
|
|
307771
308001
|
try {
|
|
@@ -307778,7 +308008,7 @@ function getVersion3() {
|
|
|
307778
308008
|
];
|
|
307779
308009
|
for (const pkgPath of candidates) {
|
|
307780
308010
|
try {
|
|
307781
|
-
if (!
|
|
308011
|
+
if (!existsSync69(pkgPath)) continue;
|
|
307782
308012
|
const pkg = require3(pkgPath);
|
|
307783
308013
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli" || pkg.name === "@open-agents/monorepo") {
|
|
307784
308014
|
return pkg.version ?? "0.0.0";
|
|
@@ -308073,7 +308303,7 @@ function jobsDir() {
|
|
|
308073
308303
|
}
|
|
308074
308304
|
function loadJob(id) {
|
|
308075
308305
|
const file = join85(jobsDir(), `${id}.json`);
|
|
308076
|
-
if (!
|
|
308306
|
+
if (!existsSync69(file)) return null;
|
|
308077
308307
|
try {
|
|
308078
308308
|
return JSON.parse(readFileSync54(file, "utf-8"));
|
|
308079
308309
|
} catch {
|
|
@@ -308082,7 +308312,7 @@ function loadJob(id) {
|
|
|
308082
308312
|
}
|
|
308083
308313
|
function listJobs() {
|
|
308084
308314
|
const dir = jobsDir();
|
|
308085
|
-
if (!
|
|
308315
|
+
if (!existsSync69(dir)) return [];
|
|
308086
308316
|
const files = readdirSync23(dir).filter((f2) => f2.endsWith(".json")).sort();
|
|
308087
308317
|
const jobs = [];
|
|
308088
308318
|
for (const file of files) {
|
|
@@ -308772,7 +309002,7 @@ function handleV1RunsDelete(res, id) {
|
|
|
308772
309002
|
const containerName = `oa-${id}`;
|
|
308773
309003
|
if (job.sandbox === "container") {
|
|
308774
309004
|
try {
|
|
308775
|
-
|
|
309005
|
+
execSync49(`docker stop ${containerName}`, { timeout: 5e3, stdio: "ignore" });
|
|
308776
309006
|
} catch {
|
|
308777
309007
|
}
|
|
308778
309008
|
}
|
|
@@ -309452,7 +309682,7 @@ function startApiServer(options2 = {}) {
|
|
|
309452
309682
|
if (retentionDays > 0) {
|
|
309453
309683
|
try {
|
|
309454
309684
|
const jobsDir3 = join85(cwd4, ".oa", "jobs");
|
|
309455
|
-
if (
|
|
309685
|
+
if (existsSync69(jobsDir3)) {
|
|
309456
309686
|
const cutoff = Date.now() - retentionDays * 864e5;
|
|
309457
309687
|
for (const f2 of readdirSync23(jobsDir3)) {
|
|
309458
309688
|
if (!f2.endsWith(".json")) continue;
|
|
@@ -309681,8 +309911,8 @@ import { resolve as resolve35, join as join86, dirname as dirname26, extname as
|
|
|
309681
309911
|
import { createRequire as createRequire5 } from "node:module";
|
|
309682
309912
|
import { fileURLToPath as fileURLToPath17 } from "node:url";
|
|
309683
309913
|
import { readFileSync as readFileSync55, writeFileSync as writeFileSync35, appendFileSync as appendFileSync6, rmSync as rmSync4, readdirSync as readdirSync24, mkdirSync as mkdirSync38 } from "node:fs";
|
|
309684
|
-
import { existsSync as
|
|
309685
|
-
import { execSync as
|
|
309914
|
+
import { existsSync as existsSync70 } from "node:fs";
|
|
309915
|
+
import { execSync as execSync50 } from "node:child_process";
|
|
309686
309916
|
import { homedir as homedir25 } from "node:os";
|
|
309687
309917
|
function formatTimeAgo(date) {
|
|
309688
309918
|
const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
|
|
@@ -309704,7 +309934,7 @@ function getVersion4() {
|
|
|
309704
309934
|
join86(thisDir, "..", "..", "..", "package.json")
|
|
309705
309935
|
];
|
|
309706
309936
|
for (const pkgPath of candidates) {
|
|
309707
|
-
if (
|
|
309937
|
+
if (existsSync70(pkgPath)) {
|
|
309708
309938
|
const pkg = require3(pkgPath);
|
|
309709
309939
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli" || pkg.name === "@open-agents/monorepo") {
|
|
309710
309940
|
return pkg.version ?? "0.0.0";
|
|
@@ -309853,6 +310083,7 @@ function buildTools(repoRoot, config, contextWindowSize, modelTier) {
|
|
|
309853
310083
|
new BluetoothScanTool(),
|
|
309854
310084
|
new SdrScanTool(),
|
|
309855
310085
|
new FlipperZeroTool(),
|
|
310086
|
+
new MeshtasticTool(),
|
|
309856
310087
|
// Full OA sub-process — callbacks wired after runner + statusBar created
|
|
309857
310088
|
(() => {
|
|
309858
310089
|
_fullSubAgentToolRef = new FullSubAgentTool(repoRoot, config.model, config.backendUrl);
|
|
@@ -310208,7 +310439,7 @@ function gatherMemorySnippets(root) {
|
|
|
310208
310439
|
join86(root, ".open-agents", "memory")
|
|
310209
310440
|
];
|
|
310210
310441
|
for (const dir of dirs) {
|
|
310211
|
-
if (!
|
|
310442
|
+
if (!existsSync70(dir)) continue;
|
|
310212
310443
|
try {
|
|
310213
310444
|
for (const f2 of readdirSync24(dir).filter((f3) => f3.endsWith(".json"))) {
|
|
310214
310445
|
const data = JSON.parse(readFileSync55(join86(dir, f2), "utf-8"));
|
|
@@ -310366,7 +310597,7 @@ ${metabolismMemories}
|
|
|
310366
310597
|
}
|
|
310367
310598
|
try {
|
|
310368
310599
|
const archeFile = join86(repoRoot, ".oa", "arche", "variants.json");
|
|
310369
|
-
if (
|
|
310600
|
+
if (existsSync70(archeFile)) {
|
|
310370
310601
|
const variants = JSON.parse(readFileSync55(archeFile, "utf8"));
|
|
310371
310602
|
if (variants.length > 0) {
|
|
310372
310603
|
let filtered = variants;
|
|
@@ -310537,7 +310768,7 @@ RULES:
|
|
|
310537
310768
|
let identityInjection = "";
|
|
310538
310769
|
try {
|
|
310539
310770
|
const ikStateFile = join86(repoRoot, ".oa", "identity", "self-state.json");
|
|
310540
|
-
if (
|
|
310771
|
+
if (existsSync70(ikStateFile)) {
|
|
310541
310772
|
const selfState = JSON.parse(readFileSync55(ikStateFile, "utf8"));
|
|
310542
310773
|
const lines = [
|
|
310543
310774
|
`[Identity State v${selfState.version}]`,
|
|
@@ -311269,7 +311500,7 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
311269
311500
|
const ikDir = join86(repoRoot, ".oa", "identity");
|
|
311270
311501
|
const ikFile = join86(ikDir, "self-state.json");
|
|
311271
311502
|
let ikState;
|
|
311272
|
-
if (
|
|
311503
|
+
if (existsSync70(ikFile)) {
|
|
311273
311504
|
ikState = JSON.parse(readFileSync55(ikFile, "utf8"));
|
|
311274
311505
|
} else {
|
|
311275
311506
|
mkdirSync38(ikDir, { recursive: true });
|
|
@@ -311348,7 +311579,7 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
311348
311579
|
renderTaskIncomplete(result.turns, result.toolCalls, result.durationMs, tokens);
|
|
311349
311580
|
try {
|
|
311350
311581
|
const ikFile = join86(repoRoot, ".oa", "identity", "self-state.json");
|
|
311351
|
-
if (
|
|
311582
|
+
if (existsSync70(ikFile)) {
|
|
311352
311583
|
const ikState = JSON.parse(readFileSync55(ikFile, "utf8"));
|
|
311353
311584
|
if (!ikState.stats) ikState.stats = { queries_served: 0 };
|
|
311354
311585
|
ikState.stats.queries_served = (ikState.stats.queries_served || 0) + 1;
|
|
@@ -311477,7 +311708,7 @@ async function startInteractive(config, repoPath) {
|
|
|
311477
311708
|
try {
|
|
311478
311709
|
const oaDir = join86(repoRoot, ".oa");
|
|
311479
311710
|
const nexusPidFile = join86(oaDir, "nexus", "daemon.pid");
|
|
311480
|
-
if (
|
|
311711
|
+
if (existsSync70(nexusPidFile)) {
|
|
311481
311712
|
const pid = parseInt(readFileSync55(nexusPidFile, "utf8").trim(), 10);
|
|
311482
311713
|
if (pid > 0) {
|
|
311483
311714
|
try {
|
|
@@ -312247,7 +312478,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
312247
312478
|
const MAX_HISTORY_LINES = 500;
|
|
312248
312479
|
let savedHistory = [];
|
|
312249
312480
|
try {
|
|
312250
|
-
if (
|
|
312481
|
+
if (existsSync70(HISTORY_FILE)) {
|
|
312251
312482
|
const raw = readFileSync55(HISTORY_FILE, "utf8").trim();
|
|
312252
312483
|
if (raw) savedHistory = raw.split("\n").reverse();
|
|
312253
312484
|
}
|
|
@@ -312555,7 +312786,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
312555
312786
|
join86(repoRoot, ".oa", "nexus", "nexus-daemon.mjs"),
|
|
312556
312787
|
join86(_hdir(), ".open-agents", ".oa", "nexus", "nexus-daemon.mjs")
|
|
312557
312788
|
]) {
|
|
312558
|
-
if (
|
|
312789
|
+
if (existsSync70(dp)) try {
|
|
312559
312790
|
_rmStale(dp);
|
|
312560
312791
|
} catch {
|
|
312561
312792
|
}
|
|
@@ -312567,7 +312798,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
312567
312798
|
const _registerNexusDaemon = () => {
|
|
312568
312799
|
try {
|
|
312569
312800
|
const nexusPidFile = join86(repoRoot, ".oa", "nexus", "daemon.pid");
|
|
312570
|
-
if (
|
|
312801
|
+
if (existsSync70(nexusPidFile)) {
|
|
312571
312802
|
const nPid = parseInt(readFileSync55(nexusPidFile, "utf8").trim(), 10);
|
|
312572
312803
|
if (nPid > 0 && !registry2.daemons.has("Nexus")) {
|
|
312573
312804
|
registry2.register({ name: "Nexus", pid: nPid, startedAt: Date.now(), status: "running" });
|
|
@@ -312691,7 +312922,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
312691
312922
|
const globalNamePath = join86(_hd(), ".open-agents", "agent-name");
|
|
312692
312923
|
let agName = "";
|
|
312693
312924
|
try {
|
|
312694
|
-
if (
|
|
312925
|
+
if (existsSync70(globalNamePath)) agName = readFileSync55(globalNamePath, "utf8").trim();
|
|
312695
312926
|
} catch {
|
|
312696
312927
|
}
|
|
312697
312928
|
if (!agName) {
|
|
@@ -312723,7 +312954,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
312723
312954
|
const savedSponsorsPath = join86(repoRoot, ".oa", "sponsor", "known-sponsors.json");
|
|
312724
312955
|
let savedSponsors = [];
|
|
312725
312956
|
try {
|
|
312726
|
-
if (
|
|
312957
|
+
if (existsSync70(savedSponsorsPath)) {
|
|
312727
312958
|
savedSponsors = JSON.parse(readFileSync55(savedSponsorsPath, "utf8"));
|
|
312728
312959
|
const oneHourAgo = Date.now() - 36e5;
|
|
312729
312960
|
savedSponsors = savedSponsors.filter((s2) => (s2.lastVerified || 0) > oneHourAgo);
|
|
@@ -313816,7 +314047,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
313816
314047
|
if (!result.success) throw new Error(result.error || "Connect failed");
|
|
313817
314048
|
try {
|
|
313818
314049
|
const nexusPidFile = join86(repoRoot, ".oa", "nexus", "daemon.pid");
|
|
313819
|
-
if (
|
|
314050
|
+
if (existsSync70(nexusPidFile)) {
|
|
313820
314051
|
const pid = parseInt(readFileSync55(nexusPidFile, "utf8").trim(), 10);
|
|
313821
314052
|
if (pid > 0) {
|
|
313822
314053
|
registry2.register({
|
|
@@ -314005,13 +314236,13 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
314005
314236
|
try {
|
|
314006
314237
|
const nexusDir = join86(repoRoot, OA_DIR, "nexus");
|
|
314007
314238
|
const pidFile = join86(nexusDir, "daemon.pid");
|
|
314008
|
-
if (
|
|
314239
|
+
if (existsSync70(pidFile)) {
|
|
314009
314240
|
const pid = parseInt(readFileSync55(pidFile, "utf8").trim(), 10);
|
|
314010
314241
|
if (pid > 0) {
|
|
314011
314242
|
try {
|
|
314012
314243
|
if (process.platform === "win32") {
|
|
314013
314244
|
try {
|
|
314014
|
-
|
|
314245
|
+
execSync50(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
|
|
314015
314246
|
} catch {
|
|
314016
314247
|
}
|
|
314017
314248
|
} else {
|
|
@@ -314032,13 +314263,13 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
314032
314263
|
const voicePidFiles = ["luxtts-daemon.pid", "piper-daemon.pid"];
|
|
314033
314264
|
for (const pf of voicePidFiles) {
|
|
314034
314265
|
const pidPath = join86(voiceDir2, pf);
|
|
314035
|
-
if (
|
|
314266
|
+
if (existsSync70(pidPath)) {
|
|
314036
314267
|
try {
|
|
314037
314268
|
const pid = parseInt(readFileSync55(pidPath, "utf8").trim(), 10);
|
|
314038
314269
|
if (pid > 0) {
|
|
314039
314270
|
if (process.platform === "win32") {
|
|
314040
314271
|
try {
|
|
314041
|
-
|
|
314272
|
+
execSync50(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
|
|
314042
314273
|
} catch {
|
|
314043
314274
|
}
|
|
314044
314275
|
} else {
|
|
@@ -314055,11 +314286,11 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
314055
314286
|
} catch {
|
|
314056
314287
|
}
|
|
314057
314288
|
try {
|
|
314058
|
-
|
|
314289
|
+
execSync50(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.5", { timeout: 3e3, stdio: "ignore" });
|
|
314059
314290
|
} catch {
|
|
314060
314291
|
}
|
|
314061
314292
|
const oaPath = join86(repoRoot, OA_DIR);
|
|
314062
|
-
if (
|
|
314293
|
+
if (existsSync70(oaPath)) {
|
|
314063
314294
|
let deleted = false;
|
|
314064
314295
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
314065
314296
|
try {
|
|
@@ -314069,14 +314300,14 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
314069
314300
|
} catch (err) {
|
|
314070
314301
|
if (attempt < 2) {
|
|
314071
314302
|
try {
|
|
314072
|
-
|
|
314303
|
+
execSync50(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.3", { timeout: 3e3, stdio: "ignore" });
|
|
314073
314304
|
} catch {
|
|
314074
314305
|
}
|
|
314075
314306
|
} else {
|
|
314076
314307
|
writeContent(() => renderWarning(`Could not fully remove ${OA_DIR}/: ${err instanceof Error ? err.message : String(err)}`));
|
|
314077
314308
|
if (process.platform === "win32") {
|
|
314078
314309
|
try {
|
|
314079
|
-
|
|
314310
|
+
execSync50(`rd /s /q "${oaPath}"`, { timeout: 1e4, stdio: "ignore" });
|
|
314080
314311
|
deleted = true;
|
|
314081
314312
|
} catch {
|
|
314082
314313
|
}
|
|
@@ -314143,16 +314374,16 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
314143
314374
|
if (isPersonaPlexRunning2()) {
|
|
314144
314375
|
const ppPidFile = join86(homedir25(), ".open-agents", "voice", "personaplex", "daemon.pid");
|
|
314145
314376
|
const ppPortFile = join86(homedir25(), ".open-agents", "voice", "personaplex", "daemon.port");
|
|
314146
|
-
if (
|
|
314377
|
+
if (existsSync70(ppPidFile)) {
|
|
314147
314378
|
const ppPid = parseInt(readFileSync55(ppPidFile, "utf8").trim(), 10);
|
|
314148
|
-
const ppPort =
|
|
314379
|
+
const ppPort = existsSync70(ppPortFile) ? parseInt(readFileSync55(ppPortFile, "utf8").trim(), 10) : void 0;
|
|
314149
314380
|
if (ppPid > 0 && !registry2.daemons.has("PersonaPlex")) {
|
|
314150
314381
|
registry2.register({ name: "PersonaPlex", pid: ppPid, port: ppPort, startedAt: Date.now(), status: "running" });
|
|
314151
314382
|
}
|
|
314152
314383
|
}
|
|
314153
314384
|
}
|
|
314154
314385
|
const nexusPidFile = join86(repoRoot, ".oa", "nexus", "daemon.pid");
|
|
314155
|
-
if (
|
|
314386
|
+
if (existsSync70(nexusPidFile)) {
|
|
314156
314387
|
const nPid = parseInt(readFileSync55(nexusPidFile, "utf8").trim(), 10);
|
|
314157
314388
|
if (nPid > 0 && !registry2.daemons.has("Nexus")) {
|
|
314158
314389
|
try {
|
|
@@ -314494,8 +314725,8 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
314494
314725
|
}
|
|
314495
314726
|
}
|
|
314496
314727
|
const cleanPath = input.replace(/^['"]|['"]$/g, "").trim();
|
|
314497
|
-
const isImage = isImagePath(cleanPath) &&
|
|
314498
|
-
const isMedia = !isImage && isTranscribablePath(cleanPath) &&
|
|
314728
|
+
const isImage = isImagePath(cleanPath) && existsSync70(resolve35(repoRoot, cleanPath));
|
|
314729
|
+
const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync70(resolve35(repoRoot, cleanPath));
|
|
314499
314730
|
if (activeTask) {
|
|
314500
314731
|
if (activeTask.runner.isPaused) {
|
|
314501
314732
|
activeTask.runner.resume();
|
|
@@ -314723,7 +314954,7 @@ Summarize or analyze this transcription as appropriate.`;
|
|
|
314723
314954
|
|
|
314724
314955
|
NEW TASK: ${fullInput}`;
|
|
314725
314956
|
restoredSessionContext = null;
|
|
314726
|
-
} else if (
|
|
314957
|
+
} else if (existsSync70(join86(repoRoot, ".oa", "context", "session-diary.md"))) {
|
|
314727
314958
|
taskInput = `[Previous sessions exist \u2014 file_read(".oa/context/session-diary.md") to recall]
|
|
314728
314959
|
|
|
314729
314960
|
${fullInput}`;
|
|
@@ -315060,7 +315291,7 @@ async function runWithTUI(task, config, repoPath, callbacks) {
|
|
|
315060
315291
|
const ikDir = join86(repoRoot, ".oa", "identity");
|
|
315061
315292
|
const ikFile = join86(ikDir, "self-state.json");
|
|
315062
315293
|
let ikState;
|
|
315063
|
-
if (
|
|
315294
|
+
if (existsSync70(ikFile)) {
|
|
315064
315295
|
ikState = JSON.parse(readFileSync55(ikFile, "utf8"));
|
|
315065
315296
|
} else {
|
|
315066
315297
|
mkdirSync38(ikDir, { recursive: true });
|
|
@@ -315102,7 +315333,7 @@ async function runWithTUI(task, config, repoPath, callbacks) {
|
|
|
315102
315333
|
const archeFile = join86(archeDir, "variants.json");
|
|
315103
315334
|
let variants = [];
|
|
315104
315335
|
try {
|
|
315105
|
-
if (
|
|
315336
|
+
if (existsSync70(archeFile)) variants = JSON.parse(readFileSync55(archeFile, "utf8"));
|
|
315106
315337
|
} catch {
|
|
315107
315338
|
}
|
|
315108
315339
|
variants.push({
|
|
@@ -315123,7 +315354,7 @@ async function runWithTUI(task, config, repoPath, callbacks) {
|
|
|
315123
315354
|
}
|
|
315124
315355
|
try {
|
|
315125
315356
|
const metaFile = join86(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
315126
|
-
if (
|
|
315357
|
+
if (existsSync70(metaFile)) {
|
|
315127
315358
|
const store2 = JSON.parse(readFileSync55(metaFile, "utf8"));
|
|
315128
315359
|
const surfaced = store2.filter((m2) => m2.type !== "quarantine" && m2.scores?.confidence > 0.15).sort((a2, b) => b.scores.utility * b.scores.confidence - a2.scores.utility * a2.scores.confidence).slice(0, 5);
|
|
315129
315360
|
let updated = false;
|
|
@@ -315209,7 +315440,7 @@ Rules:
|
|
|
315209
315440
|
const storeFile = join86(metaDir, "store.json");
|
|
315210
315441
|
let store2 = [];
|
|
315211
315442
|
try {
|
|
315212
|
-
if (
|
|
315443
|
+
if (existsSync70(storeFile)) store2 = JSON.parse(readFileSync55(storeFile, "utf8"));
|
|
315213
315444
|
} catch {
|
|
315214
315445
|
}
|
|
315215
315446
|
store2.push({
|
|
@@ -315234,7 +315465,7 @@ Rules:
|
|
|
315234
315465
|
const cohereSettingsFile = join86(repoRoot, ".oa", "settings.json");
|
|
315235
315466
|
let cohereActive = false;
|
|
315236
315467
|
try {
|
|
315237
|
-
if (
|
|
315468
|
+
if (existsSync70(cohereSettingsFile)) {
|
|
315238
315469
|
const settings = JSON.parse(readFileSync55(cohereSettingsFile, "utf8"));
|
|
315239
315470
|
cohereActive = settings.cohere === true;
|
|
315240
315471
|
}
|
|
@@ -315242,7 +315473,7 @@ Rules:
|
|
|
315242
315473
|
}
|
|
315243
315474
|
if (cohereActive) {
|
|
315244
315475
|
const metaFile = join86(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
315245
|
-
if (
|
|
315476
|
+
if (existsSync70(metaFile)) {
|
|
315246
315477
|
const store2 = JSON.parse(readFileSync55(metaFile, "utf8"));
|
|
315247
315478
|
const latest = store2.filter((m2) => m2.sourceTrace === "trajectory-extraction" || m2.sourceTrace === "llm-trajectory-extraction").slice(-1)[0];
|
|
315248
315479
|
if (latest && latest.scores?.confidence >= 0.6) {
|
|
@@ -315269,7 +315500,7 @@ Rules:
|
|
|
315269
315500
|
} catch (err) {
|
|
315270
315501
|
try {
|
|
315271
315502
|
const ikFile = join86(repoRoot, ".oa", "identity", "self-state.json");
|
|
315272
|
-
if (
|
|
315503
|
+
if (existsSync70(ikFile)) {
|
|
315273
315504
|
const ikState = JSON.parse(readFileSync55(ikFile, "utf8"));
|
|
315274
315505
|
ikState.homeostasis.uncertainty = Math.min(1, ikState.homeostasis.uncertainty + 0.1);
|
|
315275
315506
|
ikState.homeostasis.coherence = Math.max(0, ikState.homeostasis.coherence - 0.05);
|
|
@@ -315278,7 +315509,7 @@ Rules:
|
|
|
315278
315509
|
writeFileSync35(ikFile, JSON.stringify(ikState, null, 2));
|
|
315279
315510
|
}
|
|
315280
315511
|
const metaFile = join86(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
315281
|
-
if (
|
|
315512
|
+
if (existsSync70(metaFile)) {
|
|
315282
315513
|
const store2 = JSON.parse(readFileSync55(metaFile, "utf8"));
|
|
315283
315514
|
const surfaced = store2.filter((m2) => m2.type !== "quarantine" && m2.scores?.confidence > 0.15).sort((a2, b) => b.scores.utility * b.scores.confidence - a2.scores.utility * a2.scores.confidence).slice(0, 5);
|
|
315284
315515
|
for (const item of surfaced) {
|
|
@@ -315294,7 +315525,7 @@ Rules:
|
|
|
315294
315525
|
const archeFile = join86(archeDir, "variants.json");
|
|
315295
315526
|
let variants = [];
|
|
315296
315527
|
try {
|
|
315297
|
-
if (
|
|
315528
|
+
if (existsSync70(archeFile)) variants = JSON.parse(readFileSync55(archeFile, "utf8"));
|
|
315298
315529
|
} catch {
|
|
315299
315530
|
}
|
|
315300
315531
|
variants.push({
|
|
@@ -315391,7 +315622,7 @@ __export(run_exports, {
|
|
|
315391
315622
|
});
|
|
315392
315623
|
import { resolve as resolve36 } from "node:path";
|
|
315393
315624
|
import { spawn as spawn25 } from "node:child_process";
|
|
315394
|
-
import { mkdirSync as mkdirSync39, writeFileSync as writeFileSync36, readFileSync as readFileSync56, readdirSync as readdirSync25, existsSync as
|
|
315625
|
+
import { mkdirSync as mkdirSync39, writeFileSync as writeFileSync36, readFileSync as readFileSync56, readdirSync as readdirSync25, existsSync as existsSync71 } from "node:fs";
|
|
315395
315626
|
import { randomBytes as randomBytes20 } from "node:crypto";
|
|
315396
315627
|
import { join as join87 } from "node:path";
|
|
315397
315628
|
function jobsDir2(repoPath) {
|
|
@@ -315545,7 +315776,7 @@ async function runBackground(task, config, opts) {
|
|
|
315545
315776
|
function statusCommand(jobId, repoPath) {
|
|
315546
315777
|
const dir = jobsDir2(repoPath);
|
|
315547
315778
|
const file = join87(dir, `${jobId}.json`);
|
|
315548
|
-
if (!
|
|
315779
|
+
if (!existsSync71(file)) {
|
|
315549
315780
|
console.error(`Job not found: ${jobId}`);
|
|
315550
315781
|
console.log(`Available jobs: oa jobs`);
|
|
315551
315782
|
process.exit(1);
|
|
@@ -315803,13 +316034,13 @@ __export(index_repo_exports, {
|
|
|
315803
316034
|
indexRepoCommand: () => indexRepoCommand
|
|
315804
316035
|
});
|
|
315805
316036
|
import { resolve as resolve37 } from "node:path";
|
|
315806
|
-
import { existsSync as
|
|
316037
|
+
import { existsSync as existsSync72, statSync as statSync21 } from "node:fs";
|
|
315807
316038
|
import { cwd as cwd2 } from "node:process";
|
|
315808
316039
|
async function indexRepoCommand(opts, _config3) {
|
|
315809
316040
|
const repoRoot = resolve37(opts.repoPath ?? cwd2());
|
|
315810
316041
|
printHeader("Index Repository");
|
|
315811
316042
|
printInfo(`Indexing: ${repoRoot}`);
|
|
315812
|
-
if (!
|
|
316043
|
+
if (!existsSync72(repoRoot)) {
|
|
315813
316044
|
printError(`Path does not exist: ${repoRoot}`);
|
|
315814
316045
|
process.exit(1);
|
|
315815
316046
|
}
|