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