open-agents-ai 0.187.142 → 0.187.144
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 +679 -477
- 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" },
|
|
@@ -254956,6 +254956,11 @@ var init_wifi_control = __esm({
|
|
|
254956
254956
|
if (!iface) {
|
|
254957
254957
|
return { success: false, output: "", error: "No WiFi interface found. Connect a WiFi adapter.", durationMs: performance.now() - start2 };
|
|
254958
254958
|
}
|
|
254959
|
+
try {
|
|
254960
|
+
execSync30(`test -d /sys/class/net/${iface}`, { timeout: 2e3, stdio: "pipe" });
|
|
254961
|
+
} catch {
|
|
254962
|
+
return { success: false, output: "", error: `WiFi interface '${iface}' does not exist. Use wifi_control action='interfaces' to see available adapters.`, durationMs: performance.now() - start2 };
|
|
254963
|
+
}
|
|
254959
254964
|
try {
|
|
254960
254965
|
execSync30(`nmcli device wifi rescan ifname ${iface} 2>/dev/null`, { timeout: 1e4, stdio: "pipe" });
|
|
254961
254966
|
execSync30("sleep 1", { timeout: 5e3 });
|
|
@@ -255559,11 +255564,16 @@ Tools installed but rtl_test failed \u2014 device may be in use by another proce
|
|
|
255559
255564
|
mkdirSync12(captureDir, { recursive: true });
|
|
255560
255565
|
const outFile = join46(captureDir, `scan-${Date.now()}.csv`);
|
|
255561
255566
|
const gainArg = gain !== void 0 ? `-g ${gain}` : "";
|
|
255562
|
-
const cmd = `timeout ${duration +
|
|
255567
|
+
const cmd = `timeout ${duration + 15} rtl_power -f ${startFreq}:${endFreq}:10k ${gainArg} -i 1 -e ${duration}s ${outFile} 2>&1`;
|
|
255563
255568
|
try {
|
|
255564
|
-
|
|
255565
|
-
|
|
255566
|
-
|
|
255569
|
+
let output = "";
|
|
255570
|
+
try {
|
|
255571
|
+
output = execSync32(cmd, { encoding: "utf8", timeout: (duration + 20) * 1e3 });
|
|
255572
|
+
} catch (cmdErr) {
|
|
255573
|
+
output = cmdErr.stdout?.toString() || cmdErr.stderr?.toString() || "";
|
|
255574
|
+
}
|
|
255575
|
+
if (!existsSync31(outFile) || statSync13(outFile).size === 0) {
|
|
255576
|
+
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 };
|
|
255567
255577
|
}
|
|
255568
255578
|
const csv = readFileSync23(outFile, "utf8");
|
|
255569
255579
|
const lines = csv.trim().split("\n");
|
|
@@ -255890,6 +255900,195 @@ ${cleanOutput}`, durationMs: performance.now() - start2 };
|
|
|
255890
255900
|
}
|
|
255891
255901
|
});
|
|
255892
255902
|
|
|
255903
|
+
// packages/execution/dist/tools/meshtastic-tool.js
|
|
255904
|
+
import { execSync as execSync34 } from "node:child_process";
|
|
255905
|
+
import { existsSync as existsSync32 } from "node:fs";
|
|
255906
|
+
var MESH_VENV, MESH_CLI, MeshtasticTool;
|
|
255907
|
+
var init_meshtastic_tool = __esm({
|
|
255908
|
+
"packages/execution/dist/tools/meshtastic-tool.js"() {
|
|
255909
|
+
"use strict";
|
|
255910
|
+
init_system_auth();
|
|
255911
|
+
MESH_VENV = "/tmp/mesh-venv";
|
|
255912
|
+
MESH_CLI = `${MESH_VENV}/bin/meshtastic`;
|
|
255913
|
+
MeshtasticTool = class {
|
|
255914
|
+
name = "meshtastic";
|
|
255915
|
+
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.";
|
|
255916
|
+
parameters = {
|
|
255917
|
+
type: "object",
|
|
255918
|
+
properties: {
|
|
255919
|
+
action: {
|
|
255920
|
+
type: "string",
|
|
255921
|
+
enum: ["info", "nodes", "send", "position", "telemetry", "channels"],
|
|
255922
|
+
description: "Action to perform"
|
|
255923
|
+
},
|
|
255924
|
+
message: {
|
|
255925
|
+
type: "string",
|
|
255926
|
+
description: "Text message to send (for 'send' action)"
|
|
255927
|
+
},
|
|
255928
|
+
channel: {
|
|
255929
|
+
type: "number",
|
|
255930
|
+
description: "Channel index to send on (default: 0 = primary)"
|
|
255931
|
+
},
|
|
255932
|
+
destination: {
|
|
255933
|
+
type: "string",
|
|
255934
|
+
description: "Destination node ID for direct message (default: broadcast). Use '!hexid' format."
|
|
255935
|
+
},
|
|
255936
|
+
port: {
|
|
255937
|
+
type: "string",
|
|
255938
|
+
description: "Serial port (default: auto-detect /dev/ttyACM0 or /dev/ttyUSB0)"
|
|
255939
|
+
}
|
|
255940
|
+
},
|
|
255941
|
+
required: ["action"]
|
|
255942
|
+
};
|
|
255943
|
+
async execute(args) {
|
|
255944
|
+
const action = args["action"];
|
|
255945
|
+
const start2 = performance.now();
|
|
255946
|
+
const cliReady = await this.ensureMeshtasticCli();
|
|
255947
|
+
if (!cliReady) {
|
|
255948
|
+
return { success: false, output: "", error: "Could not install meshtastic CLI. Run: pip install meshtastic", durationMs: performance.now() - start2 };
|
|
255949
|
+
}
|
|
255950
|
+
const port = args["port"] || this.findMeshtasticPort();
|
|
255951
|
+
if (!port) {
|
|
255952
|
+
return { success: false, output: "", error: "No Meshtastic device found. Connect a Meshtastic device via USB.", durationMs: performance.now() - start2 };
|
|
255953
|
+
}
|
|
255954
|
+
try {
|
|
255955
|
+
switch (action) {
|
|
255956
|
+
case "info":
|
|
255957
|
+
return this.getInfo(port, start2);
|
|
255958
|
+
case "nodes":
|
|
255959
|
+
return this.listNodes(port, start2);
|
|
255960
|
+
case "send":
|
|
255961
|
+
return this.sendMessage(port, args, start2);
|
|
255962
|
+
case "position":
|
|
255963
|
+
return this.getPosition(port, start2);
|
|
255964
|
+
case "telemetry":
|
|
255965
|
+
return this.getTelemetry(port, start2);
|
|
255966
|
+
case "channels":
|
|
255967
|
+
return this.getChannels(port, start2);
|
|
255968
|
+
default:
|
|
255969
|
+
return { success: false, output: "", error: `Unknown action: ${action}`, durationMs: performance.now() - start2 };
|
|
255970
|
+
}
|
|
255971
|
+
} catch (err) {
|
|
255972
|
+
return { success: false, output: "", error: `meshtastic error: ${err instanceof Error ? err.message : String(err)}`, durationMs: performance.now() - start2 };
|
|
255973
|
+
}
|
|
255974
|
+
}
|
|
255975
|
+
async getInfo(port, start2) {
|
|
255976
|
+
return this.runMeshCmd(port, "--info", start2, "Device info");
|
|
255977
|
+
}
|
|
255978
|
+
async listNodes(port, start2) {
|
|
255979
|
+
return this.runMeshCmd(port, "--nodes", start2, "Mesh nodes");
|
|
255980
|
+
}
|
|
255981
|
+
async sendMessage(port, args, start2) {
|
|
255982
|
+
const message2 = args["message"];
|
|
255983
|
+
if (!message2) {
|
|
255984
|
+
return { success: false, output: "", error: "Missing 'message'. Provide text to send.", durationMs: performance.now() - start2 };
|
|
255985
|
+
}
|
|
255986
|
+
const channel = args["channel"] ?? 0;
|
|
255987
|
+
const dest = args["destination"];
|
|
255988
|
+
let cmd = `--sendtext "${message2.replace(/"/g, '\\"')}" --ch-index ${channel}`;
|
|
255989
|
+
if (dest)
|
|
255990
|
+
cmd += ` --dest ${dest}`;
|
|
255991
|
+
return this.runMeshCmd(port, cmd, start2, `Sent: "${message2.slice(0, 50)}"`);
|
|
255992
|
+
}
|
|
255993
|
+
async getPosition(port, start2) {
|
|
255994
|
+
return this.runMeshCmd(port, "--info", start2, "Position", (output) => {
|
|
255995
|
+
const posMatch = output.match(/"position":\s*\{[^}]+\}/s);
|
|
255996
|
+
return posMatch ? `GPS Position:
|
|
255997
|
+
${posMatch[0]}` : "Position data not available (device may not have GPS fix)";
|
|
255998
|
+
});
|
|
255999
|
+
}
|
|
256000
|
+
async getTelemetry(port, start2) {
|
|
256001
|
+
return this.runMeshCmd(port, "--info", start2, "Telemetry", (output) => {
|
|
256002
|
+
const metricMatch = output.match(/"deviceMetrics":\s*\{[^}]+\}/s);
|
|
256003
|
+
return metricMatch ? `Device Telemetry:
|
|
256004
|
+
${metricMatch[0]}` : "Telemetry data not available";
|
|
256005
|
+
});
|
|
256006
|
+
}
|
|
256007
|
+
async getChannels(port, start2) {
|
|
256008
|
+
return this.runMeshCmd(port, "--ch-index 0 --get lora", start2, "Channel config");
|
|
256009
|
+
}
|
|
256010
|
+
// =========================================================================
|
|
256011
|
+
// Helpers
|
|
256012
|
+
// =========================================================================
|
|
256013
|
+
async runMeshCmd(port, cmdArgs, start2, label, transform) {
|
|
256014
|
+
await this.ensureSerialAccess(port);
|
|
256015
|
+
try {
|
|
256016
|
+
const output = execSync34(`${MESH_CLI} --port ${port} ${cmdArgs}`, { encoding: "utf8", timeout: 3e4, stdio: ["pipe", "pipe", "pipe"] });
|
|
256017
|
+
const result = transform ? transform(output) : output;
|
|
256018
|
+
return { success: true, output: `${label}:
|
|
256019
|
+
${result.trim()}`, durationMs: performance.now() - start2 };
|
|
256020
|
+
} catch (err) {
|
|
256021
|
+
const stderr = err.stderr?.toString() || "";
|
|
256022
|
+
const stdout = err.stdout?.toString() || "";
|
|
256023
|
+
if (stderr.includes("Permission") || stderr.includes("denied")) {
|
|
256024
|
+
try {
|
|
256025
|
+
await runElevated(`chmod 666 ${port} && usermod -a -G dialout $(whoami)`, {
|
|
256026
|
+
timeout: 3e4,
|
|
256027
|
+
description: "Open Agents needs serial port access for Meshtastic device"
|
|
256028
|
+
});
|
|
256029
|
+
const output2 = execSync34(`${MESH_CLI} --port ${port} ${cmdArgs}`, { encoding: "utf8", timeout: 3e4, stdio: ["pipe", "pipe", "pipe"] });
|
|
256030
|
+
const result2 = transform ? transform(output2) : output2;
|
|
256031
|
+
return { success: true, output: `${label}:
|
|
256032
|
+
${result2.trim()}`, durationMs: performance.now() - start2 };
|
|
256033
|
+
} catch {
|
|
256034
|
+
return { success: false, output: "", error: `Permission denied on ${port}. Run: sudo chmod 666 ${port}`, durationMs: performance.now() - start2 };
|
|
256035
|
+
}
|
|
256036
|
+
}
|
|
256037
|
+
if (stdout.includes("Connected to radio")) {
|
|
256038
|
+
const result = transform ? transform(stdout) : stdout;
|
|
256039
|
+
return { success: true, output: `${label}:
|
|
256040
|
+
${result.trim()}`, durationMs: performance.now() - start2 };
|
|
256041
|
+
}
|
|
256042
|
+
return { success: false, output: stdout.slice(0, 500), error: `${label} failed: ${stderr.slice(0, 300)}`, durationMs: performance.now() - start2 };
|
|
256043
|
+
}
|
|
256044
|
+
}
|
|
256045
|
+
/** Ensure serial port is accessible without sudo */
|
|
256046
|
+
async ensureSerialAccess(port) {
|
|
256047
|
+
try {
|
|
256048
|
+
execSync34(`test -r ${port} && test -w ${port}`, { timeout: 2e3, stdio: "pipe" });
|
|
256049
|
+
} catch {
|
|
256050
|
+
try {
|
|
256051
|
+
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" });
|
|
256052
|
+
} catch {
|
|
256053
|
+
}
|
|
256054
|
+
}
|
|
256055
|
+
}
|
|
256056
|
+
findMeshtasticPort() {
|
|
256057
|
+
for (const dev of ["/dev/ttyACM0", "/dev/ttyACM1", "/dev/ttyUSB0", "/dev/ttyUSB1"]) {
|
|
256058
|
+
if (!existsSync32(dev))
|
|
256059
|
+
continue;
|
|
256060
|
+
try {
|
|
256061
|
+
const udev = execSync34(`udevadm info --query=all --name=${dev} 2>/dev/null`, { encoding: "utf8", timeout: 3e3 });
|
|
256062
|
+
if (/heltec|meshtastic|t-beam|espressif|rak|wisblock/i.test(udev)) {
|
|
256063
|
+
return dev;
|
|
256064
|
+
}
|
|
256065
|
+
} catch {
|
|
256066
|
+
}
|
|
256067
|
+
}
|
|
256068
|
+
for (const dev of ["/dev/ttyACM0", "/dev/ttyUSB0"]) {
|
|
256069
|
+
if (existsSync32(dev))
|
|
256070
|
+
return dev;
|
|
256071
|
+
}
|
|
256072
|
+
return null;
|
|
256073
|
+
}
|
|
256074
|
+
/** Auto-install meshtastic CLI into a venv */
|
|
256075
|
+
async ensureMeshtasticCli() {
|
|
256076
|
+
if (existsSync32(MESH_CLI))
|
|
256077
|
+
return true;
|
|
256078
|
+
try {
|
|
256079
|
+
execSync34(`python3 -m venv ${MESH_VENV} && ${MESH_VENV}/bin/pip install meshtastic`, {
|
|
256080
|
+
timeout: 12e4,
|
|
256081
|
+
stdio: "pipe"
|
|
256082
|
+
});
|
|
256083
|
+
return existsSync32(MESH_CLI);
|
|
256084
|
+
} catch {
|
|
256085
|
+
return false;
|
|
256086
|
+
}
|
|
256087
|
+
}
|
|
256088
|
+
};
|
|
256089
|
+
}
|
|
256090
|
+
});
|
|
256091
|
+
|
|
255893
256092
|
// packages/execution/dist/tools/full-sub-agent.js
|
|
255894
256093
|
import { spawn as spawn13, ChildProcess } from "node:child_process";
|
|
255895
256094
|
import { randomBytes as randomBytes13 } from "node:crypto";
|
|
@@ -256334,8 +256533,8 @@ var init_agent_tool = __esm({
|
|
|
256334
256533
|
});
|
|
256335
256534
|
|
|
256336
256535
|
// packages/execution/dist/tools/worktree.js
|
|
256337
|
-
import { execSync as
|
|
256338
|
-
import { existsSync as
|
|
256536
|
+
import { execSync as execSync35 } from "node:child_process";
|
|
256537
|
+
import { existsSync as existsSync33, mkdirSync as mkdirSync13, rmSync } from "node:fs";
|
|
256339
256538
|
import { join as join47, resolve as resolve30 } from "node:path";
|
|
256340
256539
|
function validateSlug(slug) {
|
|
256341
256540
|
if (!slug)
|
|
@@ -256353,7 +256552,7 @@ function flattenSlug(slug) {
|
|
|
256353
256552
|
}
|
|
256354
256553
|
function isGitRepo(cwd4) {
|
|
256355
256554
|
try {
|
|
256356
|
-
|
|
256555
|
+
execSync35("git rev-parse --is-inside-work-tree", { cwd: cwd4, stdio: "pipe" });
|
|
256357
256556
|
return true;
|
|
256358
256557
|
} catch {
|
|
256359
256558
|
return false;
|
|
@@ -256361,14 +256560,14 @@ function isGitRepo(cwd4) {
|
|
|
256361
256560
|
}
|
|
256362
256561
|
function getCurrentBranch(cwd4) {
|
|
256363
256562
|
try {
|
|
256364
|
-
return
|
|
256563
|
+
return execSync35("git rev-parse --abbrev-ref HEAD", { cwd: cwd4, stdio: "pipe" }).toString().trim();
|
|
256365
256564
|
} catch {
|
|
256366
256565
|
return void 0;
|
|
256367
256566
|
}
|
|
256368
256567
|
}
|
|
256369
256568
|
function getCurrentCommit(cwd4) {
|
|
256370
256569
|
try {
|
|
256371
|
-
return
|
|
256570
|
+
return execSync35("git rev-parse --short HEAD", { cwd: cwd4, stdio: "pipe" }).toString().trim();
|
|
256372
256571
|
} catch {
|
|
256373
256572
|
return void 0;
|
|
256374
256573
|
}
|
|
@@ -256384,7 +256583,7 @@ function createWorktree(repoRoot, slug) {
|
|
|
256384
256583
|
const worktreeBase = join47(repoRoot, ".oa", "worktrees");
|
|
256385
256584
|
const worktreePath = join47(worktreeBase, flat);
|
|
256386
256585
|
const branchName = `worktree-${flat}`;
|
|
256387
|
-
if (
|
|
256586
|
+
if (existsSync33(worktreePath)) {
|
|
256388
256587
|
const session2 = {
|
|
256389
256588
|
slug,
|
|
256390
256589
|
worktreePath: resolve30(worktreePath),
|
|
@@ -256399,13 +256598,13 @@ function createWorktree(repoRoot, slug) {
|
|
|
256399
256598
|
}
|
|
256400
256599
|
mkdirSync13(worktreeBase, { recursive: true });
|
|
256401
256600
|
try {
|
|
256402
|
-
|
|
256601
|
+
execSync35(`git worktree add "${worktreePath}" -b "${branchName}"`, {
|
|
256403
256602
|
cwd: repoRoot,
|
|
256404
256603
|
stdio: "pipe"
|
|
256405
256604
|
});
|
|
256406
256605
|
} catch (err) {
|
|
256407
256606
|
try {
|
|
256408
|
-
|
|
256607
|
+
execSync35(`git worktree add "${worktreePath}" "${branchName}"`, {
|
|
256409
256608
|
cwd: repoRoot,
|
|
256410
256609
|
stdio: "pipe"
|
|
256411
256610
|
});
|
|
@@ -256427,7 +256626,7 @@ function createWorktree(repoRoot, slug) {
|
|
|
256427
256626
|
}
|
|
256428
256627
|
function worktreeHasChanges(worktreePath) {
|
|
256429
256628
|
try {
|
|
256430
|
-
const status =
|
|
256629
|
+
const status = execSync35("git status --porcelain", {
|
|
256431
256630
|
cwd: worktreePath,
|
|
256432
256631
|
stdio: "pipe"
|
|
256433
256632
|
}).toString().trim();
|
|
@@ -256440,7 +256639,7 @@ function removeWorktree(repoRoot, slug, force = false) {
|
|
|
256440
256639
|
const flat = flattenSlug(slug);
|
|
256441
256640
|
const worktreePath = join47(repoRoot, ".oa", "worktrees", flat);
|
|
256442
256641
|
const branchName = `worktree-${flat}`;
|
|
256443
|
-
if (!
|
|
256642
|
+
if (!existsSync33(worktreePath)) {
|
|
256444
256643
|
_sessions.delete(slug);
|
|
256445
256644
|
return true;
|
|
256446
256645
|
}
|
|
@@ -256448,20 +256647,20 @@ function removeWorktree(repoRoot, slug, force = false) {
|
|
|
256448
256647
|
return "Worktree has uncommitted changes. Use force=true to discard, or commit/stash first.";
|
|
256449
256648
|
}
|
|
256450
256649
|
try {
|
|
256451
|
-
|
|
256650
|
+
execSync35(`git worktree remove "${worktreePath}" ${force ? "--force" : ""}`, {
|
|
256452
256651
|
cwd: repoRoot,
|
|
256453
256652
|
stdio: "pipe"
|
|
256454
256653
|
});
|
|
256455
256654
|
} catch (err) {
|
|
256456
256655
|
try {
|
|
256457
256656
|
rmSync(worktreePath, { recursive: true, force: true });
|
|
256458
|
-
|
|
256657
|
+
execSync35("git worktree prune", { cwd: repoRoot, stdio: "pipe" });
|
|
256459
256658
|
} catch {
|
|
256460
256659
|
return `Failed to remove worktree: ${err}`;
|
|
256461
256660
|
}
|
|
256462
256661
|
}
|
|
256463
256662
|
try {
|
|
256464
|
-
|
|
256663
|
+
execSync35(`git branch -D "${branchName}"`, { cwd: repoRoot, stdio: "pipe" });
|
|
256465
256664
|
} catch {
|
|
256466
256665
|
}
|
|
256467
256666
|
_sessions.delete(slug);
|
|
@@ -257112,13 +257311,13 @@ var init_client3 = __esm({
|
|
|
257112
257311
|
});
|
|
257113
257312
|
|
|
257114
257313
|
// packages/execution/dist/mcp/manager.js
|
|
257115
|
-
import { existsSync as
|
|
257314
|
+
import { existsSync as existsSync34, readFileSync as readFileSync24 } from "node:fs";
|
|
257116
257315
|
import { join as join48 } from "node:path";
|
|
257117
257316
|
import { homedir as homedir12 } from "node:os";
|
|
257118
257317
|
function loadMcpConfig(repoRoot) {
|
|
257119
257318
|
const servers = {};
|
|
257120
257319
|
const globalPath = join48(homedir12(), ".open-agents", "mcp.json");
|
|
257121
|
-
if (
|
|
257320
|
+
if (existsSync34(globalPath)) {
|
|
257122
257321
|
try {
|
|
257123
257322
|
const global2 = JSON.parse(readFileSync24(globalPath, "utf8"));
|
|
257124
257323
|
Object.assign(servers, global2.mcpServers ?? {});
|
|
@@ -257126,7 +257325,7 @@ function loadMcpConfig(repoRoot) {
|
|
|
257126
257325
|
}
|
|
257127
257326
|
}
|
|
257128
257327
|
const localPath = join48(repoRoot, ".oa", "mcp.json");
|
|
257129
|
-
if (
|
|
257328
|
+
if (existsSync34(localPath)) {
|
|
257130
257329
|
try {
|
|
257131
257330
|
const local = JSON.parse(readFileSync24(localPath, "utf8"));
|
|
257132
257331
|
Object.assign(servers, local.mcpServers ?? {});
|
|
@@ -257134,7 +257333,7 @@ function loadMcpConfig(repoRoot) {
|
|
|
257134
257333
|
}
|
|
257135
257334
|
}
|
|
257136
257335
|
const rootPath = join48(repoRoot, ".mcp.json");
|
|
257137
|
-
if (
|
|
257336
|
+
if (existsSync34(rootPath)) {
|
|
257138
257337
|
try {
|
|
257139
257338
|
const root = JSON.parse(readFileSync24(rootPath, "utf8"));
|
|
257140
257339
|
Object.assign(servers, root.mcpServers ?? {});
|
|
@@ -257419,17 +257618,17 @@ var init_mcp = __esm({
|
|
|
257419
257618
|
});
|
|
257420
257619
|
|
|
257421
257620
|
// packages/execution/dist/plugins/plugin-system.js
|
|
257422
|
-
import { existsSync as
|
|
257621
|
+
import { existsSync as existsSync35, readdirSync as readdirSync7, readFileSync as readFileSync25 } from "node:fs";
|
|
257423
257622
|
import { join as join49 } from "node:path";
|
|
257424
257623
|
import { homedir as homedir13 } from "node:os";
|
|
257425
257624
|
function discoverPlugins(repoRoot) {
|
|
257426
257625
|
const plugins = [];
|
|
257427
257626
|
const globalDir = join49(homedir13(), ".open-agents", "plugins");
|
|
257428
|
-
if (
|
|
257627
|
+
if (existsSync35(globalDir)) {
|
|
257429
257628
|
plugins.push(...loadPluginsFromDir(globalDir));
|
|
257430
257629
|
}
|
|
257431
257630
|
const localDir = join49(repoRoot, ".oa", "plugins");
|
|
257432
|
-
if (
|
|
257631
|
+
if (existsSync35(localDir)) {
|
|
257433
257632
|
plugins.push(...loadPluginsFromDir(localDir));
|
|
257434
257633
|
}
|
|
257435
257634
|
return plugins;
|
|
@@ -257452,7 +257651,7 @@ function loadPluginsFromDir(dir) {
|
|
|
257452
257651
|
}
|
|
257453
257652
|
function loadPlugin(pluginPath) {
|
|
257454
257653
|
const oaManifestPath = join49(pluginPath, "oa-plugin.json");
|
|
257455
|
-
if (
|
|
257654
|
+
if (existsSync35(oaManifestPath)) {
|
|
257456
257655
|
try {
|
|
257457
257656
|
const manifest = JSON.parse(readFileSync25(oaManifestPath, "utf8"));
|
|
257458
257657
|
if (!manifest.name || !manifest.oa) {
|
|
@@ -257464,7 +257663,7 @@ function loadPlugin(pluginPath) {
|
|
|
257464
257663
|
}
|
|
257465
257664
|
}
|
|
257466
257665
|
const pkgPath = join49(pluginPath, "package.json");
|
|
257467
|
-
if (
|
|
257666
|
+
if (existsSync35(pkgPath)) {
|
|
257468
257667
|
try {
|
|
257469
257668
|
const pkg = JSON.parse(readFileSync25(pkgPath, "utf8"));
|
|
257470
257669
|
if (pkg.oa) {
|
|
@@ -257525,7 +257724,7 @@ var init_plugin_system = __esm({
|
|
|
257525
257724
|
if (skills) {
|
|
257526
257725
|
for (const relPath of skills) {
|
|
257527
257726
|
const absPath = join49(plugin.rootPath, relPath);
|
|
257528
|
-
if (
|
|
257727
|
+
if (existsSync35(absPath))
|
|
257529
257728
|
paths.push(absPath);
|
|
257530
257729
|
}
|
|
257531
257730
|
}
|
|
@@ -257579,9 +257778,9 @@ var init_plugin_system = __esm({
|
|
|
257579
257778
|
});
|
|
257580
257779
|
|
|
257581
257780
|
// packages/execution/dist/tools/notebook-edit.js
|
|
257582
|
-
import { readFileSync as readFileSync26, writeFileSync as writeFileSync12, existsSync as
|
|
257781
|
+
import { readFileSync as readFileSync26, writeFileSync as writeFileSync12, existsSync as existsSync36 } from "node:fs";
|
|
257583
257782
|
function readNotebook(path5) {
|
|
257584
|
-
if (!
|
|
257783
|
+
if (!existsSync36(path5))
|
|
257585
257784
|
return `File not found: ${path5}`;
|
|
257586
257785
|
if (!path5.endsWith(".ipynb"))
|
|
257587
257786
|
return `Not a notebook file (must be .ipynb): ${path5}`;
|
|
@@ -257738,7 +257937,7 @@ var init_notebook_edit = __esm({
|
|
|
257738
257937
|
});
|
|
257739
257938
|
|
|
257740
257939
|
// packages/execution/dist/tools/environment-snapshot.js
|
|
257741
|
-
import { execSync as
|
|
257940
|
+
import { execSync as execSync36 } from "node:child_process";
|
|
257742
257941
|
import { cpus, totalmem, freemem, hostname as hostname2, platform, arch, uptime } from "node:os";
|
|
257743
257942
|
import { statfsSync } from "node:fs";
|
|
257744
257943
|
function collectSnapshot(workingDir) {
|
|
@@ -257756,7 +257955,7 @@ function collectSnapshot(workingDir) {
|
|
|
257756
257955
|
}
|
|
257757
257956
|
let gpu = void 0;
|
|
257758
257957
|
try {
|
|
257759
|
-
const nvOut =
|
|
257958
|
+
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());
|
|
257760
257959
|
if (nvOut.length >= 3) {
|
|
257761
257960
|
gpu = {
|
|
257762
257961
|
name: nvOut[0],
|
|
@@ -257771,12 +257970,12 @@ function collectSnapshot(workingDir) {
|
|
|
257771
257970
|
let battery = void 0;
|
|
257772
257971
|
try {
|
|
257773
257972
|
if (platform() === "linux") {
|
|
257774
|
-
const cap =
|
|
257775
|
-
const status =
|
|
257973
|
+
const cap = execSync36("cat /sys/class/power_supply/BAT0/capacity 2>/dev/null", { encoding: "utf-8", timeout: 1e3 }).trim();
|
|
257974
|
+
const status = execSync36("cat /sys/class/power_supply/BAT0/status 2>/dev/null", { encoding: "utf-8", timeout: 1e3 }).trim();
|
|
257776
257975
|
if (cap)
|
|
257777
257976
|
battery = { percent: parseInt(cap, 10), charging: status === "Charging" || status === "Full" };
|
|
257778
257977
|
} else if (platform() === "darwin") {
|
|
257779
|
-
const pmOut =
|
|
257978
|
+
const pmOut = execSync36("pmset -g batt", { encoding: "utf-8", timeout: 2e3 });
|
|
257780
257979
|
const match = pmOut.match(/(\d+)%;\s*(charging|discharging|charged)/i);
|
|
257781
257980
|
if (match)
|
|
257782
257981
|
battery = { percent: parseInt(match[1], 10), charging: match[2].toLowerCase() !== "discharging" };
|
|
@@ -257797,8 +257996,8 @@ function collectSnapshot(workingDir) {
|
|
|
257797
257996
|
}
|
|
257798
257997
|
let processInfo = { total: 0, nodeCount: 0, oaSpawned: 0, topCpu: [] };
|
|
257799
257998
|
try {
|
|
257800
|
-
const psLines =
|
|
257801
|
-
const total = parseInt(
|
|
257999
|
+
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");
|
|
258000
|
+
const total = parseInt(execSync36("ps aux | wc -l", { encoding: "utf-8", timeout: 2e3 }).trim(), 10);
|
|
257802
258001
|
let nodeCount = 0;
|
|
257803
258002
|
let oaSpawned = 0;
|
|
257804
258003
|
const topCpu = [];
|
|
@@ -257879,8 +258078,8 @@ var init_environment_snapshot = __esm({
|
|
|
257879
258078
|
});
|
|
257880
258079
|
|
|
257881
258080
|
// packages/execution/dist/tools/video-understand.js
|
|
257882
|
-
import { execSync as
|
|
257883
|
-
import { existsSync as
|
|
258081
|
+
import { execSync as execSync37 } from "node:child_process";
|
|
258082
|
+
import { existsSync as existsSync37, mkdirSync as mkdirSync14, writeFileSync as writeFileSync13, readFileSync as readFileSync27, readdirSync as readdirSync8, unlinkSync as unlinkSync8 } from "node:fs";
|
|
257884
258083
|
import { join as join50, basename as basename11 } from "node:path";
|
|
257885
258084
|
import { createHash as createHash2 } from "node:crypto";
|
|
257886
258085
|
function isYouTubeUrl2(url) {
|
|
@@ -257888,11 +258087,11 @@ function isYouTubeUrl2(url) {
|
|
|
257888
258087
|
}
|
|
257889
258088
|
function ensureYtDlp2() {
|
|
257890
258089
|
try {
|
|
257891
|
-
|
|
258090
|
+
execSync37("yt-dlp --version", { timeout: 5e3, stdio: "pipe" });
|
|
257892
258091
|
return true;
|
|
257893
258092
|
} catch {
|
|
257894
258093
|
try {
|
|
257895
|
-
|
|
258094
|
+
execSync37("pip3 install --break-system-packages yt-dlp 2>/dev/null || pip3 install --user yt-dlp 2>/dev/null", { timeout: 6e4, stdio: "pipe" });
|
|
257896
258095
|
return true;
|
|
257897
258096
|
} catch {
|
|
257898
258097
|
return false;
|
|
@@ -257901,7 +258100,7 @@ function ensureYtDlp2() {
|
|
|
257901
258100
|
}
|
|
257902
258101
|
function ensureFfmpeg() {
|
|
257903
258102
|
try {
|
|
257904
|
-
|
|
258103
|
+
execSync37("ffmpeg -version", { timeout: 3e3, stdio: "pipe" });
|
|
257905
258104
|
return true;
|
|
257906
258105
|
} catch {
|
|
257907
258106
|
return false;
|
|
@@ -257981,32 +258180,32 @@ var init_video_understand = __esm({
|
|
|
257981
258180
|
return { success: false, output: "", error: "yt-dlp required but not available. Install: pip3 install yt-dlp", durationMs: performance.now() - start2 };
|
|
257982
258181
|
}
|
|
257983
258182
|
try {
|
|
257984
|
-
|
|
258183
|
+
execSync37(`yt-dlp -f "worst[ext=mp4]" -o "${join50(tmpDir, "video.%(ext)s")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
|
|
257985
258184
|
} catch {
|
|
257986
|
-
|
|
258185
|
+
execSync37(`yt-dlp -f worst -o "${join50(tmpDir, "video.%(ext)s")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
|
|
257987
258186
|
}
|
|
257988
|
-
|
|
258187
|
+
execSync37(`yt-dlp -x --audio-format mp3 --audio-quality 5 -o "${join50(tmpDir, "audio.%(ext)s")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
|
|
257989
258188
|
try {
|
|
257990
|
-
title =
|
|
258189
|
+
title = execSync37(`yt-dlp --get-title "${url}"`, { encoding: "utf-8", timeout: 15e3, stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
257991
258190
|
} catch {
|
|
257992
258191
|
}
|
|
257993
258192
|
} else {
|
|
257994
|
-
|
|
257995
|
-
|
|
258193
|
+
execSync37(`curl -sL -o "${join50(tmpDir, "video.mp4")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
|
|
258194
|
+
execSync37(`ffmpeg -i "${join50(tmpDir, "video.mp4")}" -vn -acodec libmp3lame -q:a 5 "${join50(tmpDir, "audio.mp3")}" -y`, { timeout: 12e4, stdio: "pipe" });
|
|
257996
258195
|
}
|
|
257997
258196
|
videoPath = readdirSync8(tmpDir).find((f2) => f2.startsWith("video")) ? join50(tmpDir, readdirSync8(tmpDir).find((f2) => f2.startsWith("video"))) : join50(tmpDir, "video.mp4");
|
|
257998
258197
|
audioPath = readdirSync8(tmpDir).find((f2) => f2.startsWith("audio")) ? join50(tmpDir, readdirSync8(tmpDir).find((f2) => f2.startsWith("audio"))) : join50(tmpDir, "audio.mp3");
|
|
257999
258198
|
} else {
|
|
258000
258199
|
videoPath = localPath;
|
|
258001
258200
|
audioPath = join50(tmpDir, "audio.mp3");
|
|
258002
|
-
|
|
258201
|
+
execSync37(`ffmpeg -i "${videoPath}" -vn -acodec libmp3lame -q:a 5 "${audioPath}" -y`, { timeout: 12e4, stdio: "pipe" });
|
|
258003
258202
|
}
|
|
258004
258203
|
let segments = [];
|
|
258005
258204
|
let language = "en";
|
|
258006
258205
|
let duration = 0;
|
|
258007
258206
|
try {
|
|
258008
258207
|
const jsonOut = join50(tmpDir, "transcript.json");
|
|
258009
|
-
|
|
258208
|
+
execSync37(`transcribe-cli transcribe "${audioPath}" --model ${whisperModel} --format json -o "${tmpDir}"`, { timeout: 6e5, stdio: "pipe" });
|
|
258010
258209
|
const jsonFile = readdirSync8(tmpDir).find((f2) => f2.endsWith(".json") && f2 !== "result.json");
|
|
258011
258210
|
if (jsonFile) {
|
|
258012
258211
|
const data = JSON.parse(readFileSync27(join50(tmpDir, jsonFile), "utf-8"));
|
|
@@ -258023,13 +258222,13 @@ var init_video_understand = __esm({
|
|
|
258023
258222
|
segments = [];
|
|
258024
258223
|
}
|
|
258025
258224
|
let frames = [];
|
|
258026
|
-
if (!skipFrames && ensureFfmpeg() &&
|
|
258225
|
+
if (!skipFrames && ensureFfmpeg() && existsSync37(videoPath)) {
|
|
258027
258226
|
const framesDir = join50(tmpDir, "frames");
|
|
258028
258227
|
mkdirSync14(framesDir, { recursive: true });
|
|
258029
258228
|
const fps = 25;
|
|
258030
258229
|
const intervalFrames = Math.max(1, frameInterval * fps);
|
|
258031
258230
|
try {
|
|
258032
|
-
|
|
258231
|
+
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" });
|
|
258033
258232
|
} catch {
|
|
258034
258233
|
}
|
|
258035
258234
|
const frameFiles = readdirSync8(framesDir).filter((f2) => f2.endsWith(".jpg")).sort();
|
|
@@ -258162,7 +258361,7 @@ Topic: ${segments.slice(0, 5).map((s2) => s2.text).join(" ").slice(0, 300)}`,
|
|
|
258162
258361
|
}
|
|
258163
258362
|
}
|
|
258164
258363
|
try {
|
|
258165
|
-
|
|
258364
|
+
execSync37(`rm -rf "${tmpDir}"`, { timeout: 1e4, stdio: "pipe" });
|
|
258166
258365
|
} catch {
|
|
258167
258366
|
}
|
|
258168
258367
|
return {
|
|
@@ -258206,11 +258405,11 @@ var init_venv_paths = __esm({
|
|
|
258206
258405
|
});
|
|
258207
258406
|
|
|
258208
258407
|
// packages/execution/dist/tools/fortemi-bridge.js
|
|
258209
|
-
import { existsSync as
|
|
258408
|
+
import { existsSync as existsSync38, readFileSync as readFileSync28 } from "node:fs";
|
|
258210
258409
|
import { join as join52 } from "node:path";
|
|
258211
258410
|
function loadBridgeState(repoRoot) {
|
|
258212
258411
|
const bridgeFile = join52(repoRoot, ".oa", "fortemi-bridge.json");
|
|
258213
|
-
if (!
|
|
258412
|
+
if (!existsSync38(bridgeFile))
|
|
258214
258413
|
return null;
|
|
258215
258414
|
try {
|
|
258216
258415
|
return JSON.parse(readFileSync28(bridgeFile, "utf8"));
|
|
@@ -258461,7 +258660,7 @@ var init_gitWorktree = __esm({
|
|
|
258461
258660
|
});
|
|
258462
258661
|
|
|
258463
258662
|
// packages/execution/dist/patchApplier.js
|
|
258464
|
-
import { readFileSync as readFileSync29, writeFileSync as writeFileSync14, existsSync as
|
|
258663
|
+
import { readFileSync as readFileSync29, writeFileSync as writeFileSync14, existsSync as existsSync39, mkdirSync as mkdirSync15 } from "node:fs";
|
|
258465
258664
|
import { dirname as dirname14 } from "node:path";
|
|
258466
258665
|
import { spawn as spawn16 } from "node:child_process";
|
|
258467
258666
|
async function applyPatch(patch) {
|
|
@@ -258488,7 +258687,7 @@ function applyRewrite(patch) {
|
|
|
258488
258687
|
writeFileSync14(patch.filePath, patch.newContent, "utf-8");
|
|
258489
258688
|
}
|
|
258490
258689
|
function applyNewFile(patch) {
|
|
258491
|
-
if (
|
|
258690
|
+
if (existsSync39(patch.filePath)) {
|
|
258492
258691
|
throw new Error(`Cannot create new file: "${patch.filePath}" already exists.`);
|
|
258493
258692
|
}
|
|
258494
258693
|
mkdirSync15(dirname14(patch.filePath), { recursive: true });
|
|
@@ -258849,7 +259048,7 @@ var init_buildRunner = __esm({
|
|
|
258849
259048
|
});
|
|
258850
259049
|
|
|
258851
259050
|
// packages/execution/dist/constraints.js
|
|
258852
|
-
import { existsSync as
|
|
259051
|
+
import { existsSync as existsSync40, readFileSync as readFileSync30, writeFileSync as writeFileSync15, mkdirSync as mkdirSync16 } from "node:fs";
|
|
258853
259052
|
import { join as join53 } from "node:path";
|
|
258854
259053
|
import { homedir as homedir14 } from "node:os";
|
|
258855
259054
|
function loadConstraints(projectRoot) {
|
|
@@ -258858,7 +259057,7 @@ function loadConstraints(projectRoot) {
|
|
|
258858
259057
|
}
|
|
258859
259058
|
function loadFile(path5) {
|
|
258860
259059
|
try {
|
|
258861
|
-
if (!
|
|
259060
|
+
if (!existsSync40(path5))
|
|
258862
259061
|
return [];
|
|
258863
259062
|
const data = JSON.parse(readFileSync30(path5, "utf-8"));
|
|
258864
259063
|
return data.constraints || [];
|
|
@@ -258875,7 +259074,7 @@ function addProjectConstraint(projectRoot, constraint) {
|
|
|
258875
259074
|
const path5 = join53(projectRoot, ".oa", "constraints.json");
|
|
258876
259075
|
let data = { version: 1, constraints: [] };
|
|
258877
259076
|
try {
|
|
258878
|
-
if (
|
|
259077
|
+
if (existsSync40(path5))
|
|
258879
259078
|
data = JSON.parse(readFileSync30(path5, "utf-8"));
|
|
258880
259079
|
} catch {
|
|
258881
259080
|
}
|
|
@@ -259097,6 +259296,7 @@ __export(dist_exports, {
|
|
|
259097
259296
|
MemoryReadTool: () => MemoryReadTool,
|
|
259098
259297
|
MemorySearchTool: () => MemorySearchTool,
|
|
259099
259298
|
MemoryWriteTool: () => MemoryWriteTool,
|
|
259299
|
+
MeshtasticTool: () => MeshtasticTool,
|
|
259100
259300
|
NexusTool: () => NexusTool,
|
|
259101
259301
|
NotebookEditTool: () => NotebookEditTool,
|
|
259102
259302
|
OCRTool: () => OCRTool,
|
|
@@ -259300,6 +259500,7 @@ var init_dist4 = __esm({
|
|
|
259300
259500
|
init_bluetooth_scan();
|
|
259301
259501
|
init_sdr_scan();
|
|
259302
259502
|
init_flipper_zero();
|
|
259503
|
+
init_meshtastic_tool();
|
|
259303
259504
|
init_system_auth();
|
|
259304
259505
|
init_full_sub_agent();
|
|
259305
259506
|
init_agent_tool();
|
|
@@ -259999,14 +260200,14 @@ var init_dist5 = __esm({
|
|
|
259999
260200
|
});
|
|
260000
260201
|
|
|
260001
260202
|
// packages/orchestrator/dist/promptLoader.js
|
|
260002
|
-
import { readFileSync as readFileSync31, existsSync as
|
|
260203
|
+
import { readFileSync as readFileSync31, existsSync as existsSync41 } from "node:fs";
|
|
260003
260204
|
import { join as join54, dirname as dirname15 } from "node:path";
|
|
260004
260205
|
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
260005
260206
|
function loadPrompt(promptPath, vars) {
|
|
260006
260207
|
let content = cache4.get(promptPath);
|
|
260007
260208
|
if (content === void 0) {
|
|
260008
260209
|
const fullPath = join54(PROMPTS_DIR, promptPath);
|
|
260009
|
-
if (!
|
|
260210
|
+
if (!existsSync41(fullPath)) {
|
|
260010
260211
|
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
260011
260212
|
}
|
|
260012
260213
|
content = readFileSync31(fullPath, "utf-8");
|
|
@@ -262204,12 +262405,12 @@ var init_tool_batching = __esm({
|
|
|
262204
262405
|
});
|
|
262205
262406
|
|
|
262206
262407
|
// packages/orchestrator/dist/hooks.js
|
|
262207
|
-
import { execSync as
|
|
262408
|
+
import { execSync as execSync38 } from "node:child_process";
|
|
262208
262409
|
function executeHook(hook, env2 = {}) {
|
|
262209
262410
|
const start2 = performance.now();
|
|
262210
262411
|
const timeout2 = hook.timeoutMs ?? DEFAULT_HOOK_TIMEOUT;
|
|
262211
262412
|
try {
|
|
262212
|
-
const output =
|
|
262413
|
+
const output = execSync38(hook.command, {
|
|
262213
262414
|
timeout: timeout2,
|
|
262214
262415
|
env: { ...process.env, ...env2 },
|
|
262215
262416
|
encoding: "utf8",
|
|
@@ -266433,7 +266634,7 @@ ${result}`
|
|
|
266433
266634
|
const buffer2 = Buffer.from(rawBase64, "base64");
|
|
266434
266635
|
let resizedBase64 = null;
|
|
266435
266636
|
try {
|
|
266436
|
-
const { execSync:
|
|
266637
|
+
const { execSync: execSync51 } = await import("node:child_process");
|
|
266437
266638
|
const { writeFileSync: writeFileSync38, readFileSync: readFileSync57, unlinkSync: unlinkSync18 } = await import("node:fs");
|
|
266438
266639
|
const { join: join92 } = await import("node:path");
|
|
266439
266640
|
const { tmpdir: tmpdir15 } = await import("node:os");
|
|
@@ -266443,7 +266644,7 @@ ${result}`
|
|
|
266443
266644
|
const pyBin = process.platform === "win32" ? "python" : "python3";
|
|
266444
266645
|
const escapedIn = tmpIn.replace(/\\/g, "\\\\");
|
|
266445
266646
|
const escapedOut = tmpOut.replace(/\\/g, "\\\\");
|
|
266446
|
-
|
|
266647
|
+
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" });
|
|
266447
266648
|
const resizedBuf = readFileSync57(tmpOut);
|
|
266448
266649
|
resizedBase64 = `data:image/jpeg;base64,${resizedBuf.toString("base64")}`;
|
|
266449
266650
|
try {
|
|
@@ -266497,8 +266698,8 @@ ${result}`
|
|
|
266497
266698
|
if (!res.ok && model === "moondream" && res.status === 404) {
|
|
266498
266699
|
this.emit({ type: "status", content: `Pulling moondream vision model...`, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
266499
266700
|
try {
|
|
266500
|
-
const { execSync:
|
|
266501
|
-
|
|
266701
|
+
const { execSync: execSync51 } = await import("node:child_process");
|
|
266702
|
+
execSync51("ollama pull moondream", { timeout: 3e5, stdio: "pipe" });
|
|
266502
266703
|
res = await fetch(`${ollamaHost}/api/generate`, {
|
|
266503
266704
|
method: "POST",
|
|
266504
266705
|
headers: { "Content-Type": "application/json" },
|
|
@@ -267064,7 +267265,7 @@ var init_constraint_learner = __esm({
|
|
|
267064
267265
|
});
|
|
267065
267266
|
|
|
267066
267267
|
// packages/orchestrator/dist/nexusBackend.js
|
|
267067
|
-
import { existsSync as
|
|
267268
|
+
import { existsSync as existsSync42, statSync as statSync14, openSync, readSync, closeSync, unlinkSync as unlinkSync9, writeFileSync as writeFileSync16 } from "node:fs";
|
|
267068
267269
|
import { watch as fsWatch } from "node:fs";
|
|
267069
267270
|
import { join as join57 } from "node:path";
|
|
267070
267271
|
import { tmpdir as tmpdir11 } from "node:os";
|
|
@@ -268862,8 +269063,8 @@ __export(listen_exports, {
|
|
|
268862
269063
|
isVideoPath: () => isVideoPath,
|
|
268863
269064
|
waitForTranscribeCli: () => waitForTranscribeCli
|
|
268864
269065
|
});
|
|
268865
|
-
import { spawn as spawn17, execSync as
|
|
268866
|
-
import { existsSync as
|
|
269066
|
+
import { spawn as spawn17, execSync as execSync39 } from "node:child_process";
|
|
269067
|
+
import { existsSync as existsSync43, mkdirSync as mkdirSync17, writeFileSync as writeFileSync17, readdirSync as readdirSync9 } from "node:fs";
|
|
268867
269068
|
import { join as join58, dirname as dirname16 } from "node:path";
|
|
268868
269069
|
import { homedir as homedir15 } from "node:os";
|
|
268869
269070
|
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
@@ -268884,7 +269085,7 @@ function findMicCaptureCommand() {
|
|
|
268884
269085
|
const platform6 = process.platform;
|
|
268885
269086
|
if (platform6 === "linux") {
|
|
268886
269087
|
try {
|
|
268887
|
-
|
|
269088
|
+
execSync39("which arecord", { stdio: "pipe" });
|
|
268888
269089
|
return {
|
|
268889
269090
|
cmd: "arecord",
|
|
268890
269091
|
args: ["-f", "S16_LE", "-r", "16000", "-c", "1", "-t", "raw", "-q", "-"]
|
|
@@ -268894,7 +269095,7 @@ function findMicCaptureCommand() {
|
|
|
268894
269095
|
}
|
|
268895
269096
|
if (platform6 === "darwin") {
|
|
268896
269097
|
try {
|
|
268897
|
-
|
|
269098
|
+
execSync39("which sox", { stdio: "pipe" });
|
|
268898
269099
|
return {
|
|
268899
269100
|
cmd: "sox",
|
|
268900
269101
|
args: ["-d", "-t", "raw", "-r", "16000", "-c", "1", "-b", "16", "-e", "signed-integer", "-"]
|
|
@@ -268903,7 +269104,7 @@ function findMicCaptureCommand() {
|
|
|
268903
269104
|
}
|
|
268904
269105
|
}
|
|
268905
269106
|
try {
|
|
268906
|
-
|
|
269107
|
+
execSync39("which ffmpeg", { stdio: "pipe" });
|
|
268907
269108
|
if (platform6 === "linux") {
|
|
268908
269109
|
return {
|
|
268909
269110
|
cmd: "ffmpeg",
|
|
@@ -268958,10 +269159,10 @@ function findLiveWhisperScript() {
|
|
|
268958
269159
|
join58(thisDir, "../../scripts/live-whisper.py")
|
|
268959
269160
|
];
|
|
268960
269161
|
for (const p2 of candidates) {
|
|
268961
|
-
if (
|
|
269162
|
+
if (existsSync43(p2)) return p2;
|
|
268962
269163
|
}
|
|
268963
269164
|
try {
|
|
268964
|
-
const globalRoot =
|
|
269165
|
+
const globalRoot = execSync39("npm root -g", {
|
|
268965
269166
|
encoding: "utf-8",
|
|
268966
269167
|
timeout: 5e3,
|
|
268967
269168
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -268971,16 +269172,16 @@ function findLiveWhisperScript() {
|
|
|
268971
269172
|
join58(globalRoot, "open-agents-ai", "scripts", "live-whisper.py")
|
|
268972
269173
|
];
|
|
268973
269174
|
for (const p2 of candidates2) {
|
|
268974
|
-
if (
|
|
269175
|
+
if (existsSync43(p2)) return p2;
|
|
268975
269176
|
}
|
|
268976
269177
|
} catch {
|
|
268977
269178
|
}
|
|
268978
269179
|
const nvmBase = join58(homedir15(), ".nvm", "versions", "node");
|
|
268979
|
-
if (
|
|
269180
|
+
if (existsSync43(nvmBase)) {
|
|
268980
269181
|
try {
|
|
268981
269182
|
for (const ver of readdirSync9(nvmBase)) {
|
|
268982
269183
|
const p2 = join58(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
|
|
268983
|
-
if (
|
|
269184
|
+
if (existsSync43(p2)) return p2;
|
|
268984
269185
|
}
|
|
268985
269186
|
} catch {
|
|
268986
269187
|
}
|
|
@@ -268991,12 +269192,12 @@ function ensureTranscribeCliBackground() {
|
|
|
268991
269192
|
if (_bgInstallPromise) return;
|
|
268992
269193
|
_bgInstallPromise = (async () => {
|
|
268993
269194
|
try {
|
|
268994
|
-
const globalRoot =
|
|
269195
|
+
const globalRoot = execSync39("npm root -g", {
|
|
268995
269196
|
encoding: "utf-8",
|
|
268996
269197
|
timeout: 5e3,
|
|
268997
269198
|
stdio: ["pipe", "pipe", "pipe"]
|
|
268998
269199
|
}).trim();
|
|
268999
|
-
if (
|
|
269200
|
+
if (existsSync43(join58(globalRoot, "transcribe-cli", "dist", "index.js"))) {
|
|
269000
269201
|
return true;
|
|
269001
269202
|
}
|
|
269002
269203
|
} catch {
|
|
@@ -269193,7 +269394,7 @@ var init_listen = __esm({
|
|
|
269193
269394
|
}
|
|
269194
269395
|
if (!this.transcribeCliAvailable) {
|
|
269195
269396
|
try {
|
|
269196
|
-
|
|
269397
|
+
execSync39("which transcribe-cli", { stdio: "pipe" });
|
|
269197
269398
|
this.transcribeCliAvailable = true;
|
|
269198
269399
|
} catch {
|
|
269199
269400
|
this.transcribeCliAvailable = false;
|
|
@@ -269210,13 +269411,13 @@ var init_listen = __esm({
|
|
|
269210
269411
|
} catch {
|
|
269211
269412
|
}
|
|
269212
269413
|
try {
|
|
269213
|
-
const globalRoot =
|
|
269414
|
+
const globalRoot = execSync39("npm root -g", {
|
|
269214
269415
|
encoding: "utf-8",
|
|
269215
269416
|
timeout: 5e3,
|
|
269216
269417
|
stdio: ["pipe", "pipe", "pipe"]
|
|
269217
269418
|
}).trim();
|
|
269218
269419
|
const tcPath = join58(globalRoot, "transcribe-cli");
|
|
269219
|
-
if (
|
|
269420
|
+
if (existsSync43(join58(tcPath, "dist", "index.js"))) {
|
|
269220
269421
|
const { createRequire: createRequire7 } = await import("node:module");
|
|
269221
269422
|
const req2 = createRequire7(import.meta.url);
|
|
269222
269423
|
return req2(join58(tcPath, "dist", "index.js"));
|
|
@@ -269224,12 +269425,12 @@ var init_listen = __esm({
|
|
|
269224
269425
|
} catch {
|
|
269225
269426
|
}
|
|
269226
269427
|
const nvmBase = join58(homedir15(), ".nvm", "versions", "node");
|
|
269227
|
-
if (
|
|
269428
|
+
if (existsSync43(nvmBase)) {
|
|
269228
269429
|
try {
|
|
269229
269430
|
const { readdirSync: readdirSync26 } = await import("node:fs");
|
|
269230
269431
|
for (const ver of readdirSync26(nvmBase)) {
|
|
269231
269432
|
const tcPath = join58(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
|
|
269232
|
-
if (
|
|
269433
|
+
if (existsSync43(join58(tcPath, "dist", "index.js"))) {
|
|
269233
269434
|
const { createRequire: createRequire7 } = await import("node:module");
|
|
269234
269435
|
const req2 = createRequire7(import.meta.url);
|
|
269235
269436
|
return req2(join58(tcPath, "dist", "index.js"));
|
|
@@ -269259,7 +269460,7 @@ var init_listen = __esm({
|
|
|
269259
269460
|
}
|
|
269260
269461
|
if (!tc) {
|
|
269261
269462
|
try {
|
|
269262
|
-
|
|
269463
|
+
execSync39("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
|
|
269263
269464
|
this.transcribeCliAvailable = null;
|
|
269264
269465
|
tc = await this.loadTranscribeCli();
|
|
269265
269466
|
} catch {
|
|
@@ -269437,7 +269638,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
269437
269638
|
}
|
|
269438
269639
|
if (!tc) {
|
|
269439
269640
|
try {
|
|
269440
|
-
|
|
269641
|
+
execSync39("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
|
|
269441
269642
|
this.transcribeCliAvailable = null;
|
|
269442
269643
|
tc = await this.loadTranscribeCli();
|
|
269443
269644
|
} catch {
|
|
@@ -269490,7 +269691,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
269490
269691
|
}
|
|
269491
269692
|
if (!tc) {
|
|
269492
269693
|
try {
|
|
269493
|
-
|
|
269694
|
+
execSync39("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
|
|
269494
269695
|
this.transcribeCliAvailable = null;
|
|
269495
269696
|
tc = await this.loadTranscribeCli();
|
|
269496
269697
|
} catch {
|
|
@@ -274412,7 +274613,7 @@ var init_render = __esm({
|
|
|
274412
274613
|
|
|
274413
274614
|
// packages/cli/src/tui/voice-session.ts
|
|
274414
274615
|
import { createServer as createServer3 } from "node:http";
|
|
274415
|
-
import { spawn as spawn18, execSync as
|
|
274616
|
+
import { spawn as spawn18, execSync as execSync40 } from "node:child_process";
|
|
274416
274617
|
import { EventEmitter as EventEmitter4 } from "node:events";
|
|
274417
274618
|
function generateFrontendHTML() {
|
|
274418
274619
|
return `<!DOCTYPE html>
|
|
@@ -275535,7 +275736,7 @@ import { EventEmitter as EventEmitter5 } from "node:events";
|
|
|
275535
275736
|
import { randomBytes as randomBytes15 } from "node:crypto";
|
|
275536
275737
|
import { URL as URL2 } from "node:url";
|
|
275537
275738
|
import { loadavg, cpus as cpus2, totalmem as totalmem2, freemem as freemem2 } from "node:os";
|
|
275538
|
-
import { existsSync as
|
|
275739
|
+
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";
|
|
275539
275740
|
import { join as join59 } from "node:path";
|
|
275540
275741
|
function cleanForwardHeaders(raw, targetHost) {
|
|
275541
275742
|
const out = {};
|
|
@@ -275558,7 +275759,7 @@ function fmtTokens(n2) {
|
|
|
275558
275759
|
function readExposeState(stateDir) {
|
|
275559
275760
|
try {
|
|
275560
275761
|
const path5 = join59(stateDir, STATE_FILE_NAME);
|
|
275561
|
-
if (!
|
|
275762
|
+
if (!existsSync44(path5)) return null;
|
|
275562
275763
|
const raw = readFileSync32(path5, "utf8");
|
|
275563
275764
|
const data = JSON.parse(raw);
|
|
275564
275765
|
if (!data.pid || !data.tunnelUrl || !data.authKey || !data.proxyPort) return null;
|
|
@@ -275674,7 +275875,7 @@ async function collectSystemMetricsAsync() {
|
|
|
275674
275875
|
function readP2PExposeState(stateDir) {
|
|
275675
275876
|
try {
|
|
275676
275877
|
const path5 = join59(stateDir, P2P_STATE_FILE_NAME);
|
|
275677
|
-
if (!
|
|
275878
|
+
if (!existsSync44(path5)) return null;
|
|
275678
275879
|
const raw = readFileSync32(path5, "utf8");
|
|
275679
275880
|
const data = JSON.parse(raw);
|
|
275680
275881
|
if (!data.peerId || !data.authKey) return null;
|
|
@@ -276717,7 +276918,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
276717
276918
|
}
|
|
276718
276919
|
try {
|
|
276719
276920
|
const invocDir = join59(nexusDir, "invocations");
|
|
276720
|
-
if (
|
|
276921
|
+
if (existsSync44(invocDir)) {
|
|
276721
276922
|
this._prevInvocCount = readdirSync10(invocDir).filter((f2) => f2.endsWith(".json")).length;
|
|
276722
276923
|
this._stats.totalRequests = this._prevInvocCount;
|
|
276723
276924
|
}
|
|
@@ -276746,7 +276947,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
276746
276947
|
const nexusDir = nexusTool.getNexusDir();
|
|
276747
276948
|
const statusPath = join59(nexusDir, "status.json");
|
|
276748
276949
|
try {
|
|
276749
|
-
if (!
|
|
276950
|
+
if (!existsSync44(statusPath)) {
|
|
276750
276951
|
removeP2PExposeState(stateDir);
|
|
276751
276952
|
return null;
|
|
276752
276953
|
}
|
|
@@ -276804,7 +277005,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
276804
277005
|
this._activityPollTimer = setInterval(() => {
|
|
276805
277006
|
try {
|
|
276806
277007
|
const invocDir = join59(nexusDir, "invocations");
|
|
276807
|
-
if (!
|
|
277008
|
+
if (!existsSync44(invocDir)) return;
|
|
276808
277009
|
const files = readdirSync10(invocDir).filter((f2) => f2.endsWith(".json"));
|
|
276809
277010
|
const invocCount = files.length;
|
|
276810
277011
|
const newRequests = invocCount - this._prevInvocCount;
|
|
@@ -276826,7 +277027,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
276826
277027
|
const meteringFile = join59(nexusDir, "metering.jsonl");
|
|
276827
277028
|
let meteringLines = lastMeteringLineCount;
|
|
276828
277029
|
try {
|
|
276829
|
-
if (
|
|
277030
|
+
if (existsSync44(meteringFile)) {
|
|
276830
277031
|
const content = readFileSync32(meteringFile, "utf8");
|
|
276831
277032
|
meteringLines = content.split("\n").filter((l2) => l2.trim()).length;
|
|
276832
277033
|
}
|
|
@@ -276853,7 +277054,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
276853
277054
|
this._pollTimer = setInterval(() => {
|
|
276854
277055
|
try {
|
|
276855
277056
|
const statusPath = join59(nexusDir, "status.json");
|
|
276856
|
-
if (
|
|
277057
|
+
if (existsSync44(statusPath)) {
|
|
276857
277058
|
const status = JSON.parse(readFileSync32(statusPath, "utf8"));
|
|
276858
277059
|
if (status.peerId && !this._peerId) {
|
|
276859
277060
|
this._peerId = status.peerId;
|
|
@@ -276864,7 +277065,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
276864
277065
|
}
|
|
276865
277066
|
try {
|
|
276866
277067
|
const invocDir = join59(nexusDir, "invocations");
|
|
276867
|
-
if (
|
|
277068
|
+
if (existsSync44(invocDir)) {
|
|
276868
277069
|
const files = readdirSync10(invocDir);
|
|
276869
277070
|
const invocCount = files.filter((f2) => f2.endsWith(".json")).length;
|
|
276870
277071
|
if (invocCount > this._stats.totalRequests) {
|
|
@@ -276876,7 +277077,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
276876
277077
|
}
|
|
276877
277078
|
try {
|
|
276878
277079
|
const meteringFile = join59(nexusDir, "metering.jsonl");
|
|
276879
|
-
if (
|
|
277080
|
+
if (existsSync44(meteringFile)) {
|
|
276880
277081
|
const content = readFileSync32(meteringFile, "utf8");
|
|
276881
277082
|
if (content.length > lastMeteringSize) {
|
|
276882
277083
|
const newContent = content.slice(lastMeteringSize);
|
|
@@ -277088,7 +277289,7 @@ var init_types = __esm({
|
|
|
277088
277289
|
|
|
277089
277290
|
// packages/cli/src/tui/p2p/secret-vault.ts
|
|
277090
277291
|
import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes16, scryptSync as scryptSync2, createHash as createHash3 } from "node:crypto";
|
|
277091
|
-
import { readFileSync as readFileSync33, writeFileSync as writeFileSync19, existsSync as
|
|
277292
|
+
import { readFileSync as readFileSync33, writeFileSync as writeFileSync19, existsSync as existsSync45, mkdirSync as mkdirSync19 } from "node:fs";
|
|
277092
277293
|
import { dirname as dirname17 } from "node:path";
|
|
277093
277294
|
var PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, CIPHER_ALGO, SALT_LEN, IV_LEN, KEY_LEN, SecretVault;
|
|
277094
277295
|
var init_secret_vault = __esm({
|
|
@@ -277296,7 +277497,7 @@ var init_secret_vault = __esm({
|
|
|
277296
277497
|
const tag = cipher.getAuthTag();
|
|
277297
277498
|
const blob = Buffer.concat([salt, iv, tag, encrypted]);
|
|
277298
277499
|
const dir = dirname17(this.storePath);
|
|
277299
|
-
if (!
|
|
277500
|
+
if (!existsSync45(dir)) mkdirSync19(dir, { recursive: true });
|
|
277300
277501
|
writeFileSync19(this.storePath, blob, { mode: 384 });
|
|
277301
277502
|
}
|
|
277302
277503
|
/**
|
|
@@ -277304,7 +277505,7 @@ var init_secret_vault = __esm({
|
|
|
277304
277505
|
* Returns the number of secrets loaded.
|
|
277305
277506
|
*/
|
|
277306
277507
|
load(passphrase) {
|
|
277307
|
-
if (!this.storePath || !
|
|
277508
|
+
if (!this.storePath || !existsSync45(this.storePath)) return 0;
|
|
277308
277509
|
const blob = readFileSync33(this.storePath);
|
|
277309
277510
|
if (blob.length < SALT_LEN + IV_LEN + 16) {
|
|
277310
277511
|
throw new Error("Vault file is corrupted (too small)");
|
|
@@ -278458,7 +278659,7 @@ async function fetchOpenAIModels(baseUrl, apiKey) {
|
|
|
278458
278659
|
async function fetchPeerModels(peerId, authKey) {
|
|
278459
278660
|
try {
|
|
278460
278661
|
const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist4(), dist_exports));
|
|
278461
|
-
const { existsSync:
|
|
278662
|
+
const { existsSync: existsSync73, readFileSync: readFileSync57 } = await import("node:fs");
|
|
278462
278663
|
const { join: join92 } = await import("node:path");
|
|
278463
278664
|
const cwd4 = process.cwd();
|
|
278464
278665
|
const nexusTool = new NexusTool2(cwd4);
|
|
@@ -278466,7 +278667,7 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
278466
278667
|
let isLocalPeer = false;
|
|
278467
278668
|
try {
|
|
278468
278669
|
const statusPath = join92(nexusDir, "status.json");
|
|
278469
|
-
if (
|
|
278670
|
+
if (existsSync73(statusPath)) {
|
|
278470
278671
|
const status = JSON.parse(readFileSync57(statusPath, "utf8"));
|
|
278471
278672
|
if (status.peerId === peerId) isLocalPeer = true;
|
|
278472
278673
|
}
|
|
@@ -278474,7 +278675,7 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
278474
278675
|
}
|
|
278475
278676
|
if (isLocalPeer) {
|
|
278476
278677
|
const pricingPath = join92(nexusDir, "pricing.json");
|
|
278477
|
-
if (
|
|
278678
|
+
if (existsSync73(pricingPath)) {
|
|
278478
278679
|
try {
|
|
278479
278680
|
const pricing = JSON.parse(readFileSync57(pricingPath, "utf8"));
|
|
278480
278681
|
const localModels = (pricing.models || []).map((m2) => ({
|
|
@@ -278490,7 +278691,7 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
278490
278691
|
}
|
|
278491
278692
|
}
|
|
278492
278693
|
const cachePath = join92(nexusDir, "peer-models-cache.json");
|
|
278493
|
-
if (
|
|
278694
|
+
if (existsSync73(cachePath)) {
|
|
278494
278695
|
try {
|
|
278495
278696
|
const cache7 = JSON.parse(readFileSync57(cachePath, "utf8"));
|
|
278496
278697
|
if (cache7.peerId === peerId && cache7.models?.length > 0) {
|
|
@@ -278605,7 +278806,7 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
278605
278806
|
}
|
|
278606
278807
|
if (isLocalPeer) {
|
|
278607
278808
|
const pricingPath = join92(nexusDir, "pricing.json");
|
|
278608
|
-
if (
|
|
278809
|
+
if (existsSync73(pricingPath)) {
|
|
278609
278810
|
try {
|
|
278610
278811
|
const pricing = JSON.parse(readFileSync57(pricingPath, "utf8"));
|
|
278611
278812
|
return (pricing.models || []).map((m2) => ({
|
|
@@ -278863,14 +279064,14 @@ var init_render2 = __esm({
|
|
|
278863
279064
|
});
|
|
278864
279065
|
|
|
278865
279066
|
// packages/prompts/dist/promptLoader.js
|
|
278866
|
-
import { readFileSync as readFileSync34, existsSync as
|
|
279067
|
+
import { readFileSync as readFileSync34, existsSync as existsSync46 } from "node:fs";
|
|
278867
279068
|
import { join as join61, dirname as dirname18 } from "node:path";
|
|
278868
279069
|
import { fileURLToPath as fileURLToPath10 } from "node:url";
|
|
278869
279070
|
function loadPrompt2(promptPath, vars) {
|
|
278870
279071
|
let content = cache5.get(promptPath);
|
|
278871
279072
|
if (content === void 0) {
|
|
278872
279073
|
const fullPath = join61(PROMPTS_DIR2, promptPath);
|
|
278873
|
-
if (!
|
|
279074
|
+
if (!existsSync46(fullPath)) {
|
|
278874
279075
|
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
278875
279076
|
}
|
|
278876
279077
|
content = readFileSync34(fullPath, "utf-8");
|
|
@@ -278888,7 +279089,7 @@ var init_promptLoader2 = __esm({
|
|
|
278888
279089
|
__dirname6 = dirname18(__filename4);
|
|
278889
279090
|
devPath = join61(__dirname6, "..", "templates");
|
|
278890
279091
|
publishedPath = join61(__dirname6, "..", "prompts", "templates");
|
|
278891
|
-
PROMPTS_DIR2 =
|
|
279092
|
+
PROMPTS_DIR2 = existsSync46(devPath) ? devPath : publishedPath;
|
|
278892
279093
|
cache5 = /* @__PURE__ */ new Map();
|
|
278893
279094
|
}
|
|
278894
279095
|
});
|
|
@@ -279047,7 +279248,7 @@ __export(oa_directory_exports, {
|
|
|
279047
279248
|
writeIndexData: () => writeIndexData,
|
|
279048
279249
|
writeIndexMeta: () => writeIndexMeta
|
|
279049
279250
|
});
|
|
279050
|
-
import { existsSync as
|
|
279251
|
+
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";
|
|
279051
279252
|
import { join as join63, relative as relative4, basename as basename12 } from "node:path";
|
|
279052
279253
|
import { homedir as homedir16 } from "node:os";
|
|
279053
279254
|
function initOaDirectory(repoRoot) {
|
|
@@ -279058,7 +279259,7 @@ function initOaDirectory(repoRoot) {
|
|
|
279058
279259
|
try {
|
|
279059
279260
|
const gitignorePath = join63(repoRoot, ".gitignore");
|
|
279060
279261
|
const settingsPattern = ".oa/settings.json";
|
|
279061
|
-
if (
|
|
279262
|
+
if (existsSync47(gitignorePath)) {
|
|
279062
279263
|
const content = readFileSync35(gitignorePath, "utf-8");
|
|
279063
279264
|
if (!content.includes(settingsPattern)) {
|
|
279064
279265
|
writeFileSync20(gitignorePath, content.trimEnd() + "\n" + settingsPattern + "\n", "utf-8");
|
|
@@ -279069,12 +279270,12 @@ function initOaDirectory(repoRoot) {
|
|
|
279069
279270
|
return oaPath;
|
|
279070
279271
|
}
|
|
279071
279272
|
function hasOaDirectory(repoRoot) {
|
|
279072
|
-
return
|
|
279273
|
+
return existsSync47(join63(repoRoot, OA_DIR, "index"));
|
|
279073
279274
|
}
|
|
279074
279275
|
function loadProjectSettings(repoRoot) {
|
|
279075
279276
|
const settingsPath = join63(repoRoot, OA_DIR, "settings.json");
|
|
279076
279277
|
try {
|
|
279077
|
-
if (
|
|
279278
|
+
if (existsSync47(settingsPath)) {
|
|
279078
279279
|
return JSON.parse(readFileSync35(settingsPath, "utf-8"));
|
|
279079
279280
|
}
|
|
279080
279281
|
} catch {
|
|
@@ -279091,7 +279292,7 @@ function saveProjectSettings(repoRoot, settings) {
|
|
|
279091
279292
|
function loadGlobalSettings() {
|
|
279092
279293
|
const settingsPath = join63(homedir16(), ".open-agents", "settings.json");
|
|
279093
279294
|
try {
|
|
279094
|
-
if (
|
|
279295
|
+
if (existsSync47(settingsPath)) {
|
|
279095
279296
|
return JSON.parse(readFileSync35(settingsPath, "utf-8"));
|
|
279096
279297
|
}
|
|
279097
279298
|
} catch {
|
|
@@ -279120,7 +279321,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
279120
279321
|
for (const name10 of CONTEXT_FILES) {
|
|
279121
279322
|
const filePath = join63(dir, name10);
|
|
279122
279323
|
const normalizedName = name10.toLowerCase();
|
|
279123
|
-
if (
|
|
279324
|
+
if (existsSync47(filePath) && !seen.has(filePath)) {
|
|
279124
279325
|
seen.add(filePath);
|
|
279125
279326
|
try {
|
|
279126
279327
|
let content = readFileSync35(filePath, "utf-8");
|
|
@@ -279138,7 +279339,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
279138
279339
|
}
|
|
279139
279340
|
}
|
|
279140
279341
|
const projectMap = join63(dir, OA_DIR, "context", "project-map.md");
|
|
279141
|
-
if (
|
|
279342
|
+
if (existsSync47(projectMap) && !seen.has(projectMap)) {
|
|
279142
279343
|
seen.add(projectMap);
|
|
279143
279344
|
try {
|
|
279144
279345
|
let content = readFileSync35(projectMap, "utf-8");
|
|
@@ -279256,7 +279457,7 @@ function saveSession(repoRoot, session) {
|
|
|
279256
279457
|
}
|
|
279257
279458
|
function loadRecentSessions(repoRoot, limit = 5) {
|
|
279258
279459
|
const historyDir = join63(repoRoot, OA_DIR, "history");
|
|
279259
|
-
if (!
|
|
279460
|
+
if (!existsSync47(historyDir)) return [];
|
|
279260
279461
|
try {
|
|
279261
279462
|
const files = readdirSync11(historyDir).filter((f2) => f2.endsWith(".json") && f2 !== "pending-task.json").map((f2) => {
|
|
279262
279463
|
const stat6 = statSync16(join63(historyDir, f2));
|
|
@@ -279287,7 +279488,7 @@ function savePendingTask(repoRoot, task) {
|
|
|
279287
279488
|
function loadPendingTask(repoRoot) {
|
|
279288
279489
|
const filePath = join63(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
|
|
279289
279490
|
try {
|
|
279290
|
-
if (!
|
|
279491
|
+
if (!existsSync47(filePath)) return null;
|
|
279291
279492
|
const data = JSON.parse(readFileSync35(filePath, "utf-8"));
|
|
279292
279493
|
try {
|
|
279293
279494
|
unlinkSync11(filePath);
|
|
@@ -279304,7 +279505,7 @@ function saveSessionContext(repoRoot, entry) {
|
|
|
279304
279505
|
const filePath = join63(contextDir, CONTEXT_SAVE_FILE);
|
|
279305
279506
|
let ctx3;
|
|
279306
279507
|
try {
|
|
279307
|
-
if (
|
|
279508
|
+
if (existsSync47(filePath)) {
|
|
279308
279509
|
ctx3 = JSON.parse(readFileSync35(filePath, "utf-8"));
|
|
279309
279510
|
} else {
|
|
279310
279511
|
ctx3 = { entries: [], maxEntries: MAX_CONTEXT_ENTRIES, updatedAt: "" };
|
|
@@ -279338,7 +279539,7 @@ function saveSessionContext(repoRoot, entry) {
|
|
|
279338
279539
|
function loadSessionContext(repoRoot) {
|
|
279339
279540
|
const filePath = join63(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
|
|
279340
279541
|
try {
|
|
279341
|
-
if (!
|
|
279542
|
+
if (!existsSync47(filePath)) return null;
|
|
279342
279543
|
return JSON.parse(readFileSync35(filePath, "utf-8"));
|
|
279343
279544
|
} catch {
|
|
279344
279545
|
return null;
|
|
@@ -279378,7 +279579,7 @@ function saveSessionHistory(repoRoot, sessionId, contentLines, meta) {
|
|
|
279378
279579
|
const indexPath = join63(sessDir, SESSIONS_INDEX);
|
|
279379
279580
|
let index = [];
|
|
279380
279581
|
try {
|
|
279381
|
-
if (
|
|
279582
|
+
if (existsSync47(indexPath)) {
|
|
279382
279583
|
index = JSON.parse(readFileSync35(indexPath, "utf-8"));
|
|
279383
279584
|
}
|
|
279384
279585
|
} catch {
|
|
@@ -279410,7 +279611,7 @@ function saveSessionHistory(repoRoot, sessionId, contentLines, meta) {
|
|
|
279410
279611
|
function listSessions(repoRoot) {
|
|
279411
279612
|
const indexPath = join63(repoRoot, OA_DIR, SESSIONS_DIR, SESSIONS_INDEX);
|
|
279412
279613
|
try {
|
|
279413
|
-
if (!
|
|
279614
|
+
if (!existsSync47(indexPath)) return [];
|
|
279414
279615
|
const index = JSON.parse(readFileSync35(indexPath, "utf-8"));
|
|
279415
279616
|
return index.sort((a2, b) => b.updatedAt.localeCompare(a2.updatedAt));
|
|
279416
279617
|
} catch {
|
|
@@ -279420,7 +279621,7 @@ function listSessions(repoRoot) {
|
|
|
279420
279621
|
function loadSessionHistory(repoRoot, sessionId) {
|
|
279421
279622
|
const contentPath = join63(repoRoot, OA_DIR, SESSIONS_DIR, `${sessionId}.jsonl`);
|
|
279422
279623
|
try {
|
|
279423
|
-
if (!
|
|
279624
|
+
if (!existsSync47(contentPath)) return null;
|
|
279424
279625
|
return readFileSync35(contentPath, "utf-8").split("\n");
|
|
279425
279626
|
} catch {
|
|
279426
279627
|
return null;
|
|
@@ -279431,8 +279632,8 @@ function deleteSession(repoRoot, sessionId) {
|
|
|
279431
279632
|
const indexPath = join63(sessDir, SESSIONS_INDEX);
|
|
279432
279633
|
try {
|
|
279433
279634
|
const contentPath = join63(sessDir, `${sessionId}.jsonl`);
|
|
279434
|
-
if (
|
|
279435
|
-
if (
|
|
279635
|
+
if (existsSync47(contentPath)) unlinkSync11(contentPath);
|
|
279636
|
+
if (existsSync47(indexPath)) {
|
|
279436
279637
|
let index = JSON.parse(readFileSync35(indexPath, "utf-8"));
|
|
279437
279638
|
index = index.filter((s2) => s2.id !== sessionId);
|
|
279438
279639
|
writeFileSync20(indexPath, JSON.stringify(index, null, 2), "utf-8");
|
|
@@ -279487,7 +279688,7 @@ function detectManifests(repoRoot) {
|
|
|
279487
279688
|
];
|
|
279488
279689
|
for (const check of checks) {
|
|
279489
279690
|
const filePath = join63(repoRoot, check.file);
|
|
279490
|
-
if (
|
|
279691
|
+
if (existsSync47(filePath)) {
|
|
279491
279692
|
let name10;
|
|
279492
279693
|
if (check.nameField) {
|
|
279493
279694
|
try {
|
|
@@ -279520,7 +279721,7 @@ function findKeyFiles(repoRoot) {
|
|
|
279520
279721
|
{ pattern: "CLAUDE.md", description: "Claude Code context" }
|
|
279521
279722
|
];
|
|
279522
279723
|
for (const check of checks) {
|
|
279523
|
-
if (
|
|
279724
|
+
if (existsSync47(join63(repoRoot, check.pattern))) {
|
|
279524
279725
|
keyFiles.push({ path: check.pattern, description: check.description });
|
|
279525
279726
|
}
|
|
279526
279727
|
}
|
|
@@ -279560,7 +279761,7 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
|
|
|
279560
279761
|
}
|
|
279561
279762
|
function loadUsageFile(filePath) {
|
|
279562
279763
|
try {
|
|
279563
|
-
if (
|
|
279764
|
+
if (existsSync47(filePath)) {
|
|
279564
279765
|
return JSON.parse(readFileSync35(filePath, "utf-8"));
|
|
279565
279766
|
}
|
|
279566
279767
|
} catch {
|
|
@@ -280281,7 +280482,7 @@ __export(text_selection_exports, {
|
|
|
280281
280482
|
stripAnsi: () => stripAnsi,
|
|
280282
280483
|
visibleLength: () => visibleLength
|
|
280283
280484
|
});
|
|
280284
|
-
import { execSync as
|
|
280485
|
+
import { execSync as execSync41 } from "node:child_process";
|
|
280285
280486
|
function stripAnsi(s2) {
|
|
280286
280487
|
return s2.replace(/\x1B\[[0-9;]*[A-Za-z]|\x1B\].*?(?:\x07|\x1B\\)/g, "");
|
|
280287
280488
|
}
|
|
@@ -280292,16 +280493,16 @@ function copyText(text) {
|
|
|
280292
280493
|
try {
|
|
280293
280494
|
const platform6 = process.platform;
|
|
280294
280495
|
if (platform6 === "darwin") {
|
|
280295
|
-
|
|
280496
|
+
execSync41("pbcopy", { input: text, timeout: 3e3 });
|
|
280296
280497
|
return true;
|
|
280297
280498
|
}
|
|
280298
280499
|
if (platform6 === "win32") {
|
|
280299
|
-
|
|
280500
|
+
execSync41("clip", { input: text, timeout: 3e3 });
|
|
280300
280501
|
return true;
|
|
280301
280502
|
}
|
|
280302
280503
|
for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
|
|
280303
280504
|
try {
|
|
280304
|
-
|
|
280505
|
+
execSync41(tool, { input: text, timeout: 3e3 });
|
|
280305
280506
|
return true;
|
|
280306
280507
|
} catch {
|
|
280307
280508
|
continue;
|
|
@@ -280310,10 +280511,10 @@ function copyText(text) {
|
|
|
280310
280511
|
if (!_clipboardAutoInstallAttempted) {
|
|
280311
280512
|
_clipboardAutoInstallAttempted = true;
|
|
280312
280513
|
try {
|
|
280313
|
-
|
|
280514
|
+
execSync41("which apt-get", { timeout: 2e3, stdio: "pipe" });
|
|
280314
280515
|
try {
|
|
280315
|
-
|
|
280316
|
-
|
|
280516
|
+
execSync41("sudo -n apt-get install -y xclip 2>/dev/null", { timeout: 15e3, stdio: "pipe" });
|
|
280517
|
+
execSync41("xclip -selection clipboard", { input: text, timeout: 3e3 });
|
|
280317
280518
|
return true;
|
|
280318
280519
|
} catch {
|
|
280319
280520
|
}
|
|
@@ -284188,10 +284389,10 @@ __export(personaplex_exports, {
|
|
|
284188
284389
|
startPersonaPlexDaemon: () => startPersonaPlexDaemon,
|
|
284189
284390
|
stopPersonaPlex: () => stopPersonaPlex
|
|
284190
284391
|
});
|
|
284191
|
-
import { existsSync as
|
|
284392
|
+
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";
|
|
284192
284393
|
import { join as join64, dirname as dirname20 } from "node:path";
|
|
284193
284394
|
import { homedir as homedir17 } from "node:os";
|
|
284194
|
-
import { execSync as
|
|
284395
|
+
import { execSync as execSync42, spawn as spawn20 } from "node:child_process";
|
|
284195
284396
|
import { fileURLToPath as fileURLToPath12 } from "node:url";
|
|
284196
284397
|
function execAsync(cmd, opts = {}) {
|
|
284197
284398
|
return new Promise((resolve39, reject) => {
|
|
@@ -284224,7 +284425,7 @@ function detectJetson() {
|
|
|
284224
284425
|
try {
|
|
284225
284426
|
const model = readFileSync37("/proc/device-tree/model", "utf8").replace(/\0/g, "").trim();
|
|
284226
284427
|
if (/jetson|orin|tegra/i.test(model)) {
|
|
284227
|
-
const memInfo =
|
|
284428
|
+
const memInfo = execSync42("grep MemTotal /proc/meminfo", { encoding: "utf8", timeout: 3e3, stdio: "pipe" });
|
|
284228
284429
|
const memKB = parseInt(memInfo.match(/(\d+)/)?.[1] ?? "0", 10);
|
|
284229
284430
|
return { isJetson: true, model, totalMemGB: memKB / 1024 / 1024 };
|
|
284230
284431
|
}
|
|
@@ -284258,7 +284459,7 @@ function detectPersonaPlexCapability() {
|
|
|
284258
284459
|
};
|
|
284259
284460
|
}
|
|
284260
284461
|
try {
|
|
284261
|
-
const nvsmi =
|
|
284462
|
+
const nvsmi = execSync42("nvidia-smi --query-gpu=name,memory.total --format=csv,noheader,nounits", {
|
|
284262
284463
|
encoding: "utf8",
|
|
284263
284464
|
timeout: 5e3,
|
|
284264
284465
|
stdio: "pipe"
|
|
@@ -284270,7 +284471,7 @@ function detectPersonaPlexCapability() {
|
|
|
284270
284471
|
return { ...fail2(`GPU has ${vramGB.toFixed(1)}GB VRAM (need \u22658GB)`), gpuName: gpuName ?? "", vramGB };
|
|
284271
284472
|
}
|
|
284272
284473
|
try {
|
|
284273
|
-
|
|
284474
|
+
execSync42('python3 -c "import torch; assert torch.cuda.is_available()"', {
|
|
284274
284475
|
timeout: 1e4,
|
|
284275
284476
|
stdio: "pipe"
|
|
284276
284477
|
});
|
|
@@ -284299,7 +284500,7 @@ function fileLink2(filePath, label) {
|
|
|
284299
284500
|
return `\x1B]8;;${url}\x1B\\${text}\x1B]8;;\x1B\\`;
|
|
284300
284501
|
}
|
|
284301
284502
|
function isPersonaPlexRunning() {
|
|
284302
|
-
if (!
|
|
284503
|
+
if (!existsSync48(PID_FILE)) return false;
|
|
284303
284504
|
const pid = parseInt(readFileSync37(PID_FILE, "utf8").trim(), 10);
|
|
284304
284505
|
if (isNaN(pid) || pid <= 0) return false;
|
|
284305
284506
|
try {
|
|
@@ -284311,17 +284512,17 @@ function isPersonaPlexRunning() {
|
|
|
284311
284512
|
}
|
|
284312
284513
|
function getPersonaPlexWSUrl() {
|
|
284313
284514
|
if (!isPersonaPlexRunning()) return null;
|
|
284314
|
-
if (!
|
|
284515
|
+
if (!existsSync48(PORT_FILE)) return null;
|
|
284315
284516
|
const port = parseInt(readFileSync37(PORT_FILE, "utf8").trim(), 10);
|
|
284316
284517
|
return isNaN(port) ? null : `wss://127.0.0.1:${port}`;
|
|
284317
284518
|
}
|
|
284318
284519
|
function isPersonaPlexInstalled() {
|
|
284319
|
-
return
|
|
284520
|
+
return existsSync48(join64(PERSONAPLEX_DIR, "model_ready"));
|
|
284320
284521
|
}
|
|
284321
284522
|
function getWeightTier() {
|
|
284322
284523
|
const detected = detectPersonaPlexCapability();
|
|
284323
284524
|
const tierFile = join64(PERSONAPLEX_DIR, "weight_tier");
|
|
284324
|
-
if (
|
|
284525
|
+
if (existsSync48(tierFile)) {
|
|
284325
284526
|
const saved = readFileSync37(tierFile, "utf8").trim();
|
|
284326
284527
|
if (saved in WEIGHT_REPOS) {
|
|
284327
284528
|
const vram = detected.vramGB;
|
|
@@ -284343,13 +284544,13 @@ async function installPersonaPlex(onInfo, weightTier) {
|
|
|
284343
284544
|
mkdirSync21(PERSONAPLEX_DIR, { recursive: true });
|
|
284344
284545
|
let arch2 = "";
|
|
284345
284546
|
try {
|
|
284346
|
-
arch2 =
|
|
284547
|
+
arch2 = execSync42("uname -m", { encoding: "utf8", timeout: 3e3, stdio: "pipe" }).trim();
|
|
284347
284548
|
} catch {
|
|
284348
284549
|
}
|
|
284349
284550
|
const isAarch64 = arch2 === "aarch64" || arch2 === "arm64";
|
|
284350
284551
|
if (isAarch64) log22(`Detected ARM64 platform (${arch2}) \u2014 Jetson/ARM install path`);
|
|
284351
284552
|
const venvDir = join64(PERSONAPLEX_DIR, "venv");
|
|
284352
|
-
if (!
|
|
284553
|
+
if (!existsSync48(venvDir)) {
|
|
284353
284554
|
log22("Creating Python virtual environment...");
|
|
284354
284555
|
try {
|
|
284355
284556
|
const ssp = isAarch64 ? " --system-site-packages" : "";
|
|
@@ -284364,16 +284565,16 @@ async function installPersonaPlex(onInfo, weightTier) {
|
|
|
284364
284565
|
log22("Checking system dependencies (libopus)...");
|
|
284365
284566
|
try {
|
|
284366
284567
|
if (process.platform === "linux") {
|
|
284367
|
-
|
|
284568
|
+
execSync42("dpkg -l libopus-dev 2>/dev/null || sudo apt-get install -y libopus-dev", { timeout: 3e4, stdio: "pipe" });
|
|
284368
284569
|
} else if (process.platform === "darwin") {
|
|
284369
|
-
|
|
284570
|
+
execSync42("brew list opus 2>/dev/null || brew install opus", { timeout: 6e4, stdio: "pipe" });
|
|
284370
284571
|
}
|
|
284371
284572
|
} catch {
|
|
284372
284573
|
}
|
|
284373
284574
|
if (isAarch64) {
|
|
284374
284575
|
log22("ARM64: Checking Rust toolchain for sphn build...");
|
|
284375
284576
|
try {
|
|
284376
|
-
|
|
284577
|
+
execSync42("rustc --version", { timeout: 5e3, stdio: "pipe" });
|
|
284377
284578
|
} catch {
|
|
284378
284579
|
log22("ARM64: Installing Rust toolchain (needed for sphn audio codec)...");
|
|
284379
284580
|
try {
|
|
@@ -284392,7 +284593,7 @@ async function installPersonaPlex(onInfo, weightTier) {
|
|
|
284392
284593
|
log22("Installing PersonaPlex (moshi package)...");
|
|
284393
284594
|
const repoDir = join64(PERSONAPLEX_DIR, "personaplex-repo");
|
|
284394
284595
|
try {
|
|
284395
|
-
if (!
|
|
284596
|
+
if (!existsSync48(repoDir)) {
|
|
284396
284597
|
await execAsync(
|
|
284397
284598
|
`git clone https://github.com/NVIDIA/personaplex.git "${repoDir}"`,
|
|
284398
284599
|
{ timeout: 12e4 }
|
|
@@ -284446,13 +284647,13 @@ async function installPersonaPlex(onInfo, weightTier) {
|
|
|
284446
284647
|
}
|
|
284447
284648
|
const serverPy = join64(venvDir, "lib", `python3.${process.versions.node ? "12" : "10"}`, "site-packages", "moshi", "server.py");
|
|
284448
284649
|
try {
|
|
284449
|
-
const sitePackages =
|
|
284650
|
+
const sitePackages = execSync42(`"${python}" -c "import moshi, os; print(os.path.dirname(moshi.__file__))"`, {
|
|
284450
284651
|
encoding: "utf8",
|
|
284451
284652
|
timeout: 5e3,
|
|
284452
284653
|
stdio: "pipe"
|
|
284453
284654
|
}).trim();
|
|
284454
284655
|
const serverFile = join64(sitePackages, "server.py");
|
|
284455
|
-
if (
|
|
284656
|
+
if (existsSync48(serverFile)) {
|
|
284456
284657
|
let src2 = readFileSync37(serverFile, "utf8");
|
|
284457
284658
|
if (src2.includes('int(request["seed"])')) {
|
|
284458
284659
|
src2 = src2.replace('int(request["seed"])', 'int(request.query["seed"])');
|
|
@@ -284463,13 +284664,13 @@ async function installPersonaPlex(onInfo, weightTier) {
|
|
|
284463
284664
|
} catch {
|
|
284464
284665
|
}
|
|
284465
284666
|
try {
|
|
284466
|
-
const sitePackages =
|
|
284667
|
+
const sitePackages = execSync42(`"${python}" -c "import moshi, os; print(os.path.dirname(moshi.__file__))"`, {
|
|
284467
284668
|
encoding: "utf8",
|
|
284468
284669
|
timeout: 5e3,
|
|
284469
284670
|
stdio: "pipe"
|
|
284470
284671
|
}).trim();
|
|
284471
284672
|
const loadersFile = join64(sitePackages, "models", "loaders.py");
|
|
284472
|
-
if (
|
|
284673
|
+
if (existsSync48(loadersFile)) {
|
|
284473
284674
|
let src2 = readFileSync37(loadersFile, "utf8");
|
|
284474
284675
|
if (!src2.includes("_dequantize_2bit_state_dict")) {
|
|
284475
284676
|
const dequantPatch = `
|
|
@@ -284567,21 +284768,21 @@ $2if filename.endswith(".safetensors"):`
|
|
|
284567
284768
|
} catch {
|
|
284568
284769
|
}
|
|
284569
284770
|
try {
|
|
284570
|
-
const sitePackages2 =
|
|
284771
|
+
const sitePackages2 = execSync42(`"${python}" -c "import moshi, os; print(os.path.dirname(moshi.__file__))"`, {
|
|
284571
284772
|
encoding: "utf8",
|
|
284572
284773
|
timeout: 5e3,
|
|
284573
284774
|
stdio: "pipe"
|
|
284574
284775
|
}).trim();
|
|
284575
284776
|
const hybridDest = join64(sitePackages2, "hybrid_agent.py");
|
|
284576
284777
|
const serverDest = join64(sitePackages2, "server.py");
|
|
284577
|
-
if (!
|
|
284778
|
+
if (!existsSync48(hybridDest) || !readFileSync37(hybridDest, "utf8").includes("OA_API_BASE")) {
|
|
284578
284779
|
log22("Deploying hybrid_agent.py (OA API integration)...");
|
|
284579
284780
|
try {
|
|
284580
284781
|
await execAsync(
|
|
284581
284782
|
`curl -sL "https://raw.githubusercontent.com/robit-man/personaplex/main/personaplex-setup/moshi/moshi/hybrid_agent.py" -o "${hybridDest}"`,
|
|
284582
284783
|
{ timeout: 3e4 }
|
|
284583
284784
|
);
|
|
284584
|
-
if (
|
|
284785
|
+
if (existsSync48(hybridDest) && readFileSync37(hybridDest, "utf8").includes("OA_API_BASE")) {
|
|
284585
284786
|
log22("hybrid_agent.py deployed (OA API + Ollama fallback).");
|
|
284586
284787
|
}
|
|
284587
284788
|
} catch {
|
|
@@ -284702,14 +284903,14 @@ async function startPersonaPlexDaemon(onInfo) {
|
|
|
284702
284903
|
if (tier === "nf4-distilled") {
|
|
284703
284904
|
log22(`Weight tier: ${tier} \u2014 distilled NF4 (90% token match, ${repoInfo.sizeGB}GB)...`);
|
|
284704
284905
|
try {
|
|
284705
|
-
const weightPath =
|
|
284906
|
+
const weightPath = execSync42(
|
|
284706
284907
|
`"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', '${repoInfo.file}', token=False))"`,
|
|
284707
284908
|
{ encoding: "utf8", timeout: 6e4, stdio: "pipe" }
|
|
284708
284909
|
).trim();
|
|
284709
|
-
if (
|
|
284710
|
-
if (!
|
|
284910
|
+
if (existsSync48(weightPath)) {
|
|
284911
|
+
if (!existsSync48(cachedBf16)) {
|
|
284711
284912
|
log22("Converting .pt checkpoint to safetensors (one-time)...");
|
|
284712
|
-
|
|
284913
|
+
execSync42(
|
|
284713
284914
|
`"${venvPython2}" -c "
|
|
284714
284915
|
import torch; from safetensors.torch import save_file
|
|
284715
284916
|
state = torch.load('${weightPath}', map_location='cpu', weights_only=True)
|
|
@@ -284720,7 +284921,7 @@ print('Converted')
|
|
|
284720
284921
|
{ timeout: 18e4, stdio: "pipe" }
|
|
284721
284922
|
);
|
|
284722
284923
|
}
|
|
284723
|
-
if (
|
|
284924
|
+
if (existsSync48(cachedBf16)) {
|
|
284724
284925
|
extraArgs.push("--moshi-weight", cachedBf16);
|
|
284725
284926
|
log22(`Using distilled weights: ${(statSync17(cachedBf16).size / 1024 ** 3).toFixed(1)}GB`);
|
|
284726
284927
|
} else {
|
|
@@ -284733,25 +284934,25 @@ print('Converted')
|
|
|
284733
284934
|
} else {
|
|
284734
284935
|
log22(`Weight tier: ${tier} (${repoInfo.sizeGB}GB) \u2014 dequantizing to bf16 cache...`);
|
|
284735
284936
|
const dequantScript = join64(PERSONAPLEX_DIR, "dequant-loader.py");
|
|
284736
|
-
if (!
|
|
284937
|
+
if (!existsSync48(dequantScript)) {
|
|
284737
284938
|
const shipped = getShippedVoicesDir();
|
|
284738
284939
|
if (shipped) {
|
|
284739
284940
|
const src2 = join64(shipped, "dequant-loader.py");
|
|
284740
|
-
if (
|
|
284941
|
+
if (existsSync48(src2)) copyFileSync2(src2, dequantScript);
|
|
284741
284942
|
}
|
|
284742
284943
|
}
|
|
284743
284944
|
try {
|
|
284744
|
-
const weightPath =
|
|
284945
|
+
const weightPath = execSync42(
|
|
284745
284946
|
`"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', '${repoInfo.file}'${repoInfo.needsToken ? "" : ", token=False"}))"`,
|
|
284746
284947
|
{ encoding: "utf8", timeout: 3e4, stdio: "pipe" }
|
|
284747
284948
|
).trim();
|
|
284748
|
-
if (
|
|
284949
|
+
if (existsSync48(dequantScript) && existsSync48(weightPath)) {
|
|
284749
284950
|
try {
|
|
284750
|
-
|
|
284951
|
+
execSync42(
|
|
284751
284952
|
`"${venvPython2}" "${dequantScript}" --input "${weightPath}" --output "${cachedBf16}"`,
|
|
284752
284953
|
{ timeout: 3e5, stdio: "pipe" }
|
|
284753
284954
|
);
|
|
284754
|
-
if (
|
|
284955
|
+
if (existsSync48(cachedBf16)) {
|
|
284755
284956
|
extraArgs.push("--moshi-weight", cachedBf16);
|
|
284756
284957
|
log22(`Using dequantized cache: ${(statSync17(cachedBf16).size / 1024 ** 3).toFixed(1)}GB`);
|
|
284757
284958
|
}
|
|
@@ -284760,19 +284961,19 @@ print('Converted')
|
|
|
284760
284961
|
}
|
|
284761
284962
|
}
|
|
284762
284963
|
try {
|
|
284763
|
-
const mimiPath =
|
|
284964
|
+
const mimiPath = execSync42(
|
|
284764
284965
|
`"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', 'tokenizer-e351c8d8-checkpoint125.safetensors', token=False))"`,
|
|
284765
284966
|
{ encoding: "utf8", timeout: 3e4, stdio: "pipe" }
|
|
284766
284967
|
).trim();
|
|
284767
|
-
if (
|
|
284968
|
+
if (existsSync48(mimiPath)) extraArgs.push("--mimi-weight", mimiPath);
|
|
284768
284969
|
} catch {
|
|
284769
284970
|
}
|
|
284770
284971
|
try {
|
|
284771
|
-
const tokPath =
|
|
284972
|
+
const tokPath = execSync42(
|
|
284772
284973
|
`"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', 'tokenizer_spm_32k_3.model', token=False))"`,
|
|
284773
284974
|
{ encoding: "utf8", timeout: 3e4, stdio: "pipe" }
|
|
284774
284975
|
).trim();
|
|
284775
|
-
if (
|
|
284976
|
+
if (existsSync48(tokPath)) extraArgs.push("--tokenizer", tokPath);
|
|
284776
284977
|
} catch {
|
|
284777
284978
|
}
|
|
284778
284979
|
} catch {
|
|
@@ -284792,7 +284993,7 @@ print('Converted')
|
|
|
284792
284993
|
}
|
|
284793
284994
|
if (!ollamaModel) ollamaModel = "qwen3.5:4b";
|
|
284794
284995
|
try {
|
|
284795
|
-
const ollamaCheck =
|
|
284996
|
+
const ollamaCheck = execSync42("curl -s http://localhost:11434/api/tags", {
|
|
284796
284997
|
timeout: 3e3,
|
|
284797
284998
|
stdio: "pipe",
|
|
284798
284999
|
encoding: "utf8"
|
|
@@ -284866,7 +285067,7 @@ print('Converted')
|
|
|
284866
285067
|
return null;
|
|
284867
285068
|
}
|
|
284868
285069
|
try {
|
|
284869
|
-
|
|
285070
|
+
execSync42(`curl -sk -o /dev/null -w "%{http_code}" https://127.0.0.1:${PORT}/`, {
|
|
284870
285071
|
timeout: 3e3,
|
|
284871
285072
|
stdio: "pipe",
|
|
284872
285073
|
encoding: "utf8"
|
|
@@ -284884,12 +285085,12 @@ print('Converted')
|
|
|
284884
285085
|
return null;
|
|
284885
285086
|
}
|
|
284886
285087
|
function stopPersonaPlex() {
|
|
284887
|
-
if (!
|
|
285088
|
+
if (!existsSync48(PID_FILE)) return;
|
|
284888
285089
|
const pid = parseInt(readFileSync37(PID_FILE, "utf8").trim(), 10);
|
|
284889
285090
|
if (isNaN(pid) || pid <= 0) return;
|
|
284890
285091
|
try {
|
|
284891
285092
|
if (process.platform === "win32") {
|
|
284892
|
-
|
|
285093
|
+
execSync42(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
|
|
284893
285094
|
} else {
|
|
284894
285095
|
process.kill(pid, "SIGTERM");
|
|
284895
285096
|
}
|
|
@@ -284921,7 +285122,7 @@ function listPersonaPlexVoices() {
|
|
|
284921
285122
|
for (const name10 of builtins) {
|
|
284922
285123
|
voices.push({ name: name10, type: "builtin", path: `${name10}.pt` });
|
|
284923
285124
|
}
|
|
284924
|
-
if (
|
|
285125
|
+
if (existsSync48(CUSTOM_VOICES_DIR)) {
|
|
284925
285126
|
try {
|
|
284926
285127
|
for (const f2 of readdirSync12(CUSTOM_VOICES_DIR)) {
|
|
284927
285128
|
if (f2.endsWith(".pt")) {
|
|
@@ -284941,19 +285142,19 @@ async function clonePersonaPlexVoice(inputWav, voiceName, onInfo) {
|
|
|
284941
285142
|
log22("PersonaPlex not installed. Run /voice personaplex first.");
|
|
284942
285143
|
return null;
|
|
284943
285144
|
}
|
|
284944
|
-
if (!
|
|
285145
|
+
if (!existsSync48(inputWav)) {
|
|
284945
285146
|
log22(`Input WAV not found: ${inputWav}`);
|
|
284946
285147
|
return null;
|
|
284947
285148
|
}
|
|
284948
285149
|
mkdirSync21(CUSTOM_VOICES_DIR, { recursive: true });
|
|
284949
285150
|
const outputPt = join64(CUSTOM_VOICES_DIR, `${voiceName}.pt`);
|
|
284950
|
-
if (
|
|
285151
|
+
if (existsSync48(outputPt)) {
|
|
284951
285152
|
log22(`Voice "${voiceName}" already exists. Delete ${outputPt} to re-clone.`);
|
|
284952
285153
|
return outputPt;
|
|
284953
285154
|
}
|
|
284954
285155
|
const venvPython2 = process.platform === "win32" ? join64(PERSONAPLEX_DIR, "venv", "Scripts", "python.exe") : join64(PERSONAPLEX_DIR, "venv", "bin", "python3");
|
|
284955
285156
|
const cloneScript = join64(PERSONAPLEX_DIR, "clone-voice.py");
|
|
284956
|
-
if (!
|
|
285157
|
+
if (!existsSync48(cloneScript)) {
|
|
284957
285158
|
log22("clone-voice.py not found. Reinstall PersonaPlex.");
|
|
284958
285159
|
return null;
|
|
284959
285160
|
}
|
|
@@ -284985,7 +285186,7 @@ async function clonePersonaPlexVoice(inputWav, voiceName, onInfo) {
|
|
|
284985
285186
|
output += d2.toString();
|
|
284986
285187
|
});
|
|
284987
285188
|
child.on("close", (code8) => {
|
|
284988
|
-
if (code8 === 0 &&
|
|
285189
|
+
if (code8 === 0 && existsSync48(outputPt)) {
|
|
284989
285190
|
log22(`Voice "${voiceName}" cloned successfully.`);
|
|
284990
285191
|
resolve39(outputPt);
|
|
284991
285192
|
} else {
|
|
@@ -285009,7 +285210,7 @@ function getShippedVoicesDir() {
|
|
|
285009
285210
|
} catch {
|
|
285010
285211
|
}
|
|
285011
285212
|
for (const dir of candidates) {
|
|
285012
|
-
if (
|
|
285213
|
+
if (existsSync48(dir)) {
|
|
285013
285214
|
try {
|
|
285014
285215
|
const files = readdirSync12(dir);
|
|
285015
285216
|
if (files.some((f2) => f2.endsWith(".pt"))) return dir;
|
|
@@ -285031,12 +285232,12 @@ function provisionShippedVoices(onInfo) {
|
|
|
285031
285232
|
for (const f2 of readdirSync12(shippedDir)) {
|
|
285032
285233
|
if (!f2.endsWith(".pt")) continue;
|
|
285033
285234
|
const customDst = join64(CUSTOM_VOICES_DIR, f2);
|
|
285034
|
-
if (!
|
|
285235
|
+
if (!existsSync48(customDst)) {
|
|
285035
285236
|
copyFileSync2(join64(shippedDir, f2), customDst);
|
|
285036
285237
|
}
|
|
285037
285238
|
if (hfVoicesDir) {
|
|
285038
285239
|
const hfDst = join64(hfVoicesDir, f2);
|
|
285039
|
-
if (!
|
|
285240
|
+
if (!existsSync48(hfDst)) {
|
|
285040
285241
|
copyFileSync2(join64(shippedDir, f2), hfDst);
|
|
285041
285242
|
log22(`Deployed voice: ${f2.replace(".pt", "")}`);
|
|
285042
285243
|
deployed++;
|
|
@@ -285047,7 +285248,7 @@ function provisionShippedVoices(onInfo) {
|
|
|
285047
285248
|
}
|
|
285048
285249
|
const shippedScript = join64(shippedDir, "clone-voice.py");
|
|
285049
285250
|
const targetScript = join64(PERSONAPLEX_DIR, "clone-voice.py");
|
|
285050
|
-
if (
|
|
285251
|
+
if (existsSync48(shippedScript) && !existsSync48(targetScript)) {
|
|
285051
285252
|
try {
|
|
285052
285253
|
copyFileSync2(shippedScript, targetScript);
|
|
285053
285254
|
} catch {
|
|
@@ -285057,13 +285258,13 @@ function provisionShippedVoices(onInfo) {
|
|
|
285057
285258
|
}
|
|
285058
285259
|
function getHFVoicesDir() {
|
|
285059
285260
|
const hfBase = join64(homedir17(), ".cache", "huggingface", "hub", "models--nvidia--personaplex-7b-v1");
|
|
285060
|
-
if (!
|
|
285261
|
+
if (!existsSync48(hfBase)) return null;
|
|
285061
285262
|
try {
|
|
285062
285263
|
const snapshots = join64(hfBase, "snapshots");
|
|
285063
|
-
if (!
|
|
285264
|
+
if (!existsSync48(snapshots)) return null;
|
|
285064
285265
|
for (const snap of readdirSync12(snapshots)) {
|
|
285065
285266
|
const voicesDir = join64(snapshots, snap, "voices");
|
|
285066
|
-
if (
|
|
285267
|
+
if (existsSync48(voicesDir)) return voicesDir;
|
|
285067
285268
|
}
|
|
285068
285269
|
} catch {
|
|
285069
285270
|
}
|
|
@@ -285073,18 +285274,18 @@ function patchFrontendVoiceList(onInfo) {
|
|
|
285073
285274
|
const log22 = onInfo ?? (() => {
|
|
285074
285275
|
});
|
|
285075
285276
|
const hfBase = join64(homedir17(), ".cache", "huggingface", "hub", "models--nvidia--personaplex-7b-v1");
|
|
285076
|
-
if (!
|
|
285277
|
+
if (!existsSync48(hfBase)) return;
|
|
285077
285278
|
try {
|
|
285078
285279
|
const snapshots = join64(hfBase, "snapshots");
|
|
285079
285280
|
for (const snap of readdirSync12(snapshots)) {
|
|
285080
285281
|
const distDir = join64(snapshots, snap, "dist", "assets");
|
|
285081
|
-
if (!
|
|
285282
|
+
if (!existsSync48(distDir)) continue;
|
|
285082
285283
|
for (const f2 of readdirSync12(distDir)) {
|
|
285083
285284
|
if (!f2.startsWith("index-") || !f2.endsWith(".js")) continue;
|
|
285084
285285
|
const jsPath = join64(distDir, f2);
|
|
285085
285286
|
let js = readFileSync37(jsPath, "utf8");
|
|
285086
285287
|
const customVoices = [];
|
|
285087
|
-
if (
|
|
285288
|
+
if (existsSync48(CUSTOM_VOICES_DIR)) {
|
|
285088
285289
|
for (const vf of readdirSync12(CUSTOM_VOICES_DIR)) {
|
|
285089
285290
|
if (vf.endsWith(".pt")) {
|
|
285090
285291
|
const name10 = vf.replace(".pt", "");
|
|
@@ -285193,9 +285394,9 @@ __export(setup_exports, {
|
|
|
285193
285394
|
updateOllama: () => updateOllama
|
|
285194
285395
|
});
|
|
285195
285396
|
import * as readline from "node:readline";
|
|
285196
|
-
import { execSync as
|
|
285397
|
+
import { execSync as execSync43, spawn as spawn21, exec as exec4 } from "node:child_process";
|
|
285197
285398
|
import { promisify as promisify7 } from "node:util";
|
|
285198
|
-
import { existsSync as
|
|
285399
|
+
import { existsSync as existsSync49, writeFileSync as writeFileSync22, readFileSync as readFileSync38, appendFileSync as appendFileSync2, mkdirSync as mkdirSync22 } from "node:fs";
|
|
285199
285400
|
import { join as join65 } from "node:path";
|
|
285200
285401
|
import { homedir as homedir18, platform as platform3 } from "node:os";
|
|
285201
285402
|
async function checkToolSupport(modelName, backendUrl = "http://localhost:11434") {
|
|
@@ -285231,7 +285432,7 @@ function detectSystemSpecs() {
|
|
|
285231
285432
|
let gpuVramGB = 0;
|
|
285232
285433
|
let gpuName = "";
|
|
285233
285434
|
try {
|
|
285234
|
-
const memInfo =
|
|
285435
|
+
const memInfo = execSync43("free -b 2>/dev/null || sysctl -n hw.memsize 2>/dev/null", {
|
|
285235
285436
|
encoding: "utf8",
|
|
285236
285437
|
timeout: 5e3
|
|
285237
285438
|
});
|
|
@@ -285251,7 +285452,7 @@ function detectSystemSpecs() {
|
|
|
285251
285452
|
} catch {
|
|
285252
285453
|
}
|
|
285253
285454
|
try {
|
|
285254
|
-
const nvidiaSmi =
|
|
285455
|
+
const nvidiaSmi = execSync43(
|
|
285255
285456
|
"nvidia-smi --query-gpu=memory.total,name --format=csv,noheader,nounits 2>/dev/null",
|
|
285256
285457
|
{ encoding: "utf8", timeout: 5e3 }
|
|
285257
285458
|
);
|
|
@@ -285425,7 +285626,7 @@ function ensureCurl() {
|
|
|
285425
285626
|
for (const s2 of strategies) {
|
|
285426
285627
|
if (hasCmd(s2.check)) {
|
|
285427
285628
|
try {
|
|
285428
|
-
|
|
285629
|
+
execSync43(s2.install, { stdio: "inherit", timeout: 12e4 });
|
|
285429
285630
|
if (hasCmd("curl")) {
|
|
285430
285631
|
process.stdout.write(` ${c3.green("\u2714")} curl installed via ${s2.label}.
|
|
285431
285632
|
`);
|
|
@@ -285439,7 +285640,7 @@ function ensureCurl() {
|
|
|
285439
285640
|
}
|
|
285440
285641
|
if (plat === "darwin") {
|
|
285441
285642
|
try {
|
|
285442
|
-
|
|
285643
|
+
execSync43("xcode-select --install", { stdio: "inherit", timeout: 3e5 });
|
|
285443
285644
|
if (hasCmd("curl")) return true;
|
|
285444
285645
|
} catch {
|
|
285445
285646
|
}
|
|
@@ -285473,7 +285674,7 @@ function installOllamaLinux() {
|
|
|
285473
285674
|
|
|
285474
285675
|
`);
|
|
285475
285676
|
try {
|
|
285476
|
-
|
|
285677
|
+
execSync43("curl -fsSL https://ollama.com/install.sh | sh", {
|
|
285477
285678
|
stdio: "inherit",
|
|
285478
285679
|
timeout: 3e5
|
|
285479
285680
|
});
|
|
@@ -285501,13 +285702,13 @@ async function installOllamaMac(_rl) {
|
|
|
285501
285702
|
|
|
285502
285703
|
`);
|
|
285503
285704
|
try {
|
|
285504
|
-
|
|
285705
|
+
execSync43(
|
|
285505
285706
|
'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"',
|
|
285506
285707
|
{ stdio: "inherit", timeout: 6e5 }
|
|
285507
285708
|
);
|
|
285508
285709
|
if (!hasCmd("brew")) {
|
|
285509
285710
|
try {
|
|
285510
|
-
const brewPrefix =
|
|
285711
|
+
const brewPrefix = existsSync49("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
|
|
285511
285712
|
process.env["PATH"] = `${brewPrefix}/bin:${process.env["PATH"]}`;
|
|
285512
285713
|
} catch {
|
|
285513
285714
|
}
|
|
@@ -285537,7 +285738,7 @@ async function installOllamaMac(_rl) {
|
|
|
285537
285738
|
|
|
285538
285739
|
`);
|
|
285539
285740
|
try {
|
|
285540
|
-
|
|
285741
|
+
execSync43("brew install ollama", {
|
|
285541
285742
|
stdio: "inherit",
|
|
285542
285743
|
timeout: 3e5
|
|
285543
285744
|
});
|
|
@@ -285564,7 +285765,7 @@ function installOllamaWindows() {
|
|
|
285564
285765
|
|
|
285565
285766
|
`);
|
|
285566
285767
|
try {
|
|
285567
|
-
|
|
285768
|
+
execSync43('powershell -Command "irm https://ollama.com/install.ps1 | iex"', {
|
|
285568
285769
|
stdio: "inherit",
|
|
285569
285770
|
timeout: 3e5
|
|
285570
285771
|
});
|
|
@@ -285644,7 +285845,7 @@ async function ensureOllamaRunning(backendUrl, rl) {
|
|
|
285644
285845
|
}
|
|
285645
285846
|
function getOllamaVersion() {
|
|
285646
285847
|
try {
|
|
285647
|
-
const out =
|
|
285848
|
+
const out = execSync43("ollama --version", { encoding: "utf8", timeout: 5e3 });
|
|
285648
285849
|
const match = out.match(/(\d+\.\d+\.\d+)/);
|
|
285649
285850
|
return match ? match[1] : null;
|
|
285650
285851
|
} catch {
|
|
@@ -285690,7 +285891,7 @@ function updateOllama() {
|
|
|
285690
285891
|
return false;
|
|
285691
285892
|
}
|
|
285692
285893
|
try {
|
|
285693
|
-
|
|
285894
|
+
execSync43("curl -fsSL https://ollama.com/install.sh | sh", {
|
|
285694
285895
|
stdio: "inherit",
|
|
285695
285896
|
timeout: 3e5
|
|
285696
285897
|
});
|
|
@@ -285701,7 +285902,7 @@ function updateOllama() {
|
|
|
285701
285902
|
}
|
|
285702
285903
|
function pullModelWithAutoUpdate(tag) {
|
|
285703
285904
|
try {
|
|
285704
|
-
|
|
285905
|
+
execSync43(`ollama pull ${tag}`, {
|
|
285705
285906
|
stdio: "inherit",
|
|
285706
285907
|
timeout: 36e5
|
|
285707
285908
|
// 1 hour max
|
|
@@ -285721,7 +285922,7 @@ function pullModelWithAutoUpdate(tag) {
|
|
|
285721
285922
|
|
|
285722
285923
|
`);
|
|
285723
285924
|
try {
|
|
285724
|
-
|
|
285925
|
+
execSync43("curl -fsSL https://ollama.com/install.sh | sh", {
|
|
285725
285926
|
stdio: "inherit",
|
|
285726
285927
|
timeout: 3e5
|
|
285727
285928
|
// 5 min max for install
|
|
@@ -285732,7 +285933,7 @@ function pullModelWithAutoUpdate(tag) {
|
|
|
285732
285933
|
process.stdout.write(` ${c3.cyan("\u25CF")} Retrying pull of ${c3.bold(tag)}...
|
|
285733
285934
|
|
|
285734
285935
|
`);
|
|
285735
|
-
|
|
285936
|
+
execSync43(`ollama pull ${tag}`, {
|
|
285736
285937
|
stdio: "inherit",
|
|
285737
285938
|
timeout: 36e5
|
|
285738
285939
|
});
|
|
@@ -285821,7 +286022,7 @@ function ensurePython3() {
|
|
|
285821
286022
|
if (plat === "darwin") {
|
|
285822
286023
|
if (hasCmd("brew")) {
|
|
285823
286024
|
try {
|
|
285824
|
-
|
|
286025
|
+
execSync43("brew install python3", { stdio: "inherit", timeout: 3e5 });
|
|
285825
286026
|
if (hasCmd("python3")) {
|
|
285826
286027
|
process.stdout.write(` ${c3.green("\u2714")} Python3 installed via Homebrew.
|
|
285827
286028
|
`);
|
|
@@ -285834,7 +286035,7 @@ function ensurePython3() {
|
|
|
285834
286035
|
for (const s2 of strategies) {
|
|
285835
286036
|
if (hasCmd(s2.check)) {
|
|
285836
286037
|
try {
|
|
285837
|
-
|
|
286038
|
+
execSync43(s2.install, { stdio: "inherit", timeout: 12e4 });
|
|
285838
286039
|
if (hasCmd("python3") || hasCmd("python")) {
|
|
285839
286040
|
process.stdout.write(` ${c3.green("\u2714")} Python3 installed via ${s2.label}.
|
|
285840
286041
|
`);
|
|
@@ -285850,11 +286051,11 @@ function ensurePython3() {
|
|
|
285850
286051
|
}
|
|
285851
286052
|
function checkPythonVenv() {
|
|
285852
286053
|
try {
|
|
285853
|
-
|
|
286054
|
+
execSync43("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
|
|
285854
286055
|
return true;
|
|
285855
286056
|
} catch {
|
|
285856
286057
|
try {
|
|
285857
|
-
|
|
286058
|
+
execSync43("python -m venv --help", { stdio: "pipe", timeout: 5e3 });
|
|
285858
286059
|
return true;
|
|
285859
286060
|
} catch {
|
|
285860
286061
|
return false;
|
|
@@ -285873,7 +286074,7 @@ function ensurePythonVenv() {
|
|
|
285873
286074
|
for (const s2 of strategies) {
|
|
285874
286075
|
if (hasCmd(s2.check)) {
|
|
285875
286076
|
try {
|
|
285876
|
-
|
|
286077
|
+
execSync43(s2.install, { stdio: "inherit", timeout: 12e4 });
|
|
285877
286078
|
if (checkPythonVenv()) {
|
|
285878
286079
|
process.stdout.write(` ${c3.green("\u2714")} python3-venv installed via ${s2.label}.
|
|
285879
286080
|
`);
|
|
@@ -286301,7 +286502,7 @@ async function doSetup(config, rl) {
|
|
|
286301
286502
|
const modelfilePath = join65(modelDir2, `Modelfile.${customName}`);
|
|
286302
286503
|
writeFileSync22(modelfilePath, modelfileContent + "\n", "utf8");
|
|
286303
286504
|
process.stdout.write(` ${c3.dim("Creating model...")} `);
|
|
286304
|
-
|
|
286505
|
+
execSync43(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
286305
286506
|
stdio: "pipe",
|
|
286306
286507
|
timeout: 12e4
|
|
286307
286508
|
});
|
|
@@ -286344,7 +286545,7 @@ async function isModelAvailable(config) {
|
|
|
286344
286545
|
}
|
|
286345
286546
|
function isFirstRun() {
|
|
286346
286547
|
try {
|
|
286347
|
-
return !
|
|
286548
|
+
return !existsSync49(join65(homedir18(), ".open-agents", "config.json"));
|
|
286348
286549
|
} catch {
|
|
286349
286550
|
return true;
|
|
286350
286551
|
}
|
|
@@ -286352,7 +286553,7 @@ function isFirstRun() {
|
|
|
286352
286553
|
function hasCmd(cmd) {
|
|
286353
286554
|
try {
|
|
286354
286555
|
const whichCmd = process.platform === "win32" ? `where ${cmd}` : `which ${cmd}`;
|
|
286355
|
-
|
|
286556
|
+
execSync43(whichCmd, { stdio: "pipe", timeout: 3e3 });
|
|
286356
286557
|
return true;
|
|
286357
286558
|
} catch {
|
|
286358
286559
|
return false;
|
|
@@ -286364,7 +286565,7 @@ function detectPkgManager() {
|
|
|
286364
286565
|
if (hasCmd("choco")) return "choco";
|
|
286365
286566
|
if (hasCmd("winget")) return "winget";
|
|
286366
286567
|
try {
|
|
286367
|
-
|
|
286568
|
+
execSync43(
|
|
286368
286569
|
`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'))"`,
|
|
286369
286570
|
{ stdio: "pipe", timeout: 12e4 }
|
|
286370
286571
|
);
|
|
@@ -286376,7 +286577,7 @@ function detectPkgManager() {
|
|
|
286376
286577
|
if (plat === "darwin") {
|
|
286377
286578
|
if (hasCmd("brew")) return "brew";
|
|
286378
286579
|
try {
|
|
286379
|
-
|
|
286580
|
+
execSync43(
|
|
286380
286581
|
'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"',
|
|
286381
286582
|
{ stdio: "pipe", timeout: 3e5, env: { ...process.env, NONINTERACTIVE: "1" } }
|
|
286382
286583
|
);
|
|
@@ -286396,7 +286597,7 @@ function getVenvDir() {
|
|
|
286396
286597
|
}
|
|
286397
286598
|
function hasVenvModule() {
|
|
286398
286599
|
try {
|
|
286399
|
-
|
|
286600
|
+
execSync43("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
|
|
286400
286601
|
return true;
|
|
286401
286602
|
} catch {
|
|
286402
286603
|
return false;
|
|
@@ -286407,7 +286608,7 @@ function ensureVenv(log22) {
|
|
|
286407
286608
|
const isWin2 = process.platform === "win32";
|
|
286408
286609
|
const pipPath = isWin2 ? join65(venvDir, "Scripts", "pip.exe") : join65(venvDir, "bin", "pip");
|
|
286409
286610
|
const pythonCmd = isWin2 ? "python" : "python3";
|
|
286410
|
-
if (
|
|
286611
|
+
if (existsSync49(pipPath)) return venvDir;
|
|
286411
286612
|
log22("Creating Python venv for vision deps...");
|
|
286412
286613
|
if (!hasCmd(pythonCmd) && !hasCmd("python3")) {
|
|
286413
286614
|
log22(`${pythonCmd} not found \u2014 cannot create venv.`);
|
|
@@ -286420,8 +286621,8 @@ function ensureVenv(log22) {
|
|
|
286420
286621
|
try {
|
|
286421
286622
|
mkdirSync22(join65(homedir18(), ".open-agents"), { recursive: true });
|
|
286422
286623
|
const pyCmd = hasCmd(pythonCmd) ? pythonCmd : "python3";
|
|
286423
|
-
|
|
286424
|
-
|
|
286624
|
+
execSync43(`${pyCmd} -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
|
|
286625
|
+
execSync43(`"${pipPath}" install --upgrade pip`, {
|
|
286425
286626
|
stdio: "pipe",
|
|
286426
286627
|
timeout: 6e4
|
|
286427
286628
|
});
|
|
@@ -286434,7 +286635,7 @@ function ensureVenv(log22) {
|
|
|
286434
286635
|
}
|
|
286435
286636
|
function trySudoPasswordless(cmd, timeoutMs = 12e4) {
|
|
286436
286637
|
try {
|
|
286437
|
-
|
|
286638
|
+
execSync43(`sudo -n ${cmd}`, {
|
|
286438
286639
|
stdio: "pipe",
|
|
286439
286640
|
timeout: timeoutMs,
|
|
286440
286641
|
env: { ...process.env, DEBIAN_FRONTEND: "noninteractive" }
|
|
@@ -286447,7 +286648,7 @@ function trySudoPasswordless(cmd, timeoutMs = 12e4) {
|
|
|
286447
286648
|
function runWithSudo(cmd, password, timeoutMs = 12e4) {
|
|
286448
286649
|
try {
|
|
286449
286650
|
const escaped = cmd.replace(/'/g, "'\\''");
|
|
286450
|
-
|
|
286651
|
+
execSync43(`sudo -S bash -c '${escaped}'`, {
|
|
286451
286652
|
input: password + "\n",
|
|
286452
286653
|
stdio: ["pipe", "pipe", "pipe"],
|
|
286453
286654
|
timeout: timeoutMs,
|
|
@@ -286522,7 +286723,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
286522
286723
|
const _visionMarkerFile = join65(_visionMarkerDir, "vision-deps-installed.json");
|
|
286523
286724
|
let _visionPreviouslyInstalled = /* @__PURE__ */ new Set();
|
|
286524
286725
|
try {
|
|
286525
|
-
if (
|
|
286726
|
+
if (existsSync49(_visionMarkerFile)) {
|
|
286526
286727
|
const _vm = JSON.parse(readFileSync38(_visionMarkerFile, "utf8"));
|
|
286527
286728
|
_visionPreviouslyInstalled = new Set(_vm.installed || []);
|
|
286528
286729
|
}
|
|
@@ -286541,7 +286742,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
286541
286742
|
let winNeedsElevation = false;
|
|
286542
286743
|
if (process.platform === "win32") {
|
|
286543
286744
|
try {
|
|
286544
|
-
|
|
286745
|
+
execSync43("net session", { stdio: "pipe", timeout: 3e3 });
|
|
286545
286746
|
} catch {
|
|
286546
286747
|
winNeedsElevation = true;
|
|
286547
286748
|
log22(`Installing ${labels} via ${pm2} (requires admin \u2014 UAC prompt will appear)...`);
|
|
@@ -286588,12 +286789,12 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
286588
286789
|
if (needsSudo) {
|
|
286589
286790
|
await sudoInstall(installCmd, getPassword, log22, cachedPasswordRef, 18e4);
|
|
286590
286791
|
} else if (winNeedsElevation) {
|
|
286591
|
-
|
|
286792
|
+
execSync43(
|
|
286592
286793
|
`powershell -NoProfile -Command "Start-Process -FilePath 'cmd.exe' -ArgumentList '/c ${installCmd.replace(/'/g, "''")}' -Verb RunAs -Wait"`,
|
|
286593
286794
|
{ stdio: "pipe", timeout: 18e4 }
|
|
286594
286795
|
);
|
|
286595
286796
|
} else {
|
|
286596
|
-
|
|
286797
|
+
execSync43(installCmd, { stdio: "pipe", timeout: 18e4 });
|
|
286597
286798
|
}
|
|
286598
286799
|
} catch (e2) {
|
|
286599
286800
|
const stderr = e2.stderr?.toString?.()?.trim?.() ?? "";
|
|
@@ -286606,7 +286807,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
286606
286807
|
if (!hasCmd(d2.binary) && pipPkg) {
|
|
286607
286808
|
try {
|
|
286608
286809
|
const pipCmd = process.platform === "win32" ? `pip install ${pipPkg}` : `pip3 install ${pipPkg}`;
|
|
286609
|
-
|
|
286810
|
+
execSync43(pipCmd, { stdio: "pipe", timeout: 12e4 });
|
|
286610
286811
|
lastError = "";
|
|
286611
286812
|
} catch (e2) {
|
|
286612
286813
|
const stderr = e2.stderr?.toString?.()?.trim?.() ?? "";
|
|
@@ -286618,7 +286819,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
286618
286819
|
}
|
|
286619
286820
|
if (process.platform === "win32" && !hasCmd(d2.binary)) {
|
|
286620
286821
|
try {
|
|
286621
|
-
const freshPath =
|
|
286822
|
+
const freshPath = execSync43(
|
|
286622
286823
|
`powershell -NoProfile -Command "[System.Environment]::GetEnvironmentVariable('Path','Machine') + ';' + [System.Environment]::GetEnvironmentVariable('Path','User')"`,
|
|
286623
286824
|
{ encoding: "utf8", timeout: 5e3, stdio: "pipe" }
|
|
286624
286825
|
).trim();
|
|
@@ -286664,7 +286865,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
286664
286865
|
const venvCmds = {
|
|
286665
286866
|
apt: () => {
|
|
286666
286867
|
try {
|
|
286667
|
-
const pyVer =
|
|
286868
|
+
const pyVer = execSync43(
|
|
286668
286869
|
`python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"`,
|
|
286669
286870
|
{ encoding: "utf8", stdio: "pipe", timeout: 5e3 }
|
|
286670
286871
|
).trim();
|
|
@@ -286692,16 +286893,16 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
286692
286893
|
const venvBin = join65(venvDir, isWin2 ? "Scripts" : "bin");
|
|
286693
286894
|
const venvMoondream = join65(venvBin, isWin2 ? "moondream-station.exe" : "moondream-station");
|
|
286694
286895
|
const venv = ensureVenv(log22);
|
|
286695
|
-
if (venv && !hasCmd("moondream-station") && !
|
|
286896
|
+
if (venv && !hasCmd("moondream-station") && !existsSync49(venvMoondream)) {
|
|
286696
286897
|
const venvPip2 = join65(venvBin, "pip");
|
|
286697
286898
|
log22("Installing moondream-station in ~/.open-agents/venv...");
|
|
286698
286899
|
try {
|
|
286699
|
-
|
|
286700
|
-
if (
|
|
286900
|
+
execSync43(`"${venvPip2}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
|
|
286901
|
+
if (existsSync49(venvMoondream)) {
|
|
286701
286902
|
log22("moondream-station installed successfully.");
|
|
286702
286903
|
} else {
|
|
286703
286904
|
try {
|
|
286704
|
-
const check =
|
|
286905
|
+
const check = execSync43(`"${venvPip2}" show moondream-station`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 });
|
|
286705
286906
|
if (check.includes("moondream")) {
|
|
286706
286907
|
log22("moondream-station package installed.");
|
|
286707
286908
|
}
|
|
@@ -286718,7 +286919,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
286718
286919
|
const venvPip2 = join65(venvBin, isWin2 ? "pip.exe" : "pip");
|
|
286719
286920
|
let ocrStackInstalled = false;
|
|
286720
286921
|
try {
|
|
286721
|
-
|
|
286922
|
+
execSync43(
|
|
286722
286923
|
`"${venvPython2}" -c "import cv2, pytesseract, numpy, PIL"`,
|
|
286723
286924
|
{ stdio: "pipe", timeout: 1e4 }
|
|
286724
286925
|
);
|
|
@@ -286729,12 +286930,12 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
286729
286930
|
const ocrPackages = "pytesseract Pillow opencv-python-headless numpy";
|
|
286730
286931
|
log22("Installing OCR Python stack (pytesseract, OpenCV, Pillow, numpy)...");
|
|
286731
286932
|
try {
|
|
286732
|
-
|
|
286933
|
+
execSync43(
|
|
286733
286934
|
`"${venvPip2}" install ${ocrPackages}`,
|
|
286734
286935
|
{ stdio: "pipe", timeout: 3e5 }
|
|
286735
286936
|
);
|
|
286736
286937
|
try {
|
|
286737
|
-
|
|
286938
|
+
execSync43(
|
|
286738
286939
|
`"${venvPython2}" -c "import cv2, pytesseract, numpy, PIL"`,
|
|
286739
286940
|
{ stdio: "pipe", timeout: 1e4 }
|
|
286740
286941
|
);
|
|
@@ -286770,7 +286971,7 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
286770
286971
|
const archMap = { x64: "amd64", arm64: "arm64", arm: "arm" };
|
|
286771
286972
|
const cfArch = archMap[arch2] ?? "amd64";
|
|
286772
286973
|
try {
|
|
286773
|
-
|
|
286974
|
+
execSync43(
|
|
286774
286975
|
`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"`,
|
|
286775
286976
|
{ stdio: "pipe", timeout: 6e4 }
|
|
286776
286977
|
);
|
|
@@ -286784,7 +286985,7 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
286784
286985
|
} catch {
|
|
286785
286986
|
}
|
|
286786
286987
|
try {
|
|
286787
|
-
|
|
286988
|
+
execSync43(
|
|
286788
286989
|
`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`,
|
|
286789
286990
|
{ stdio: "pipe", timeout: 6e4 }
|
|
286790
286991
|
);
|
|
@@ -286796,7 +286997,7 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
286796
286997
|
}
|
|
286797
286998
|
} else if (os8 === "darwin") {
|
|
286798
286999
|
try {
|
|
286799
|
-
|
|
287000
|
+
execSync43("brew install cloudflared", { stdio: "pipe", timeout: 12e4 });
|
|
286800
287001
|
if (hasCmd("cloudflared")) {
|
|
286801
287002
|
log22("cloudflared installed via Homebrew.");
|
|
286802
287003
|
return true;
|
|
@@ -286876,7 +287077,7 @@ function createExpandedVariant(baseModel, specs, sizeGB, kvBytesPerToken, archMa
|
|
|
286876
287077
|
mkdirSync22(modelDir2, { recursive: true });
|
|
286877
287078
|
const modelfilePath = join65(modelDir2, `Modelfile.${customName}`);
|
|
286878
287079
|
writeFileSync22(modelfilePath, modelfileContent + "\n", "utf8");
|
|
286879
|
-
|
|
287080
|
+
execSync43(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
286880
287081
|
stdio: "pipe",
|
|
286881
287082
|
timeout: 12e4
|
|
286882
287083
|
});
|
|
@@ -286962,7 +287163,7 @@ async function ensureExpandedContext(modelName, backendUrl) {
|
|
|
286962
287163
|
}
|
|
286963
287164
|
async function ensureNeovim() {
|
|
286964
287165
|
try {
|
|
286965
|
-
const nvimPath =
|
|
287166
|
+
const nvimPath = execSync43("which nvim 2>/dev/null || where nvim 2>nul", {
|
|
286966
287167
|
encoding: "utf8",
|
|
286967
287168
|
stdio: "pipe",
|
|
286968
287169
|
timeout: 5e3
|
|
@@ -286983,14 +287184,14 @@ async function ensureNeovim() {
|
|
|
286983
287184
|
const url = `https://github.com/neovim/neovim/releases/latest/download/${appImageName}`;
|
|
286984
287185
|
console.log(` Downloading Neovim (${appImageName})...`);
|
|
286985
287186
|
try {
|
|
286986
|
-
|
|
286987
|
-
|
|
287187
|
+
execSync43(`curl -fsSL "${url}" -o "${nvimDest}"`, { stdio: "pipe", timeout: 6e4 });
|
|
287188
|
+
execSync43(`chmod +x "${nvimDest}"`, { stdio: "pipe", timeout: 3e3 });
|
|
286988
287189
|
} catch (err) {
|
|
286989
287190
|
console.log(` Failed to download Neovim: ${err instanceof Error ? err.message : String(err)}`);
|
|
286990
287191
|
return null;
|
|
286991
287192
|
}
|
|
286992
287193
|
try {
|
|
286993
|
-
const ver =
|
|
287194
|
+
const ver = execSync43(`"${nvimDest}" --version`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).split("\n")[0];
|
|
286994
287195
|
console.log(` Installed: ${ver}`);
|
|
286995
287196
|
} catch {
|
|
286996
287197
|
console.log(" Warning: nvim binary downloaded but may not work (missing FUSE? Try: nvim --appimage-extract)");
|
|
@@ -287005,8 +287206,8 @@ async function ensureNeovim() {
|
|
|
287005
287206
|
if (hasCmd("brew")) {
|
|
287006
287207
|
console.log(" Installing Neovim via Homebrew...");
|
|
287007
287208
|
try {
|
|
287008
|
-
|
|
287009
|
-
const nvimPath =
|
|
287209
|
+
execSync43("brew install neovim", { stdio: "inherit", timeout: 12e4 });
|
|
287210
|
+
const nvimPath = execSync43("which nvim", { encoding: "utf8", stdio: "pipe", timeout: 3e3 }).trim();
|
|
287010
287211
|
return nvimPath || null;
|
|
287011
287212
|
} catch {
|
|
287012
287213
|
console.log(" brew install neovim failed.");
|
|
@@ -287020,7 +287221,7 @@ async function ensureNeovim() {
|
|
|
287020
287221
|
if (hasCmd("choco")) {
|
|
287021
287222
|
console.log(" Installing Neovim via Chocolatey...");
|
|
287022
287223
|
try {
|
|
287023
|
-
|
|
287224
|
+
execSync43("choco install neovim -y", { stdio: "inherit", timeout: 12e4 });
|
|
287024
287225
|
return "nvim";
|
|
287025
287226
|
} catch {
|
|
287026
287227
|
console.log(" choco install neovim failed.");
|
|
@@ -287029,7 +287230,7 @@ async function ensureNeovim() {
|
|
|
287029
287230
|
if (hasCmd("winget")) {
|
|
287030
287231
|
console.log(" Installing Neovim via winget...");
|
|
287031
287232
|
try {
|
|
287032
|
-
|
|
287233
|
+
execSync43("winget install Neovim.Neovim --accept-source-agreements --accept-package-agreements", {
|
|
287033
287234
|
stdio: "inherit",
|
|
287034
287235
|
timeout: 12e4
|
|
287035
287236
|
});
|
|
@@ -287047,7 +287248,7 @@ function ensurePathInShellRc(binDir) {
|
|
|
287047
287248
|
const shell = process.env.SHELL ?? "";
|
|
287048
287249
|
const rcFile = shell.includes("zsh") ? join65(homedir18(), ".zshrc") : join65(homedir18(), ".bashrc");
|
|
287049
287250
|
try {
|
|
287050
|
-
const rcContent =
|
|
287251
|
+
const rcContent = existsSync49(rcFile) ? readFileSync38(rcFile, "utf8") : "";
|
|
287051
287252
|
if (rcContent.includes(binDir)) return;
|
|
287052
287253
|
const exportLine = `
|
|
287053
287254
|
export PATH="${binDir}:$PATH" # Added by open-agents for nvim
|
|
@@ -287084,7 +287285,7 @@ var init_setup = __esm({
|
|
|
287084
287285
|
});
|
|
287085
287286
|
|
|
287086
287287
|
// packages/cli/src/tui/drop-panel.ts
|
|
287087
|
-
import { existsSync as
|
|
287288
|
+
import { existsSync as existsSync50 } from "node:fs";
|
|
287088
287289
|
import { extname as extname10, resolve as resolve31 } from "node:path";
|
|
287089
287290
|
function ansi4(code8, text) {
|
|
287090
287291
|
return isTTY4 ? `\x1B[${code8}m${text}\x1B[0m` : text;
|
|
@@ -287205,7 +287406,7 @@ function showDropPanel(opts) {
|
|
|
287205
287406
|
filePath = decodeURIComponent(filePath.slice(7));
|
|
287206
287407
|
}
|
|
287207
287408
|
filePath = resolve31(filePath);
|
|
287208
|
-
if (!
|
|
287409
|
+
if (!existsSync50(filePath)) {
|
|
287209
287410
|
errorMsg = `File not found: ${filePath}`;
|
|
287210
287411
|
render();
|
|
287211
287412
|
return;
|
|
@@ -287277,10 +287478,10 @@ var init_drop_panel = __esm({
|
|
|
287277
287478
|
});
|
|
287278
287479
|
|
|
287279
287480
|
// packages/cli/src/tui/neovim-mode.ts
|
|
287280
|
-
import { existsSync as
|
|
287481
|
+
import { existsSync as existsSync51, unlinkSync as unlinkSync12 } from "node:fs";
|
|
287281
287482
|
import { tmpdir as tmpdir12 } from "node:os";
|
|
287282
287483
|
import { join as join66 } from "node:path";
|
|
287283
|
-
import { execSync as
|
|
287484
|
+
import { execSync as execSync44 } from "node:child_process";
|
|
287284
287485
|
function isNeovimActive() {
|
|
287285
287486
|
return _state !== null && !_state.cleanedUp;
|
|
287286
287487
|
}
|
|
@@ -287297,7 +287498,7 @@ async function startNeovimMode(opts) {
|
|
|
287297
287498
|
}
|
|
287298
287499
|
let nvimPath;
|
|
287299
287500
|
try {
|
|
287300
|
-
nvimPath =
|
|
287501
|
+
nvimPath = execSync44("which nvim 2>/dev/null", { encoding: "utf8" }).trim();
|
|
287301
287502
|
if (!nvimPath) throw new Error();
|
|
287302
287503
|
} catch {
|
|
287303
287504
|
const installed = await ensureNeovim();
|
|
@@ -287327,7 +287528,7 @@ async function startNeovimMode(opts) {
|
|
|
287327
287528
|
}
|
|
287328
287529
|
const socketPath = join66(tmpdir12(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
|
|
287329
287530
|
try {
|
|
287330
|
-
if (
|
|
287531
|
+
if (existsSync51(socketPath)) unlinkSync12(socketPath);
|
|
287331
287532
|
} catch {
|
|
287332
287533
|
}
|
|
287333
287534
|
const ptyCols = opts.cols;
|
|
@@ -287574,12 +287775,12 @@ function resizeNeovim(cols, contentRows) {
|
|
|
287574
287775
|
}
|
|
287575
287776
|
async function connectRPC(state, neovimPkg, cols) {
|
|
287576
287777
|
let attempts = 0;
|
|
287577
|
-
while (!
|
|
287778
|
+
while (!existsSync51(state.socketPath) && attempts < 30) {
|
|
287578
287779
|
await new Promise((r2) => setTimeout(r2, 200));
|
|
287579
287780
|
attempts++;
|
|
287580
287781
|
if (state.cleanedUp) return;
|
|
287581
287782
|
}
|
|
287582
|
-
if (!
|
|
287783
|
+
if (!existsSync51(state.socketPath)) return;
|
|
287583
287784
|
const nvim = neovimPkg.attach({ socket: state.socketPath });
|
|
287584
287785
|
state.nvim = nvim;
|
|
287585
287786
|
await new Promise((r2) => setTimeout(r2, 300));
|
|
@@ -287716,7 +287917,7 @@ function doCleanup(state) {
|
|
|
287716
287917
|
state.pty = null;
|
|
287717
287918
|
}
|
|
287718
287919
|
try {
|
|
287719
|
-
if (
|
|
287920
|
+
if (existsSync51(state.socketPath)) unlinkSync12(state.socketPath);
|
|
287720
287921
|
} catch {
|
|
287721
287922
|
}
|
|
287722
287923
|
if (state.stdinHandler) {
|
|
@@ -287786,7 +287987,7 @@ __export(daemon_exports, {
|
|
|
287786
287987
|
stopDaemon: () => stopDaemon
|
|
287787
287988
|
});
|
|
287788
287989
|
import { spawn as spawn22 } from "node:child_process";
|
|
287789
|
-
import { existsSync as
|
|
287990
|
+
import { existsSync as existsSync52, readFileSync as readFileSync39, writeFileSync as writeFileSync23, mkdirSync as mkdirSync23, unlinkSync as unlinkSync13 } from "node:fs";
|
|
287790
287991
|
import { join as join67 } from "node:path";
|
|
287791
287992
|
import { homedir as homedir19 } from "node:os";
|
|
287792
287993
|
import { fileURLToPath as fileURLToPath13 } from "node:url";
|
|
@@ -287812,7 +288013,7 @@ async function isDaemonRunning(port) {
|
|
|
287812
288013
|
}
|
|
287813
288014
|
}
|
|
287814
288015
|
function getDaemonPid() {
|
|
287815
|
-
if (!
|
|
288016
|
+
if (!existsSync52(PID_FILE2)) return null;
|
|
287816
288017
|
try {
|
|
287817
288018
|
const pid = parseInt(readFileSync39(PID_FILE2, "utf8").trim(), 10);
|
|
287818
288019
|
if (!pid || pid <= 0) return null;
|
|
@@ -287832,8 +288033,8 @@ async function startDaemon() {
|
|
|
287832
288033
|
let oaScript = process.argv[1];
|
|
287833
288034
|
if (!oaScript) {
|
|
287834
288035
|
try {
|
|
287835
|
-
const { execSync:
|
|
287836
|
-
const whichOa =
|
|
288036
|
+
const { execSync: execSync51 } = await import("node:child_process");
|
|
288037
|
+
const whichOa = execSync51("which oa 2>/dev/null || where oa 2>nul", { encoding: "utf8" }).trim();
|
|
287837
288038
|
if (whichOa) oaScript = whichOa;
|
|
287838
288039
|
} catch {
|
|
287839
288040
|
}
|
|
@@ -287841,7 +288042,7 @@ async function startDaemon() {
|
|
|
287841
288042
|
if (!oaScript) {
|
|
287842
288043
|
const thisDir = dirname21(fileURLToPath13(import.meta.url));
|
|
287843
288044
|
const indexJs = join67(thisDir, "index.js");
|
|
287844
|
-
if (
|
|
288045
|
+
if (existsSync52(indexJs)) oaScript = indexJs;
|
|
287845
288046
|
}
|
|
287846
288047
|
if (!oaScript) return null;
|
|
287847
288048
|
try {
|
|
@@ -288325,7 +288526,7 @@ __export(sponsor_wizard_exports, {
|
|
|
288325
288526
|
saveSponsorConfig: () => saveSponsorConfig,
|
|
288326
288527
|
showSponsorDashboard: () => showSponsorDashboard
|
|
288327
288528
|
});
|
|
288328
|
-
import { existsSync as
|
|
288529
|
+
import { existsSync as existsSync53, readFileSync as readFileSync40, writeFileSync as writeFileSync24, mkdirSync as mkdirSync24 } from "node:fs";
|
|
288329
288530
|
import { join as join68 } from "node:path";
|
|
288330
288531
|
function colorPreview(code8) {
|
|
288331
288532
|
return `\x1B[38;5;${code8}m\u2588\u2588\u2588\u2588\x1B[0m (${code8})`;
|
|
@@ -288346,7 +288547,7 @@ function configPath(projectDir) {
|
|
|
288346
288547
|
}
|
|
288347
288548
|
function loadSponsorConfig(projectDir) {
|
|
288348
288549
|
const p2 = configPath(projectDir);
|
|
288349
|
-
if (!
|
|
288550
|
+
if (!existsSync53(p2)) return null;
|
|
288350
288551
|
try {
|
|
288351
288552
|
return JSON.parse(readFileSync40(p2, "utf8"));
|
|
288352
288553
|
} catch {
|
|
@@ -289237,10 +289438,10 @@ __export(voice_exports, {
|
|
|
289237
289438
|
registerCustomOnnxModel: () => registerCustomOnnxModel,
|
|
289238
289439
|
resetNarrationContext: () => resetNarrationContext
|
|
289239
289440
|
});
|
|
289240
|
-
import { existsSync as
|
|
289441
|
+
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";
|
|
289241
289442
|
import { join as join69, dirname as dirname22 } from "node:path";
|
|
289242
289443
|
import { homedir as homedir20, tmpdir as tmpdir13, platform as platform4 } from "node:os";
|
|
289243
|
-
import { execSync as
|
|
289444
|
+
import { execSync as execSync45, spawn as nodeSpawn } from "node:child_process";
|
|
289244
289445
|
import { createRequire as createRequire2 } from "node:module";
|
|
289245
289446
|
function sanitizeForTTS(text) {
|
|
289246
289447
|
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();
|
|
@@ -289293,7 +289494,7 @@ function luxttsInferScript() {
|
|
|
289293
289494
|
return join69(voiceDir(), "luxtts-infer.py");
|
|
289294
289495
|
}
|
|
289295
289496
|
function writeDetectTorchScript(targetPath) {
|
|
289296
|
-
if (
|
|
289497
|
+
if (existsSync54(targetPath)) return;
|
|
289297
289498
|
try {
|
|
289298
289499
|
mkdirSync25(dirname22(targetPath), { recursive: true });
|
|
289299
289500
|
} catch {
|
|
@@ -290119,7 +290320,7 @@ var init_voice = __esm({
|
|
|
290119
290320
|
const targets = ["glados", "overwatch"];
|
|
290120
290321
|
for (const modelId of targets) {
|
|
290121
290322
|
const refFile = join69(refsDir, `${modelId}-ref.wav`);
|
|
290122
|
-
if (
|
|
290323
|
+
if (existsSync54(refFile)) continue;
|
|
290123
290324
|
try {
|
|
290124
290325
|
await this.generateCloneRef(modelId);
|
|
290125
290326
|
const meta = this.loadCloneMeta();
|
|
@@ -290197,13 +290398,13 @@ var init_voice = __esm({
|
|
|
290197
290398
|
if (p2.startsWith("~/") || p2 === "~") {
|
|
290198
290399
|
p2 = join69(homedir20(), p2.slice(1));
|
|
290199
290400
|
}
|
|
290200
|
-
if (!
|
|
290401
|
+
if (!existsSync54(p2)) {
|
|
290201
290402
|
return `File not found: ${p2}
|
|
290202
290403
|
(original input: ${audioPath})`;
|
|
290203
290404
|
}
|
|
290204
290405
|
audioPath = p2;
|
|
290205
290406
|
const refsDir = luxttsCloneRefsDir();
|
|
290206
|
-
if (!
|
|
290407
|
+
if (!existsSync54(refsDir)) mkdirSync25(refsDir, { recursive: true });
|
|
290207
290408
|
const ext = audioPath.split(".").pop() || "wav";
|
|
290208
290409
|
const srcName = (audioPath.split("/").pop() ?? "clone").replace(/\.[^.]+$/, "").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
290209
290410
|
const ts = Date.now().toString(36);
|
|
@@ -290251,7 +290452,7 @@ var init_voice = __esm({
|
|
|
290251
290452
|
return `Failed to synthesize reference audio from ${source.label}.`;
|
|
290252
290453
|
}
|
|
290253
290454
|
const refsDir = luxttsCloneRefsDir();
|
|
290254
|
-
if (!
|
|
290455
|
+
if (!existsSync54(refsDir)) mkdirSync25(refsDir, { recursive: true });
|
|
290255
290456
|
const destPath = join69(refsDir, `${sourceModelId}-ref.wav`);
|
|
290256
290457
|
const sampleRate = this.config?.audio?.sample_rate ?? 22050;
|
|
290257
290458
|
this.writeWav(audioData, sampleRate, destPath);
|
|
@@ -290272,7 +290473,7 @@ var init_voice = __esm({
|
|
|
290272
290473
|
}
|
|
290273
290474
|
loadCloneMeta() {
|
|
290274
290475
|
const p2 = _VoiceEngine.cloneMetaFile();
|
|
290275
|
-
if (!
|
|
290476
|
+
if (!existsSync54(p2)) return {};
|
|
290276
290477
|
try {
|
|
290277
290478
|
return JSON.parse(readFileSync41(p2, "utf8"));
|
|
290278
290479
|
} catch {
|
|
@@ -290281,7 +290482,7 @@ var init_voice = __esm({
|
|
|
290281
290482
|
}
|
|
290282
290483
|
saveCloneMeta(meta) {
|
|
290283
290484
|
const dir = luxttsCloneRefsDir();
|
|
290284
|
-
if (!
|
|
290485
|
+
if (!existsSync54(dir)) mkdirSync25(dir, { recursive: true });
|
|
290285
290486
|
writeFileSync25(_VoiceEngine.cloneMetaFile(), JSON.stringify(meta, null, 2));
|
|
290286
290487
|
}
|
|
290287
290488
|
/** Audio file extensions recognized as clone references */
|
|
@@ -290292,7 +290493,7 @@ var init_voice = __esm({
|
|
|
290292
290493
|
*/
|
|
290293
290494
|
listCloneRefs() {
|
|
290294
290495
|
const dir = luxttsCloneRefsDir();
|
|
290295
|
-
if (!
|
|
290496
|
+
if (!existsSync54(dir)) return [];
|
|
290296
290497
|
const meta = this.loadCloneMeta();
|
|
290297
290498
|
const files = readdirSync13(dir).filter((f2) => {
|
|
290298
290499
|
const ext = f2.split(".").pop()?.toLowerCase() ?? "";
|
|
@@ -290317,7 +290518,7 @@ var init_voice = __esm({
|
|
|
290317
290518
|
/** Delete a clone reference file by filename. Returns true if deleted. */
|
|
290318
290519
|
deleteCloneRef(filename) {
|
|
290319
290520
|
const p2 = join69(luxttsCloneRefsDir(), filename);
|
|
290320
|
-
if (!
|
|
290521
|
+
if (!existsSync54(p2)) return false;
|
|
290321
290522
|
try {
|
|
290322
290523
|
unlinkSync14(p2);
|
|
290323
290524
|
const meta = this.loadCloneMeta();
|
|
@@ -290341,7 +290542,7 @@ var init_voice = __esm({
|
|
|
290341
290542
|
/** Set the active clone reference by filename. */
|
|
290342
290543
|
setActiveCloneRef(filename) {
|
|
290343
290544
|
const p2 = join69(luxttsCloneRefsDir(), filename);
|
|
290344
|
-
if (!
|
|
290545
|
+
if (!existsSync54(p2)) return `File not found: ${filename}`;
|
|
290345
290546
|
this.luxttsCloneRef = p2;
|
|
290346
290547
|
return `Active clone voice set to: ${filename}`;
|
|
290347
290548
|
}
|
|
@@ -290928,7 +291129,7 @@ var init_voice = __esm({
|
|
|
290928
291129
|
}
|
|
290929
291130
|
for (const player of ["paplay", "pw-play", "aplay"]) {
|
|
290930
291131
|
try {
|
|
290931
|
-
|
|
291132
|
+
execSync45(`which ${player}`, { stdio: "pipe" });
|
|
290932
291133
|
return [player, path5];
|
|
290933
291134
|
} catch {
|
|
290934
291135
|
}
|
|
@@ -290956,7 +291157,7 @@ var init_voice = __esm({
|
|
|
290956
291157
|
if (this.python3Path) return this.python3Path;
|
|
290957
291158
|
for (const bin of ["python3", "python"]) {
|
|
290958
291159
|
try {
|
|
290959
|
-
const path5 =
|
|
291160
|
+
const path5 = execSync45(`which ${bin}`, { stdio: "pipe", timeout: 5e3 }).toString().trim();
|
|
290960
291161
|
if (path5) {
|
|
290961
291162
|
this.python3Path = path5;
|
|
290962
291163
|
return path5;
|
|
@@ -291018,7 +291219,7 @@ var init_voice = __esm({
|
|
|
291018
291219
|
return false;
|
|
291019
291220
|
}
|
|
291020
291221
|
try {
|
|
291021
|
-
|
|
291222
|
+
execSync45(`${py} -c "import mlx_audio"`, { stdio: "pipe", timeout: 1e4 });
|
|
291022
291223
|
this.mlxInstalled = true;
|
|
291023
291224
|
return true;
|
|
291024
291225
|
} catch {
|
|
@@ -291081,14 +291282,14 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
291081
291282
|
`tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
|
|
291082
291283
|
].join("; ");
|
|
291083
291284
|
try {
|
|
291084
|
-
|
|
291285
|
+
execSync45(
|
|
291085
291286
|
`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`,
|
|
291086
291287
|
{ stdio: "pipe", timeout: 6e4, cwd: tmpdir13() }
|
|
291087
291288
|
);
|
|
291088
291289
|
} catch (err) {
|
|
291089
291290
|
try {
|
|
291090
291291
|
const safeText = cleaned.replace(/'/g, "'\\''");
|
|
291091
|
-
|
|
291292
|
+
execSync45(
|
|
291092
291293
|
`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`,
|
|
291093
291294
|
{ stdio: "pipe", timeout: 6e4, cwd: tmpdir13() }
|
|
291094
291295
|
);
|
|
@@ -291096,7 +291297,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
291096
291297
|
return;
|
|
291097
291298
|
}
|
|
291098
291299
|
}
|
|
291099
|
-
if (!
|
|
291300
|
+
if (!existsSync54(wavPath)) return;
|
|
291100
291301
|
if (volume !== 1) {
|
|
291101
291302
|
try {
|
|
291102
291303
|
const wavData = readFileSync41(wavPath);
|
|
@@ -291155,14 +291356,14 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
291155
291356
|
`tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
|
|
291156
291357
|
].join("; ");
|
|
291157
291358
|
try {
|
|
291158
|
-
|
|
291359
|
+
execSync45(
|
|
291159
291360
|
`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`,
|
|
291160
291361
|
{ stdio: "pipe", timeout: 6e4, cwd: tmpdir13() }
|
|
291161
291362
|
);
|
|
291162
291363
|
} catch {
|
|
291163
291364
|
try {
|
|
291164
291365
|
const safeText = cleaned.replace(/'/g, "'\\''");
|
|
291165
|
-
|
|
291366
|
+
execSync45(
|
|
291166
291367
|
`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`,
|
|
291167
291368
|
{ stdio: "pipe", timeout: 6e4, cwd: tmpdir13() }
|
|
291168
291369
|
);
|
|
@@ -291170,7 +291371,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
291170
291371
|
return null;
|
|
291171
291372
|
}
|
|
291172
291373
|
}
|
|
291173
|
-
if (!
|
|
291374
|
+
if (!existsSync54(wavPath)) return null;
|
|
291174
291375
|
try {
|
|
291175
291376
|
const data = readFileSync41(wavPath);
|
|
291176
291377
|
unlinkSync14(wavPath);
|
|
@@ -291197,7 +291398,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
291197
291398
|
}
|
|
291198
291399
|
const venvDir = luxttsVenvDir();
|
|
291199
291400
|
const venvPy = luxttsVenvPy();
|
|
291200
|
-
if (
|
|
291401
|
+
if (existsSync54(venvPy)) {
|
|
291201
291402
|
try {
|
|
291202
291403
|
const quotedPy = `"${venvPy}"`;
|
|
291203
291404
|
const repoPath = luxttsRepoDir().replace(/\\/g, "/");
|
|
@@ -291246,7 +291447,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
291246
291447
|
}
|
|
291247
291448
|
}
|
|
291248
291449
|
renderInfo("Setting up LuxTTS voice cloning (first-time setup, this takes several minutes)...");
|
|
291249
|
-
if (!
|
|
291450
|
+
if (!existsSync54(venvDir)) {
|
|
291250
291451
|
renderInfo(" Creating Python virtual environment...");
|
|
291251
291452
|
try {
|
|
291252
291453
|
await this.asyncShell(`${py} -m venv ${JSON.stringify(venvDir)}`, 6e4);
|
|
@@ -291302,10 +291503,10 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
291302
291503
|
}
|
|
291303
291504
|
}
|
|
291304
291505
|
const repoDir = luxttsRepoDir();
|
|
291305
|
-
if (!
|
|
291506
|
+
if (!existsSync54(join69(repoDir, "zipvoice", "luxvoice.py"))) {
|
|
291306
291507
|
renderInfo(" Cloning LuxTTS repository...");
|
|
291307
291508
|
try {
|
|
291308
|
-
if (
|
|
291509
|
+
if (existsSync54(repoDir)) {
|
|
291309
291510
|
const rmCmd = process.platform === "win32" ? `rmdir /s /q ${JSON.stringify(repoDir)}` : `rm -rf ${JSON.stringify(repoDir)}`;
|
|
291310
291511
|
await this.asyncShell(rmCmd, 3e4);
|
|
291311
291512
|
}
|
|
@@ -291394,7 +291595,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
291394
291595
|
renderWarning(` Could not install system build deps: ${err instanceof Error ? err.message : String(err)}`);
|
|
291395
291596
|
}
|
|
291396
291597
|
}
|
|
291397
|
-
const isJetson = isArm && (
|
|
291598
|
+
const isJetson = isArm && (existsSync54("/etc/nv_tegra_release") || existsSync54("/usr/local/cuda/targets/aarch64-linux") || (process.env.JETSON_L4T_VERSION ?? "") !== "");
|
|
291398
291599
|
const installSteps = isArm ? [
|
|
291399
291600
|
// ARM: install individually so we get clear error messages per package.
|
|
291400
291601
|
// ALL are fatal because LuxTTS hard-imports them (no lazy/optional imports).
|
|
@@ -291469,12 +291670,12 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
291469
291670
|
}
|
|
291470
291671
|
/** Auto-detect an existing clone reference in the refs directory */
|
|
291471
291672
|
autoDetectCloneRef() {
|
|
291472
|
-
if (this.luxttsCloneRef &&
|
|
291673
|
+
if (this.luxttsCloneRef && existsSync54(this.luxttsCloneRef)) return;
|
|
291473
291674
|
const refsDir = luxttsCloneRefsDir();
|
|
291474
|
-
if (!
|
|
291675
|
+
if (!existsSync54(refsDir)) return;
|
|
291475
291676
|
for (const name10 of ["custom-clone.wav", "custom-clone.mp3", "glados-ref.wav", "overwatch-ref.wav"]) {
|
|
291476
291677
|
const p2 = join69(refsDir, name10);
|
|
291477
|
-
if (
|
|
291678
|
+
if (existsSync54(p2)) {
|
|
291478
291679
|
this.luxttsCloneRef = p2;
|
|
291479
291680
|
return;
|
|
291480
291681
|
}
|
|
@@ -291581,7 +291782,7 @@ if __name__ == '__main__':
|
|
|
291581
291782
|
async ensureLuxttsDaemon() {
|
|
291582
291783
|
if (this._luxttsDaemon && !this._luxttsDaemon.killed) return true;
|
|
291583
291784
|
const venvPy = luxttsVenvPy();
|
|
291584
|
-
if (!
|
|
291785
|
+
if (!existsSync54(venvPy)) return false;
|
|
291585
291786
|
return new Promise((resolve39) => {
|
|
291586
291787
|
const env2 = { ...process.env, LUXTTS_REPO_PATH: luxttsRepoDir() };
|
|
291587
291788
|
const daemon = nodeSpawn(venvPy, [luxttsInferScript()], {
|
|
@@ -291670,7 +291871,7 @@ if __name__ == '__main__':
|
|
|
291670
291871
|
* Used by drainQueue's pre-fetch pipeline for gapless back-to-back playback.
|
|
291671
291872
|
*/
|
|
291672
291873
|
async synthesizeLuxttsWav(text, speedFactor = 1) {
|
|
291673
|
-
if (!this.luxttsCloneRef || !
|
|
291874
|
+
if (!this.luxttsCloneRef || !existsSync54(this.luxttsCloneRef)) return null;
|
|
291674
291875
|
const cleaned = text.replace(/\*/g, "").trim();
|
|
291675
291876
|
if (!cleaned) return null;
|
|
291676
291877
|
const ready = await this.ensureLuxttsDaemon();
|
|
@@ -291687,14 +291888,14 @@ if __name__ == '__main__':
|
|
|
291687
291888
|
} catch {
|
|
291688
291889
|
return null;
|
|
291689
291890
|
}
|
|
291690
|
-
return
|
|
291891
|
+
return existsSync54(wavPath) ? wavPath : null;
|
|
291691
291892
|
}
|
|
291692
291893
|
/**
|
|
291693
291894
|
* Post-process (fade-in, volume, pitch, stereo) and play a LuxTTS WAV file.
|
|
291694
291895
|
* Cleans up the WAV file after playback.
|
|
291695
291896
|
*/
|
|
291696
291897
|
async postProcessAndPlayLuxtts(wavPath, volume = 1, pitchFactor = 1, stereoDelayMs = 0.6) {
|
|
291697
|
-
if (!
|
|
291898
|
+
if (!existsSync54(wavPath)) return;
|
|
291698
291899
|
try {
|
|
291699
291900
|
const wavData = readFileSync41(wavPath);
|
|
291700
291901
|
if (wavData.length > 44) {
|
|
@@ -291790,7 +291991,7 @@ if __name__ == '__main__':
|
|
|
291790
291991
|
* Used for Telegram voice messages and WebSocket streaming.
|
|
291791
291992
|
*/
|
|
291792
291993
|
async synthesizeLuxttsToBuffer(text) {
|
|
291793
|
-
if (!this.luxttsCloneRef || !
|
|
291994
|
+
if (!this.luxttsCloneRef || !existsSync54(this.luxttsCloneRef)) return null;
|
|
291794
291995
|
const cleaned = text.replace(/\*/g, "").trim();
|
|
291795
291996
|
if (!cleaned) return null;
|
|
291796
291997
|
const ready = await this.ensureLuxttsDaemon();
|
|
@@ -291807,7 +292008,7 @@ if __name__ == '__main__':
|
|
|
291807
292008
|
} catch {
|
|
291808
292009
|
return null;
|
|
291809
292010
|
}
|
|
291810
|
-
if (!
|
|
292011
|
+
if (!existsSync54(wavPath)) return null;
|
|
291811
292012
|
try {
|
|
291812
292013
|
const data = readFileSync41(wavPath);
|
|
291813
292014
|
unlinkSync14(wavPath);
|
|
@@ -291828,7 +292029,7 @@ if __name__ == '__main__':
|
|
|
291828
292029
|
"onnxruntime-node": "^1.21.0",
|
|
291829
292030
|
"phonemizer": "^1.2.1"
|
|
291830
292031
|
};
|
|
291831
|
-
if (
|
|
292032
|
+
if (existsSync54(pkgPath)) {
|
|
291832
292033
|
try {
|
|
291833
292034
|
const existing = JSON.parse(readFileSync41(pkgPath, "utf8"));
|
|
291834
292035
|
if (!existing.dependencies?.["phonemizer"]) {
|
|
@@ -291838,7 +292039,7 @@ if __name__ == '__main__':
|
|
|
291838
292039
|
} catch {
|
|
291839
292040
|
}
|
|
291840
292041
|
}
|
|
291841
|
-
if (!
|
|
292042
|
+
if (!existsSync54(pkgPath)) {
|
|
291842
292043
|
writeFileSync25(pkgPath, JSON.stringify({
|
|
291843
292044
|
name: "open-agents-voice",
|
|
291844
292045
|
private: true,
|
|
@@ -291858,7 +292059,7 @@ if __name__ == '__main__':
|
|
|
291858
292059
|
}
|
|
291859
292060
|
};
|
|
291860
292061
|
const onnxNodeModules = join69(voiceDir(), "node_modules", "onnxruntime-node");
|
|
291861
|
-
const onnxInstalled =
|
|
292062
|
+
const onnxInstalled = existsSync54(onnxNodeModules);
|
|
291862
292063
|
if (onnxInstalled && !await probeOnnx()) {
|
|
291863
292064
|
throw new Error(
|
|
291864
292065
|
`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.`
|
|
@@ -291917,16 +292118,16 @@ Error: ${err instanceof Error ? err.message : String(err)}`
|
|
|
291917
292118
|
const dir = modelDir(id);
|
|
291918
292119
|
const onnxPath = modelOnnxPath(id);
|
|
291919
292120
|
const configPath2 = modelConfigPath(id);
|
|
291920
|
-
if (
|
|
292121
|
+
if (existsSync54(onnxPath) && existsSync54(configPath2)) return;
|
|
291921
292122
|
mkdirSync25(dir, { recursive: true });
|
|
291922
|
-
if (!
|
|
292123
|
+
if (!existsSync54(configPath2)) {
|
|
291923
292124
|
renderInfo(`Downloading ${model.label} voice config...`);
|
|
291924
292125
|
const configResp = await fetch(model.configUrl);
|
|
291925
292126
|
if (!configResp.ok) throw new Error(`Failed to download config: HTTP ${configResp.status}`);
|
|
291926
292127
|
const configText = await configResp.text();
|
|
291927
292128
|
writeFileSync25(configPath2, configText);
|
|
291928
292129
|
}
|
|
291929
|
-
if (!
|
|
292130
|
+
if (!existsSync54(onnxPath)) {
|
|
291930
292131
|
renderInfo(`Downloading ${model.label} voice model (this may take a minute)...`);
|
|
291931
292132
|
const onnxResp = await fetch(model.onnxUrl);
|
|
291932
292133
|
if (!onnxResp.ok) throw new Error(`Failed to download model: HTTP ${onnxResp.status}`);
|
|
@@ -291959,7 +292160,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`
|
|
|
291959
292160
|
if (!this.ort) throw new Error("ONNX runtime not loaded");
|
|
291960
292161
|
const onnxPath = modelOnnxPath(this.modelId);
|
|
291961
292162
|
const configPath2 = modelConfigPath(this.modelId);
|
|
291962
|
-
if (!
|
|
292163
|
+
if (!existsSync54(onnxPath) || !existsSync54(configPath2)) {
|
|
291963
292164
|
throw new Error(`Model files not found for ${this.modelId}`);
|
|
291964
292165
|
}
|
|
291965
292166
|
this.config = JSON.parse(readFileSync41(configPath2, "utf8"));
|
|
@@ -291989,7 +292190,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`
|
|
|
291989
292190
|
// packages/cli/src/tui/commands.ts
|
|
291990
292191
|
import * as nodeOs from "node:os";
|
|
291991
292192
|
import { execSync as nodeExecSync } from "node:child_process";
|
|
291992
|
-
import { existsSync as
|
|
292193
|
+
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";
|
|
291993
292194
|
import { join as join70 } from "node:path";
|
|
291994
292195
|
async function _immediateReregister(newUrl) {
|
|
291995
292196
|
if (!_lastRegisteredSponsorPayload) return;
|
|
@@ -292504,7 +292705,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
292504
292705
|
renderInfo(out.split("\n").slice(0, 4).join("\n"));
|
|
292505
292706
|
try {
|
|
292506
292707
|
const pidFile = join70(ctx3.repoRoot ?? process.cwd(), ".oa", "nexus", "daemon.pid");
|
|
292507
|
-
if (
|
|
292708
|
+
if (existsSync55(pidFile)) {
|
|
292508
292709
|
const pid = parseInt(readFileSync42(pidFile, "utf8").trim(), 10);
|
|
292509
292710
|
if (pid > 0 && !registry2.daemons.has("Nexus")) {
|
|
292510
292711
|
registry2.register({ name: "Nexus", pid, startedAt: Date.now(), status: "running" });
|
|
@@ -292811,7 +293012,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
292811
293012
|
if (shareType === "tool") {
|
|
292812
293013
|
const toolDir = join70(ctx3.repoRoot, ".oa", "tools");
|
|
292813
293014
|
const toolFile = join70(toolDir, shareName.endsWith(".json") ? shareName : `${shareName}.json`);
|
|
292814
|
-
if (!
|
|
293015
|
+
if (!existsSync55(toolFile)) {
|
|
292815
293016
|
renderWarning(`Tool not found: ${toolFile}`);
|
|
292816
293017
|
return "handled";
|
|
292817
293018
|
}
|
|
@@ -292820,7 +293021,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
292820
293021
|
} else if (shareType === "skill") {
|
|
292821
293022
|
const skillDir = join70(ctx3.repoRoot, ".oa", "skills", shareName);
|
|
292822
293023
|
const skillFile = join70(skillDir, "SKILL.md");
|
|
292823
|
-
if (!
|
|
293024
|
+
if (!existsSync55(skillFile)) {
|
|
292824
293025
|
renderWarning(`Skill not found: ${skillFile}`);
|
|
292825
293026
|
return "handled";
|
|
292826
293027
|
}
|
|
@@ -292862,7 +293063,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
292862
293063
|
const nexus = new NexusTool(ctx3.repoRoot);
|
|
292863
293064
|
await nexus.execute({ action: "ipfs_pin", cid: importCid, source: "import" });
|
|
292864
293065
|
const regFile = join70(ctx3.repoRoot, ".oa", "nexus", "ipfs", "cid-registry", "learning-cids.json");
|
|
292865
|
-
if (
|
|
293066
|
+
if (existsSync55(regFile)) {
|
|
292866
293067
|
const reg = JSON.parse(readFileSync42(regFile, "utf8"));
|
|
292867
293068
|
const pinned = Object.values(reg).some((e2) => e2.cid === importCid && e2.pinned);
|
|
292868
293069
|
if (pinned) {
|
|
@@ -292921,7 +293122,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
292921
293122
|
let heliaBlocks = 0;
|
|
292922
293123
|
let heliaBytes = 0;
|
|
292923
293124
|
try {
|
|
292924
|
-
if (
|
|
293125
|
+
if (existsSync55(ipfsLocalDir)) {
|
|
292925
293126
|
const files = readdirSync14(ipfsLocalDir).filter((f2) => f2.endsWith(".json"));
|
|
292926
293127
|
ipfsFiles = files.length;
|
|
292927
293128
|
for (const f2 of files) {
|
|
@@ -292932,7 +293133,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
292932
293133
|
}
|
|
292933
293134
|
}
|
|
292934
293135
|
const heliaBlockDir = join70(ipfsDir, "blocks");
|
|
292935
|
-
if (
|
|
293136
|
+
if (existsSync55(heliaBlockDir)) {
|
|
292936
293137
|
const walkDir = (dir) => {
|
|
292937
293138
|
for (const entry of readdirSync14(dir, { withFileTypes: true })) {
|
|
292938
293139
|
if (entry.isDirectory()) walkDir(join70(dir, entry.name));
|
|
@@ -292956,7 +293157,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
292956
293157
|
lines.push(` Backend: ${heliaBlocks > 0 ? c3.green("helia-ipfs") : c3.yellow("sha256-local (Helia not initialized)")}`);
|
|
292957
293158
|
try {
|
|
292958
293159
|
const statusFile = join70(ctx3.repoRoot, ".oa", "nexus", "status.json");
|
|
292959
|
-
if (
|
|
293160
|
+
if (existsSync55(statusFile)) {
|
|
292960
293161
|
const status = JSON.parse(readFileSync42(statusFile, "utf8"));
|
|
292961
293162
|
if (status.peerId) {
|
|
292962
293163
|
lines.push(`
|
|
@@ -292979,7 +293180,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
292979
293180
|
const idDir = join70(ctx3.repoRoot, ".oa", "identity");
|
|
292980
293181
|
try {
|
|
292981
293182
|
const stateFile = join70(idDir, "self-state.json");
|
|
292982
|
-
if (
|
|
293183
|
+
if (existsSync55(stateFile)) {
|
|
292983
293184
|
const state = JSON.parse(readFileSync42(stateFile, "utf8"));
|
|
292984
293185
|
lines.push(` Version: ${c3.bold("v" + (state.version ?? "?"))} Sessions: ${c3.bold(String(state.session_count ?? 0))}`);
|
|
292985
293186
|
if (state.narrative_summary) {
|
|
@@ -292990,7 +293191,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
292990
293191
|
lines.push(` Traits: ${c3.dim(traits.slice(0, 60))}`);
|
|
292991
293192
|
}
|
|
292992
293193
|
const cidFile = join70(idDir, "cids.json");
|
|
292993
|
-
if (
|
|
293194
|
+
if (existsSync55(cidFile)) {
|
|
292994
293195
|
const cids = JSON.parse(readFileSync42(cidFile, "utf8"));
|
|
292995
293196
|
const lastCid = Array.isArray(cids) ? cids[cids.length - 1] : cids.latest;
|
|
292996
293197
|
if (lastCid) lines.push(` Last CID: ${c3.dim(String(lastCid).slice(0, 50))}`);
|
|
@@ -293004,7 +293205,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
293004
293205
|
${c3.bold("Memory Sentiment")}`);
|
|
293005
293206
|
try {
|
|
293006
293207
|
const metaFile = join70(ctx3.repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
293007
|
-
if (
|
|
293208
|
+
if (existsSync55(metaFile)) {
|
|
293008
293209
|
const store2 = JSON.parse(readFileSync42(metaFile, "utf8"));
|
|
293009
293210
|
const active = store2.filter((m2) => m2.type !== "quarantine");
|
|
293010
293211
|
const recoveries = active.filter((m2) => m2.content?.startsWith("[recovery]")).length;
|
|
@@ -293024,7 +293225,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
293024
293225
|
}
|
|
293025
293226
|
try {
|
|
293026
293227
|
const dbPath = join70(ctx3.repoRoot, ".oa", "memory", "structured.db");
|
|
293027
|
-
if (
|
|
293228
|
+
if (existsSync55(dbPath)) {
|
|
293028
293229
|
const { initDb: initDb2, closeDb: cDb, ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
|
|
293029
293230
|
const db = initDb2(dbPath);
|
|
293030
293231
|
const memStore = new ProceduralMemoryStore2(db);
|
|
@@ -293046,7 +293247,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
293046
293247
|
${c3.bold("Storage Overview")}
|
|
293047
293248
|
`);
|
|
293048
293249
|
const oaDir = join70(ctx3.repoRoot, ".oa");
|
|
293049
|
-
if (!
|
|
293250
|
+
if (!existsSync55(oaDir)) {
|
|
293050
293251
|
lines.push(` ${c3.dim("No .oa/ directory found.")}`);
|
|
293051
293252
|
safeLog(lines.join("\n") + "\n");
|
|
293052
293253
|
return "handled";
|
|
@@ -293122,7 +293323,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
293122
293323
|
return "handled";
|
|
293123
293324
|
}
|
|
293124
293325
|
const resolvedPath = join70(ctx3.repoRoot, filePath);
|
|
293125
|
-
if (!
|
|
293326
|
+
if (!existsSync55(resolvedPath)) {
|
|
293126
293327
|
renderWarning(`File not found: ${resolvedPath}`);
|
|
293127
293328
|
return "handled";
|
|
293128
293329
|
}
|
|
@@ -293224,7 +293425,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
293224
293425
|
const fortemiSubCmd = (arg || "").trim().toLowerCase();
|
|
293225
293426
|
const fortemiDir = join70(ctx3.repoRoot, "..", "fortemi-react");
|
|
293226
293427
|
const altFortemiDir = join70(nodeOs.homedir(), "fortemi-react");
|
|
293227
|
-
const fDir =
|
|
293428
|
+
const fDir = existsSync55(fortemiDir) ? fortemiDir : existsSync55(altFortemiDir) ? altFortemiDir : null;
|
|
293228
293429
|
if (fortemiSubCmd === "start" || fortemiSubCmd === "") {
|
|
293229
293430
|
if (!fDir) {
|
|
293230
293431
|
renderWarning("fortemi-react not found adjacent or in home directory.");
|
|
@@ -293269,7 +293470,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
293269
293470
|
}
|
|
293270
293471
|
if (fortemiSubCmd === "status") {
|
|
293271
293472
|
const bridgeFile = join70(ctx3.repoRoot, ".oa", "fortemi-bridge.json");
|
|
293272
|
-
if (!
|
|
293473
|
+
if (!existsSync55(bridgeFile)) {
|
|
293273
293474
|
renderInfo("Fortemi bridge: not connected. Run /fortemi start");
|
|
293274
293475
|
return "handled";
|
|
293275
293476
|
}
|
|
@@ -293293,14 +293494,14 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
293293
293494
|
lines.push(` Process: ${alive ? c3.green("running") : c3.yellow("not running")} (PID ${bridge.pid})`);
|
|
293294
293495
|
lines.push(` HTTP: ${httpOk ? c3.green("connected") : c3.yellow("unreachable")}`);
|
|
293295
293496
|
lines.push(` Started: ${bridge.startedAt}`);
|
|
293296
|
-
lines.push(` JWT: ${
|
|
293497
|
+
lines.push(` JWT: ${existsSync55(bridge.jwtFile) ? c3.green("valid") : c3.yellow("missing")}`);
|
|
293297
293498
|
lines.push("");
|
|
293298
293499
|
safeLog(lines.join("\n"));
|
|
293299
293500
|
return "handled";
|
|
293300
293501
|
}
|
|
293301
293502
|
if (fortemiSubCmd === "stop") {
|
|
293302
293503
|
const bridgeFile = join70(ctx3.repoRoot, ".oa", "fortemi-bridge.json");
|
|
293303
|
-
if (
|
|
293504
|
+
if (existsSync55(bridgeFile)) {
|
|
293304
293505
|
const bridge = JSON.parse(readFileSync42(bridgeFile, "utf8"));
|
|
293305
293506
|
try {
|
|
293306
293507
|
process.kill(bridge.pid, "SIGTERM");
|
|
@@ -294220,8 +294421,8 @@ The session corrections MUST become hard rules in the SKILL.md Rules section.`;
|
|
|
294220
294421
|
if (!sponsorUrl && !sponsorPeerId) {
|
|
294221
294422
|
_spLog("FAILED \u2014 no tunnelUrl and no peerId");
|
|
294222
294423
|
_spLog(`nexusDir checked: ${join70(projectDir, ".oa", "nexus")}`);
|
|
294223
|
-
_spLog(`status.json exists: ${
|
|
294224
|
-
_spLog(`daemon.pid exists: ${
|
|
294424
|
+
_spLog(`status.json exists: ${existsSync55(join70(projectDir, ".oa", "nexus", "status.json"))}`);
|
|
294425
|
+
_spLog(`daemon.pid exists: ${existsSync55(join70(projectDir, ".oa", "nexus", "daemon.pid"))}`);
|
|
294225
294426
|
try {
|
|
294226
294427
|
const _statusRaw = readFileSync42(join70(projectDir, ".oa", "nexus", "status.json"), "utf8");
|
|
294227
294428
|
_spLog(`status.json content: ${_statusRaw.slice(0, 300)}`);
|
|
@@ -294248,7 +294449,7 @@ The session corrections MUST become hard rules in the SKILL.md Rules section.`;
|
|
|
294248
294449
|
try {
|
|
294249
294450
|
const { homedir: homedir27 } = __require("os");
|
|
294250
294451
|
const namePath = __require("path").join(homedir27(), ".open-agents", "agent-name");
|
|
294251
|
-
if (
|
|
294452
|
+
if (existsSync55(namePath)) sponsorName = readFileSync42(namePath, "utf8").trim();
|
|
294252
294453
|
} catch {
|
|
294253
294454
|
}
|
|
294254
294455
|
if (!sponsorName) sponsorName = "OA Sponsor";
|
|
@@ -294324,7 +294525,7 @@ The session corrections MUST become hard rules in the SKILL.md Rules section.`;
|
|
|
294324
294525
|
renderInfo("Sponsor wizard completed.");
|
|
294325
294526
|
try {
|
|
294326
294527
|
const nexusPidFile = join70(projectDir, ".oa", "nexus", "daemon.pid");
|
|
294327
|
-
if (
|
|
294528
|
+
if (existsSync55(nexusPidFile)) {
|
|
294328
294529
|
const nPid = parseInt(readFileSync42(nexusPidFile, "utf8").trim(), 10);
|
|
294329
294530
|
if (nPid > 0) {
|
|
294330
294531
|
registry2.register({ name: "Nexus", pid: nPid, startedAt: Date.now(), status: "running" });
|
|
@@ -295390,7 +295591,7 @@ async function showCohereDashboard(ctx3) {
|
|
|
295390
295591
|
await ik.execute({ operation: "hydrate" });
|
|
295391
295592
|
} else if (idResult.key === "history") {
|
|
295392
295593
|
const snapDir = join70(ctx3.repoRoot, ".oa", "identity", "snapshots");
|
|
295393
|
-
if (
|
|
295594
|
+
if (existsSync55(snapDir)) {
|
|
295394
295595
|
const snaps = readdirSync14(snapDir).filter((f2) => f2.endsWith(".json")).sort().reverse();
|
|
295395
295596
|
const snapItems = snaps.slice(0, 20).map((f2) => ({
|
|
295396
295597
|
key: f2,
|
|
@@ -296401,7 +296602,7 @@ async function handleSponsoredEndpoint(ctx3, local) {
|
|
|
296401
296602
|
const sponsorDir2 = join70(ctx3.repoRoot ?? process.cwd(), ".oa", "sponsor");
|
|
296402
296603
|
const knownFile = join70(sponsorDir2, "known-sponsors.json");
|
|
296403
296604
|
try {
|
|
296404
|
-
if (
|
|
296605
|
+
if (existsSync55(knownFile)) {
|
|
296405
296606
|
const saved = JSON.parse(readFileSync42(knownFile, "utf8"));
|
|
296406
296607
|
for (const s2 of saved) {
|
|
296407
296608
|
if (!sponsors.some((sp) => sp.url === s2.url)) {
|
|
@@ -296553,7 +296754,7 @@ async function handleSponsoredEndpoint(ctx3, local) {
|
|
|
296553
296754
|
const saveKey = selected.url || selected.peerId || selected.name;
|
|
296554
296755
|
try {
|
|
296555
296756
|
mkdirSync26(sponsorDir2, { recursive: true });
|
|
296556
|
-
const existing =
|
|
296757
|
+
const existing = existsSync55(knownFile) ? JSON.parse(readFileSync42(knownFile, "utf8")) : [];
|
|
296557
296758
|
const updated = existing.filter((s2) => (s2.url || s2.peerId || s2.name) !== saveKey);
|
|
296558
296759
|
updated.push(selected);
|
|
296559
296760
|
writeFileSync26(knownFile, JSON.stringify(updated, null, 2), "utf8");
|
|
@@ -296677,7 +296878,7 @@ async function handlePeerEndpoint(peerId, authKey, ctx3, local) {
|
|
|
296677
296878
|
}
|
|
296678
296879
|
}
|
|
296679
296880
|
async function handleParallel(arg, ctx3) {
|
|
296680
|
-
const { execSync:
|
|
296881
|
+
const { execSync: execSync51 } = await import("node:child_process");
|
|
296681
296882
|
const baseUrl = ctx3.config.backendUrl || "http://localhost:11434";
|
|
296682
296883
|
const isRemote = ctx3.config.backendType === "nexus";
|
|
296683
296884
|
if (isRemote) {
|
|
@@ -296701,7 +296902,7 @@ async function handleParallel(arg, ctx3) {
|
|
|
296701
296902
|
}
|
|
296702
296903
|
let systemdVal = "";
|
|
296703
296904
|
try {
|
|
296704
|
-
const out =
|
|
296905
|
+
const out = execSync51("systemctl show ollama.service -p Environment 2>/dev/null || true", { encoding: "utf8" });
|
|
296705
296906
|
const match = out.match(/OLLAMA_NUM_PARALLEL=(\d+)/);
|
|
296706
296907
|
if (match) systemdVal = match[1];
|
|
296707
296908
|
} catch {
|
|
@@ -296729,7 +296930,7 @@ async function handleParallel(arg, ctx3) {
|
|
|
296729
296930
|
}
|
|
296730
296931
|
const isSystemd = (() => {
|
|
296731
296932
|
try {
|
|
296732
|
-
const out =
|
|
296933
|
+
const out = execSync51("systemctl is-active ollama.service 2>/dev/null", { encoding: "utf8" }).trim();
|
|
296733
296934
|
return out === "active" || out === "inactive";
|
|
296734
296935
|
} catch {
|
|
296735
296936
|
return false;
|
|
@@ -296743,10 +296944,10 @@ async function handleParallel(arg, ctx3) {
|
|
|
296743
296944
|
const overrideContent = `[Service]
|
|
296744
296945
|
Environment="OLLAMA_NUM_PARALLEL=${n2}"
|
|
296745
296946
|
`;
|
|
296746
|
-
|
|
296747
|
-
|
|
296748
|
-
|
|
296749
|
-
|
|
296947
|
+
execSync51(`sudo mkdir -p ${overrideDir}`, { stdio: "pipe" });
|
|
296948
|
+
execSync51(`echo '${overrideContent}' | sudo tee ${overrideFile} > /dev/null`, { stdio: "pipe" });
|
|
296949
|
+
execSync51("sudo systemctl daemon-reload", { stdio: "pipe" });
|
|
296950
|
+
execSync51("sudo systemctl restart ollama.service", { stdio: "pipe" });
|
|
296750
296951
|
let ready = false;
|
|
296751
296952
|
for (let i2 = 0; i2 < 30 && !ready; i2++) {
|
|
296752
296953
|
await new Promise((r2) => setTimeout(r2, 500));
|
|
@@ -296772,7 +296973,7 @@ Environment="OLLAMA_NUM_PARALLEL=${n2}"
|
|
|
296772
296973
|
renderInfo(`Setting OLLAMA_NUM_PARALLEL=${n2}...`);
|
|
296773
296974
|
try {
|
|
296774
296975
|
try {
|
|
296775
|
-
|
|
296976
|
+
execSync51("pkill -f 'ollama serve' 2>/dev/null || true", { stdio: "pipe" });
|
|
296776
296977
|
} catch {
|
|
296777
296978
|
}
|
|
296778
296979
|
await new Promise((r2) => setTimeout(r2, 1e3));
|
|
@@ -296825,7 +297026,7 @@ async function handleUpdate(subcommand, ctx3) {
|
|
|
296825
297026
|
const { createRequire: createRequire7 } = await import("node:module");
|
|
296826
297027
|
const { fileURLToPath: fileURLToPath19 } = await import("node:url");
|
|
296827
297028
|
const { dirname: dirname28, join: join92 } = await import("node:path");
|
|
296828
|
-
const { existsSync:
|
|
297029
|
+
const { existsSync: existsSync73 } = await import("node:fs");
|
|
296829
297030
|
const req2 = createRequire7(import.meta.url);
|
|
296830
297031
|
const thisDir = dirname28(fileURLToPath19(import.meta.url));
|
|
296831
297032
|
const candidates = [
|
|
@@ -296834,7 +297035,7 @@ async function handleUpdate(subcommand, ctx3) {
|
|
|
296834
297035
|
join92(thisDir, "..", "..", "..", "package.json")
|
|
296835
297036
|
];
|
|
296836
297037
|
for (const pkgPath of candidates) {
|
|
296837
|
-
if (
|
|
297038
|
+
if (existsSync73(pkgPath)) {
|
|
296838
297039
|
const pkg = req2(pkgPath);
|
|
296839
297040
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
|
|
296840
297041
|
currentVersion = pkg.version ?? "0.0.0";
|
|
@@ -297824,18 +298025,18 @@ async function showExposeDashboard(gateway, rl, ctx3) {
|
|
|
297824
298025
|
const cmd = `/endpoint ${id} --auth ${gateway.authKey ?? ""}`;
|
|
297825
298026
|
let copied = false;
|
|
297826
298027
|
try {
|
|
297827
|
-
const { execSync:
|
|
298028
|
+
const { execSync: execSync51 } = __require("node:child_process");
|
|
297828
298029
|
const platform6 = process.platform;
|
|
297829
298030
|
if (platform6 === "darwin") {
|
|
297830
|
-
|
|
298031
|
+
execSync51("pbcopy", { input: cmd, timeout: 3e3 });
|
|
297831
298032
|
copied = true;
|
|
297832
298033
|
} else if (platform6 === "win32") {
|
|
297833
|
-
|
|
298034
|
+
execSync51("clip", { input: cmd, timeout: 3e3 });
|
|
297834
298035
|
copied = true;
|
|
297835
298036
|
} else {
|
|
297836
298037
|
for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
|
|
297837
298038
|
try {
|
|
297838
|
-
|
|
298039
|
+
execSync51(tool, { input: cmd, timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] });
|
|
297839
298040
|
copied = true;
|
|
297840
298041
|
break;
|
|
297841
298042
|
} catch {
|
|
@@ -297928,9 +298129,9 @@ var init_commands = __esm({
|
|
|
297928
298129
|
});
|
|
297929
298130
|
|
|
297930
298131
|
// packages/cli/src/tui/project-context.ts
|
|
297931
|
-
import { existsSync as
|
|
298132
|
+
import { existsSync as existsSync56, readFileSync as readFileSync43, readdirSync as readdirSync15 } from "node:fs";
|
|
297932
298133
|
import { join as join71, basename as basename13 } from "node:path";
|
|
297933
|
-
import { execSync as
|
|
298134
|
+
import { execSync as execSync46 } from "node:child_process";
|
|
297934
298135
|
import { homedir as homedir22, platform as platform5, release } from "node:os";
|
|
297935
298136
|
function getModelTier(modelName) {
|
|
297936
298137
|
const m2 = modelName.toLowerCase();
|
|
@@ -297961,7 +298162,7 @@ function loadProjectMap(repoRoot) {
|
|
|
297961
298162
|
initOaDirectory(repoRoot);
|
|
297962
298163
|
}
|
|
297963
298164
|
const mapPath2 = join71(repoRoot, OA_DIR, "context", "project-map.md");
|
|
297964
|
-
if (
|
|
298165
|
+
if (existsSync56(mapPath2)) {
|
|
297965
298166
|
try {
|
|
297966
298167
|
const content = readFileSync43(mapPath2, "utf-8");
|
|
297967
298168
|
return content;
|
|
@@ -297972,18 +298173,18 @@ function loadProjectMap(repoRoot) {
|
|
|
297972
298173
|
}
|
|
297973
298174
|
function getGitInfo(repoRoot) {
|
|
297974
298175
|
try {
|
|
297975
|
-
|
|
298176
|
+
execSync46("git rev-parse --is-inside-work-tree", { cwd: repoRoot, stdio: "pipe" });
|
|
297976
298177
|
} catch {
|
|
297977
298178
|
return "";
|
|
297978
298179
|
}
|
|
297979
298180
|
const lines = [];
|
|
297980
298181
|
try {
|
|
297981
|
-
const branch =
|
|
298182
|
+
const branch = execSync46("git branch --show-current", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
297982
298183
|
if (branch) lines.push(`Branch: ${branch}`);
|
|
297983
298184
|
} catch {
|
|
297984
298185
|
}
|
|
297985
298186
|
try {
|
|
297986
|
-
const status =
|
|
298187
|
+
const status = execSync46("git status --porcelain", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
297987
298188
|
if (status) {
|
|
297988
298189
|
const changed = status.split("\n").length;
|
|
297989
298190
|
lines.push(`Working tree: ${changed} changed file(s)`);
|
|
@@ -297993,7 +298194,7 @@ function getGitInfo(repoRoot) {
|
|
|
297993
298194
|
} catch {
|
|
297994
298195
|
}
|
|
297995
298196
|
try {
|
|
297996
|
-
const log22 =
|
|
298197
|
+
const log22 = execSync46("git log --oneline -5 --no-decorate", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
297997
298198
|
if (log22) lines.push(`Recent commits:
|
|
297998
298199
|
${log22}`);
|
|
297999
298200
|
} catch {
|
|
@@ -298006,7 +298207,7 @@ function loadMemoryContext(repoRoot) {
|
|
|
298006
298207
|
const oaEntries = loadMemoryDir(oaMemDir, "project");
|
|
298007
298208
|
if (oaEntries) sections.push(oaEntries);
|
|
298008
298209
|
const legacyMemDir = join71(repoRoot, ".open-agents", "memory");
|
|
298009
|
-
if (legacyMemDir !== oaMemDir &&
|
|
298210
|
+
if (legacyMemDir !== oaMemDir && existsSync56(legacyMemDir)) {
|
|
298010
298211
|
const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
|
|
298011
298212
|
if (legacyEntries) sections.push(legacyEntries);
|
|
298012
298213
|
}
|
|
@@ -298016,7 +298217,7 @@ function loadMemoryContext(repoRoot) {
|
|
|
298016
298217
|
return sections.join("\n\n");
|
|
298017
298218
|
}
|
|
298018
298219
|
function loadMemoryDir(memDir, scope) {
|
|
298019
|
-
if (!
|
|
298220
|
+
if (!existsSync56(memDir)) return "";
|
|
298020
298221
|
const lines = [];
|
|
298021
298222
|
try {
|
|
298022
298223
|
const files = readdirSync15(memDir).filter((f2) => f2.endsWith(".json"));
|
|
@@ -299157,7 +299358,7 @@ __export(banner_exports, {
|
|
|
299157
299358
|
saveBannerDesign: () => saveBannerDesign,
|
|
299158
299359
|
setGridText: () => setGridText
|
|
299159
299360
|
});
|
|
299160
|
-
import { existsSync as
|
|
299361
|
+
import { existsSync as existsSync57, readFileSync as readFileSync44, writeFileSync as writeFileSync27, mkdirSync as mkdirSync27 } from "node:fs";
|
|
299161
299362
|
import { join as join72 } from "node:path";
|
|
299162
299363
|
function generateMnemonic(seed) {
|
|
299163
299364
|
let h = 2166136261;
|
|
@@ -299294,7 +299495,7 @@ function saveBannerDesign(workDir, design) {
|
|
|
299294
299495
|
}
|
|
299295
299496
|
function loadBannerDesign(workDir, id) {
|
|
299296
299497
|
const file = join72(workDir, ".oa", "banners", `${id}.json`);
|
|
299297
|
-
if (!
|
|
299498
|
+
if (!existsSync57(file)) return null;
|
|
299298
299499
|
try {
|
|
299299
299500
|
return JSON.parse(readFileSync44(file, "utf8"));
|
|
299300
299501
|
} catch {
|
|
@@ -299303,7 +299504,7 @@ function loadBannerDesign(workDir, id) {
|
|
|
299303
299504
|
}
|
|
299304
299505
|
function listBannerDesigns(workDir) {
|
|
299305
299506
|
const dir = join72(workDir, ".oa", "banners");
|
|
299306
|
-
if (!
|
|
299507
|
+
if (!existsSync57(dir)) return [];
|
|
299307
299508
|
try {
|
|
299308
299509
|
const { readdirSync: readdirSync26 } = __require("node:fs");
|
|
299309
299510
|
return readdirSync26(dir).filter((f2) => f2.endsWith(".json")).map((f2) => f2.replace(".json", ""));
|
|
@@ -299610,12 +299811,12 @@ var init_banner = __esm({
|
|
|
299610
299811
|
});
|
|
299611
299812
|
|
|
299612
299813
|
// packages/cli/src/tui/carousel-descriptors.ts
|
|
299613
|
-
import { existsSync as
|
|
299814
|
+
import { existsSync as existsSync58, readFileSync as readFileSync45, writeFileSync as writeFileSync28, mkdirSync as mkdirSync28, readdirSync as readdirSync16 } from "node:fs";
|
|
299614
299815
|
import { join as join73, basename as basename14 } from "node:path";
|
|
299615
299816
|
function loadToolProfile(repoRoot) {
|
|
299616
299817
|
const filePath = join73(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
|
|
299617
299818
|
try {
|
|
299618
|
-
if (!
|
|
299819
|
+
if (!existsSync58(filePath)) return null;
|
|
299619
299820
|
return JSON.parse(readFileSync45(filePath, "utf-8"));
|
|
299620
299821
|
} catch {
|
|
299621
299822
|
return null;
|
|
@@ -299681,7 +299882,7 @@ function weightedColor(profile) {
|
|
|
299681
299882
|
function loadCachedDescriptors(repoRoot) {
|
|
299682
299883
|
const filePath = join73(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
|
|
299683
299884
|
try {
|
|
299684
|
-
if (!
|
|
299885
|
+
if (!existsSync58(filePath)) return null;
|
|
299685
299886
|
const cached = JSON.parse(readFileSync45(filePath, "utf-8"));
|
|
299686
299887
|
return cached.phrases.length > 0 ? cached.phrases : null;
|
|
299687
299888
|
} catch {
|
|
@@ -299745,7 +299946,7 @@ function generateDescriptors(repoRoot) {
|
|
|
299745
299946
|
function extractFromPackageJson(repoRoot, tags) {
|
|
299746
299947
|
const pkgPath = join73(repoRoot, "package.json");
|
|
299747
299948
|
try {
|
|
299748
|
-
if (!
|
|
299949
|
+
if (!existsSync58(pkgPath)) return;
|
|
299749
299950
|
const pkg = JSON.parse(readFileSync45(pkgPath, "utf-8"));
|
|
299750
299951
|
if (pkg.name && typeof pkg.name === "string") {
|
|
299751
299952
|
const parts = pkg.name.replace(/^@/, "").split("/");
|
|
@@ -299787,7 +299988,7 @@ function extractFromManifests(repoRoot, tags) {
|
|
|
299787
299988
|
{ file: ".github/workflows", tag: "ci/cd" }
|
|
299788
299989
|
];
|
|
299789
299990
|
for (const check of manifestChecks) {
|
|
299790
|
-
if (
|
|
299991
|
+
if (existsSync58(join73(repoRoot, check.file))) {
|
|
299791
299992
|
tags.push(check.tag);
|
|
299792
299993
|
}
|
|
299793
299994
|
}
|
|
@@ -299811,7 +300012,7 @@ function extractFromSessions(repoRoot, tags) {
|
|
|
299811
300012
|
function extractFromMemory(repoRoot, tags) {
|
|
299812
300013
|
const memoryDir = join73(repoRoot, OA_DIR, "memory");
|
|
299813
300014
|
try {
|
|
299814
|
-
if (!
|
|
300015
|
+
if (!existsSync58(memoryDir)) return;
|
|
299815
300016
|
const files = readdirSync16(memoryDir).filter((f2) => f2.endsWith(".json"));
|
|
299816
300017
|
for (const file of files) {
|
|
299817
300018
|
const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
|
|
@@ -300625,14 +300826,14 @@ var init_edit_history = __esm({
|
|
|
300625
300826
|
});
|
|
300626
300827
|
|
|
300627
300828
|
// packages/cli/src/tui/promptLoader.ts
|
|
300628
|
-
import { readFileSync as readFileSync46, existsSync as
|
|
300829
|
+
import { readFileSync as readFileSync46, existsSync as existsSync59 } from "node:fs";
|
|
300629
300830
|
import { join as join75, dirname as dirname23 } from "node:path";
|
|
300630
300831
|
import { fileURLToPath as fileURLToPath14 } from "node:url";
|
|
300631
300832
|
function loadPrompt3(promptPath, vars) {
|
|
300632
300833
|
let content = cache6.get(promptPath);
|
|
300633
300834
|
if (content === void 0) {
|
|
300634
300835
|
const fullPath = join75(PROMPTS_DIR3, promptPath);
|
|
300635
|
-
if (!
|
|
300836
|
+
if (!existsSync59(fullPath)) {
|
|
300636
300837
|
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
300637
300838
|
}
|
|
300638
300839
|
content = readFileSync46(fullPath, "utf-8");
|
|
@@ -300649,15 +300850,15 @@ var init_promptLoader3 = __esm({
|
|
|
300649
300850
|
__dirname7 = dirname23(__filename5);
|
|
300650
300851
|
devPath2 = join75(__dirname7, "..", "..", "prompts");
|
|
300651
300852
|
publishedPath2 = join75(__dirname7, "..", "prompts");
|
|
300652
|
-
PROMPTS_DIR3 =
|
|
300853
|
+
PROMPTS_DIR3 = existsSync59(devPath2) ? devPath2 : publishedPath2;
|
|
300653
300854
|
cache6 = /* @__PURE__ */ new Map();
|
|
300654
300855
|
}
|
|
300655
300856
|
});
|
|
300656
300857
|
|
|
300657
300858
|
// packages/cli/src/tui/dream-engine.ts
|
|
300658
|
-
import { mkdirSync as mkdirSync30, writeFileSync as writeFileSync29, readFileSync as readFileSync47, existsSync as
|
|
300859
|
+
import { mkdirSync as mkdirSync30, writeFileSync as writeFileSync29, readFileSync as readFileSync47, existsSync as existsSync60, readdirSync as readdirSync17 } from "node:fs";
|
|
300659
300860
|
import { join as join76, basename as basename15 } from "node:path";
|
|
300660
|
-
import { execSync as
|
|
300861
|
+
import { execSync as execSync47 } from "node:child_process";
|
|
300661
300862
|
function setDreamWriteContent(fn) {
|
|
300662
300863
|
_dreamWriteContent = fn;
|
|
300663
300864
|
}
|
|
@@ -300670,7 +300871,7 @@ function dreamWrite(fn) {
|
|
|
300670
300871
|
}
|
|
300671
300872
|
function loadAutoresearchMemory(repoRoot) {
|
|
300672
300873
|
const memoryPath = join76(repoRoot, ".oa", "memory", "autoresearch.json");
|
|
300673
|
-
if (!
|
|
300874
|
+
if (!existsSync60(memoryPath)) return "";
|
|
300674
300875
|
try {
|
|
300675
300876
|
const raw = readFileSync47(memoryPath, "utf-8");
|
|
300676
300877
|
const data = JSON.parse(raw);
|
|
@@ -300907,7 +301108,7 @@ var init_dream_engine = __esm({
|
|
|
300907
301108
|
return { success: false, output: "", error: "Autoresearch mode: edits are confined to .oa/autoresearch/", durationMs: Date.now() - start2 };
|
|
300908
301109
|
}
|
|
300909
301110
|
try {
|
|
300910
|
-
if (!
|
|
301111
|
+
if (!existsSync60(targetPath)) {
|
|
300911
301112
|
return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start2 };
|
|
300912
301113
|
}
|
|
300913
301114
|
let content = readFileSync47(targetPath, "utf-8");
|
|
@@ -300993,7 +301194,7 @@ var init_dream_engine = __esm({
|
|
|
300993
301194
|
return { success: false, output: "", error: "Dream mode: edits are confined to .oa/dreams/", durationMs: Date.now() - start2 };
|
|
300994
301195
|
}
|
|
300995
301196
|
try {
|
|
300996
|
-
if (!
|
|
301197
|
+
if (!existsSync60(targetPath)) {
|
|
300997
301198
|
return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start2 };
|
|
300998
301199
|
}
|
|
300999
301200
|
let content = readFileSync47(targetPath, "utf-8");
|
|
@@ -301031,7 +301232,7 @@ var init_dream_engine = __esm({
|
|
|
301031
301232
|
}
|
|
301032
301233
|
}
|
|
301033
301234
|
try {
|
|
301034
|
-
const output =
|
|
301235
|
+
const output = execSync47(cmd, {
|
|
301035
301236
|
cwd: this.repoRoot,
|
|
301036
301237
|
timeout: 3e4,
|
|
301037
301238
|
encoding: "utf-8",
|
|
@@ -301890,17 +302091,17 @@ ${summaryResult}
|
|
|
301890
302091
|
try {
|
|
301891
302092
|
mkdirSync30(checkpointDir, { recursive: true });
|
|
301892
302093
|
try {
|
|
301893
|
-
const gitStatus =
|
|
302094
|
+
const gitStatus = execSync47("git status --porcelain", {
|
|
301894
302095
|
cwd: this.repoRoot,
|
|
301895
302096
|
encoding: "utf-8",
|
|
301896
302097
|
timeout: 1e4
|
|
301897
302098
|
});
|
|
301898
|
-
const gitDiff =
|
|
302099
|
+
const gitDiff = execSync47("git diff", {
|
|
301899
302100
|
cwd: this.repoRoot,
|
|
301900
302101
|
encoding: "utf-8",
|
|
301901
302102
|
timeout: 1e4
|
|
301902
302103
|
});
|
|
301903
|
-
const gitHash =
|
|
302104
|
+
const gitHash = execSync47("git rev-parse HEAD 2>/dev/null || echo 'no-git'", {
|
|
301904
302105
|
cwd: this.repoRoot,
|
|
301905
302106
|
encoding: "utf-8",
|
|
301906
302107
|
timeout: 5e3
|
|
@@ -302457,7 +302658,7 @@ var init_bless_engine = __esm({
|
|
|
302457
302658
|
});
|
|
302458
302659
|
|
|
302459
302660
|
// packages/cli/src/tui/dmn-engine.ts
|
|
302460
|
-
import { existsSync as
|
|
302661
|
+
import { existsSync as existsSync61, readFileSync as readFileSync48, writeFileSync as writeFileSync30, mkdirSync as mkdirSync31, readdirSync as readdirSync18, unlinkSync as unlinkSync15 } from "node:fs";
|
|
302461
302662
|
import { join as join77, basename as basename16 } from "node:path";
|
|
302462
302663
|
function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
|
|
302463
302664
|
const competenceReport = competence.length > 0 ? competence.map((c7) => {
|
|
@@ -303200,7 +303401,7 @@ OUTPUT: Call task_complete with JSON:
|
|
|
303200
303401
|
join77(this.repoRoot, ".open-agents", "memory")
|
|
303201
303402
|
];
|
|
303202
303403
|
for (const dir of dirs) {
|
|
303203
|
-
if (!
|
|
303404
|
+
if (!existsSync61(dir)) continue;
|
|
303204
303405
|
try {
|
|
303205
303406
|
const files = readdirSync18(dir).filter((f2) => f2.endsWith(".json"));
|
|
303206
303407
|
for (const f2 of files) {
|
|
@@ -303215,7 +303416,7 @@ OUTPUT: Call task_complete with JSON:
|
|
|
303215
303416
|
// ── State persistence ─────────────────────────────────────────────────
|
|
303216
303417
|
loadState() {
|
|
303217
303418
|
const path5 = join77(this.stateDir, "state.json");
|
|
303218
|
-
if (
|
|
303419
|
+
if (existsSync61(path5)) {
|
|
303219
303420
|
try {
|
|
303220
303421
|
this.state = JSON.parse(readFileSync48(path5, "utf-8"));
|
|
303221
303422
|
} catch {
|
|
@@ -303257,7 +303458,7 @@ OUTPUT: Call task_complete with JSON:
|
|
|
303257
303458
|
});
|
|
303258
303459
|
|
|
303259
303460
|
// packages/cli/src/tui/snr-engine.ts
|
|
303260
|
-
import { existsSync as
|
|
303461
|
+
import { existsSync as existsSync62, readdirSync as readdirSync19, readFileSync as readFileSync49 } from "node:fs";
|
|
303261
303462
|
import { join as join78, basename as basename17 } from "node:path";
|
|
303262
303463
|
function computeDPrime(signalScores, noiseScores) {
|
|
303263
303464
|
if (signalScores.length === 0 || noiseScores.length === 0) return 0;
|
|
@@ -303546,7 +303747,7 @@ Call task_complete with the JSON array when done.`,
|
|
|
303546
303747
|
join78(this.repoRoot, ".open-agents", "memory")
|
|
303547
303748
|
];
|
|
303548
303749
|
for (const dir of dirs) {
|
|
303549
|
-
if (!
|
|
303750
|
+
if (!existsSync62(dir)) continue;
|
|
303550
303751
|
try {
|
|
303551
303752
|
const files = readdirSync19(dir).filter((f2) => f2.endsWith(".json"));
|
|
303552
303753
|
for (const f2 of files) {
|
|
@@ -305769,7 +305970,7 @@ var init_direct_input = __esm({
|
|
|
305769
305970
|
});
|
|
305770
305971
|
|
|
305771
305972
|
// packages/cli/src/api/audit-log.ts
|
|
305772
|
-
import { mkdirSync as mkdirSync33, appendFileSync as appendFileSync5, readFileSync as readFileSync50, existsSync as
|
|
305973
|
+
import { mkdirSync as mkdirSync33, appendFileSync as appendFileSync5, readFileSync as readFileSync50, existsSync as existsSync64 } from "node:fs";
|
|
305773
305974
|
import { join as join80 } from "node:path";
|
|
305774
305975
|
function initAuditLog(oaDir) {
|
|
305775
305976
|
auditDir = join80(oaDir, "audit");
|
|
@@ -305789,7 +305990,7 @@ function recordAudit(record) {
|
|
|
305789
305990
|
}
|
|
305790
305991
|
}
|
|
305791
305992
|
function queryAudit(opts) {
|
|
305792
|
-
if (!initialized || !
|
|
305993
|
+
if (!initialized || !existsSync64(auditFile)) return [];
|
|
305793
305994
|
try {
|
|
305794
305995
|
const raw = readFileSync50(auditFile, "utf-8");
|
|
305795
305996
|
const lines = raw.split("\n").filter(Boolean);
|
|
@@ -307111,7 +307312,7 @@ var init_auth_oidc = __esm({
|
|
|
307111
307312
|
|
|
307112
307313
|
// packages/cli/src/api/chat-session.ts
|
|
307113
307314
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
307114
|
-
import { existsSync as
|
|
307315
|
+
import { existsSync as existsSync65, readFileSync as readFileSync51, readdirSync as readdirSync21 } from "node:fs";
|
|
307115
307316
|
import { join as join81 } from "node:path";
|
|
307116
307317
|
function buildSystemPrompt(cwd4) {
|
|
307117
307318
|
const parts = [];
|
|
@@ -307120,7 +307321,7 @@ function buildSystemPrompt(cwd4) {
|
|
|
307120
307321
|
);
|
|
307121
307322
|
parts.push(`\\nEnvironment: ${process.platform}, Node ${process.version}, CWD: ${cwd4}`);
|
|
307122
307323
|
const diaryPath = join81(cwd4, ".oa", "context", "session-diary.md");
|
|
307123
|
-
if (
|
|
307324
|
+
if (existsSync65(diaryPath)) {
|
|
307124
307325
|
try {
|
|
307125
307326
|
const diary = readFileSync51(diaryPath, "utf-8").slice(0, 1e3);
|
|
307126
307327
|
parts.push(`\\nPrevious session history:\\n${diary}`);
|
|
@@ -307128,7 +307329,7 @@ function buildSystemPrompt(cwd4) {
|
|
|
307128
307329
|
}
|
|
307129
307330
|
}
|
|
307130
307331
|
const memDir = join81(cwd4, ".oa", "memory");
|
|
307131
|
-
if (
|
|
307332
|
+
if (existsSync65(memDir)) {
|
|
307132
307333
|
try {
|
|
307133
307334
|
const files = readdirSync21(memDir).filter((f2) => f2.endsWith(".json")).slice(0, 5);
|
|
307134
307335
|
if (files.length > 0) {
|
|
@@ -307149,7 +307350,7 @@ function buildSystemPrompt(cwd4) {
|
|
|
307149
307350
|
}
|
|
307150
307351
|
for (const name10 of ["AGENTS.md", "OA.md", ".open-agents.md"]) {
|
|
307151
307352
|
const p2 = join81(cwd4, name10);
|
|
307152
|
-
if (
|
|
307353
|
+
if (existsSync65(p2)) {
|
|
307153
307354
|
try {
|
|
307154
307355
|
const content = readFileSync51(p2, "utf-8").slice(0, 500);
|
|
307155
307356
|
parts.push(`\\nProject instructions (${name10}):\\n${content}`);
|
|
@@ -307227,14 +307428,14 @@ var init_chat_session = __esm({
|
|
|
307227
307428
|
});
|
|
307228
307429
|
|
|
307229
307430
|
// packages/cli/src/api/usage-tracker.ts
|
|
307230
|
-
import { mkdirSync as mkdirSync34, readFileSync as readFileSync52, writeFileSync as writeFileSync31, existsSync as
|
|
307431
|
+
import { mkdirSync as mkdirSync34, readFileSync as readFileSync52, writeFileSync as writeFileSync31, existsSync as existsSync66 } from "node:fs";
|
|
307231
307432
|
import { join as join82 } from "node:path";
|
|
307232
307433
|
function initUsageTracker(oaDir) {
|
|
307233
307434
|
const dir = join82(oaDir, "usage");
|
|
307234
307435
|
mkdirSync34(dir, { recursive: true });
|
|
307235
307436
|
usageFile = join82(dir, "token-usage.json");
|
|
307236
307437
|
try {
|
|
307237
|
-
if (
|
|
307438
|
+
if (existsSync66(usageFile)) {
|
|
307238
307439
|
store = JSON.parse(readFileSync52(usageFile, "utf-8"));
|
|
307239
307440
|
}
|
|
307240
307441
|
} catch {
|
|
@@ -307299,7 +307500,7 @@ var init_usage_tracker = __esm({
|
|
|
307299
307500
|
});
|
|
307300
307501
|
|
|
307301
307502
|
// packages/cli/src/api/profiles.ts
|
|
307302
|
-
import { existsSync as
|
|
307503
|
+
import { existsSync as existsSync67, readFileSync as readFileSync53, writeFileSync as writeFileSync32, mkdirSync as mkdirSync35, readdirSync as readdirSync22, unlinkSync as unlinkSync17 } from "node:fs";
|
|
307303
307504
|
import { join as join83 } from "node:path";
|
|
307304
307505
|
import { homedir as homedir23 } from "node:os";
|
|
307305
307506
|
import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, randomBytes as randomBytes18, scryptSync as scryptSync3 } from "node:crypto";
|
|
@@ -307313,7 +307514,7 @@ function listProfiles(projectDir) {
|
|
|
307313
307514
|
const result = [];
|
|
307314
307515
|
const seen = /* @__PURE__ */ new Set();
|
|
307315
307516
|
const projDir = projectProfileDir(projectDir);
|
|
307316
|
-
if (
|
|
307517
|
+
if (existsSync67(projDir)) {
|
|
307317
307518
|
for (const f2 of readdirSync22(projDir).filter((f3) => f3.endsWith(".json"))) {
|
|
307318
307519
|
try {
|
|
307319
307520
|
const raw = JSON.parse(readFileSync53(join83(projDir, f2), "utf8"));
|
|
@@ -307330,7 +307531,7 @@ function listProfiles(projectDir) {
|
|
|
307330
307531
|
}
|
|
307331
307532
|
}
|
|
307332
307533
|
const globDir = globalProfileDir();
|
|
307333
|
-
if (
|
|
307534
|
+
if (existsSync67(globDir)) {
|
|
307334
307535
|
for (const f2 of readdirSync22(globDir).filter((f3) => f3.endsWith(".json"))) {
|
|
307335
307536
|
const name10 = f2.replace(".json", "");
|
|
307336
307537
|
if (seen.has(name10)) continue;
|
|
@@ -307352,7 +307553,7 @@ function loadProfile(name10, password, projectDir) {
|
|
|
307352
307553
|
const sanitized = name10.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
307353
307554
|
const projPath = join83(projectProfileDir(projectDir), `${sanitized}.json`);
|
|
307354
307555
|
const globPath = join83(globalProfileDir(), `${sanitized}.json`);
|
|
307355
|
-
const filePath =
|
|
307556
|
+
const filePath = existsSync67(projPath) ? projPath : existsSync67(globPath) ? globPath : null;
|
|
307356
307557
|
if (!filePath) return null;
|
|
307357
307558
|
const raw = JSON.parse(readFileSync53(filePath, "utf8"));
|
|
307358
307559
|
if (raw.encrypted === true) {
|
|
@@ -307379,7 +307580,7 @@ function deleteProfile(name10, scope = "global", projectDir) {
|
|
|
307379
307580
|
const sanitized = name10.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
307380
307581
|
const dir = scope === "project" ? projectProfileDir(projectDir) : globalProfileDir();
|
|
307381
307582
|
const filePath = join83(dir, `${sanitized}.json`);
|
|
307382
|
-
if (
|
|
307583
|
+
if (existsSync67(filePath)) {
|
|
307383
307584
|
unlinkSync17(filePath);
|
|
307384
307585
|
return true;
|
|
307385
307586
|
}
|
|
@@ -307493,8 +307694,8 @@ var init_profiles = __esm({
|
|
|
307493
307694
|
});
|
|
307494
307695
|
|
|
307495
307696
|
// packages/cli/src/docker.ts
|
|
307496
|
-
import { execSync as
|
|
307497
|
-
import { existsSync as
|
|
307697
|
+
import { execSync as execSync48, spawn as spawn23 } from "node:child_process";
|
|
307698
|
+
import { existsSync as existsSync68, mkdirSync as mkdirSync36, writeFileSync as writeFileSync33 } from "node:fs";
|
|
307498
307699
|
import { join as join84, resolve as resolve33, dirname as dirname24 } from "node:path";
|
|
307499
307700
|
import { homedir as homedir24 } from "node:os";
|
|
307500
307701
|
import { fileURLToPath as fileURLToPath15 } from "node:url";
|
|
@@ -307514,7 +307715,7 @@ function getDockerDir() {
|
|
|
307514
307715
|
}
|
|
307515
307716
|
function isDockerAvailable() {
|
|
307516
307717
|
try {
|
|
307517
|
-
|
|
307718
|
+
execSync48("docker info", { stdio: "pipe", timeout: 1e4 });
|
|
307518
307719
|
return true;
|
|
307519
307720
|
} catch {
|
|
307520
307721
|
return false;
|
|
@@ -307522,7 +307723,7 @@ function isDockerAvailable() {
|
|
|
307522
307723
|
}
|
|
307523
307724
|
function isDockerInstalled() {
|
|
307524
307725
|
try {
|
|
307525
|
-
|
|
307726
|
+
execSync48("docker --version", { stdio: "pipe", timeout: 5e3 });
|
|
307526
307727
|
return true;
|
|
307527
307728
|
} catch {
|
|
307528
307729
|
return false;
|
|
@@ -307547,31 +307748,31 @@ async function ensureDocker() {
|
|
|
307547
307748
|
}
|
|
307548
307749
|
try {
|
|
307549
307750
|
console.log("[oa-docker] Docker not found. Installing via get.docker.com...");
|
|
307550
|
-
|
|
307751
|
+
execSync48("curl -fsSL https://get.docker.com | sh", {
|
|
307551
307752
|
stdio: "inherit",
|
|
307552
307753
|
timeout: 3e5
|
|
307553
307754
|
});
|
|
307554
307755
|
const user = process.env["USER"] || process.env["LOGNAME"];
|
|
307555
307756
|
if (user) {
|
|
307556
307757
|
try {
|
|
307557
|
-
|
|
307758
|
+
execSync48(`sudo usermod -aG docker ${user}`, { stdio: "pipe" });
|
|
307558
307759
|
} catch {
|
|
307559
307760
|
}
|
|
307560
307761
|
}
|
|
307561
307762
|
try {
|
|
307562
|
-
|
|
307763
|
+
execSync48("sudo systemctl start docker", { stdio: "pipe", timeout: 15e3 });
|
|
307563
307764
|
} catch {
|
|
307564
307765
|
}
|
|
307565
307766
|
try {
|
|
307566
|
-
|
|
307567
|
-
const runtimes =
|
|
307767
|
+
execSync48("nvidia-smi", { stdio: "pipe", timeout: 5e3 });
|
|
307768
|
+
const runtimes = execSync48("docker info --format '{{json .Runtimes}}'", {
|
|
307568
307769
|
stdio: "pipe",
|
|
307569
307770
|
timeout: 5e3
|
|
307570
307771
|
}).toString();
|
|
307571
307772
|
if (!runtimes.includes("nvidia")) {
|
|
307572
307773
|
console.log("[oa-docker] NVIDIA GPU detected. Installing nvidia-container-toolkit...");
|
|
307573
307774
|
try {
|
|
307574
|
-
|
|
307775
|
+
execSync48(`
|
|
307575
307776
|
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg 2>/dev/null
|
|
307576
307777
|
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
|
|
307577
307778
|
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 )
|
|
@@ -307601,7 +307802,7 @@ async function ensureDocker() {
|
|
|
307601
307802
|
}
|
|
307602
307803
|
async function ensureNvidiaToolkit() {
|
|
307603
307804
|
try {
|
|
307604
|
-
|
|
307805
|
+
execSync48("nvidia-smi --query-gpu=name --format=csv,noheader", { stdio: "pipe", timeout: 5e3 });
|
|
307605
307806
|
} catch {
|
|
307606
307807
|
return { ok: false, message: "No NVIDIA GPU detected (nvidia-smi not found)" };
|
|
307607
307808
|
}
|
|
@@ -307612,7 +307813,7 @@ async function ensureNvidiaToolkit() {
|
|
|
307612
307813
|
return { ok: false, message: "Auto-install only supported on Linux. Install manually: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html" };
|
|
307613
307814
|
}
|
|
307614
307815
|
try {
|
|
307615
|
-
|
|
307816
|
+
execSync48(`
|
|
307616
307817
|
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg 2>/dev/null
|
|
307617
307818
|
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
|
|
307618
307819
|
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 )
|
|
@@ -307626,7 +307827,7 @@ async function ensureNvidiaToolkit() {
|
|
|
307626
307827
|
}
|
|
307627
307828
|
function isOaImageBuilt() {
|
|
307628
307829
|
try {
|
|
307629
|
-
const out =
|
|
307830
|
+
const out = execSync48(`docker images -q ${OA_IMAGE}:${OA_IMAGE_TAG}`, {
|
|
307630
307831
|
stdio: "pipe",
|
|
307631
307832
|
timeout: 5e3
|
|
307632
307833
|
}).toString().trim();
|
|
@@ -307641,7 +307842,7 @@ async function ensureOaImage(force = false) {
|
|
|
307641
307842
|
}
|
|
307642
307843
|
let buildContext;
|
|
307643
307844
|
const dockerDir = getDockerDir();
|
|
307644
|
-
if (
|
|
307845
|
+
if (existsSync68(join84(dockerDir, "Dockerfile"))) {
|
|
307645
307846
|
buildContext = dockerDir;
|
|
307646
307847
|
} else {
|
|
307647
307848
|
buildContext = join84(homedir24(), ".oa", "docker-build");
|
|
@@ -307650,7 +307851,7 @@ async function ensureOaImage(force = false) {
|
|
|
307650
307851
|
}
|
|
307651
307852
|
try {
|
|
307652
307853
|
console.log(`[oa-docker] Building image ${OA_IMAGE}:${OA_IMAGE_TAG}...`);
|
|
307653
|
-
|
|
307854
|
+
execSync48(`docker build -t ${OA_IMAGE}:${OA_IMAGE_TAG} ${buildContext}`, {
|
|
307654
307855
|
stdio: "inherit",
|
|
307655
307856
|
timeout: 6e5
|
|
307656
307857
|
// 10 min
|
|
@@ -307724,11 +307925,11 @@ exec "$@"
|
|
|
307724
307925
|
}
|
|
307725
307926
|
function hasNvidiaGpu() {
|
|
307726
307927
|
try {
|
|
307727
|
-
|
|
307928
|
+
execSync48("nvidia-smi --query-gpu=name --format=csv,noheader", {
|
|
307728
307929
|
stdio: "pipe",
|
|
307729
307930
|
timeout: 5e3
|
|
307730
307931
|
});
|
|
307731
|
-
const runtimes =
|
|
307932
|
+
const runtimes = execSync48("docker info --format '{{json .Runtimes}}'", {
|
|
307732
307933
|
stdio: "pipe",
|
|
307733
307934
|
timeout: 5e3
|
|
307734
307935
|
}).toString();
|
|
@@ -307798,8 +307999,8 @@ import * as https3 from "node:https";
|
|
|
307798
307999
|
import { createRequire as createRequire4 } from "node:module";
|
|
307799
308000
|
import { fileURLToPath as fileURLToPath16 } from "node:url";
|
|
307800
308001
|
import { dirname as dirname25, join as join85, resolve as resolve34 } from "node:path";
|
|
307801
|
-
import { spawn as spawn24, execSync as
|
|
307802
|
-
import { mkdirSync as mkdirSync37, writeFileSync as writeFileSync34, readFileSync as readFileSync54, readdirSync as readdirSync23, existsSync as
|
|
308002
|
+
import { spawn as spawn24, execSync as execSync49 } from "node:child_process";
|
|
308003
|
+
import { mkdirSync as mkdirSync37, writeFileSync as writeFileSync34, readFileSync as readFileSync54, readdirSync as readdirSync23, existsSync as existsSync69 } from "node:fs";
|
|
307803
308004
|
import { randomBytes as randomBytes19, randomUUID as randomUUID5 } from "node:crypto";
|
|
307804
308005
|
function getVersion3() {
|
|
307805
308006
|
try {
|
|
@@ -307812,7 +308013,7 @@ function getVersion3() {
|
|
|
307812
308013
|
];
|
|
307813
308014
|
for (const pkgPath of candidates) {
|
|
307814
308015
|
try {
|
|
307815
|
-
if (!
|
|
308016
|
+
if (!existsSync69(pkgPath)) continue;
|
|
307816
308017
|
const pkg = require3(pkgPath);
|
|
307817
308018
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli" || pkg.name === "@open-agents/monorepo") {
|
|
307818
308019
|
return pkg.version ?? "0.0.0";
|
|
@@ -308107,7 +308308,7 @@ function jobsDir() {
|
|
|
308107
308308
|
}
|
|
308108
308309
|
function loadJob(id) {
|
|
308109
308310
|
const file = join85(jobsDir(), `${id}.json`);
|
|
308110
|
-
if (!
|
|
308311
|
+
if (!existsSync69(file)) return null;
|
|
308111
308312
|
try {
|
|
308112
308313
|
return JSON.parse(readFileSync54(file, "utf-8"));
|
|
308113
308314
|
} catch {
|
|
@@ -308116,7 +308317,7 @@ function loadJob(id) {
|
|
|
308116
308317
|
}
|
|
308117
308318
|
function listJobs() {
|
|
308118
308319
|
const dir = jobsDir();
|
|
308119
|
-
if (!
|
|
308320
|
+
if (!existsSync69(dir)) return [];
|
|
308120
308321
|
const files = readdirSync23(dir).filter((f2) => f2.endsWith(".json")).sort();
|
|
308121
308322
|
const jobs = [];
|
|
308122
308323
|
for (const file of files) {
|
|
@@ -308806,7 +309007,7 @@ function handleV1RunsDelete(res, id) {
|
|
|
308806
309007
|
const containerName = `oa-${id}`;
|
|
308807
309008
|
if (job.sandbox === "container") {
|
|
308808
309009
|
try {
|
|
308809
|
-
|
|
309010
|
+
execSync49(`docker stop ${containerName}`, { timeout: 5e3, stdio: "ignore" });
|
|
308810
309011
|
} catch {
|
|
308811
309012
|
}
|
|
308812
309013
|
}
|
|
@@ -309486,7 +309687,7 @@ function startApiServer(options2 = {}) {
|
|
|
309486
309687
|
if (retentionDays > 0) {
|
|
309487
309688
|
try {
|
|
309488
309689
|
const jobsDir3 = join85(cwd4, ".oa", "jobs");
|
|
309489
|
-
if (
|
|
309690
|
+
if (existsSync69(jobsDir3)) {
|
|
309490
309691
|
const cutoff = Date.now() - retentionDays * 864e5;
|
|
309491
309692
|
for (const f2 of readdirSync23(jobsDir3)) {
|
|
309492
309693
|
if (!f2.endsWith(".json")) continue;
|
|
@@ -309715,8 +309916,8 @@ import { resolve as resolve35, join as join86, dirname as dirname26, extname as
|
|
|
309715
309916
|
import { createRequire as createRequire5 } from "node:module";
|
|
309716
309917
|
import { fileURLToPath as fileURLToPath17 } from "node:url";
|
|
309717
309918
|
import { readFileSync as readFileSync55, writeFileSync as writeFileSync35, appendFileSync as appendFileSync6, rmSync as rmSync4, readdirSync as readdirSync24, mkdirSync as mkdirSync38 } from "node:fs";
|
|
309718
|
-
import { existsSync as
|
|
309719
|
-
import { execSync as
|
|
309919
|
+
import { existsSync as existsSync70 } from "node:fs";
|
|
309920
|
+
import { execSync as execSync50 } from "node:child_process";
|
|
309720
309921
|
import { homedir as homedir25 } from "node:os";
|
|
309721
309922
|
function formatTimeAgo(date) {
|
|
309722
309923
|
const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
|
|
@@ -309738,7 +309939,7 @@ function getVersion4() {
|
|
|
309738
309939
|
join86(thisDir, "..", "..", "..", "package.json")
|
|
309739
309940
|
];
|
|
309740
309941
|
for (const pkgPath of candidates) {
|
|
309741
|
-
if (
|
|
309942
|
+
if (existsSync70(pkgPath)) {
|
|
309742
309943
|
const pkg = require3(pkgPath);
|
|
309743
309944
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli" || pkg.name === "@open-agents/monorepo") {
|
|
309744
309945
|
return pkg.version ?? "0.0.0";
|
|
@@ -309887,6 +310088,7 @@ function buildTools(repoRoot, config, contextWindowSize, modelTier) {
|
|
|
309887
310088
|
new BluetoothScanTool(),
|
|
309888
310089
|
new SdrScanTool(),
|
|
309889
310090
|
new FlipperZeroTool(),
|
|
310091
|
+
new MeshtasticTool(),
|
|
309890
310092
|
// Full OA sub-process — callbacks wired after runner + statusBar created
|
|
309891
310093
|
(() => {
|
|
309892
310094
|
_fullSubAgentToolRef = new FullSubAgentTool(repoRoot, config.model, config.backendUrl);
|
|
@@ -310242,7 +310444,7 @@ function gatherMemorySnippets(root) {
|
|
|
310242
310444
|
join86(root, ".open-agents", "memory")
|
|
310243
310445
|
];
|
|
310244
310446
|
for (const dir of dirs) {
|
|
310245
|
-
if (!
|
|
310447
|
+
if (!existsSync70(dir)) continue;
|
|
310246
310448
|
try {
|
|
310247
310449
|
for (const f2 of readdirSync24(dir).filter((f3) => f3.endsWith(".json"))) {
|
|
310248
310450
|
const data = JSON.parse(readFileSync55(join86(dir, f2), "utf-8"));
|
|
@@ -310400,7 +310602,7 @@ ${metabolismMemories}
|
|
|
310400
310602
|
}
|
|
310401
310603
|
try {
|
|
310402
310604
|
const archeFile = join86(repoRoot, ".oa", "arche", "variants.json");
|
|
310403
|
-
if (
|
|
310605
|
+
if (existsSync70(archeFile)) {
|
|
310404
310606
|
const variants = JSON.parse(readFileSync55(archeFile, "utf8"));
|
|
310405
310607
|
if (variants.length > 0) {
|
|
310406
310608
|
let filtered = variants;
|
|
@@ -310571,7 +310773,7 @@ RULES:
|
|
|
310571
310773
|
let identityInjection = "";
|
|
310572
310774
|
try {
|
|
310573
310775
|
const ikStateFile = join86(repoRoot, ".oa", "identity", "self-state.json");
|
|
310574
|
-
if (
|
|
310776
|
+
if (existsSync70(ikStateFile)) {
|
|
310575
310777
|
const selfState = JSON.parse(readFileSync55(ikStateFile, "utf8"));
|
|
310576
310778
|
const lines = [
|
|
310577
310779
|
`[Identity State v${selfState.version}]`,
|
|
@@ -311303,7 +311505,7 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
311303
311505
|
const ikDir = join86(repoRoot, ".oa", "identity");
|
|
311304
311506
|
const ikFile = join86(ikDir, "self-state.json");
|
|
311305
311507
|
let ikState;
|
|
311306
|
-
if (
|
|
311508
|
+
if (existsSync70(ikFile)) {
|
|
311307
311509
|
ikState = JSON.parse(readFileSync55(ikFile, "utf8"));
|
|
311308
311510
|
} else {
|
|
311309
311511
|
mkdirSync38(ikDir, { recursive: true });
|
|
@@ -311382,7 +311584,7 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
311382
311584
|
renderTaskIncomplete(result.turns, result.toolCalls, result.durationMs, tokens);
|
|
311383
311585
|
try {
|
|
311384
311586
|
const ikFile = join86(repoRoot, ".oa", "identity", "self-state.json");
|
|
311385
|
-
if (
|
|
311587
|
+
if (existsSync70(ikFile)) {
|
|
311386
311588
|
const ikState = JSON.parse(readFileSync55(ikFile, "utf8"));
|
|
311387
311589
|
if (!ikState.stats) ikState.stats = { queries_served: 0 };
|
|
311388
311590
|
ikState.stats.queries_served = (ikState.stats.queries_served || 0) + 1;
|
|
@@ -311511,7 +311713,7 @@ async function startInteractive(config, repoPath) {
|
|
|
311511
311713
|
try {
|
|
311512
311714
|
const oaDir = join86(repoRoot, ".oa");
|
|
311513
311715
|
const nexusPidFile = join86(oaDir, "nexus", "daemon.pid");
|
|
311514
|
-
if (
|
|
311716
|
+
if (existsSync70(nexusPidFile)) {
|
|
311515
311717
|
const pid = parseInt(readFileSync55(nexusPidFile, "utf8").trim(), 10);
|
|
311516
311718
|
if (pid > 0) {
|
|
311517
311719
|
try {
|
|
@@ -312281,7 +312483,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
312281
312483
|
const MAX_HISTORY_LINES = 500;
|
|
312282
312484
|
let savedHistory = [];
|
|
312283
312485
|
try {
|
|
312284
|
-
if (
|
|
312486
|
+
if (existsSync70(HISTORY_FILE)) {
|
|
312285
312487
|
const raw = readFileSync55(HISTORY_FILE, "utf8").trim();
|
|
312286
312488
|
if (raw) savedHistory = raw.split("\n").reverse();
|
|
312287
312489
|
}
|
|
@@ -312589,7 +312791,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
312589
312791
|
join86(repoRoot, ".oa", "nexus", "nexus-daemon.mjs"),
|
|
312590
312792
|
join86(_hdir(), ".open-agents", ".oa", "nexus", "nexus-daemon.mjs")
|
|
312591
312793
|
]) {
|
|
312592
|
-
if (
|
|
312794
|
+
if (existsSync70(dp)) try {
|
|
312593
312795
|
_rmStale(dp);
|
|
312594
312796
|
} catch {
|
|
312595
312797
|
}
|
|
@@ -312601,7 +312803,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
312601
312803
|
const _registerNexusDaemon = () => {
|
|
312602
312804
|
try {
|
|
312603
312805
|
const nexusPidFile = join86(repoRoot, ".oa", "nexus", "daemon.pid");
|
|
312604
|
-
if (
|
|
312806
|
+
if (existsSync70(nexusPidFile)) {
|
|
312605
312807
|
const nPid = parseInt(readFileSync55(nexusPidFile, "utf8").trim(), 10);
|
|
312606
312808
|
if (nPid > 0 && !registry2.daemons.has("Nexus")) {
|
|
312607
312809
|
registry2.register({ name: "Nexus", pid: nPid, startedAt: Date.now(), status: "running" });
|
|
@@ -312725,7 +312927,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
312725
312927
|
const globalNamePath = join86(_hd(), ".open-agents", "agent-name");
|
|
312726
312928
|
let agName = "";
|
|
312727
312929
|
try {
|
|
312728
|
-
if (
|
|
312930
|
+
if (existsSync70(globalNamePath)) agName = readFileSync55(globalNamePath, "utf8").trim();
|
|
312729
312931
|
} catch {
|
|
312730
312932
|
}
|
|
312731
312933
|
if (!agName) {
|
|
@@ -312757,7 +312959,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
312757
312959
|
const savedSponsorsPath = join86(repoRoot, ".oa", "sponsor", "known-sponsors.json");
|
|
312758
312960
|
let savedSponsors = [];
|
|
312759
312961
|
try {
|
|
312760
|
-
if (
|
|
312962
|
+
if (existsSync70(savedSponsorsPath)) {
|
|
312761
312963
|
savedSponsors = JSON.parse(readFileSync55(savedSponsorsPath, "utf8"));
|
|
312762
312964
|
const oneHourAgo = Date.now() - 36e5;
|
|
312763
312965
|
savedSponsors = savedSponsors.filter((s2) => (s2.lastVerified || 0) > oneHourAgo);
|
|
@@ -313850,7 +314052,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
313850
314052
|
if (!result.success) throw new Error(result.error || "Connect failed");
|
|
313851
314053
|
try {
|
|
313852
314054
|
const nexusPidFile = join86(repoRoot, ".oa", "nexus", "daemon.pid");
|
|
313853
|
-
if (
|
|
314055
|
+
if (existsSync70(nexusPidFile)) {
|
|
313854
314056
|
const pid = parseInt(readFileSync55(nexusPidFile, "utf8").trim(), 10);
|
|
313855
314057
|
if (pid > 0) {
|
|
313856
314058
|
registry2.register({
|
|
@@ -314039,13 +314241,13 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
314039
314241
|
try {
|
|
314040
314242
|
const nexusDir = join86(repoRoot, OA_DIR, "nexus");
|
|
314041
314243
|
const pidFile = join86(nexusDir, "daemon.pid");
|
|
314042
|
-
if (
|
|
314244
|
+
if (existsSync70(pidFile)) {
|
|
314043
314245
|
const pid = parseInt(readFileSync55(pidFile, "utf8").trim(), 10);
|
|
314044
314246
|
if (pid > 0) {
|
|
314045
314247
|
try {
|
|
314046
314248
|
if (process.platform === "win32") {
|
|
314047
314249
|
try {
|
|
314048
|
-
|
|
314250
|
+
execSync50(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
|
|
314049
314251
|
} catch {
|
|
314050
314252
|
}
|
|
314051
314253
|
} else {
|
|
@@ -314066,13 +314268,13 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
314066
314268
|
const voicePidFiles = ["luxtts-daemon.pid", "piper-daemon.pid"];
|
|
314067
314269
|
for (const pf of voicePidFiles) {
|
|
314068
314270
|
const pidPath = join86(voiceDir2, pf);
|
|
314069
|
-
if (
|
|
314271
|
+
if (existsSync70(pidPath)) {
|
|
314070
314272
|
try {
|
|
314071
314273
|
const pid = parseInt(readFileSync55(pidPath, "utf8").trim(), 10);
|
|
314072
314274
|
if (pid > 0) {
|
|
314073
314275
|
if (process.platform === "win32") {
|
|
314074
314276
|
try {
|
|
314075
|
-
|
|
314277
|
+
execSync50(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
|
|
314076
314278
|
} catch {
|
|
314077
314279
|
}
|
|
314078
314280
|
} else {
|
|
@@ -314089,11 +314291,11 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
314089
314291
|
} catch {
|
|
314090
314292
|
}
|
|
314091
314293
|
try {
|
|
314092
|
-
|
|
314294
|
+
execSync50(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.5", { timeout: 3e3, stdio: "ignore" });
|
|
314093
314295
|
} catch {
|
|
314094
314296
|
}
|
|
314095
314297
|
const oaPath = join86(repoRoot, OA_DIR);
|
|
314096
|
-
if (
|
|
314298
|
+
if (existsSync70(oaPath)) {
|
|
314097
314299
|
let deleted = false;
|
|
314098
314300
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
314099
314301
|
try {
|
|
@@ -314103,14 +314305,14 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
314103
314305
|
} catch (err) {
|
|
314104
314306
|
if (attempt < 2) {
|
|
314105
314307
|
try {
|
|
314106
|
-
|
|
314308
|
+
execSync50(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.3", { timeout: 3e3, stdio: "ignore" });
|
|
314107
314309
|
} catch {
|
|
314108
314310
|
}
|
|
314109
314311
|
} else {
|
|
314110
314312
|
writeContent(() => renderWarning(`Could not fully remove ${OA_DIR}/: ${err instanceof Error ? err.message : String(err)}`));
|
|
314111
314313
|
if (process.platform === "win32") {
|
|
314112
314314
|
try {
|
|
314113
|
-
|
|
314315
|
+
execSync50(`rd /s /q "${oaPath}"`, { timeout: 1e4, stdio: "ignore" });
|
|
314114
314316
|
deleted = true;
|
|
314115
314317
|
} catch {
|
|
314116
314318
|
}
|
|
@@ -314177,16 +314379,16 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
314177
314379
|
if (isPersonaPlexRunning2()) {
|
|
314178
314380
|
const ppPidFile = join86(homedir25(), ".open-agents", "voice", "personaplex", "daemon.pid");
|
|
314179
314381
|
const ppPortFile = join86(homedir25(), ".open-agents", "voice", "personaplex", "daemon.port");
|
|
314180
|
-
if (
|
|
314382
|
+
if (existsSync70(ppPidFile)) {
|
|
314181
314383
|
const ppPid = parseInt(readFileSync55(ppPidFile, "utf8").trim(), 10);
|
|
314182
|
-
const ppPort =
|
|
314384
|
+
const ppPort = existsSync70(ppPortFile) ? parseInt(readFileSync55(ppPortFile, "utf8").trim(), 10) : void 0;
|
|
314183
314385
|
if (ppPid > 0 && !registry2.daemons.has("PersonaPlex")) {
|
|
314184
314386
|
registry2.register({ name: "PersonaPlex", pid: ppPid, port: ppPort, startedAt: Date.now(), status: "running" });
|
|
314185
314387
|
}
|
|
314186
314388
|
}
|
|
314187
314389
|
}
|
|
314188
314390
|
const nexusPidFile = join86(repoRoot, ".oa", "nexus", "daemon.pid");
|
|
314189
|
-
if (
|
|
314391
|
+
if (existsSync70(nexusPidFile)) {
|
|
314190
314392
|
const nPid = parseInt(readFileSync55(nexusPidFile, "utf8").trim(), 10);
|
|
314191
314393
|
if (nPid > 0 && !registry2.daemons.has("Nexus")) {
|
|
314192
314394
|
try {
|
|
@@ -314528,8 +314730,8 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
314528
314730
|
}
|
|
314529
314731
|
}
|
|
314530
314732
|
const cleanPath = input.replace(/^['"]|['"]$/g, "").trim();
|
|
314531
|
-
const isImage = isImagePath(cleanPath) &&
|
|
314532
|
-
const isMedia = !isImage && isTranscribablePath(cleanPath) &&
|
|
314733
|
+
const isImage = isImagePath(cleanPath) && existsSync70(resolve35(repoRoot, cleanPath));
|
|
314734
|
+
const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync70(resolve35(repoRoot, cleanPath));
|
|
314533
314735
|
if (activeTask) {
|
|
314534
314736
|
if (activeTask.runner.isPaused) {
|
|
314535
314737
|
activeTask.runner.resume();
|
|
@@ -314757,7 +314959,7 @@ Summarize or analyze this transcription as appropriate.`;
|
|
|
314757
314959
|
|
|
314758
314960
|
NEW TASK: ${fullInput}`;
|
|
314759
314961
|
restoredSessionContext = null;
|
|
314760
|
-
} else if (
|
|
314962
|
+
} else if (existsSync70(join86(repoRoot, ".oa", "context", "session-diary.md"))) {
|
|
314761
314963
|
taskInput = `[Previous sessions exist \u2014 file_read(".oa/context/session-diary.md") to recall]
|
|
314762
314964
|
|
|
314763
314965
|
${fullInput}`;
|
|
@@ -315094,7 +315296,7 @@ async function runWithTUI(task, config, repoPath, callbacks) {
|
|
|
315094
315296
|
const ikDir = join86(repoRoot, ".oa", "identity");
|
|
315095
315297
|
const ikFile = join86(ikDir, "self-state.json");
|
|
315096
315298
|
let ikState;
|
|
315097
|
-
if (
|
|
315299
|
+
if (existsSync70(ikFile)) {
|
|
315098
315300
|
ikState = JSON.parse(readFileSync55(ikFile, "utf8"));
|
|
315099
315301
|
} else {
|
|
315100
315302
|
mkdirSync38(ikDir, { recursive: true });
|
|
@@ -315136,7 +315338,7 @@ async function runWithTUI(task, config, repoPath, callbacks) {
|
|
|
315136
315338
|
const archeFile = join86(archeDir, "variants.json");
|
|
315137
315339
|
let variants = [];
|
|
315138
315340
|
try {
|
|
315139
|
-
if (
|
|
315341
|
+
if (existsSync70(archeFile)) variants = JSON.parse(readFileSync55(archeFile, "utf8"));
|
|
315140
315342
|
} catch {
|
|
315141
315343
|
}
|
|
315142
315344
|
variants.push({
|
|
@@ -315157,7 +315359,7 @@ async function runWithTUI(task, config, repoPath, callbacks) {
|
|
|
315157
315359
|
}
|
|
315158
315360
|
try {
|
|
315159
315361
|
const metaFile = join86(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
315160
|
-
if (
|
|
315362
|
+
if (existsSync70(metaFile)) {
|
|
315161
315363
|
const store2 = JSON.parse(readFileSync55(metaFile, "utf8"));
|
|
315162
315364
|
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);
|
|
315163
315365
|
let updated = false;
|
|
@@ -315243,7 +315445,7 @@ Rules:
|
|
|
315243
315445
|
const storeFile = join86(metaDir, "store.json");
|
|
315244
315446
|
let store2 = [];
|
|
315245
315447
|
try {
|
|
315246
|
-
if (
|
|
315448
|
+
if (existsSync70(storeFile)) store2 = JSON.parse(readFileSync55(storeFile, "utf8"));
|
|
315247
315449
|
} catch {
|
|
315248
315450
|
}
|
|
315249
315451
|
store2.push({
|
|
@@ -315268,7 +315470,7 @@ Rules:
|
|
|
315268
315470
|
const cohereSettingsFile = join86(repoRoot, ".oa", "settings.json");
|
|
315269
315471
|
let cohereActive = false;
|
|
315270
315472
|
try {
|
|
315271
|
-
if (
|
|
315473
|
+
if (existsSync70(cohereSettingsFile)) {
|
|
315272
315474
|
const settings = JSON.parse(readFileSync55(cohereSettingsFile, "utf8"));
|
|
315273
315475
|
cohereActive = settings.cohere === true;
|
|
315274
315476
|
}
|
|
@@ -315276,7 +315478,7 @@ Rules:
|
|
|
315276
315478
|
}
|
|
315277
315479
|
if (cohereActive) {
|
|
315278
315480
|
const metaFile = join86(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
315279
|
-
if (
|
|
315481
|
+
if (existsSync70(metaFile)) {
|
|
315280
315482
|
const store2 = JSON.parse(readFileSync55(metaFile, "utf8"));
|
|
315281
315483
|
const latest = store2.filter((m2) => m2.sourceTrace === "trajectory-extraction" || m2.sourceTrace === "llm-trajectory-extraction").slice(-1)[0];
|
|
315282
315484
|
if (latest && latest.scores?.confidence >= 0.6) {
|
|
@@ -315303,7 +315505,7 @@ Rules:
|
|
|
315303
315505
|
} catch (err) {
|
|
315304
315506
|
try {
|
|
315305
315507
|
const ikFile = join86(repoRoot, ".oa", "identity", "self-state.json");
|
|
315306
|
-
if (
|
|
315508
|
+
if (existsSync70(ikFile)) {
|
|
315307
315509
|
const ikState = JSON.parse(readFileSync55(ikFile, "utf8"));
|
|
315308
315510
|
ikState.homeostasis.uncertainty = Math.min(1, ikState.homeostasis.uncertainty + 0.1);
|
|
315309
315511
|
ikState.homeostasis.coherence = Math.max(0, ikState.homeostasis.coherence - 0.05);
|
|
@@ -315312,7 +315514,7 @@ Rules:
|
|
|
315312
315514
|
writeFileSync35(ikFile, JSON.stringify(ikState, null, 2));
|
|
315313
315515
|
}
|
|
315314
315516
|
const metaFile = join86(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
315315
|
-
if (
|
|
315517
|
+
if (existsSync70(metaFile)) {
|
|
315316
315518
|
const store2 = JSON.parse(readFileSync55(metaFile, "utf8"));
|
|
315317
315519
|
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);
|
|
315318
315520
|
for (const item of surfaced) {
|
|
@@ -315328,7 +315530,7 @@ Rules:
|
|
|
315328
315530
|
const archeFile = join86(archeDir, "variants.json");
|
|
315329
315531
|
let variants = [];
|
|
315330
315532
|
try {
|
|
315331
|
-
if (
|
|
315533
|
+
if (existsSync70(archeFile)) variants = JSON.parse(readFileSync55(archeFile, "utf8"));
|
|
315332
315534
|
} catch {
|
|
315333
315535
|
}
|
|
315334
315536
|
variants.push({
|
|
@@ -315425,7 +315627,7 @@ __export(run_exports, {
|
|
|
315425
315627
|
});
|
|
315426
315628
|
import { resolve as resolve36 } from "node:path";
|
|
315427
315629
|
import { spawn as spawn25 } from "node:child_process";
|
|
315428
|
-
import { mkdirSync as mkdirSync39, writeFileSync as writeFileSync36, readFileSync as readFileSync56, readdirSync as readdirSync25, existsSync as
|
|
315630
|
+
import { mkdirSync as mkdirSync39, writeFileSync as writeFileSync36, readFileSync as readFileSync56, readdirSync as readdirSync25, existsSync as existsSync71 } from "node:fs";
|
|
315429
315631
|
import { randomBytes as randomBytes20 } from "node:crypto";
|
|
315430
315632
|
import { join as join87 } from "node:path";
|
|
315431
315633
|
function jobsDir2(repoPath) {
|
|
@@ -315579,7 +315781,7 @@ async function runBackground(task, config, opts) {
|
|
|
315579
315781
|
function statusCommand(jobId, repoPath) {
|
|
315580
315782
|
const dir = jobsDir2(repoPath);
|
|
315581
315783
|
const file = join87(dir, `${jobId}.json`);
|
|
315582
|
-
if (!
|
|
315784
|
+
if (!existsSync71(file)) {
|
|
315583
315785
|
console.error(`Job not found: ${jobId}`);
|
|
315584
315786
|
console.log(`Available jobs: oa jobs`);
|
|
315585
315787
|
process.exit(1);
|
|
@@ -315837,13 +316039,13 @@ __export(index_repo_exports, {
|
|
|
315837
316039
|
indexRepoCommand: () => indexRepoCommand
|
|
315838
316040
|
});
|
|
315839
316041
|
import { resolve as resolve37 } from "node:path";
|
|
315840
|
-
import { existsSync as
|
|
316042
|
+
import { existsSync as existsSync72, statSync as statSync21 } from "node:fs";
|
|
315841
316043
|
import { cwd as cwd2 } from "node:process";
|
|
315842
316044
|
async function indexRepoCommand(opts, _config3) {
|
|
315843
316045
|
const repoRoot = resolve37(opts.repoPath ?? cwd2());
|
|
315844
316046
|
printHeader("Index Repository");
|
|
315845
316047
|
printInfo(`Indexing: ${repoRoot}`);
|
|
315846
|
-
if (!
|
|
316048
|
+
if (!existsSync72(repoRoot)) {
|
|
315847
316049
|
printError(`Path does not exist: ${repoRoot}`);
|
|
315848
316050
|
process.exit(1);
|
|
315849
316051
|
}
|