open-agents-ai 0.169.0 → 0.170.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 +1111 -834
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -10483,8 +10483,8 @@ function deleteCustomToolDefinition(name, scope, repoRoot) {
|
|
|
10483
10483
|
const dir = scope === "project" && repoRoot ? projectToolsDir(repoRoot) : globalToolsDir();
|
|
10484
10484
|
const filePath = join16(dir, `${name}.json`);
|
|
10485
10485
|
if (existsSync13(filePath)) {
|
|
10486
|
-
const { unlinkSync:
|
|
10487
|
-
|
|
10486
|
+
const { unlinkSync: unlinkSync12 } = __require("node:fs");
|
|
10487
|
+
unlinkSync12(filePath);
|
|
10488
10488
|
return true;
|
|
10489
10489
|
}
|
|
10490
10490
|
return false;
|
|
@@ -11659,8 +11659,8 @@ async function loadTranscribeCli() {
|
|
|
11659
11659
|
const nvmBase = join19(homedir6(), ".nvm", "versions", "node");
|
|
11660
11660
|
if (existsSync16(nvmBase)) {
|
|
11661
11661
|
try {
|
|
11662
|
-
const { readdirSync:
|
|
11663
|
-
for (const ver of
|
|
11662
|
+
const { readdirSync: readdirSync20 } = await import("node:fs");
|
|
11663
|
+
for (const ver of readdirSync20(nvmBase)) {
|
|
11664
11664
|
const tcPath = join19(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
|
|
11665
11665
|
if (existsSync16(join19(tcPath, "dist", "index.js"))) {
|
|
11666
11666
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
@@ -12713,13 +12713,13 @@ Justification: ${justification || "(none provided)"}`,
|
|
|
12713
12713
|
}
|
|
12714
12714
|
const snapshot = JSON.stringify(this.selfState, null, 2);
|
|
12715
12715
|
try {
|
|
12716
|
-
const { createHash:
|
|
12716
|
+
const { createHash: createHash6 } = await import("node:crypto");
|
|
12717
12717
|
const snapshotDir = join21(this.cwd, ".oa", "identity", "snapshots");
|
|
12718
12718
|
await mkdir5(snapshotDir, { recursive: true });
|
|
12719
12719
|
const version = this.selfState.version;
|
|
12720
12720
|
const snapshotPath = join21(snapshotDir, `v${version}.json`);
|
|
12721
12721
|
await writeFile9(snapshotPath, snapshot, "utf8");
|
|
12722
|
-
const hash =
|
|
12722
|
+
const hash = createHash6("sha256").update(snapshot).digest("hex");
|
|
12723
12723
|
await writeFile9(join21(this.cwd, ".oa", "identity", "latest-hash.txt"), hash, "utf8");
|
|
12724
12724
|
let ipfsCid = "";
|
|
12725
12725
|
try {
|
|
@@ -12852,8 +12852,8 @@ New: ${newNarrative.slice(0, 200)}...`,
|
|
|
12852
12852
|
}
|
|
12853
12853
|
// ── Helpers ──────────────────────────────────────────────────────────────
|
|
12854
12854
|
createDefaultState() {
|
|
12855
|
-
const { createHash:
|
|
12856
|
-
const machineId =
|
|
12855
|
+
const { createHash: createHash6 } = __require("node:crypto");
|
|
12856
|
+
const machineId = createHash6("sha256").update(this.cwd).digest("hex").slice(0, 12);
|
|
12857
12857
|
return {
|
|
12858
12858
|
self_id: `oa-${machineId}`,
|
|
12859
12859
|
version: 1,
|
|
@@ -13402,9 +13402,9 @@ print("${sentinel}")
|
|
|
13402
13402
|
if (!this.proc || this.proc.killed) {
|
|
13403
13403
|
return { success: false, path: "" };
|
|
13404
13404
|
}
|
|
13405
|
-
const { mkdirSync:
|
|
13405
|
+
const { mkdirSync: mkdirSync25, writeFileSync: writeFileSync24 } = await import("node:fs");
|
|
13406
13406
|
const sessionDir = join22(this.cwd, ".oa", "rlm");
|
|
13407
|
-
|
|
13407
|
+
mkdirSync25(sessionDir, { recursive: true });
|
|
13408
13408
|
const sessionPath = join22(sessionDir, "session.json");
|
|
13409
13409
|
try {
|
|
13410
13410
|
const inspectCode = `
|
|
@@ -13428,7 +13428,7 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
|
|
|
13428
13428
|
trajectoryCount: this.trajectory.length,
|
|
13429
13429
|
subCallCount: this.subCallCount
|
|
13430
13430
|
};
|
|
13431
|
-
|
|
13431
|
+
writeFileSync24(sessionPath, JSON.stringify(sessionData, null, 2), "utf8");
|
|
13432
13432
|
return { success: true, path: sessionPath };
|
|
13433
13433
|
}
|
|
13434
13434
|
} catch {
|
|
@@ -13440,11 +13440,11 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
|
|
|
13440
13440
|
* what was previously computed. */
|
|
13441
13441
|
async loadSessionInfo() {
|
|
13442
13442
|
try {
|
|
13443
|
-
const { readFileSync:
|
|
13443
|
+
const { readFileSync: readFileSync39, existsSync: existsSync51 } = await import("node:fs");
|
|
13444
13444
|
const sessionPath = join22(this.cwd, ".oa", "rlm", "session.json");
|
|
13445
|
-
if (!
|
|
13445
|
+
if (!existsSync51(sessionPath))
|
|
13446
13446
|
return null;
|
|
13447
|
-
return JSON.parse(
|
|
13447
|
+
return JSON.parse(readFileSync39(sessionPath, "utf8"));
|
|
13448
13448
|
} catch {
|
|
13449
13449
|
return null;
|
|
13450
13450
|
}
|
|
@@ -13621,10 +13621,10 @@ var init_memory_metabolism = __esm({
|
|
|
13621
13621
|
const trajDir = join23(this.cwd, ".oa", "rlm-trajectories");
|
|
13622
13622
|
let lessons = [];
|
|
13623
13623
|
try {
|
|
13624
|
-
const { readdirSync:
|
|
13625
|
-
const files =
|
|
13624
|
+
const { readdirSync: readdirSync20, readFileSync: readFileSync39 } = await import("node:fs");
|
|
13625
|
+
const files = readdirSync20(trajDir).filter((f) => f.endsWith(".jsonl")).sort().reverse().slice(0, 3);
|
|
13626
13626
|
for (const file of files) {
|
|
13627
|
-
const lines =
|
|
13627
|
+
const lines = readFileSync39(join23(trajDir, file), "utf8").split("\n").filter((l) => l.trim());
|
|
13628
13628
|
for (const line of lines) {
|
|
13629
13629
|
try {
|
|
13630
13630
|
const entry = JSON.parse(line);
|
|
@@ -14008,14 +14008,14 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
|
|
|
14008
14008
|
* Optionally filter by task type for phase-aware context (FSM paper insight).
|
|
14009
14009
|
*/
|
|
14010
14010
|
getTopMemoriesSync(k = 5, taskType) {
|
|
14011
|
-
const { readFileSync:
|
|
14011
|
+
const { readFileSync: readFileSync39, existsSync: existsSync51 } = __require("node:fs");
|
|
14012
14012
|
const metaDir = join23(this.cwd, ".oa", "memory", "metabolism");
|
|
14013
14013
|
const storeFile = join23(metaDir, "store.json");
|
|
14014
|
-
if (!
|
|
14014
|
+
if (!existsSync51(storeFile))
|
|
14015
14015
|
return "";
|
|
14016
14016
|
let store = [];
|
|
14017
14017
|
try {
|
|
14018
|
-
store = JSON.parse(
|
|
14018
|
+
store = JSON.parse(readFileSync39(storeFile, "utf8"));
|
|
14019
14019
|
} catch {
|
|
14020
14020
|
return "";
|
|
14021
14021
|
}
|
|
@@ -14037,14 +14037,14 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
|
|
|
14037
14037
|
/** Update memory scores based on task outcome. Called after task completion.
|
|
14038
14038
|
* Memories used in successful tasks get boosted. Memories present during failures get decayed. */
|
|
14039
14039
|
updateFromOutcomeSync(surfacedMemoryText, succeeded) {
|
|
14040
|
-
const { readFileSync:
|
|
14040
|
+
const { readFileSync: readFileSync39, writeFileSync: writeFileSync24, existsSync: existsSync51, mkdirSync: mkdirSync25 } = __require("node:fs");
|
|
14041
14041
|
const metaDir = join23(this.cwd, ".oa", "memory", "metabolism");
|
|
14042
14042
|
const storeFile = join23(metaDir, "store.json");
|
|
14043
|
-
if (!
|
|
14043
|
+
if (!existsSync51(storeFile))
|
|
14044
14044
|
return;
|
|
14045
14045
|
let store = [];
|
|
14046
14046
|
try {
|
|
14047
|
-
store = JSON.parse(
|
|
14047
|
+
store = JSON.parse(readFileSync39(storeFile, "utf8"));
|
|
14048
14048
|
} catch {
|
|
14049
14049
|
return;
|
|
14050
14050
|
}
|
|
@@ -14068,8 +14068,8 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
|
|
|
14068
14068
|
updated = true;
|
|
14069
14069
|
}
|
|
14070
14070
|
if (updated) {
|
|
14071
|
-
|
|
14072
|
-
|
|
14071
|
+
mkdirSync25(metaDir, { recursive: true });
|
|
14072
|
+
writeFileSync24(storeFile, JSON.stringify(store, null, 2));
|
|
14073
14073
|
}
|
|
14074
14074
|
}
|
|
14075
14075
|
// ── Storage ──────────────────────────────────────────────────────────
|
|
@@ -14491,13 +14491,13 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
14491
14491
|
// Per EvoSkill (arXiv:2603.02766): retrieve relevant strategies from archive.
|
|
14492
14492
|
/** Retrieve top-K strategies for context injection. Returns "" if none. */
|
|
14493
14493
|
getRelevantStrategiesSync(k = 3, taskType) {
|
|
14494
|
-
const { readFileSync:
|
|
14494
|
+
const { readFileSync: readFileSync39, existsSync: existsSync51 } = __require("node:fs");
|
|
14495
14495
|
const archiveFile = join25(this.cwd, ".oa", "arche", "variants.json");
|
|
14496
|
-
if (!
|
|
14496
|
+
if (!existsSync51(archiveFile))
|
|
14497
14497
|
return "";
|
|
14498
14498
|
let variants = [];
|
|
14499
14499
|
try {
|
|
14500
|
-
variants = JSON.parse(
|
|
14500
|
+
variants = JSON.parse(readFileSync39(archiveFile, "utf8"));
|
|
14501
14501
|
} catch {
|
|
14502
14502
|
return "";
|
|
14503
14503
|
}
|
|
@@ -14515,13 +14515,13 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
14515
14515
|
}
|
|
14516
14516
|
/** Archive a strategy variant synchronously (for task completion path) */
|
|
14517
14517
|
archiveVariantSync(strategy, outcome, tags = []) {
|
|
14518
|
-
const { readFileSync:
|
|
14518
|
+
const { readFileSync: readFileSync39, writeFileSync: writeFileSync24, existsSync: existsSync51, mkdirSync: mkdirSync25 } = __require("node:fs");
|
|
14519
14519
|
const dir = join25(this.cwd, ".oa", "arche");
|
|
14520
14520
|
const archiveFile = join25(dir, "variants.json");
|
|
14521
14521
|
let variants = [];
|
|
14522
14522
|
try {
|
|
14523
|
-
if (
|
|
14524
|
-
variants = JSON.parse(
|
|
14523
|
+
if (existsSync51(archiveFile))
|
|
14524
|
+
variants = JSON.parse(readFileSync39(archiveFile, "utf8"));
|
|
14525
14525
|
} catch {
|
|
14526
14526
|
}
|
|
14527
14527
|
variants.push({
|
|
@@ -14536,8 +14536,8 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
14536
14536
|
});
|
|
14537
14537
|
if (variants.length > 50)
|
|
14538
14538
|
variants = variants.slice(-50);
|
|
14539
|
-
|
|
14540
|
-
|
|
14539
|
+
mkdirSync25(dir, { recursive: true });
|
|
14540
|
+
writeFileSync24(archiveFile, JSON.stringify(variants, null, 2));
|
|
14541
14541
|
}
|
|
14542
14542
|
async saveArchive(variants) {
|
|
14543
14543
|
const dir = join25(this.cwd, ".oa", "arche");
|
|
@@ -21201,19 +21201,293 @@ var init_environment_snapshot = __esm({
|
|
|
21201
21201
|
}
|
|
21202
21202
|
});
|
|
21203
21203
|
|
|
21204
|
+
// packages/execution/dist/tools/video-understand.js
|
|
21205
|
+
import { execSync as execSync24 } from "node:child_process";
|
|
21206
|
+
import { existsSync as existsSync27, mkdirSync as mkdirSync9, writeFileSync as writeFileSync9, readFileSync as readFileSync20, readdirSync as readdirSync7, unlinkSync as unlinkSync4 } from "node:fs";
|
|
21207
|
+
import { join as join41, basename as basename10 } from "node:path";
|
|
21208
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
21209
|
+
function isYouTubeUrl2(url) {
|
|
21210
|
+
return /(?:youtube\.com\/(?:watch|shorts|live|embed|v\/)|youtu\.be\/)/i.test(url);
|
|
21211
|
+
}
|
|
21212
|
+
function ensureYtDlp2() {
|
|
21213
|
+
try {
|
|
21214
|
+
execSync24("yt-dlp --version", { timeout: 5e3, stdio: "pipe" });
|
|
21215
|
+
return true;
|
|
21216
|
+
} catch {
|
|
21217
|
+
try {
|
|
21218
|
+
execSync24("pip3 install --break-system-packages yt-dlp 2>/dev/null || pip3 install --user yt-dlp 2>/dev/null", { timeout: 6e4, stdio: "pipe" });
|
|
21219
|
+
return true;
|
|
21220
|
+
} catch {
|
|
21221
|
+
return false;
|
|
21222
|
+
}
|
|
21223
|
+
}
|
|
21224
|
+
}
|
|
21225
|
+
function ensureFfmpeg() {
|
|
21226
|
+
try {
|
|
21227
|
+
execSync24("ffmpeg -version", { timeout: 3e3, stdio: "pipe" });
|
|
21228
|
+
return true;
|
|
21229
|
+
} catch {
|
|
21230
|
+
return false;
|
|
21231
|
+
}
|
|
21232
|
+
}
|
|
21233
|
+
function imageHash(imagePath) {
|
|
21234
|
+
try {
|
|
21235
|
+
const data = readFileSync20(imagePath);
|
|
21236
|
+
return createHash2("md5").update(data).digest("hex").slice(0, 12);
|
|
21237
|
+
} catch {
|
|
21238
|
+
return "unknown";
|
|
21239
|
+
}
|
|
21240
|
+
}
|
|
21241
|
+
function deduplicateFrames(frames, similarityThreshold = 0) {
|
|
21242
|
+
if (frames.length <= 1)
|
|
21243
|
+
return frames;
|
|
21244
|
+
let prevHash = "";
|
|
21245
|
+
for (const frame of frames) {
|
|
21246
|
+
if (frame.hash === prevHash) {
|
|
21247
|
+
frame.isDuplicate = true;
|
|
21248
|
+
}
|
|
21249
|
+
prevHash = frame.hash;
|
|
21250
|
+
}
|
|
21251
|
+
return frames;
|
|
21252
|
+
}
|
|
21253
|
+
function formatTime2(seconds) {
|
|
21254
|
+
const m = Math.floor(seconds / 60);
|
|
21255
|
+
const s = Math.floor(seconds % 60);
|
|
21256
|
+
const ms = Math.floor(seconds % 1 * 10);
|
|
21257
|
+
return `${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}.${ms}`;
|
|
21258
|
+
}
|
|
21259
|
+
var VideoUnderstandTool;
|
|
21260
|
+
var init_video_understand = __esm({
|
|
21261
|
+
"packages/execution/dist/tools/video-understand.js"() {
|
|
21262
|
+
"use strict";
|
|
21263
|
+
VideoUnderstandTool = class {
|
|
21264
|
+
name = "video_understand";
|
|
21265
|
+
description = "Analyze a video from URL or local file. Produces timestamped transcript aligned with keyframe descriptions. Supports YouTube URLs and direct video files. Pipeline: download \u2192 transcribe (Whisper) \u2192 extract keyframes (scene detection) \u2192 describe frames \u2192 align timestamps \u2192 save structured output.";
|
|
21266
|
+
parameters = {
|
|
21267
|
+
type: "object",
|
|
21268
|
+
properties: {
|
|
21269
|
+
url: { type: "string", description: "YouTube URL or direct video URL" },
|
|
21270
|
+
path: { type: "string", description: "Local video file path (alternative to url)" },
|
|
21271
|
+
model: { type: "string", description: "Whisper model: tiny, base, small, medium (default: base)" },
|
|
21272
|
+
frame_interval: { type: "number", description: "Seconds between forced frame samples (default: 30)" },
|
|
21273
|
+
scene_threshold: { type: "number", description: "Scene change sensitivity 0-1 (default: 0.1)" },
|
|
21274
|
+
skip_frames: { type: "boolean", description: "Skip frame extraction (audio-only, default: false)" }
|
|
21275
|
+
},
|
|
21276
|
+
required: []
|
|
21277
|
+
};
|
|
21278
|
+
workingDir;
|
|
21279
|
+
constructor(workingDir) {
|
|
21280
|
+
this.workingDir = workingDir;
|
|
21281
|
+
}
|
|
21282
|
+
async execute(args) {
|
|
21283
|
+
const start = performance.now();
|
|
21284
|
+
const url = args["url"];
|
|
21285
|
+
const localPath = args["path"];
|
|
21286
|
+
const whisperModel = String(args["model"] ?? "base");
|
|
21287
|
+
const frameInterval = Number(args["frame_interval"] ?? 30);
|
|
21288
|
+
const sceneThreshold = Number(args["scene_threshold"] ?? 0.1);
|
|
21289
|
+
const skipFrames = Boolean(args["skip_frames"]);
|
|
21290
|
+
if (!url && !localPath) {
|
|
21291
|
+
return { success: false, output: "", error: "url or path required", durationMs: performance.now() - start };
|
|
21292
|
+
}
|
|
21293
|
+
const outDir = join41(this.workingDir, ".oa", "video-analysis");
|
|
21294
|
+
mkdirSync9(outDir, { recursive: true });
|
|
21295
|
+
const tmpDir = join41(outDir, `tmp-${Date.now()}`);
|
|
21296
|
+
mkdirSync9(tmpDir, { recursive: true });
|
|
21297
|
+
try {
|
|
21298
|
+
let videoPath;
|
|
21299
|
+
let audioPath;
|
|
21300
|
+
let title;
|
|
21301
|
+
if (url) {
|
|
21302
|
+
if (isYouTubeUrl2(url)) {
|
|
21303
|
+
if (!ensureYtDlp2()) {
|
|
21304
|
+
return { success: false, output: "", error: "yt-dlp required but not available. Install: pip3 install yt-dlp", durationMs: performance.now() - start };
|
|
21305
|
+
}
|
|
21306
|
+
try {
|
|
21307
|
+
execSync24(`yt-dlp -f "worst[ext=mp4]" -o "${join41(tmpDir, "video.%(ext)s")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
|
|
21308
|
+
} catch {
|
|
21309
|
+
execSync24(`yt-dlp -f worst -o "${join41(tmpDir, "video.%(ext)s")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
|
|
21310
|
+
}
|
|
21311
|
+
execSync24(`yt-dlp -x --audio-format mp3 --audio-quality 5 -o "${join41(tmpDir, "audio.%(ext)s")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
|
|
21312
|
+
try {
|
|
21313
|
+
title = execSync24(`yt-dlp --get-title "${url}"`, { encoding: "utf-8", timeout: 15e3, stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
21314
|
+
} catch {
|
|
21315
|
+
}
|
|
21316
|
+
} else {
|
|
21317
|
+
execSync24(`curl -sL -o "${join41(tmpDir, "video.mp4")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
|
|
21318
|
+
execSync24(`ffmpeg -i "${join41(tmpDir, "video.mp4")}" -vn -acodec libmp3lame -q:a 5 "${join41(tmpDir, "audio.mp3")}" -y`, { timeout: 12e4, stdio: "pipe" });
|
|
21319
|
+
}
|
|
21320
|
+
videoPath = readdirSync7(tmpDir).find((f) => f.startsWith("video")) ? join41(tmpDir, readdirSync7(tmpDir).find((f) => f.startsWith("video"))) : join41(tmpDir, "video.mp4");
|
|
21321
|
+
audioPath = readdirSync7(tmpDir).find((f) => f.startsWith("audio")) ? join41(tmpDir, readdirSync7(tmpDir).find((f) => f.startsWith("audio"))) : join41(tmpDir, "audio.mp3");
|
|
21322
|
+
} else {
|
|
21323
|
+
videoPath = localPath;
|
|
21324
|
+
audioPath = join41(tmpDir, "audio.mp3");
|
|
21325
|
+
execSync24(`ffmpeg -i "${videoPath}" -vn -acodec libmp3lame -q:a 5 "${audioPath}" -y`, { timeout: 12e4, stdio: "pipe" });
|
|
21326
|
+
}
|
|
21327
|
+
let segments = [];
|
|
21328
|
+
let language = "en";
|
|
21329
|
+
let duration = 0;
|
|
21330
|
+
try {
|
|
21331
|
+
const jsonOut = join41(tmpDir, "transcript.json");
|
|
21332
|
+
execSync24(`transcribe-cli transcribe "${audioPath}" --model ${whisperModel} --format json -o "${tmpDir}"`, { timeout: 6e5, stdio: "pipe" });
|
|
21333
|
+
const jsonFile = readdirSync7(tmpDir).find((f) => f.endsWith(".json") && f !== "result.json");
|
|
21334
|
+
if (jsonFile) {
|
|
21335
|
+
const data = JSON.parse(readFileSync20(join41(tmpDir, jsonFile), "utf-8"));
|
|
21336
|
+
segments = (data.segments || []).map((s) => ({
|
|
21337
|
+
start: s.start ?? 0,
|
|
21338
|
+
end: s.end ?? 0,
|
|
21339
|
+
text: (s.text || "").trim(),
|
|
21340
|
+
speaker: s.speaker
|
|
21341
|
+
}));
|
|
21342
|
+
language = data.language || "en";
|
|
21343
|
+
duration = data.duration || 0;
|
|
21344
|
+
}
|
|
21345
|
+
} catch (err) {
|
|
21346
|
+
segments = [];
|
|
21347
|
+
}
|
|
21348
|
+
let frames = [];
|
|
21349
|
+
if (!skipFrames && ensureFfmpeg() && existsSync27(videoPath)) {
|
|
21350
|
+
const framesDir = join41(tmpDir, "frames");
|
|
21351
|
+
mkdirSync9(framesDir, { recursive: true });
|
|
21352
|
+
const fps = 25;
|
|
21353
|
+
const intervalFrames = Math.max(1, frameInterval * fps);
|
|
21354
|
+
try {
|
|
21355
|
+
execSync24(`ffmpeg -i "${videoPath}" -vf "select='gt(scene\\,${sceneThreshold})+not(mod(n\\,${intervalFrames}))',showinfo" -vsync vfr "${join41(framesDir, "frame_%04d.jpg")}" -y`, { timeout: 3e5, stdio: "pipe" });
|
|
21356
|
+
} catch {
|
|
21357
|
+
}
|
|
21358
|
+
const frameFiles = readdirSync7(framesDir).filter((f) => f.endsWith(".jpg")).sort();
|
|
21359
|
+
for (let i = 0; i < frameFiles.length; i++) {
|
|
21360
|
+
const framePath = join41(framesDir, frameFiles[i]);
|
|
21361
|
+
const hash = imageHash(framePath);
|
|
21362
|
+
const timestamp2 = duration > 0 ? i / Math.max(1, frameFiles.length - 1) * duration : i * frameInterval;
|
|
21363
|
+
frames.push({
|
|
21364
|
+
path: framePath,
|
|
21365
|
+
timestamp: timestamp2,
|
|
21366
|
+
hash,
|
|
21367
|
+
isDuplicate: false
|
|
21368
|
+
});
|
|
21369
|
+
}
|
|
21370
|
+
deduplicateFrames(frames);
|
|
21371
|
+
const permanentDir = join41(outDir, `frames-${Date.now()}`);
|
|
21372
|
+
mkdirSync9(permanentDir, { recursive: true });
|
|
21373
|
+
for (const frame of frames.filter((f) => !f.isDuplicate)) {
|
|
21374
|
+
const dest = join41(permanentDir, basename10(frame.path));
|
|
21375
|
+
try {
|
|
21376
|
+
writeFileSync9(dest, readFileSync20(frame.path));
|
|
21377
|
+
frame.path = dest;
|
|
21378
|
+
} catch {
|
|
21379
|
+
}
|
|
21380
|
+
}
|
|
21381
|
+
}
|
|
21382
|
+
const uniqueFrames = frames.filter((f) => !f.isDuplicate);
|
|
21383
|
+
const alignedTimeline = segments.map((seg) => {
|
|
21384
|
+
const mid = (seg.start + seg.end) / 2;
|
|
21385
|
+
let nearestFrame;
|
|
21386
|
+
let minDist = Infinity;
|
|
21387
|
+
for (const frame of uniqueFrames) {
|
|
21388
|
+
const dist = Math.abs(frame.timestamp - mid);
|
|
21389
|
+
if (dist < minDist) {
|
|
21390
|
+
minDist = dist;
|
|
21391
|
+
nearestFrame = frame;
|
|
21392
|
+
}
|
|
21393
|
+
}
|
|
21394
|
+
return {
|
|
21395
|
+
start: seg.start,
|
|
21396
|
+
end: seg.end,
|
|
21397
|
+
speech: seg.text,
|
|
21398
|
+
frameDescription: nearestFrame?.description,
|
|
21399
|
+
frameOcr: nearestFrame?.ocrText
|
|
21400
|
+
};
|
|
21401
|
+
});
|
|
21402
|
+
const result = {
|
|
21403
|
+
source: url || localPath || "unknown",
|
|
21404
|
+
title,
|
|
21405
|
+
duration,
|
|
21406
|
+
language,
|
|
21407
|
+
segments,
|
|
21408
|
+
frames: frames.filter((f) => !f.isDuplicate),
|
|
21409
|
+
alignedTimeline
|
|
21410
|
+
};
|
|
21411
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
21412
|
+
const resultFile = join41(outDir, `understanding-${timestamp}.json`);
|
|
21413
|
+
writeFileSync9(resultFile, JSON.stringify(result, null, 2), "utf-8");
|
|
21414
|
+
try {
|
|
21415
|
+
const memDir = join41(this.workingDir, ".oa", "memory");
|
|
21416
|
+
mkdirSync9(memDir, { recursive: true });
|
|
21417
|
+
const memFile = join41(memDir, "video-analyses.json");
|
|
21418
|
+
let entries = [];
|
|
21419
|
+
try {
|
|
21420
|
+
entries = JSON.parse(readFileSync20(memFile, "utf-8"));
|
|
21421
|
+
} catch {
|
|
21422
|
+
}
|
|
21423
|
+
entries.push({
|
|
21424
|
+
source: url || localPath,
|
|
21425
|
+
title,
|
|
21426
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
21427
|
+
duration,
|
|
21428
|
+
language,
|
|
21429
|
+
segmentCount: segments.length,
|
|
21430
|
+
frameCount: uniqueFrames.length,
|
|
21431
|
+
resultPath: resultFile,
|
|
21432
|
+
summary: segments.slice(0, 3).map((s) => s.text).join(" ").slice(0, 200)
|
|
21433
|
+
});
|
|
21434
|
+
if (entries.length > 30)
|
|
21435
|
+
entries = entries.slice(-30);
|
|
21436
|
+
writeFileSync9(memFile, JSON.stringify(entries, null, 2), "utf-8");
|
|
21437
|
+
} catch {
|
|
21438
|
+
}
|
|
21439
|
+
const lines = [];
|
|
21440
|
+
lines.push(`# Video Analysis${title ? `: ${title}` : ""}`);
|
|
21441
|
+
lines.push(`Source: ${url || localPath}`);
|
|
21442
|
+
lines.push(`Duration: ${duration.toFixed(1)}s | Language: ${language} | Segments: ${segments.length} | Frames: ${uniqueFrames.length}`);
|
|
21443
|
+
lines.push(`Saved: ${resultFile}`);
|
|
21444
|
+
lines.push("");
|
|
21445
|
+
lines.push("## Transcript");
|
|
21446
|
+
for (const seg of segments) {
|
|
21447
|
+
lines.push(`[${formatTime2(seg.start)} \u2192 ${formatTime2(seg.end)}] ${seg.text}`);
|
|
21448
|
+
}
|
|
21449
|
+
if (uniqueFrames.length > 0) {
|
|
21450
|
+
lines.push("");
|
|
21451
|
+
lines.push(`## Frames (${uniqueFrames.length} unique, ${frames.length - uniqueFrames.length} duplicates removed)`);
|
|
21452
|
+
for (const frame of uniqueFrames) {
|
|
21453
|
+
lines.push(` [${formatTime2(frame.timestamp)}] ${basename10(frame.path)}${frame.description ? ` \u2014 ${frame.description}` : ""}`);
|
|
21454
|
+
}
|
|
21455
|
+
}
|
|
21456
|
+
try {
|
|
21457
|
+
execSync24(`rm -rf "${tmpDir}"`, { timeout: 1e4, stdio: "pipe" });
|
|
21458
|
+
} catch {
|
|
21459
|
+
}
|
|
21460
|
+
return {
|
|
21461
|
+
success: true,
|
|
21462
|
+
output: lines.join("\n"),
|
|
21463
|
+
durationMs: performance.now() - start
|
|
21464
|
+
};
|
|
21465
|
+
} catch (err) {
|
|
21466
|
+
return {
|
|
21467
|
+
success: false,
|
|
21468
|
+
output: "",
|
|
21469
|
+
error: `Video analysis failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
21470
|
+
durationMs: performance.now() - start
|
|
21471
|
+
};
|
|
21472
|
+
}
|
|
21473
|
+
}
|
|
21474
|
+
};
|
|
21475
|
+
}
|
|
21476
|
+
});
|
|
21477
|
+
|
|
21204
21478
|
// packages/execution/dist/venv-paths.js
|
|
21205
|
-
import { join as
|
|
21479
|
+
import { join as join42 } from "node:path";
|
|
21206
21480
|
function venvPython(venvDir) {
|
|
21207
|
-
return isWin ?
|
|
21481
|
+
return isWin ? join42(venvDir, "Scripts", "python.exe") : join42(venvDir, "bin", "python");
|
|
21208
21482
|
}
|
|
21209
21483
|
function venvPip(venvDir) {
|
|
21210
|
-
return isWin ?
|
|
21484
|
+
return isWin ? join42(venvDir, "Scripts", "pip.exe") : join42(venvDir, "bin", "pip");
|
|
21211
21485
|
}
|
|
21212
21486
|
function venvBinDir(venvDir) {
|
|
21213
|
-
return isWin ?
|
|
21487
|
+
return isWin ? join42(venvDir, "Scripts") : join42(venvDir, "bin");
|
|
21214
21488
|
}
|
|
21215
21489
|
function venvExe(venvDir, name) {
|
|
21216
|
-
return isWin ?
|
|
21490
|
+
return isWin ? join42(venvDir, "Scripts", `${name}.exe`) : join42(venvDir, "bin", name);
|
|
21217
21491
|
}
|
|
21218
21492
|
var isWin;
|
|
21219
21493
|
var init_venv_paths = __esm({
|
|
@@ -21224,14 +21498,14 @@ var init_venv_paths = __esm({
|
|
|
21224
21498
|
});
|
|
21225
21499
|
|
|
21226
21500
|
// packages/execution/dist/tools/fortemi-bridge.js
|
|
21227
|
-
import { existsSync as
|
|
21228
|
-
import { join as
|
|
21501
|
+
import { existsSync as existsSync28, readFileSync as readFileSync21 } from "node:fs";
|
|
21502
|
+
import { join as join43 } from "node:path";
|
|
21229
21503
|
function loadBridgeState(repoRoot) {
|
|
21230
|
-
const bridgeFile =
|
|
21231
|
-
if (!
|
|
21504
|
+
const bridgeFile = join43(repoRoot, ".oa", "fortemi-bridge.json");
|
|
21505
|
+
if (!existsSync28(bridgeFile))
|
|
21232
21506
|
return null;
|
|
21233
21507
|
try {
|
|
21234
|
-
return JSON.parse(
|
|
21508
|
+
return JSON.parse(readFileSync21(bridgeFile, "utf8"));
|
|
21235
21509
|
} catch {
|
|
21236
21510
|
return null;
|
|
21237
21511
|
}
|
|
@@ -21479,7 +21753,7 @@ var init_gitWorktree = __esm({
|
|
|
21479
21753
|
});
|
|
21480
21754
|
|
|
21481
21755
|
// packages/execution/dist/patchApplier.js
|
|
21482
|
-
import { readFileSync as
|
|
21756
|
+
import { readFileSync as readFileSync22, writeFileSync as writeFileSync10, existsSync as existsSync29, mkdirSync as mkdirSync10 } from "node:fs";
|
|
21483
21757
|
import { dirname as dirname12 } from "node:path";
|
|
21484
21758
|
import { spawn as spawn15 } from "node:child_process";
|
|
21485
21759
|
async function applyPatch(patch) {
|
|
@@ -21495,22 +21769,22 @@ async function applyPatch(patch) {
|
|
|
21495
21769
|
}
|
|
21496
21770
|
}
|
|
21497
21771
|
function applyBlockReplace(patch) {
|
|
21498
|
-
const original =
|
|
21772
|
+
const original = readFileSync22(patch.filePath, "utf-8");
|
|
21499
21773
|
if (!original.includes(patch.oldContent)) {
|
|
21500
21774
|
throw new Error(`Block not found in "${patch.filePath}": the oldContent string was not found in the file.`);
|
|
21501
21775
|
}
|
|
21502
21776
|
const updated = original.replace(patch.oldContent, patch.newContent);
|
|
21503
|
-
|
|
21777
|
+
writeFileSync10(patch.filePath, updated, "utf-8");
|
|
21504
21778
|
}
|
|
21505
21779
|
function applyRewrite(patch) {
|
|
21506
|
-
|
|
21780
|
+
writeFileSync10(patch.filePath, patch.newContent, "utf-8");
|
|
21507
21781
|
}
|
|
21508
21782
|
function applyNewFile(patch) {
|
|
21509
|
-
if (
|
|
21783
|
+
if (existsSync29(patch.filePath)) {
|
|
21510
21784
|
throw new Error(`Cannot create new file: "${patch.filePath}" already exists.`);
|
|
21511
21785
|
}
|
|
21512
|
-
|
|
21513
|
-
|
|
21786
|
+
mkdirSync10(dirname12(patch.filePath), { recursive: true });
|
|
21787
|
+
writeFileSync10(patch.filePath, patch.newContent, "utf-8");
|
|
21514
21788
|
}
|
|
21515
21789
|
async function applyUnifiedDiff(patch) {
|
|
21516
21790
|
const { filePath, diff } = patch;
|
|
@@ -22041,6 +22315,7 @@ __export(dist_exports, {
|
|
|
22041
22315
|
ToolExecutor: () => ToolExecutor,
|
|
22042
22316
|
TranscribeFileTool: () => TranscribeFileTool,
|
|
22043
22317
|
TranscribeUrlTool: () => TranscribeUrlTool,
|
|
22318
|
+
VideoUnderstandTool: () => VideoUnderstandTool,
|
|
22044
22319
|
VisionTool: () => VisionTool,
|
|
22045
22320
|
WebCrawlTool: () => WebCrawlTool,
|
|
22046
22321
|
WebFetchTool: () => WebFetchTool,
|
|
@@ -22175,6 +22450,7 @@ var init_dist2 = __esm({
|
|
|
22175
22450
|
init_process_health();
|
|
22176
22451
|
init_full_sub_agent();
|
|
22177
22452
|
init_environment_snapshot();
|
|
22453
|
+
init_video_understand();
|
|
22178
22454
|
init_venv_paths();
|
|
22179
22455
|
init_nexus();
|
|
22180
22456
|
init_fortemi_bridge();
|
|
@@ -22862,17 +23138,17 @@ var init_dist3 = __esm({
|
|
|
22862
23138
|
});
|
|
22863
23139
|
|
|
22864
23140
|
// packages/orchestrator/dist/promptLoader.js
|
|
22865
|
-
import { readFileSync as
|
|
22866
|
-
import { join as
|
|
23141
|
+
import { readFileSync as readFileSync23, existsSync as existsSync30 } from "node:fs";
|
|
23142
|
+
import { join as join44, dirname as dirname13 } from "node:path";
|
|
22867
23143
|
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
22868
23144
|
function loadPrompt(promptPath, vars) {
|
|
22869
23145
|
let content = cache.get(promptPath);
|
|
22870
23146
|
if (content === void 0) {
|
|
22871
|
-
const fullPath =
|
|
22872
|
-
if (!
|
|
23147
|
+
const fullPath = join44(PROMPTS_DIR, promptPath);
|
|
23148
|
+
if (!existsSync30(fullPath)) {
|
|
22873
23149
|
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
22874
23150
|
}
|
|
22875
|
-
content =
|
|
23151
|
+
content = readFileSync23(fullPath, "utf-8");
|
|
22876
23152
|
cache.set(promptPath, content);
|
|
22877
23153
|
}
|
|
22878
23154
|
if (!vars)
|
|
@@ -22885,7 +23161,7 @@ var init_promptLoader = __esm({
|
|
|
22885
23161
|
"use strict";
|
|
22886
23162
|
__filename = fileURLToPath7(import.meta.url);
|
|
22887
23163
|
__dirname4 = dirname13(__filename);
|
|
22888
|
-
PROMPTS_DIR =
|
|
23164
|
+
PROMPTS_DIR = join44(__dirname4, "..", "prompts");
|
|
22889
23165
|
cache = /* @__PURE__ */ new Map();
|
|
22890
23166
|
}
|
|
22891
23167
|
});
|
|
@@ -23265,7 +23541,7 @@ var init_code_retriever = __esm({
|
|
|
23265
23541
|
import { execFile as execFile6 } from "node:child_process";
|
|
23266
23542
|
import { promisify as promisify5 } from "node:util";
|
|
23267
23543
|
import { readFile as readFile20, readdir as readdir5, stat as stat3 } from "node:fs/promises";
|
|
23268
|
-
import { join as
|
|
23544
|
+
import { join as join45, extname as extname8 } from "node:path";
|
|
23269
23545
|
async function searchByPath(pathPattern, options) {
|
|
23270
23546
|
const allFiles = await collectFiles(options.rootDir, options.includeGlobs ?? DEFAULT_INCLUDE_GLOBS, options.excludeGlobs ?? DEFAULT_EXCLUDE_GLOBS);
|
|
23271
23547
|
const pattern = options.caseInsensitive ? pathPattern.toLowerCase() : pathPattern;
|
|
@@ -23407,7 +23683,7 @@ async function walkForFiles(rootDir, dir, excludeGlobs, results) {
|
|
|
23407
23683
|
continue;
|
|
23408
23684
|
if (excludeGlobs.some((g) => entry.name === g || matchesGlob(entry.name, g)))
|
|
23409
23685
|
continue;
|
|
23410
|
-
const absPath =
|
|
23686
|
+
const absPath = join45(dir, entry.name);
|
|
23411
23687
|
if (entry.isDirectory()) {
|
|
23412
23688
|
await walkForFiles(rootDir, absPath, excludeGlobs, results);
|
|
23413
23689
|
} else if (entry.isFile()) {
|
|
@@ -23714,7 +23990,7 @@ var init_graphExpand = __esm({
|
|
|
23714
23990
|
|
|
23715
23991
|
// packages/retrieval/dist/snippetPacker.js
|
|
23716
23992
|
import { readFile as readFile21 } from "node:fs/promises";
|
|
23717
|
-
import { join as
|
|
23993
|
+
import { join as join46 } from "node:path";
|
|
23718
23994
|
async function packSnippets(requests, opts = {}) {
|
|
23719
23995
|
const maxTokens = opts.maxTokens ?? DEFAULT_MAX_TOKENS;
|
|
23720
23996
|
const contextLines = opts.contextLines ?? DEFAULT_CONTEXT_LINES;
|
|
@@ -23740,7 +24016,7 @@ async function packSnippets(requests, opts = {}) {
|
|
|
23740
24016
|
return { packed, dropped, totalTokens };
|
|
23741
24017
|
}
|
|
23742
24018
|
async function extractSnippet(req, repoRoot, contextLines = DEFAULT_CONTEXT_LINES) {
|
|
23743
|
-
const absPath = req.filePath.startsWith("/") ? req.filePath :
|
|
24019
|
+
const absPath = req.filePath.startsWith("/") ? req.filePath : join46(repoRoot, req.filePath);
|
|
23744
24020
|
let content;
|
|
23745
24021
|
try {
|
|
23746
24022
|
content = await readFile21(absPath, "utf-8");
|
|
@@ -26473,10 +26749,10 @@ ${marker}` : marker);
|
|
|
26473
26749
|
if (!this._workingDirectory)
|
|
26474
26750
|
return;
|
|
26475
26751
|
try {
|
|
26476
|
-
const { mkdirSync:
|
|
26477
|
-
const { join:
|
|
26478
|
-
const sessionDir =
|
|
26479
|
-
|
|
26752
|
+
const { mkdirSync: mkdirSync25, writeFileSync: writeFileSync24 } = __require("node:fs");
|
|
26753
|
+
const { join: join71 } = __require("node:path");
|
|
26754
|
+
const sessionDir = join71(this._workingDirectory, ".oa", "session", this._sessionId);
|
|
26755
|
+
mkdirSync25(sessionDir, { recursive: true });
|
|
26480
26756
|
const checkpoint = {
|
|
26481
26757
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
26482
26758
|
sessionId: this._sessionId,
|
|
@@ -26488,7 +26764,7 @@ ${marker}` : marker);
|
|
|
26488
26764
|
memexEntryCount: this._memexArchive.size,
|
|
26489
26765
|
fileRegistrySize: this._fileRegistry.size
|
|
26490
26766
|
};
|
|
26491
|
-
|
|
26767
|
+
writeFileSync24(join71(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
|
|
26492
26768
|
} catch {
|
|
26493
26769
|
}
|
|
26494
26770
|
}
|
|
@@ -27819,9 +28095,9 @@ ${transcript}`
|
|
|
27819
28095
|
});
|
|
27820
28096
|
|
|
27821
28097
|
// packages/orchestrator/dist/nexusBackend.js
|
|
27822
|
-
import { existsSync as
|
|
28098
|
+
import { existsSync as existsSync31, statSync as statSync10, openSync, readSync, closeSync, unlinkSync as unlinkSync5, writeFileSync as writeFileSync11 } from "node:fs";
|
|
27823
28099
|
import { watch as fsWatch } from "node:fs";
|
|
27824
|
-
import { join as
|
|
28100
|
+
import { join as join47 } from "node:path";
|
|
27825
28101
|
import { tmpdir as tmpdir7 } from "node:os";
|
|
27826
28102
|
import { randomBytes as randomBytes11 } from "node:crypto";
|
|
27827
28103
|
var NexusAgenticBackend;
|
|
@@ -27971,8 +28247,8 @@ var init_nexusBackend = __esm({
|
|
|
27971
28247
|
* Falls back to unary + word-split if streaming setup fails.
|
|
27972
28248
|
*/
|
|
27973
28249
|
async *chatCompletionStream(request) {
|
|
27974
|
-
const streamFile =
|
|
27975
|
-
|
|
28250
|
+
const streamFile = join47(tmpdir7(), `nexus-stream-${randomBytes11(6).toString("hex")}.jsonl`);
|
|
28251
|
+
writeFileSync11(streamFile, "", "utf8");
|
|
27976
28252
|
const daemonArgs = {
|
|
27977
28253
|
model: this.model,
|
|
27978
28254
|
messages: JSON.stringify(request.messages),
|
|
@@ -27992,7 +28268,7 @@ var init_nexusBackend = __esm({
|
|
|
27992
28268
|
} catch (sendErr) {
|
|
27993
28269
|
this.consecutiveFailures++;
|
|
27994
28270
|
try {
|
|
27995
|
-
|
|
28271
|
+
unlinkSync5(streamFile);
|
|
27996
28272
|
} catch {
|
|
27997
28273
|
}
|
|
27998
28274
|
throw sendErr;
|
|
@@ -28007,7 +28283,7 @@ var init_nexusBackend = __esm({
|
|
|
28007
28283
|
}
|
|
28008
28284
|
if (!isStreaming) {
|
|
28009
28285
|
try {
|
|
28010
|
-
|
|
28286
|
+
unlinkSync5(streamFile);
|
|
28011
28287
|
} catch {
|
|
28012
28288
|
}
|
|
28013
28289
|
let parsed;
|
|
@@ -28163,7 +28439,7 @@ var init_nexusBackend = __esm({
|
|
|
28163
28439
|
}
|
|
28164
28440
|
} finally {
|
|
28165
28441
|
try {
|
|
28166
|
-
|
|
28442
|
+
unlinkSync5(streamFile);
|
|
28167
28443
|
} catch {
|
|
28168
28444
|
}
|
|
28169
28445
|
}
|
|
@@ -29006,9 +29282,9 @@ __export(listen_exports, {
|
|
|
29006
29282
|
isVideoPath: () => isVideoPath,
|
|
29007
29283
|
waitForTranscribeCli: () => waitForTranscribeCli
|
|
29008
29284
|
});
|
|
29009
|
-
import { spawn as spawn16, execSync as
|
|
29010
|
-
import { existsSync as
|
|
29011
|
-
import { join as
|
|
29285
|
+
import { spawn as spawn16, execSync as execSync25 } from "node:child_process";
|
|
29286
|
+
import { existsSync as existsSync32, mkdirSync as mkdirSync11, writeFileSync as writeFileSync12, readdirSync as readdirSync8 } from "node:fs";
|
|
29287
|
+
import { join as join48, dirname as dirname14 } from "node:path";
|
|
29012
29288
|
import { homedir as homedir10 } from "node:os";
|
|
29013
29289
|
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
29014
29290
|
import { EventEmitter } from "node:events";
|
|
@@ -29028,7 +29304,7 @@ function findMicCaptureCommand() {
|
|
|
29028
29304
|
const platform6 = process.platform;
|
|
29029
29305
|
if (platform6 === "linux") {
|
|
29030
29306
|
try {
|
|
29031
|
-
|
|
29307
|
+
execSync25("which arecord", { stdio: "pipe" });
|
|
29032
29308
|
return {
|
|
29033
29309
|
cmd: "arecord",
|
|
29034
29310
|
args: ["-f", "S16_LE", "-r", "16000", "-c", "1", "-t", "raw", "-q", "-"]
|
|
@@ -29038,7 +29314,7 @@ function findMicCaptureCommand() {
|
|
|
29038
29314
|
}
|
|
29039
29315
|
if (platform6 === "darwin") {
|
|
29040
29316
|
try {
|
|
29041
|
-
|
|
29317
|
+
execSync25("which sox", { stdio: "pipe" });
|
|
29042
29318
|
return {
|
|
29043
29319
|
cmd: "sox",
|
|
29044
29320
|
args: ["-d", "-t", "raw", "-r", "16000", "-c", "1", "-b", "16", "-e", "signed-integer", "-"]
|
|
@@ -29047,7 +29323,7 @@ function findMicCaptureCommand() {
|
|
|
29047
29323
|
}
|
|
29048
29324
|
}
|
|
29049
29325
|
try {
|
|
29050
|
-
|
|
29326
|
+
execSync25("which ffmpeg", { stdio: "pipe" });
|
|
29051
29327
|
if (platform6 === "linux") {
|
|
29052
29328
|
return {
|
|
29053
29329
|
cmd: "ffmpeg",
|
|
@@ -29094,39 +29370,39 @@ function findMicCaptureCommand() {
|
|
|
29094
29370
|
function findLiveWhisperScript() {
|
|
29095
29371
|
const thisDir = dirname14(fileURLToPath8(import.meta.url));
|
|
29096
29372
|
const candidates = [
|
|
29097
|
-
|
|
29098
|
-
|
|
29099
|
-
|
|
29373
|
+
join48(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
|
|
29374
|
+
join48(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
|
|
29375
|
+
join48(thisDir, "../../execution/scripts/live-whisper.py"),
|
|
29100
29376
|
// npm install layout — scripts bundled alongside dist
|
|
29101
|
-
|
|
29102
|
-
|
|
29377
|
+
join48(thisDir, "../scripts/live-whisper.py"),
|
|
29378
|
+
join48(thisDir, "../../scripts/live-whisper.py")
|
|
29103
29379
|
];
|
|
29104
29380
|
for (const p of candidates) {
|
|
29105
|
-
if (
|
|
29381
|
+
if (existsSync32(p))
|
|
29106
29382
|
return p;
|
|
29107
29383
|
}
|
|
29108
29384
|
try {
|
|
29109
|
-
const globalRoot =
|
|
29385
|
+
const globalRoot = execSync25("npm root -g", {
|
|
29110
29386
|
encoding: "utf-8",
|
|
29111
29387
|
timeout: 5e3,
|
|
29112
29388
|
stdio: ["pipe", "pipe", "pipe"]
|
|
29113
29389
|
}).trim();
|
|
29114
29390
|
const candidates2 = [
|
|
29115
|
-
|
|
29116
|
-
|
|
29391
|
+
join48(globalRoot, "open-agents-ai", "dist", "scripts", "live-whisper.py"),
|
|
29392
|
+
join48(globalRoot, "open-agents-ai", "scripts", "live-whisper.py")
|
|
29117
29393
|
];
|
|
29118
29394
|
for (const p of candidates2) {
|
|
29119
|
-
if (
|
|
29395
|
+
if (existsSync32(p))
|
|
29120
29396
|
return p;
|
|
29121
29397
|
}
|
|
29122
29398
|
} catch {
|
|
29123
29399
|
}
|
|
29124
|
-
const nvmBase =
|
|
29125
|
-
if (
|
|
29400
|
+
const nvmBase = join48(homedir10(), ".nvm", "versions", "node");
|
|
29401
|
+
if (existsSync32(nvmBase)) {
|
|
29126
29402
|
try {
|
|
29127
|
-
for (const ver of
|
|
29128
|
-
const p =
|
|
29129
|
-
if (
|
|
29403
|
+
for (const ver of readdirSync8(nvmBase)) {
|
|
29404
|
+
const p = join48(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
|
|
29405
|
+
if (existsSync32(p))
|
|
29130
29406
|
return p;
|
|
29131
29407
|
}
|
|
29132
29408
|
} catch {
|
|
@@ -29139,12 +29415,12 @@ function ensureTranscribeCliBackground() {
|
|
|
29139
29415
|
return;
|
|
29140
29416
|
_bgInstallPromise = (async () => {
|
|
29141
29417
|
try {
|
|
29142
|
-
const globalRoot =
|
|
29418
|
+
const globalRoot = execSync25("npm root -g", {
|
|
29143
29419
|
encoding: "utf-8",
|
|
29144
29420
|
timeout: 5e3,
|
|
29145
29421
|
stdio: ["pipe", "pipe", "pipe"]
|
|
29146
29422
|
}).trim();
|
|
29147
|
-
if (
|
|
29423
|
+
if (existsSync32(join48(globalRoot, "transcribe-cli", "dist", "index.js"))) {
|
|
29148
29424
|
return true;
|
|
29149
29425
|
}
|
|
29150
29426
|
} catch {
|
|
@@ -29345,7 +29621,7 @@ var init_listen = __esm({
|
|
|
29345
29621
|
}
|
|
29346
29622
|
if (!this.transcribeCliAvailable) {
|
|
29347
29623
|
try {
|
|
29348
|
-
|
|
29624
|
+
execSync25("which transcribe-cli", { stdio: "pipe" });
|
|
29349
29625
|
this.transcribeCliAvailable = true;
|
|
29350
29626
|
} catch {
|
|
29351
29627
|
this.transcribeCliAvailable = false;
|
|
@@ -29362,29 +29638,29 @@ var init_listen = __esm({
|
|
|
29362
29638
|
} catch {
|
|
29363
29639
|
}
|
|
29364
29640
|
try {
|
|
29365
|
-
const globalRoot =
|
|
29641
|
+
const globalRoot = execSync25("npm root -g", {
|
|
29366
29642
|
encoding: "utf-8",
|
|
29367
29643
|
timeout: 5e3,
|
|
29368
29644
|
stdio: ["pipe", "pipe", "pipe"]
|
|
29369
29645
|
}).trim();
|
|
29370
|
-
const tcPath =
|
|
29371
|
-
if (
|
|
29646
|
+
const tcPath = join48(globalRoot, "transcribe-cli");
|
|
29647
|
+
if (existsSync32(join48(tcPath, "dist", "index.js"))) {
|
|
29372
29648
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
29373
29649
|
const req = createRequire4(import.meta.url);
|
|
29374
|
-
return req(
|
|
29650
|
+
return req(join48(tcPath, "dist", "index.js"));
|
|
29375
29651
|
}
|
|
29376
29652
|
} catch {
|
|
29377
29653
|
}
|
|
29378
|
-
const nvmBase =
|
|
29379
|
-
if (
|
|
29654
|
+
const nvmBase = join48(homedir10(), ".nvm", "versions", "node");
|
|
29655
|
+
if (existsSync32(nvmBase)) {
|
|
29380
29656
|
try {
|
|
29381
|
-
const { readdirSync:
|
|
29382
|
-
for (const ver of
|
|
29383
|
-
const tcPath =
|
|
29384
|
-
if (
|
|
29657
|
+
const { readdirSync: readdirSync20 } = await import("node:fs");
|
|
29658
|
+
for (const ver of readdirSync20(nvmBase)) {
|
|
29659
|
+
const tcPath = join48(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
|
|
29660
|
+
if (existsSync32(join48(tcPath, "dist", "index.js"))) {
|
|
29385
29661
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
29386
29662
|
const req = createRequire4(import.meta.url);
|
|
29387
|
-
return req(
|
|
29663
|
+
return req(join48(tcPath, "dist", "index.js"));
|
|
29388
29664
|
}
|
|
29389
29665
|
}
|
|
29390
29666
|
} catch {
|
|
@@ -29412,7 +29688,7 @@ var init_listen = __esm({
|
|
|
29412
29688
|
}
|
|
29413
29689
|
if (!tc) {
|
|
29414
29690
|
try {
|
|
29415
|
-
|
|
29691
|
+
execSync25("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
|
|
29416
29692
|
this.transcribeCliAvailable = null;
|
|
29417
29693
|
tc = await this.loadTranscribeCli();
|
|
29418
29694
|
} catch {
|
|
@@ -29595,7 +29871,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
29595
29871
|
}
|
|
29596
29872
|
if (!tc) {
|
|
29597
29873
|
try {
|
|
29598
|
-
|
|
29874
|
+
execSync25("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
|
|
29599
29875
|
this.transcribeCliAvailable = null;
|
|
29600
29876
|
tc = await this.loadTranscribeCli();
|
|
29601
29877
|
} catch {
|
|
@@ -29649,7 +29925,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
29649
29925
|
}
|
|
29650
29926
|
if (!tc) {
|
|
29651
29927
|
try {
|
|
29652
|
-
|
|
29928
|
+
execSync25("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
|
|
29653
29929
|
this.transcribeCliAvailable = null;
|
|
29654
29930
|
tc = await this.loadTranscribeCli();
|
|
29655
29931
|
} catch {
|
|
@@ -29665,11 +29941,11 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
29665
29941
|
wordTimestamps: false
|
|
29666
29942
|
});
|
|
29667
29943
|
if (outputDir) {
|
|
29668
|
-
const { basename:
|
|
29669
|
-
const transcriptDir =
|
|
29670
|
-
|
|
29671
|
-
const outFile =
|
|
29672
|
-
|
|
29944
|
+
const { basename: basename18 } = await import("node:path");
|
|
29945
|
+
const transcriptDir = join48(outputDir, ".oa", "transcripts");
|
|
29946
|
+
mkdirSync11(transcriptDir, { recursive: true });
|
|
29947
|
+
const outFile = join48(transcriptDir, `${basename18(filePath)}.txt`);
|
|
29948
|
+
writeFileSync12(outFile, result.text, "utf-8");
|
|
29673
29949
|
}
|
|
29674
29950
|
return {
|
|
29675
29951
|
text: result.text,
|
|
@@ -31917,7 +32193,7 @@ var require_websocket = __commonJS({
|
|
|
31917
32193
|
var http = __require("http");
|
|
31918
32194
|
var net = __require("net");
|
|
31919
32195
|
var tls = __require("tls");
|
|
31920
|
-
var { randomBytes: randomBytes15, createHash:
|
|
32196
|
+
var { randomBytes: randomBytes15, createHash: createHash6 } = __require("crypto");
|
|
31921
32197
|
var { Duplex, Readable } = __require("stream");
|
|
31922
32198
|
var { URL: URL3 } = __require("url");
|
|
31923
32199
|
var PerMessageDeflate = require_permessage_deflate();
|
|
@@ -32577,7 +32853,7 @@ var require_websocket = __commonJS({
|
|
|
32577
32853
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
32578
32854
|
return;
|
|
32579
32855
|
}
|
|
32580
|
-
const digest =
|
|
32856
|
+
const digest = createHash6("sha1").update(key + GUID).digest("base64");
|
|
32581
32857
|
if (res.headers["sec-websocket-accept"] !== digest) {
|
|
32582
32858
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
32583
32859
|
return;
|
|
@@ -32944,7 +33220,7 @@ var require_websocket_server = __commonJS({
|
|
|
32944
33220
|
var EventEmitter7 = __require("events");
|
|
32945
33221
|
var http = __require("http");
|
|
32946
33222
|
var { Duplex } = __require("stream");
|
|
32947
|
-
var { createHash:
|
|
33223
|
+
var { createHash: createHash6 } = __require("crypto");
|
|
32948
33224
|
var extension = require_extension();
|
|
32949
33225
|
var PerMessageDeflate = require_permessage_deflate();
|
|
32950
33226
|
var subprotocol = require_subprotocol();
|
|
@@ -33245,7 +33521,7 @@ var require_websocket_server = __commonJS({
|
|
|
33245
33521
|
);
|
|
33246
33522
|
}
|
|
33247
33523
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
33248
|
-
const digest =
|
|
33524
|
+
const digest = createHash6("sha1").update(key + GUID).digest("base64");
|
|
33249
33525
|
const headers = [
|
|
33250
33526
|
"HTTP/1.1 101 Switching Protocols",
|
|
33251
33527
|
"Upgrade: websocket",
|
|
@@ -34156,7 +34432,7 @@ var init_render = __esm({
|
|
|
34156
34432
|
|
|
34157
34433
|
// packages/cli/dist/tui/voice-session.js
|
|
34158
34434
|
import { createServer as createServer2 } from "node:http";
|
|
34159
|
-
import { spawn as spawn17, execSync as
|
|
34435
|
+
import { spawn as spawn17, execSync as execSync26 } from "node:child_process";
|
|
34160
34436
|
import { EventEmitter as EventEmitter2 } from "node:events";
|
|
34161
34437
|
function generateFrontendHTML() {
|
|
34162
34438
|
return `<!DOCTYPE html>
|
|
@@ -34889,8 +35165,8 @@ import { EventEmitter as EventEmitter3 } from "node:events";
|
|
|
34889
35165
|
import { randomBytes as randomBytes12 } from "node:crypto";
|
|
34890
35166
|
import { URL as URL2 } from "node:url";
|
|
34891
35167
|
import { loadavg, cpus as cpus2, totalmem as totalmem2, freemem as freemem2 } from "node:os";
|
|
34892
|
-
import { existsSync as
|
|
34893
|
-
import { join as
|
|
35168
|
+
import { existsSync as existsSync33, readFileSync as readFileSync24, writeFileSync as writeFileSync13, unlinkSync as unlinkSync6, mkdirSync as mkdirSync12, readdirSync as readdirSync9, statSync as statSync11 } from "node:fs";
|
|
35169
|
+
import { join as join49 } from "node:path";
|
|
34894
35170
|
function cleanForwardHeaders(raw, targetHost) {
|
|
34895
35171
|
const out = {};
|
|
34896
35172
|
for (const [key, value] of Object.entries(raw)) {
|
|
@@ -34918,10 +35194,10 @@ function fmtTokens(n) {
|
|
|
34918
35194
|
}
|
|
34919
35195
|
function readExposeState(stateDir) {
|
|
34920
35196
|
try {
|
|
34921
|
-
const path =
|
|
34922
|
-
if (!
|
|
35197
|
+
const path = join49(stateDir, STATE_FILE_NAME);
|
|
35198
|
+
if (!existsSync33(path))
|
|
34923
35199
|
return null;
|
|
34924
|
-
const raw =
|
|
35200
|
+
const raw = readFileSync24(path, "utf8");
|
|
34925
35201
|
const data = JSON.parse(raw);
|
|
34926
35202
|
if (!data.pid || !data.tunnelUrl || !data.authKey || !data.proxyPort)
|
|
34927
35203
|
return null;
|
|
@@ -34932,14 +35208,14 @@ function readExposeState(stateDir) {
|
|
|
34932
35208
|
}
|
|
34933
35209
|
function writeExposeState(stateDir, state) {
|
|
34934
35210
|
try {
|
|
34935
|
-
|
|
34936
|
-
|
|
35211
|
+
mkdirSync12(stateDir, { recursive: true });
|
|
35212
|
+
writeFileSync13(join49(stateDir, STATE_FILE_NAME), JSON.stringify(state, null, 2));
|
|
34937
35213
|
} catch {
|
|
34938
35214
|
}
|
|
34939
35215
|
}
|
|
34940
35216
|
function removeExposeState(stateDir) {
|
|
34941
35217
|
try {
|
|
34942
|
-
|
|
35218
|
+
unlinkSync6(join49(stateDir, STATE_FILE_NAME));
|
|
34943
35219
|
} catch {
|
|
34944
35220
|
}
|
|
34945
35221
|
}
|
|
@@ -35028,10 +35304,10 @@ async function collectSystemMetricsAsync() {
|
|
|
35028
35304
|
}
|
|
35029
35305
|
function readP2PExposeState(stateDir) {
|
|
35030
35306
|
try {
|
|
35031
|
-
const path =
|
|
35032
|
-
if (!
|
|
35307
|
+
const path = join49(stateDir, P2P_STATE_FILE_NAME);
|
|
35308
|
+
if (!existsSync33(path))
|
|
35033
35309
|
return null;
|
|
35034
|
-
const raw =
|
|
35310
|
+
const raw = readFileSync24(path, "utf8");
|
|
35035
35311
|
const data = JSON.parse(raw);
|
|
35036
35312
|
if (!data.peerId || !data.authKey)
|
|
35037
35313
|
return null;
|
|
@@ -35042,14 +35318,14 @@ function readP2PExposeState(stateDir) {
|
|
|
35042
35318
|
}
|
|
35043
35319
|
function writeP2PExposeState(stateDir, state) {
|
|
35044
35320
|
try {
|
|
35045
|
-
|
|
35046
|
-
|
|
35321
|
+
mkdirSync12(stateDir, { recursive: true });
|
|
35322
|
+
writeFileSync13(join49(stateDir, P2P_STATE_FILE_NAME), JSON.stringify(state, null, 2));
|
|
35047
35323
|
} catch {
|
|
35048
35324
|
}
|
|
35049
35325
|
}
|
|
35050
35326
|
function removeP2PExposeState(stateDir) {
|
|
35051
35327
|
try {
|
|
35052
|
-
|
|
35328
|
+
unlinkSync6(join49(stateDir, P2P_STATE_FILE_NAME));
|
|
35053
35329
|
} catch {
|
|
35054
35330
|
}
|
|
35055
35331
|
}
|
|
@@ -35897,10 +36173,10 @@ ${this.formatConnectionInfo()}`);
|
|
|
35897
36173
|
throw new Error(`Expose failed: ${exposeResult.error}`);
|
|
35898
36174
|
}
|
|
35899
36175
|
const nexusDir = this._nexusTool.getNexusDir();
|
|
35900
|
-
const statusPath =
|
|
36176
|
+
const statusPath = join49(nexusDir, "status.json");
|
|
35901
36177
|
for (let i = 0; i < 80; i++) {
|
|
35902
36178
|
try {
|
|
35903
|
-
const raw =
|
|
36179
|
+
const raw = readFileSync24(statusPath, "utf8");
|
|
35904
36180
|
if (raw.length > 10) {
|
|
35905
36181
|
const status = JSON.parse(raw);
|
|
35906
36182
|
if (status.connected && status.peerId) {
|
|
@@ -35931,9 +36207,9 @@ ${this.formatConnectionInfo()}`);
|
|
|
35931
36207
|
});
|
|
35932
36208
|
}
|
|
35933
36209
|
try {
|
|
35934
|
-
const invocDir =
|
|
35935
|
-
if (
|
|
35936
|
-
this._prevInvocCount =
|
|
36210
|
+
const invocDir = join49(nexusDir, "invocations");
|
|
36211
|
+
if (existsSync33(invocDir)) {
|
|
36212
|
+
this._prevInvocCount = readdirSync9(invocDir).filter((f) => f.endsWith(".json")).length;
|
|
35937
36213
|
this._stats.totalRequests = this._prevInvocCount;
|
|
35938
36214
|
}
|
|
35939
36215
|
} catch {
|
|
@@ -35961,13 +36237,13 @@ ${this.formatConnectionInfo()}`);
|
|
|
35961
36237
|
if (!state)
|
|
35962
36238
|
return null;
|
|
35963
36239
|
const nexusDir = nexusTool.getNexusDir();
|
|
35964
|
-
const statusPath =
|
|
36240
|
+
const statusPath = join49(nexusDir, "status.json");
|
|
35965
36241
|
try {
|
|
35966
|
-
if (!
|
|
36242
|
+
if (!existsSync33(statusPath)) {
|
|
35967
36243
|
removeP2PExposeState(stateDir);
|
|
35968
36244
|
return null;
|
|
35969
36245
|
}
|
|
35970
|
-
const status = JSON.parse(
|
|
36246
|
+
const status = JSON.parse(readFileSync24(statusPath, "utf8"));
|
|
35971
36247
|
if (!status.connected || !status.peerId) {
|
|
35972
36248
|
removeP2PExposeState(stateDir);
|
|
35973
36249
|
return null;
|
|
@@ -36020,10 +36296,10 @@ ${this.formatConnectionInfo()}`);
|
|
|
36020
36296
|
let lastMeteringLineCount = 0;
|
|
36021
36297
|
this._activityPollTimer = setInterval(() => {
|
|
36022
36298
|
try {
|
|
36023
|
-
const invocDir =
|
|
36024
|
-
if (!
|
|
36299
|
+
const invocDir = join49(nexusDir, "invocations");
|
|
36300
|
+
if (!existsSync33(invocDir))
|
|
36025
36301
|
return;
|
|
36026
|
-
const files =
|
|
36302
|
+
const files = readdirSync9(invocDir).filter((f) => f.endsWith(".json"));
|
|
36027
36303
|
const invocCount = files.length;
|
|
36028
36304
|
const newRequests = invocCount - this._prevInvocCount;
|
|
36029
36305
|
if (newRequests > 0) {
|
|
@@ -36036,17 +36312,17 @@ ${this.formatConnectionInfo()}`);
|
|
|
36036
36312
|
let recentActive = 0;
|
|
36037
36313
|
for (const f of files.slice(-10)) {
|
|
36038
36314
|
try {
|
|
36039
|
-
const st = statSync11(
|
|
36315
|
+
const st = statSync11(join49(invocDir, f));
|
|
36040
36316
|
if (now - st.mtimeMs < 1e4)
|
|
36041
36317
|
recentActive++;
|
|
36042
36318
|
} catch {
|
|
36043
36319
|
}
|
|
36044
36320
|
}
|
|
36045
|
-
const meteringFile =
|
|
36321
|
+
const meteringFile = join49(nexusDir, "metering.jsonl");
|
|
36046
36322
|
let meteringLines = lastMeteringLineCount;
|
|
36047
36323
|
try {
|
|
36048
|
-
if (
|
|
36049
|
-
const content =
|
|
36324
|
+
if (existsSync33(meteringFile)) {
|
|
36325
|
+
const content = readFileSync24(meteringFile, "utf8");
|
|
36050
36326
|
meteringLines = content.split("\n").filter((l) => l.trim()).length;
|
|
36051
36327
|
}
|
|
36052
36328
|
} catch {
|
|
@@ -36072,9 +36348,9 @@ ${this.formatConnectionInfo()}`);
|
|
|
36072
36348
|
this._activityPollTimer.unref();
|
|
36073
36349
|
this._pollTimer = setInterval(() => {
|
|
36074
36350
|
try {
|
|
36075
|
-
const statusPath =
|
|
36076
|
-
if (
|
|
36077
|
-
const status = JSON.parse(
|
|
36351
|
+
const statusPath = join49(nexusDir, "status.json");
|
|
36352
|
+
if (existsSync33(statusPath)) {
|
|
36353
|
+
const status = JSON.parse(readFileSync24(statusPath, "utf8"));
|
|
36078
36354
|
if (status.peerId && !this._peerId) {
|
|
36079
36355
|
this._peerId = status.peerId;
|
|
36080
36356
|
}
|
|
@@ -36083,9 +36359,9 @@ ${this.formatConnectionInfo()}`);
|
|
|
36083
36359
|
} catch {
|
|
36084
36360
|
}
|
|
36085
36361
|
try {
|
|
36086
|
-
const invocDir =
|
|
36087
|
-
if (
|
|
36088
|
-
const files =
|
|
36362
|
+
const invocDir = join49(nexusDir, "invocations");
|
|
36363
|
+
if (existsSync33(invocDir)) {
|
|
36364
|
+
const files = readdirSync9(invocDir);
|
|
36089
36365
|
const invocCount = files.filter((f) => f.endsWith(".json")).length;
|
|
36090
36366
|
if (invocCount > this._stats.totalRequests) {
|
|
36091
36367
|
this._stats.totalRequests = invocCount;
|
|
@@ -36095,9 +36371,9 @@ ${this.formatConnectionInfo()}`);
|
|
|
36095
36371
|
} catch {
|
|
36096
36372
|
}
|
|
36097
36373
|
try {
|
|
36098
|
-
const meteringFile =
|
|
36099
|
-
if (
|
|
36100
|
-
const content =
|
|
36374
|
+
const meteringFile = join49(nexusDir, "metering.jsonl");
|
|
36375
|
+
if (existsSync33(meteringFile)) {
|
|
36376
|
+
const content = readFileSync24(meteringFile, "utf8");
|
|
36101
36377
|
if (content.length > lastMeteringSize) {
|
|
36102
36378
|
const newContent = content.slice(lastMeteringSize);
|
|
36103
36379
|
lastMeteringSize = content.length;
|
|
@@ -36305,9 +36581,9 @@ var init_types = __esm({
|
|
|
36305
36581
|
});
|
|
36306
36582
|
|
|
36307
36583
|
// packages/cli/dist/tui/p2p/secret-vault.js
|
|
36308
|
-
import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes13, scryptSync as scryptSync2, createHash as
|
|
36309
|
-
import { readFileSync as
|
|
36310
|
-
import { join as
|
|
36584
|
+
import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes13, scryptSync as scryptSync2, createHash as createHash3 } from "node:crypto";
|
|
36585
|
+
import { readFileSync as readFileSync25, writeFileSync as writeFileSync14, existsSync as existsSync34, mkdirSync as mkdirSync13 } from "node:fs";
|
|
36586
|
+
import { join as join50, dirname as dirname15 } from "node:path";
|
|
36311
36587
|
var PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, CIPHER_ALGO, SALT_LEN, IV_LEN, KEY_LEN, SecretVault;
|
|
36312
36588
|
var init_secret_vault = __esm({
|
|
36313
36589
|
"packages/cli/dist/tui/p2p/secret-vault.js"() {
|
|
@@ -36519,18 +36795,18 @@ var init_secret_vault = __esm({
|
|
|
36519
36795
|
const tag = cipher.getAuthTag();
|
|
36520
36796
|
const blob = Buffer.concat([salt, iv, tag, encrypted]);
|
|
36521
36797
|
const dir = dirname15(this.storePath);
|
|
36522
|
-
if (!
|
|
36523
|
-
|
|
36524
|
-
|
|
36798
|
+
if (!existsSync34(dir))
|
|
36799
|
+
mkdirSync13(dir, { recursive: true });
|
|
36800
|
+
writeFileSync14(this.storePath, blob, { mode: 384 });
|
|
36525
36801
|
}
|
|
36526
36802
|
/**
|
|
36527
36803
|
* Load vault from disk, decrypting with the given passphrase.
|
|
36528
36804
|
* Returns the number of secrets loaded.
|
|
36529
36805
|
*/
|
|
36530
36806
|
load(passphrase) {
|
|
36531
|
-
if (!this.storePath || !
|
|
36807
|
+
if (!this.storePath || !existsSync34(this.storePath))
|
|
36532
36808
|
return 0;
|
|
36533
|
-
const blob =
|
|
36809
|
+
const blob = readFileSync25(this.storePath);
|
|
36534
36810
|
if (blob.length < SALT_LEN + IV_LEN + 16) {
|
|
36535
36811
|
throw new Error("Vault file is corrupted (too small)");
|
|
36536
36812
|
}
|
|
@@ -36556,7 +36832,7 @@ var init_secret_vault = __esm({
|
|
|
36556
36832
|
/** Generate a deterministic fingerprint of vault contents (for sync verification) */
|
|
36557
36833
|
fingerprint() {
|
|
36558
36834
|
const names = Array.from(this.secrets.keys()).sort();
|
|
36559
|
-
const hash =
|
|
36835
|
+
const hash = createHash3("sha256");
|
|
36560
36836
|
for (const name of names) {
|
|
36561
36837
|
hash.update(name + ":");
|
|
36562
36838
|
hash.update(this.secrets.get(name).value);
|
|
@@ -36571,7 +36847,7 @@ var init_secret_vault = __esm({
|
|
|
36571
36847
|
// packages/cli/dist/tui/p2p/peer-mesh.js
|
|
36572
36848
|
import { EventEmitter as EventEmitter4 } from "node:events";
|
|
36573
36849
|
import { createServer as createServer4 } from "node:http";
|
|
36574
|
-
import { randomBytes as randomBytes14, createHash as
|
|
36850
|
+
import { randomBytes as randomBytes14, createHash as createHash4, generateKeyPairSync } from "node:crypto";
|
|
36575
36851
|
var PING_INTERVAL_MS, PEER_TIMEOUT_MS, GOSSIP_INTERVAL_MS, MAX_PEERS, PeerMesh;
|
|
36576
36852
|
var init_peer_mesh = __esm({
|
|
36577
36853
|
"packages/cli/dist/tui/p2p/peer-mesh.js"() {
|
|
@@ -36620,7 +36896,7 @@ var init_peer_mesh = __esm({
|
|
|
36620
36896
|
const { publicKey, privateKey } = generateKeyPairSync("ed25519");
|
|
36621
36897
|
this.publicKey = publicKey.export({ type: "spki", format: "der" });
|
|
36622
36898
|
this.privateKey = privateKey.export({ type: "pkcs8", format: "der" });
|
|
36623
|
-
this.peerId =
|
|
36899
|
+
this.peerId = createHash4("sha256").update(this.publicKey).digest("base64url").slice(0, 22);
|
|
36624
36900
|
this.capabilities = options.capabilities;
|
|
36625
36901
|
this.displayName = options.displayName;
|
|
36626
36902
|
this._authKey = options.authKey ?? randomBytes14(24).toString("base64url");
|
|
@@ -37651,26 +37927,26 @@ async function fetchOpenAIModels(baseUrl, apiKey) {
|
|
|
37651
37927
|
async function fetchPeerModels(peerId, authKey) {
|
|
37652
37928
|
try {
|
|
37653
37929
|
const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
|
|
37654
|
-
const { existsSync:
|
|
37655
|
-
const { join:
|
|
37930
|
+
const { existsSync: existsSync51, readFileSync: readFileSync39 } = await import("node:fs");
|
|
37931
|
+
const { join: join71 } = await import("node:path");
|
|
37656
37932
|
const cwd4 = process.cwd();
|
|
37657
37933
|
const nexusTool = new NexusTool2(cwd4);
|
|
37658
37934
|
const nexusDir = nexusTool.getNexusDir();
|
|
37659
37935
|
let isLocalPeer = false;
|
|
37660
37936
|
try {
|
|
37661
|
-
const statusPath =
|
|
37662
|
-
if (
|
|
37663
|
-
const status = JSON.parse(
|
|
37937
|
+
const statusPath = join71(nexusDir, "status.json");
|
|
37938
|
+
if (existsSync51(statusPath)) {
|
|
37939
|
+
const status = JSON.parse(readFileSync39(statusPath, "utf8"));
|
|
37664
37940
|
if (status.peerId === peerId)
|
|
37665
37941
|
isLocalPeer = true;
|
|
37666
37942
|
}
|
|
37667
37943
|
} catch {
|
|
37668
37944
|
}
|
|
37669
37945
|
if (isLocalPeer) {
|
|
37670
|
-
const pricingPath =
|
|
37671
|
-
if (
|
|
37946
|
+
const pricingPath = join71(nexusDir, "pricing.json");
|
|
37947
|
+
if (existsSync51(pricingPath)) {
|
|
37672
37948
|
try {
|
|
37673
|
-
const pricing = JSON.parse(
|
|
37949
|
+
const pricing = JSON.parse(readFileSync39(pricingPath, "utf8"));
|
|
37674
37950
|
const localModels = (pricing.models || []).map((m) => ({
|
|
37675
37951
|
name: m.model || "unknown",
|
|
37676
37952
|
size: m.parameterSize || "",
|
|
@@ -37684,10 +37960,10 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
37684
37960
|
}
|
|
37685
37961
|
}
|
|
37686
37962
|
}
|
|
37687
|
-
const cachePath =
|
|
37688
|
-
if (
|
|
37963
|
+
const cachePath = join71(nexusDir, "peer-models-cache.json");
|
|
37964
|
+
if (existsSync51(cachePath)) {
|
|
37689
37965
|
try {
|
|
37690
|
-
const cache4 = JSON.parse(
|
|
37966
|
+
const cache4 = JSON.parse(readFileSync39(cachePath, "utf8"));
|
|
37691
37967
|
if (cache4.peerId === peerId && cache4.models?.length > 0) {
|
|
37692
37968
|
const age = Date.now() - new Date(cache4.cachedAt).getTime();
|
|
37693
37969
|
if (age < 5 * 60 * 1e3) {
|
|
@@ -37802,10 +38078,10 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
37802
38078
|
} catch {
|
|
37803
38079
|
}
|
|
37804
38080
|
if (isLocalPeer) {
|
|
37805
|
-
const pricingPath =
|
|
37806
|
-
if (
|
|
38081
|
+
const pricingPath = join71(nexusDir, "pricing.json");
|
|
38082
|
+
if (existsSync51(pricingPath)) {
|
|
37807
38083
|
try {
|
|
37808
|
-
const pricing = JSON.parse(
|
|
38084
|
+
const pricing = JSON.parse(readFileSync39(pricingPath, "utf8"));
|
|
37809
38085
|
return (pricing.models || []).map((m) => ({
|
|
37810
38086
|
name: m.model || "unknown",
|
|
37811
38087
|
size: m.parameterSize || "",
|
|
@@ -38085,17 +38361,17 @@ var init_render2 = __esm({
|
|
|
38085
38361
|
});
|
|
38086
38362
|
|
|
38087
38363
|
// packages/prompts/dist/promptLoader.js
|
|
38088
|
-
import { readFileSync as
|
|
38089
|
-
import { join as
|
|
38364
|
+
import { readFileSync as readFileSync26, existsSync as existsSync35 } from "node:fs";
|
|
38365
|
+
import { join as join51, dirname as dirname16 } from "node:path";
|
|
38090
38366
|
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
38091
38367
|
function loadPrompt2(promptPath, vars) {
|
|
38092
38368
|
let content = cache2.get(promptPath);
|
|
38093
38369
|
if (content === void 0) {
|
|
38094
|
-
const fullPath =
|
|
38095
|
-
if (!
|
|
38370
|
+
const fullPath = join51(PROMPTS_DIR2, promptPath);
|
|
38371
|
+
if (!existsSync35(fullPath)) {
|
|
38096
38372
|
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
38097
38373
|
}
|
|
38098
|
-
content =
|
|
38374
|
+
content = readFileSync26(fullPath, "utf-8");
|
|
38099
38375
|
cache2.set(promptPath, content);
|
|
38100
38376
|
}
|
|
38101
38377
|
if (!vars)
|
|
@@ -38108,9 +38384,9 @@ var init_promptLoader2 = __esm({
|
|
|
38108
38384
|
"use strict";
|
|
38109
38385
|
__filename2 = fileURLToPath9(import.meta.url);
|
|
38110
38386
|
__dirname5 = dirname16(__filename2);
|
|
38111
|
-
devPath =
|
|
38112
|
-
publishedPath =
|
|
38113
|
-
PROMPTS_DIR2 =
|
|
38387
|
+
devPath = join51(__dirname5, "..", "templates");
|
|
38388
|
+
publishedPath = join51(__dirname5, "..", "prompts", "templates");
|
|
38389
|
+
PROMPTS_DIR2 = existsSync35(devPath) ? devPath : publishedPath;
|
|
38114
38390
|
cache2 = /* @__PURE__ */ new Map();
|
|
38115
38391
|
}
|
|
38116
38392
|
});
|
|
@@ -38221,7 +38497,7 @@ var init_task_templates = __esm({
|
|
|
38221
38497
|
});
|
|
38222
38498
|
|
|
38223
38499
|
// packages/prompts/dist/index.js
|
|
38224
|
-
import { join as
|
|
38500
|
+
import { join as join52, dirname as dirname17 } from "node:path";
|
|
38225
38501
|
import { fileURLToPath as fileURLToPath10 } from "node:url";
|
|
38226
38502
|
var _dir, _packageRoot;
|
|
38227
38503
|
var init_dist6 = __esm({
|
|
@@ -38232,7 +38508,7 @@ var init_dist6 = __esm({
|
|
|
38232
38508
|
init_task_templates();
|
|
38233
38509
|
init_render2();
|
|
38234
38510
|
_dir = dirname17(fileURLToPath10(import.meta.url));
|
|
38235
|
-
_packageRoot =
|
|
38511
|
+
_packageRoot = join52(_dir, "..");
|
|
38236
38512
|
}
|
|
38237
38513
|
});
|
|
38238
38514
|
|
|
@@ -38265,21 +38541,21 @@ __export(oa_directory_exports, {
|
|
|
38265
38541
|
writeIndexData: () => writeIndexData,
|
|
38266
38542
|
writeIndexMeta: () => writeIndexMeta
|
|
38267
38543
|
});
|
|
38268
|
-
import { existsSync as
|
|
38269
|
-
import { join as
|
|
38544
|
+
import { existsSync as existsSync36, mkdirSync as mkdirSync14, readFileSync as readFileSync27, writeFileSync as writeFileSync15, readdirSync as readdirSync10, statSync as statSync12, unlinkSync as unlinkSync7 } from "node:fs";
|
|
38545
|
+
import { join as join53, relative as relative3, basename as basename11, extname as extname9 } from "node:path";
|
|
38270
38546
|
import { homedir as homedir11 } from "node:os";
|
|
38271
38547
|
function initOaDirectory(repoRoot) {
|
|
38272
|
-
const oaPath =
|
|
38548
|
+
const oaPath = join53(repoRoot, OA_DIR);
|
|
38273
38549
|
for (const sub of SUBDIRS) {
|
|
38274
|
-
|
|
38550
|
+
mkdirSync14(join53(oaPath, sub), { recursive: true });
|
|
38275
38551
|
}
|
|
38276
38552
|
try {
|
|
38277
|
-
const gitignorePath =
|
|
38553
|
+
const gitignorePath = join53(repoRoot, ".gitignore");
|
|
38278
38554
|
const settingsPattern = ".oa/settings.json";
|
|
38279
|
-
if (
|
|
38280
|
-
const content =
|
|
38555
|
+
if (existsSync36(gitignorePath)) {
|
|
38556
|
+
const content = readFileSync27(gitignorePath, "utf-8");
|
|
38281
38557
|
if (!content.includes(settingsPattern)) {
|
|
38282
|
-
|
|
38558
|
+
writeFileSync15(gitignorePath, content.trimEnd() + "\n" + settingsPattern + "\n", "utf-8");
|
|
38283
38559
|
}
|
|
38284
38560
|
}
|
|
38285
38561
|
} catch {
|
|
@@ -38287,41 +38563,41 @@ function initOaDirectory(repoRoot) {
|
|
|
38287
38563
|
return oaPath;
|
|
38288
38564
|
}
|
|
38289
38565
|
function hasOaDirectory(repoRoot) {
|
|
38290
|
-
return
|
|
38566
|
+
return existsSync36(join53(repoRoot, OA_DIR, "index"));
|
|
38291
38567
|
}
|
|
38292
38568
|
function loadProjectSettings(repoRoot) {
|
|
38293
|
-
const settingsPath =
|
|
38569
|
+
const settingsPath = join53(repoRoot, OA_DIR, "settings.json");
|
|
38294
38570
|
try {
|
|
38295
|
-
if (
|
|
38296
|
-
return JSON.parse(
|
|
38571
|
+
if (existsSync36(settingsPath)) {
|
|
38572
|
+
return JSON.parse(readFileSync27(settingsPath, "utf-8"));
|
|
38297
38573
|
}
|
|
38298
38574
|
} catch {
|
|
38299
38575
|
}
|
|
38300
38576
|
return {};
|
|
38301
38577
|
}
|
|
38302
38578
|
function saveProjectSettings(repoRoot, settings) {
|
|
38303
|
-
const oaPath =
|
|
38304
|
-
|
|
38579
|
+
const oaPath = join53(repoRoot, OA_DIR);
|
|
38580
|
+
mkdirSync14(oaPath, { recursive: true });
|
|
38305
38581
|
const existing = loadProjectSettings(repoRoot);
|
|
38306
38582
|
const merged = { ...existing, ...settings };
|
|
38307
|
-
|
|
38583
|
+
writeFileSync15(join53(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
38308
38584
|
}
|
|
38309
38585
|
function loadGlobalSettings() {
|
|
38310
|
-
const settingsPath =
|
|
38586
|
+
const settingsPath = join53(homedir11(), ".open-agents", "settings.json");
|
|
38311
38587
|
try {
|
|
38312
|
-
if (
|
|
38313
|
-
return JSON.parse(
|
|
38588
|
+
if (existsSync36(settingsPath)) {
|
|
38589
|
+
return JSON.parse(readFileSync27(settingsPath, "utf-8"));
|
|
38314
38590
|
}
|
|
38315
38591
|
} catch {
|
|
38316
38592
|
}
|
|
38317
38593
|
return {};
|
|
38318
38594
|
}
|
|
38319
38595
|
function saveGlobalSettings(settings) {
|
|
38320
|
-
const dir =
|
|
38321
|
-
|
|
38596
|
+
const dir = join53(homedir11(), ".open-agents");
|
|
38597
|
+
mkdirSync14(dir, { recursive: true });
|
|
38322
38598
|
const existing = loadGlobalSettings();
|
|
38323
38599
|
const merged = { ...existing, ...settings };
|
|
38324
|
-
|
|
38600
|
+
writeFileSync15(join53(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
38325
38601
|
}
|
|
38326
38602
|
function resolveSettings(repoRoot) {
|
|
38327
38603
|
const global = loadGlobalSettings();
|
|
@@ -38336,12 +38612,12 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
38336
38612
|
while (dir && !visited.has(dir)) {
|
|
38337
38613
|
visited.add(dir);
|
|
38338
38614
|
for (const name of CONTEXT_FILES) {
|
|
38339
|
-
const filePath =
|
|
38615
|
+
const filePath = join53(dir, name);
|
|
38340
38616
|
const normalizedName = name.toLowerCase();
|
|
38341
|
-
if (
|
|
38617
|
+
if (existsSync36(filePath) && !seen.has(filePath)) {
|
|
38342
38618
|
seen.add(filePath);
|
|
38343
38619
|
try {
|
|
38344
|
-
let content =
|
|
38620
|
+
let content = readFileSync27(filePath, "utf-8");
|
|
38345
38621
|
if (content.length > maxContentLen) {
|
|
38346
38622
|
content = content.slice(0, maxContentLen) + "\n\n...(truncated)";
|
|
38347
38623
|
}
|
|
@@ -38355,11 +38631,11 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
38355
38631
|
}
|
|
38356
38632
|
}
|
|
38357
38633
|
}
|
|
38358
|
-
const projectMap =
|
|
38359
|
-
if (
|
|
38634
|
+
const projectMap = join53(dir, OA_DIR, "context", "project-map.md");
|
|
38635
|
+
if (existsSync36(projectMap) && !seen.has(projectMap)) {
|
|
38360
38636
|
seen.add(projectMap);
|
|
38361
38637
|
try {
|
|
38362
|
-
let content =
|
|
38638
|
+
let content = readFileSync27(projectMap, "utf-8");
|
|
38363
38639
|
if (content.length > maxContentLen) {
|
|
38364
38640
|
content = content.slice(0, maxContentLen) + "\n\n...(truncated)";
|
|
38365
38641
|
}
|
|
@@ -38371,7 +38647,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
38371
38647
|
} catch {
|
|
38372
38648
|
}
|
|
38373
38649
|
}
|
|
38374
|
-
const parent =
|
|
38650
|
+
const parent = join53(dir, "..");
|
|
38375
38651
|
if (parent === dir)
|
|
38376
38652
|
break;
|
|
38377
38653
|
dir = parent;
|
|
@@ -38389,34 +38665,34 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
38389
38665
|
return found;
|
|
38390
38666
|
}
|
|
38391
38667
|
function readIndexMeta(repoRoot) {
|
|
38392
|
-
const metaPath =
|
|
38668
|
+
const metaPath = join53(repoRoot, OA_DIR, "index", "meta.json");
|
|
38393
38669
|
try {
|
|
38394
|
-
return JSON.parse(
|
|
38670
|
+
return JSON.parse(readFileSync27(metaPath, "utf-8"));
|
|
38395
38671
|
} catch {
|
|
38396
38672
|
return null;
|
|
38397
38673
|
}
|
|
38398
38674
|
}
|
|
38399
38675
|
function writeIndexMeta(repoRoot, meta) {
|
|
38400
|
-
const metaPath =
|
|
38401
|
-
|
|
38402
|
-
|
|
38676
|
+
const metaPath = join53(repoRoot, OA_DIR, "index", "meta.json");
|
|
38677
|
+
mkdirSync14(join53(repoRoot, OA_DIR, "index"), { recursive: true });
|
|
38678
|
+
writeFileSync15(metaPath, JSON.stringify(meta, null, 2), "utf-8");
|
|
38403
38679
|
}
|
|
38404
38680
|
function readIndexData(repoRoot, filename) {
|
|
38405
|
-
const filePath =
|
|
38681
|
+
const filePath = join53(repoRoot, OA_DIR, "index", filename);
|
|
38406
38682
|
try {
|
|
38407
|
-
return JSON.parse(
|
|
38683
|
+
return JSON.parse(readFileSync27(filePath, "utf-8"));
|
|
38408
38684
|
} catch {
|
|
38409
38685
|
return null;
|
|
38410
38686
|
}
|
|
38411
38687
|
}
|
|
38412
38688
|
function writeIndexData(repoRoot, filename, data) {
|
|
38413
|
-
const filePath =
|
|
38414
|
-
|
|
38415
|
-
|
|
38689
|
+
const filePath = join53(repoRoot, OA_DIR, "index", filename);
|
|
38690
|
+
mkdirSync14(join53(repoRoot, OA_DIR, "index"), { recursive: true });
|
|
38691
|
+
writeFileSync15(filePath, JSON.stringify(data, null, 2), "utf-8");
|
|
38416
38692
|
}
|
|
38417
38693
|
function generateProjectMap(repoRoot) {
|
|
38418
38694
|
const sections = [];
|
|
38419
|
-
const repoName2 =
|
|
38695
|
+
const repoName2 = basename11(repoRoot);
|
|
38420
38696
|
sections.push(`# Project Map: ${repoName2}
|
|
38421
38697
|
`);
|
|
38422
38698
|
sections.push(`> Auto-generated by open-agents. Updated: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
|
|
@@ -38460,28 +38736,28 @@ ${tree}\`\`\`
|
|
|
38460
38736
|
sections.push("");
|
|
38461
38737
|
}
|
|
38462
38738
|
const content = sections.join("\n");
|
|
38463
|
-
const contextDir =
|
|
38464
|
-
|
|
38465
|
-
|
|
38739
|
+
const contextDir = join53(repoRoot, OA_DIR, "context");
|
|
38740
|
+
mkdirSync14(contextDir, { recursive: true });
|
|
38741
|
+
writeFileSync15(join53(contextDir, "project-map.md"), content, "utf-8");
|
|
38466
38742
|
return content;
|
|
38467
38743
|
}
|
|
38468
38744
|
function saveSession(repoRoot, session) {
|
|
38469
|
-
const historyDir =
|
|
38470
|
-
|
|
38471
|
-
|
|
38745
|
+
const historyDir = join53(repoRoot, OA_DIR, "history");
|
|
38746
|
+
mkdirSync14(historyDir, { recursive: true });
|
|
38747
|
+
writeFileSync15(join53(historyDir, `${session.id}.json`), JSON.stringify(session, null, 2), "utf-8");
|
|
38472
38748
|
}
|
|
38473
38749
|
function loadRecentSessions(repoRoot, limit = 5) {
|
|
38474
|
-
const historyDir =
|
|
38475
|
-
if (!
|
|
38750
|
+
const historyDir = join53(repoRoot, OA_DIR, "history");
|
|
38751
|
+
if (!existsSync36(historyDir))
|
|
38476
38752
|
return [];
|
|
38477
38753
|
try {
|
|
38478
|
-
const files =
|
|
38479
|
-
const stat5 = statSync12(
|
|
38754
|
+
const files = readdirSync10(historyDir).filter((f) => f.endsWith(".json") && f !== "pending-task.json").map((f) => {
|
|
38755
|
+
const stat5 = statSync12(join53(historyDir, f));
|
|
38480
38756
|
return { file: f, mtime: stat5.mtimeMs };
|
|
38481
38757
|
}).sort((a, b) => b.mtime - a.mtime).slice(0, limit);
|
|
38482
38758
|
return files.map((f) => {
|
|
38483
38759
|
try {
|
|
38484
|
-
return JSON.parse(
|
|
38760
|
+
return JSON.parse(readFileSync27(join53(historyDir, f.file), "utf-8"));
|
|
38485
38761
|
} catch {
|
|
38486
38762
|
return null;
|
|
38487
38763
|
}
|
|
@@ -38491,18 +38767,18 @@ function loadRecentSessions(repoRoot, limit = 5) {
|
|
|
38491
38767
|
}
|
|
38492
38768
|
}
|
|
38493
38769
|
function savePendingTask(repoRoot, task) {
|
|
38494
|
-
const historyDir =
|
|
38495
|
-
|
|
38496
|
-
|
|
38770
|
+
const historyDir = join53(repoRoot, OA_DIR, "history");
|
|
38771
|
+
mkdirSync14(historyDir, { recursive: true });
|
|
38772
|
+
writeFileSync15(join53(historyDir, PENDING_TASK_FILE), JSON.stringify(task, null, 2) + "\n", "utf-8");
|
|
38497
38773
|
}
|
|
38498
38774
|
function loadPendingTask(repoRoot) {
|
|
38499
|
-
const filePath =
|
|
38775
|
+
const filePath = join53(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
|
|
38500
38776
|
try {
|
|
38501
|
-
if (!
|
|
38777
|
+
if (!existsSync36(filePath))
|
|
38502
38778
|
return null;
|
|
38503
|
-
const data = JSON.parse(
|
|
38779
|
+
const data = JSON.parse(readFileSync27(filePath, "utf-8"));
|
|
38504
38780
|
try {
|
|
38505
|
-
|
|
38781
|
+
unlinkSync7(filePath);
|
|
38506
38782
|
} catch {
|
|
38507
38783
|
}
|
|
38508
38784
|
return data;
|
|
@@ -38511,13 +38787,13 @@ function loadPendingTask(repoRoot) {
|
|
|
38511
38787
|
}
|
|
38512
38788
|
}
|
|
38513
38789
|
function saveSessionContext(repoRoot, entry) {
|
|
38514
|
-
const contextDir =
|
|
38515
|
-
|
|
38516
|
-
const filePath =
|
|
38790
|
+
const contextDir = join53(repoRoot, OA_DIR, "context");
|
|
38791
|
+
mkdirSync14(contextDir, { recursive: true });
|
|
38792
|
+
const filePath = join53(contextDir, CONTEXT_SAVE_FILE);
|
|
38517
38793
|
let ctx;
|
|
38518
38794
|
try {
|
|
38519
|
-
if (
|
|
38520
|
-
ctx = JSON.parse(
|
|
38795
|
+
if (existsSync36(filePath)) {
|
|
38796
|
+
ctx = JSON.parse(readFileSync27(filePath, "utf-8"));
|
|
38521
38797
|
} else {
|
|
38522
38798
|
ctx = { entries: [], maxEntries: MAX_CONTEXT_ENTRIES, updatedAt: "" };
|
|
38523
38799
|
}
|
|
@@ -38529,14 +38805,14 @@ function saveSessionContext(repoRoot, entry) {
|
|
|
38529
38805
|
ctx.entries = ctx.entries.slice(-ctx.maxEntries);
|
|
38530
38806
|
}
|
|
38531
38807
|
ctx.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
38532
|
-
|
|
38808
|
+
writeFileSync15(filePath, JSON.stringify(ctx, null, 2) + "\n", "utf-8");
|
|
38533
38809
|
}
|
|
38534
38810
|
function loadSessionContext(repoRoot) {
|
|
38535
|
-
const filePath =
|
|
38811
|
+
const filePath = join53(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
|
|
38536
38812
|
try {
|
|
38537
|
-
if (!
|
|
38813
|
+
if (!existsSync36(filePath))
|
|
38538
38814
|
return null;
|
|
38539
|
-
return JSON.parse(
|
|
38815
|
+
return JSON.parse(readFileSync27(filePath, "utf-8"));
|
|
38540
38816
|
} catch {
|
|
38541
38817
|
return null;
|
|
38542
38818
|
}
|
|
@@ -38582,12 +38858,12 @@ function detectManifests(repoRoot) {
|
|
|
38582
38858
|
{ file: "docker-compose.yaml", type: "Docker Compose" }
|
|
38583
38859
|
];
|
|
38584
38860
|
for (const check of checks) {
|
|
38585
|
-
const filePath =
|
|
38586
|
-
if (
|
|
38861
|
+
const filePath = join53(repoRoot, check.file);
|
|
38862
|
+
if (existsSync36(filePath)) {
|
|
38587
38863
|
let name;
|
|
38588
38864
|
if (check.nameField) {
|
|
38589
38865
|
try {
|
|
38590
|
-
const data = JSON.parse(
|
|
38866
|
+
const data = JSON.parse(readFileSync27(filePath, "utf-8"));
|
|
38591
38867
|
name = data[check.nameField];
|
|
38592
38868
|
} catch {
|
|
38593
38869
|
}
|
|
@@ -38616,7 +38892,7 @@ function findKeyFiles(repoRoot) {
|
|
|
38616
38892
|
{ pattern: "CLAUDE.md", description: "Claude Code context" }
|
|
38617
38893
|
];
|
|
38618
38894
|
for (const check of checks) {
|
|
38619
|
-
if (
|
|
38895
|
+
if (existsSync36(join53(repoRoot, check.pattern))) {
|
|
38620
38896
|
keyFiles.push({ path: check.pattern, description: check.description });
|
|
38621
38897
|
}
|
|
38622
38898
|
}
|
|
@@ -38627,7 +38903,7 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
|
|
|
38627
38903
|
return "";
|
|
38628
38904
|
let result = "";
|
|
38629
38905
|
try {
|
|
38630
|
-
const entries =
|
|
38906
|
+
const entries = readdirSync10(root, { withFileTypes: true }).filter((e) => !e.name.startsWith(".") || e.name === ".github").filter((e) => !SKIP_DIRS.has(e.name)).sort((a, b) => {
|
|
38631
38907
|
if (a.isDirectory() && !b.isDirectory())
|
|
38632
38908
|
return -1;
|
|
38633
38909
|
if (!a.isDirectory() && b.isDirectory())
|
|
@@ -38642,12 +38918,12 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
|
|
|
38642
38918
|
if (entry.isDirectory()) {
|
|
38643
38919
|
let fileCount = 0;
|
|
38644
38920
|
try {
|
|
38645
|
-
fileCount =
|
|
38921
|
+
fileCount = readdirSync10(join53(root, entry.name)).filter((f) => !f.startsWith(".")).length;
|
|
38646
38922
|
} catch {
|
|
38647
38923
|
}
|
|
38648
38924
|
result += `${prefix}${connector}${entry.name}/ (${fileCount})
|
|
38649
38925
|
`;
|
|
38650
|
-
result += buildDirTree(
|
|
38926
|
+
result += buildDirTree(join53(root, entry.name), maxDepth, childPrefix, depth + 1);
|
|
38651
38927
|
} else if (depth < maxDepth) {
|
|
38652
38928
|
result += `${prefix}${connector}${entry.name}
|
|
38653
38929
|
`;
|
|
@@ -38659,17 +38935,17 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
|
|
|
38659
38935
|
}
|
|
38660
38936
|
function loadUsageFile(filePath) {
|
|
38661
38937
|
try {
|
|
38662
|
-
if (
|
|
38663
|
-
return JSON.parse(
|
|
38938
|
+
if (existsSync36(filePath)) {
|
|
38939
|
+
return JSON.parse(readFileSync27(filePath, "utf-8"));
|
|
38664
38940
|
}
|
|
38665
38941
|
} catch {
|
|
38666
38942
|
}
|
|
38667
38943
|
return { records: [] };
|
|
38668
38944
|
}
|
|
38669
38945
|
function saveUsageFile(filePath, data) {
|
|
38670
|
-
const dir =
|
|
38671
|
-
|
|
38672
|
-
|
|
38946
|
+
const dir = join53(filePath, "..");
|
|
38947
|
+
mkdirSync14(dir, { recursive: true });
|
|
38948
|
+
writeFileSync15(filePath, JSON.stringify(data, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
38673
38949
|
}
|
|
38674
38950
|
function recordUsage(kind, value, opts) {
|
|
38675
38951
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -38697,15 +38973,15 @@ function recordUsage(kind, value, opts) {
|
|
|
38697
38973
|
}
|
|
38698
38974
|
saveUsageFile(filePath, data);
|
|
38699
38975
|
};
|
|
38700
|
-
update(
|
|
38976
|
+
update(join53(homedir11(), ".open-agents", USAGE_HISTORY_FILE));
|
|
38701
38977
|
if (opts?.repoRoot) {
|
|
38702
|
-
update(
|
|
38978
|
+
update(join53(opts.repoRoot, OA_DIR, USAGE_HISTORY_FILE));
|
|
38703
38979
|
}
|
|
38704
38980
|
}
|
|
38705
38981
|
function loadUsageHistory(kind, repoRoot) {
|
|
38706
|
-
const globalPath =
|
|
38982
|
+
const globalPath = join53(homedir11(), ".open-agents", USAGE_HISTORY_FILE);
|
|
38707
38983
|
const globalData = loadUsageFile(globalPath);
|
|
38708
|
-
const localData = repoRoot ? loadUsageFile(
|
|
38984
|
+
const localData = repoRoot ? loadUsageFile(join53(repoRoot, OA_DIR, USAGE_HISTORY_FILE)) : { records: [] };
|
|
38709
38985
|
const map = /* @__PURE__ */ new Map();
|
|
38710
38986
|
for (const r of globalData.records) {
|
|
38711
38987
|
if (r.kind !== kind)
|
|
@@ -38736,9 +39012,9 @@ function deleteUsageRecord(kind, value, repoRoot) {
|
|
|
38736
39012
|
saveUsageFile(filePath, data);
|
|
38737
39013
|
}
|
|
38738
39014
|
};
|
|
38739
|
-
remove(
|
|
39015
|
+
remove(join53(homedir11(), ".open-agents", USAGE_HISTORY_FILE));
|
|
38740
39016
|
if (repoRoot) {
|
|
38741
|
-
remove(
|
|
39017
|
+
remove(join53(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
|
|
38742
39018
|
}
|
|
38743
39019
|
}
|
|
38744
39020
|
var OA_DIR, SUBDIRS, CONTEXT_FILES, PENDING_TASK_FILE, CONTEXT_SAVE_FILE, MAX_CONTEXT_ENTRIES, SKIP_DIRS, USAGE_HISTORY_FILE, MAX_HISTORY_RECORDS;
|
|
@@ -38786,10 +39062,10 @@ var init_oa_directory = __esm({
|
|
|
38786
39062
|
|
|
38787
39063
|
// packages/cli/dist/tui/setup.js
|
|
38788
39064
|
import * as readline from "node:readline";
|
|
38789
|
-
import { execSync as
|
|
39065
|
+
import { execSync as execSync27, spawn as spawn19, exec as exec2 } from "node:child_process";
|
|
38790
39066
|
import { promisify as promisify6 } from "node:util";
|
|
38791
|
-
import { existsSync as
|
|
38792
|
-
import { join as
|
|
39067
|
+
import { existsSync as existsSync37, writeFileSync as writeFileSync16, readFileSync as readFileSync28, appendFileSync as appendFileSync2, mkdirSync as mkdirSync15 } from "node:fs";
|
|
39068
|
+
import { join as join54 } from "node:path";
|
|
38793
39069
|
import { homedir as homedir12, platform as platform2 } from "node:os";
|
|
38794
39070
|
function detectSystemSpecs() {
|
|
38795
39071
|
let totalRamGB = 0;
|
|
@@ -38797,7 +39073,7 @@ function detectSystemSpecs() {
|
|
|
38797
39073
|
let gpuVramGB = 0;
|
|
38798
39074
|
let gpuName = "";
|
|
38799
39075
|
try {
|
|
38800
|
-
const memInfo =
|
|
39076
|
+
const memInfo = execSync27("free -b 2>/dev/null || sysctl -n hw.memsize 2>/dev/null", {
|
|
38801
39077
|
encoding: "utf8",
|
|
38802
39078
|
timeout: 5e3
|
|
38803
39079
|
});
|
|
@@ -38817,7 +39093,7 @@ function detectSystemSpecs() {
|
|
|
38817
39093
|
} catch {
|
|
38818
39094
|
}
|
|
38819
39095
|
try {
|
|
38820
|
-
const nvidiaSmi =
|
|
39096
|
+
const nvidiaSmi = execSync27("nvidia-smi --query-gpu=memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 5e3 });
|
|
38821
39097
|
const lines = nvidiaSmi.trim().split("\n");
|
|
38822
39098
|
if (lines.length > 0) {
|
|
38823
39099
|
for (const line of lines) {
|
|
@@ -38996,7 +39272,7 @@ function ensureCurl() {
|
|
|
38996
39272
|
for (const s of strategies) {
|
|
38997
39273
|
if (hasCmd(s.check)) {
|
|
38998
39274
|
try {
|
|
38999
|
-
|
|
39275
|
+
execSync27(s.install, { stdio: "inherit", timeout: 12e4 });
|
|
39000
39276
|
if (hasCmd("curl")) {
|
|
39001
39277
|
process.stdout.write(` ${c2.green("\u2714")} curl installed via ${s.label}.
|
|
39002
39278
|
`);
|
|
@@ -39010,7 +39286,7 @@ function ensureCurl() {
|
|
|
39010
39286
|
}
|
|
39011
39287
|
if (plat === "darwin") {
|
|
39012
39288
|
try {
|
|
39013
|
-
|
|
39289
|
+
execSync27("xcode-select --install", { stdio: "inherit", timeout: 3e5 });
|
|
39014
39290
|
if (hasCmd("curl"))
|
|
39015
39291
|
return true;
|
|
39016
39292
|
} catch {
|
|
@@ -39045,7 +39321,7 @@ function installOllamaLinux() {
|
|
|
39045
39321
|
|
|
39046
39322
|
`);
|
|
39047
39323
|
try {
|
|
39048
|
-
|
|
39324
|
+
execSync27("curl -fsSL https://ollama.com/install.sh | sh", {
|
|
39049
39325
|
stdio: "inherit",
|
|
39050
39326
|
timeout: 3e5
|
|
39051
39327
|
});
|
|
@@ -39073,10 +39349,10 @@ async function installOllamaMac(_rl) {
|
|
|
39073
39349
|
|
|
39074
39350
|
`);
|
|
39075
39351
|
try {
|
|
39076
|
-
|
|
39352
|
+
execSync27('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"', { stdio: "inherit", timeout: 6e5 });
|
|
39077
39353
|
if (!hasCmd("brew")) {
|
|
39078
39354
|
try {
|
|
39079
|
-
const brewPrefix =
|
|
39355
|
+
const brewPrefix = existsSync37("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
|
|
39080
39356
|
process.env["PATH"] = `${brewPrefix}/bin:${process.env["PATH"]}`;
|
|
39081
39357
|
} catch {
|
|
39082
39358
|
}
|
|
@@ -39106,7 +39382,7 @@ async function installOllamaMac(_rl) {
|
|
|
39106
39382
|
|
|
39107
39383
|
`);
|
|
39108
39384
|
try {
|
|
39109
|
-
|
|
39385
|
+
execSync27("brew install ollama", {
|
|
39110
39386
|
stdio: "inherit",
|
|
39111
39387
|
timeout: 3e5
|
|
39112
39388
|
});
|
|
@@ -39133,7 +39409,7 @@ function installOllamaWindows() {
|
|
|
39133
39409
|
|
|
39134
39410
|
`);
|
|
39135
39411
|
try {
|
|
39136
|
-
|
|
39412
|
+
execSync27('powershell -Command "irm https://ollama.com/install.ps1 | iex"', {
|
|
39137
39413
|
stdio: "inherit",
|
|
39138
39414
|
timeout: 3e5
|
|
39139
39415
|
});
|
|
@@ -39214,7 +39490,7 @@ async function ensureOllamaRunning(backendUrl, rl) {
|
|
|
39214
39490
|
}
|
|
39215
39491
|
function pullModelWithAutoUpdate(tag) {
|
|
39216
39492
|
try {
|
|
39217
|
-
|
|
39493
|
+
execSync27(`ollama pull ${tag}`, {
|
|
39218
39494
|
stdio: "inherit",
|
|
39219
39495
|
timeout: 36e5
|
|
39220
39496
|
// 1 hour max
|
|
@@ -39234,7 +39510,7 @@ function pullModelWithAutoUpdate(tag) {
|
|
|
39234
39510
|
|
|
39235
39511
|
`);
|
|
39236
39512
|
try {
|
|
39237
|
-
|
|
39513
|
+
execSync27("curl -fsSL https://ollama.com/install.sh | sh", {
|
|
39238
39514
|
stdio: "inherit",
|
|
39239
39515
|
timeout: 3e5
|
|
39240
39516
|
// 5 min max for install
|
|
@@ -39245,7 +39521,7 @@ function pullModelWithAutoUpdate(tag) {
|
|
|
39245
39521
|
process.stdout.write(` ${c2.cyan("\u25CF")} Retrying pull of ${c2.bold(tag)}...
|
|
39246
39522
|
|
|
39247
39523
|
`);
|
|
39248
|
-
|
|
39524
|
+
execSync27(`ollama pull ${tag}`, {
|
|
39249
39525
|
stdio: "inherit",
|
|
39250
39526
|
timeout: 36e5
|
|
39251
39527
|
});
|
|
@@ -39347,7 +39623,7 @@ function ensurePython3() {
|
|
|
39347
39623
|
if (plat === "darwin") {
|
|
39348
39624
|
if (hasCmd("brew")) {
|
|
39349
39625
|
try {
|
|
39350
|
-
|
|
39626
|
+
execSync27("brew install python3", { stdio: "inherit", timeout: 3e5 });
|
|
39351
39627
|
if (hasCmd("python3")) {
|
|
39352
39628
|
process.stdout.write(` ${c2.green("\u2714")} Python3 installed via Homebrew.
|
|
39353
39629
|
`);
|
|
@@ -39360,7 +39636,7 @@ function ensurePython3() {
|
|
|
39360
39636
|
for (const s of strategies) {
|
|
39361
39637
|
if (hasCmd(s.check)) {
|
|
39362
39638
|
try {
|
|
39363
|
-
|
|
39639
|
+
execSync27(s.install, { stdio: "inherit", timeout: 12e4 });
|
|
39364
39640
|
if (hasCmd("python3") || hasCmd("python")) {
|
|
39365
39641
|
process.stdout.write(` ${c2.green("\u2714")} Python3 installed via ${s.label}.
|
|
39366
39642
|
`);
|
|
@@ -39376,11 +39652,11 @@ function ensurePython3() {
|
|
|
39376
39652
|
}
|
|
39377
39653
|
function checkPythonVenv() {
|
|
39378
39654
|
try {
|
|
39379
|
-
|
|
39655
|
+
execSync27("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
|
|
39380
39656
|
return true;
|
|
39381
39657
|
} catch {
|
|
39382
39658
|
try {
|
|
39383
|
-
|
|
39659
|
+
execSync27("python -m venv --help", { stdio: "pipe", timeout: 5e3 });
|
|
39384
39660
|
return true;
|
|
39385
39661
|
} catch {
|
|
39386
39662
|
return false;
|
|
@@ -39399,7 +39675,7 @@ function ensurePythonVenv() {
|
|
|
39399
39675
|
for (const s of strategies) {
|
|
39400
39676
|
if (hasCmd(s.check)) {
|
|
39401
39677
|
try {
|
|
39402
|
-
|
|
39678
|
+
execSync27(s.install, { stdio: "inherit", timeout: 12e4 });
|
|
39403
39679
|
if (checkPythonVenv()) {
|
|
39404
39680
|
process.stdout.write(` ${c2.green("\u2714")} python3-venv installed via ${s.label}.
|
|
39405
39681
|
`);
|
|
@@ -39830,12 +40106,12 @@ async function doSetup(config, rl) {
|
|
|
39830
40106
|
`PARAMETER num_predict ${numPredict}`,
|
|
39831
40107
|
`PARAMETER stop "<|endoftext|>"`
|
|
39832
40108
|
].join("\n");
|
|
39833
|
-
const modelDir2 =
|
|
39834
|
-
|
|
39835
|
-
const modelfilePath =
|
|
39836
|
-
|
|
40109
|
+
const modelDir2 = join54(homedir12(), ".open-agents", "models");
|
|
40110
|
+
mkdirSync15(modelDir2, { recursive: true });
|
|
40111
|
+
const modelfilePath = join54(modelDir2, `Modelfile.${customName}`);
|
|
40112
|
+
writeFileSync16(modelfilePath, modelfileContent + "\n", "utf8");
|
|
39837
40113
|
process.stdout.write(` ${c2.dim("Creating model...")} `);
|
|
39838
|
-
|
|
40114
|
+
execSync27(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
39839
40115
|
stdio: "pipe",
|
|
39840
40116
|
timeout: 12e4
|
|
39841
40117
|
});
|
|
@@ -39878,7 +40154,7 @@ async function isModelAvailable(config) {
|
|
|
39878
40154
|
}
|
|
39879
40155
|
function isFirstRun() {
|
|
39880
40156
|
try {
|
|
39881
|
-
return !
|
|
40157
|
+
return !existsSync37(join54(homedir12(), ".open-agents", "config.json"));
|
|
39882
40158
|
} catch {
|
|
39883
40159
|
return true;
|
|
39884
40160
|
}
|
|
@@ -39886,7 +40162,7 @@ function isFirstRun() {
|
|
|
39886
40162
|
function hasCmd(cmd) {
|
|
39887
40163
|
try {
|
|
39888
40164
|
const whichCmd = process.platform === "win32" ? `where ${cmd}` : `which ${cmd}`;
|
|
39889
|
-
|
|
40165
|
+
execSync27(whichCmd, { stdio: "pipe", timeout: 3e3 });
|
|
39890
40166
|
return true;
|
|
39891
40167
|
} catch {
|
|
39892
40168
|
return false;
|
|
@@ -39915,11 +40191,11 @@ function detectPkgManager() {
|
|
|
39915
40191
|
return null;
|
|
39916
40192
|
}
|
|
39917
40193
|
function getVenvDir() {
|
|
39918
|
-
return
|
|
40194
|
+
return join54(homedir12(), ".open-agents", "venv");
|
|
39919
40195
|
}
|
|
39920
40196
|
function hasVenvModule() {
|
|
39921
40197
|
try {
|
|
39922
|
-
|
|
40198
|
+
execSync27("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
|
|
39923
40199
|
return true;
|
|
39924
40200
|
} catch {
|
|
39925
40201
|
return false;
|
|
@@ -39928,9 +40204,9 @@ function hasVenvModule() {
|
|
|
39928
40204
|
function ensureVenv(log) {
|
|
39929
40205
|
const venvDir = getVenvDir();
|
|
39930
40206
|
const isWin2 = process.platform === "win32";
|
|
39931
|
-
const pipPath = isWin2 ?
|
|
40207
|
+
const pipPath = isWin2 ? join54(venvDir, "Scripts", "pip.exe") : join54(venvDir, "bin", "pip");
|
|
39932
40208
|
const pythonCmd = isWin2 ? "python" : "python3";
|
|
39933
|
-
if (
|
|
40209
|
+
if (existsSync37(pipPath))
|
|
39934
40210
|
return venvDir;
|
|
39935
40211
|
log("Creating Python venv for vision deps...");
|
|
39936
40212
|
if (!hasCmd(pythonCmd) && !hasCmd("python3")) {
|
|
@@ -39942,10 +40218,10 @@ function ensureVenv(log) {
|
|
|
39942
40218
|
return null;
|
|
39943
40219
|
}
|
|
39944
40220
|
try {
|
|
39945
|
-
|
|
40221
|
+
mkdirSync15(join54(homedir12(), ".open-agents"), { recursive: true });
|
|
39946
40222
|
const pyCmd = hasCmd(pythonCmd) ? pythonCmd : "python3";
|
|
39947
|
-
|
|
39948
|
-
|
|
40223
|
+
execSync27(`${pyCmd} -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
|
|
40224
|
+
execSync27(`"${pipPath}" install --upgrade pip`, {
|
|
39949
40225
|
stdio: "pipe",
|
|
39950
40226
|
timeout: 6e4
|
|
39951
40227
|
});
|
|
@@ -39958,7 +40234,7 @@ function ensureVenv(log) {
|
|
|
39958
40234
|
}
|
|
39959
40235
|
function trySudoPasswordless(cmd, timeoutMs = 12e4) {
|
|
39960
40236
|
try {
|
|
39961
|
-
|
|
40237
|
+
execSync27(`sudo -n ${cmd}`, {
|
|
39962
40238
|
stdio: "pipe",
|
|
39963
40239
|
timeout: timeoutMs,
|
|
39964
40240
|
env: { ...process.env, DEBIAN_FRONTEND: "noninteractive" }
|
|
@@ -39971,7 +40247,7 @@ function trySudoPasswordless(cmd, timeoutMs = 12e4) {
|
|
|
39971
40247
|
function runWithSudo(cmd, password, timeoutMs = 12e4) {
|
|
39972
40248
|
try {
|
|
39973
40249
|
const escaped = cmd.replace(/'/g, "'\\''");
|
|
39974
|
-
|
|
40250
|
+
execSync27(`sudo -S bash -c '${escaped}'`, {
|
|
39975
40251
|
input: password + "\n",
|
|
39976
40252
|
stdio: ["pipe", "pipe", "pipe"],
|
|
39977
40253
|
timeout: timeoutMs,
|
|
@@ -40078,7 +40354,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
40078
40354
|
ok = await sudoInstall(batchCmd, getPassword, log, cachedPasswordRef, 18e4);
|
|
40079
40355
|
} else {
|
|
40080
40356
|
try {
|
|
40081
|
-
|
|
40357
|
+
execSync27(batchCmd, { stdio: "pipe", timeout: 18e4 });
|
|
40082
40358
|
ok = true;
|
|
40083
40359
|
} catch {
|
|
40084
40360
|
ok = false;
|
|
@@ -40115,7 +40391,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
40115
40391
|
const venvCmds = {
|
|
40116
40392
|
apt: () => {
|
|
40117
40393
|
try {
|
|
40118
|
-
const pyVer =
|
|
40394
|
+
const pyVer = execSync27(`python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).trim();
|
|
40119
40395
|
return `apt-get install -y python3-venv python${pyVer}-venv`;
|
|
40120
40396
|
} catch {
|
|
40121
40397
|
return "apt-get install -y python3-venv";
|
|
@@ -40136,19 +40412,19 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
40136
40412
|
}
|
|
40137
40413
|
}
|
|
40138
40414
|
const venvDir = getVenvDir();
|
|
40139
|
-
const venvBin =
|
|
40140
|
-
const venvMoondream =
|
|
40415
|
+
const venvBin = join54(venvDir, "bin");
|
|
40416
|
+
const venvMoondream = join54(venvBin, "moondream-station");
|
|
40141
40417
|
const venv = ensureVenv(log);
|
|
40142
|
-
if (venv && !hasCmd("moondream-station") && !
|
|
40143
|
-
const venvPip2 =
|
|
40418
|
+
if (venv && !hasCmd("moondream-station") && !existsSync37(venvMoondream)) {
|
|
40419
|
+
const venvPip2 = join54(venvBin, "pip");
|
|
40144
40420
|
log("Installing moondream-station in ~/.open-agents/venv...");
|
|
40145
40421
|
try {
|
|
40146
|
-
|
|
40147
|
-
if (
|
|
40422
|
+
execSync27(`"${venvPip2}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
|
|
40423
|
+
if (existsSync37(venvMoondream)) {
|
|
40148
40424
|
log("moondream-station installed successfully.");
|
|
40149
40425
|
} else {
|
|
40150
40426
|
try {
|
|
40151
|
-
const check =
|
|
40427
|
+
const check = execSync27(`"${venvPip2}" show moondream-station`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 });
|
|
40152
40428
|
if (check.includes("moondream")) {
|
|
40153
40429
|
log("moondream-station package installed.");
|
|
40154
40430
|
}
|
|
@@ -40161,11 +40437,11 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
40161
40437
|
}
|
|
40162
40438
|
}
|
|
40163
40439
|
if (venv) {
|
|
40164
|
-
const venvPython2 =
|
|
40165
|
-
const venvPip2 =
|
|
40440
|
+
const venvPython2 = join54(venvBin, "python");
|
|
40441
|
+
const venvPip2 = join54(venvBin, "pip");
|
|
40166
40442
|
let ocrStackInstalled = false;
|
|
40167
40443
|
try {
|
|
40168
|
-
|
|
40444
|
+
execSync27(`"${venvPython2}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
|
|
40169
40445
|
ocrStackInstalled = true;
|
|
40170
40446
|
} catch {
|
|
40171
40447
|
}
|
|
@@ -40173,9 +40449,9 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
40173
40449
|
const ocrPackages = "pytesseract Pillow opencv-python-headless numpy";
|
|
40174
40450
|
log("Installing OCR Python stack (pytesseract, OpenCV, Pillow, numpy)...");
|
|
40175
40451
|
try {
|
|
40176
|
-
|
|
40452
|
+
execSync27(`"${venvPip2}" install ${ocrPackages}`, { stdio: "pipe", timeout: 3e5 });
|
|
40177
40453
|
try {
|
|
40178
|
-
|
|
40454
|
+
execSync27(`"${venvPython2}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
|
|
40179
40455
|
log("OCR Python stack installed successfully.");
|
|
40180
40456
|
} catch {
|
|
40181
40457
|
log("OCR Python stack install completed but import verification failed.");
|
|
@@ -40209,7 +40485,7 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
40209
40485
|
const archMap = { x64: "amd64", arm64: "arm64", arm: "arm" };
|
|
40210
40486
|
const cfArch = archMap[arch2] ?? "amd64";
|
|
40211
40487
|
try {
|
|
40212
|
-
|
|
40488
|
+
execSync27(`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && mkdir -p "${homedir12()}/.local/bin" && mv /tmp/cloudflared "${homedir12()}/.local/bin/cloudflared"`, { stdio: "pipe", timeout: 6e4 });
|
|
40213
40489
|
if (!process.env.PATH?.includes(`${homedir12()}/.local/bin`)) {
|
|
40214
40490
|
process.env.PATH = `${homedir12()}/.local/bin:${process.env.PATH}`;
|
|
40215
40491
|
}
|
|
@@ -40220,7 +40496,7 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
40220
40496
|
} catch {
|
|
40221
40497
|
}
|
|
40222
40498
|
try {
|
|
40223
|
-
|
|
40499
|
+
execSync27(`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 });
|
|
40224
40500
|
if (hasCmd("cloudflared")) {
|
|
40225
40501
|
log("cloudflared installed.");
|
|
40226
40502
|
return true;
|
|
@@ -40229,7 +40505,7 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
40229
40505
|
}
|
|
40230
40506
|
} else if (os === "darwin") {
|
|
40231
40507
|
try {
|
|
40232
|
-
|
|
40508
|
+
execSync27("brew install cloudflared", { stdio: "pipe", timeout: 12e4 });
|
|
40233
40509
|
if (hasCmd("cloudflared")) {
|
|
40234
40510
|
log("cloudflared installed via Homebrew.");
|
|
40235
40511
|
return true;
|
|
@@ -40306,10 +40582,10 @@ async function createExpandedVariantAsync(baseModel, specs, sizeGB, kvBytesPerTo
|
|
|
40306
40582
|
`PARAMETER num_predict ${numPredict}`,
|
|
40307
40583
|
`PARAMETER stop "<|endoftext|>"`
|
|
40308
40584
|
].join("\n");
|
|
40309
|
-
const modelDir2 =
|
|
40310
|
-
|
|
40311
|
-
const modelfilePath =
|
|
40312
|
-
|
|
40585
|
+
const modelDir2 = join54(homedir12(), ".open-agents", "models");
|
|
40586
|
+
mkdirSync15(modelDir2, { recursive: true });
|
|
40587
|
+
const modelfilePath = join54(modelDir2, `Modelfile.${customName}`);
|
|
40588
|
+
writeFileSync16(modelfilePath, modelfileContent + "\n", "utf8");
|
|
40313
40589
|
await execAsync(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
40314
40590
|
timeout: 12e4
|
|
40315
40591
|
});
|
|
@@ -40371,7 +40647,7 @@ async function ensureExpandedContext(modelName, backendUrl) {
|
|
|
40371
40647
|
}
|
|
40372
40648
|
async function ensureNeovim() {
|
|
40373
40649
|
try {
|
|
40374
|
-
const nvimPath =
|
|
40650
|
+
const nvimPath = execSync27("which nvim 2>/dev/null || where nvim 2>nul", {
|
|
40375
40651
|
encoding: "utf8",
|
|
40376
40652
|
stdio: "pipe",
|
|
40377
40653
|
timeout: 5e3
|
|
@@ -40383,24 +40659,24 @@ async function ensureNeovim() {
|
|
|
40383
40659
|
const platform6 = process.platform;
|
|
40384
40660
|
const arch2 = process.arch;
|
|
40385
40661
|
if (platform6 === "linux") {
|
|
40386
|
-
const binDir =
|
|
40387
|
-
const nvimDest =
|
|
40662
|
+
const binDir = join54(homedir12(), ".local", "bin");
|
|
40663
|
+
const nvimDest = join54(binDir, "nvim");
|
|
40388
40664
|
try {
|
|
40389
|
-
|
|
40665
|
+
mkdirSync15(binDir, { recursive: true });
|
|
40390
40666
|
} catch {
|
|
40391
40667
|
}
|
|
40392
40668
|
const appImageName = arch2 === "arm64" ? "nvim-linux-arm64.appimage" : "nvim-linux-x86_64.appimage";
|
|
40393
40669
|
const url = `https://github.com/neovim/neovim/releases/latest/download/${appImageName}`;
|
|
40394
40670
|
console.log(` Downloading Neovim (${appImageName})...`);
|
|
40395
40671
|
try {
|
|
40396
|
-
|
|
40397
|
-
|
|
40672
|
+
execSync27(`curl -fsSL "${url}" -o "${nvimDest}"`, { stdio: "pipe", timeout: 6e4 });
|
|
40673
|
+
execSync27(`chmod +x "${nvimDest}"`, { stdio: "pipe", timeout: 3e3 });
|
|
40398
40674
|
} catch (err) {
|
|
40399
40675
|
console.log(` Failed to download Neovim: ${err instanceof Error ? err.message : String(err)}`);
|
|
40400
40676
|
return null;
|
|
40401
40677
|
}
|
|
40402
40678
|
try {
|
|
40403
|
-
const ver =
|
|
40679
|
+
const ver = execSync27(`"${nvimDest}" --version`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).split("\n")[0];
|
|
40404
40680
|
console.log(` Installed: ${ver}`);
|
|
40405
40681
|
} catch {
|
|
40406
40682
|
console.log(" Warning: nvim binary downloaded but may not work (missing FUSE? Try: nvim --appimage-extract)");
|
|
@@ -40415,8 +40691,8 @@ async function ensureNeovim() {
|
|
|
40415
40691
|
if (hasCmd("brew")) {
|
|
40416
40692
|
console.log(" Installing Neovim via Homebrew...");
|
|
40417
40693
|
try {
|
|
40418
|
-
|
|
40419
|
-
const nvimPath =
|
|
40694
|
+
execSync27("brew install neovim", { stdio: "inherit", timeout: 12e4 });
|
|
40695
|
+
const nvimPath = execSync27("which nvim", { encoding: "utf8", stdio: "pipe", timeout: 3e3 }).trim();
|
|
40420
40696
|
return nvimPath || null;
|
|
40421
40697
|
} catch {
|
|
40422
40698
|
console.log(" brew install neovim failed.");
|
|
@@ -40430,7 +40706,7 @@ async function ensureNeovim() {
|
|
|
40430
40706
|
if (hasCmd("choco")) {
|
|
40431
40707
|
console.log(" Installing Neovim via Chocolatey...");
|
|
40432
40708
|
try {
|
|
40433
|
-
|
|
40709
|
+
execSync27("choco install neovim -y", { stdio: "inherit", timeout: 12e4 });
|
|
40434
40710
|
return "nvim";
|
|
40435
40711
|
} catch {
|
|
40436
40712
|
console.log(" choco install neovim failed.");
|
|
@@ -40439,7 +40715,7 @@ async function ensureNeovim() {
|
|
|
40439
40715
|
if (hasCmd("winget")) {
|
|
40440
40716
|
console.log(" Installing Neovim via winget...");
|
|
40441
40717
|
try {
|
|
40442
|
-
|
|
40718
|
+
execSync27("winget install Neovim.Neovim --accept-source-agreements --accept-package-agreements", {
|
|
40443
40719
|
stdio: "inherit",
|
|
40444
40720
|
timeout: 12e4
|
|
40445
40721
|
});
|
|
@@ -40455,9 +40731,9 @@ async function ensureNeovim() {
|
|
|
40455
40731
|
}
|
|
40456
40732
|
function ensurePathInShellRc(binDir) {
|
|
40457
40733
|
const shell = process.env.SHELL ?? "";
|
|
40458
|
-
const rcFile = shell.includes("zsh") ?
|
|
40734
|
+
const rcFile = shell.includes("zsh") ? join54(homedir12(), ".zshrc") : join54(homedir12(), ".bashrc");
|
|
40459
40735
|
try {
|
|
40460
|
-
const rcContent =
|
|
40736
|
+
const rcContent = existsSync37(rcFile) ? readFileSync28(rcFile, "utf8") : "";
|
|
40461
40737
|
if (rcContent.includes(binDir))
|
|
40462
40738
|
return;
|
|
40463
40739
|
const exportLine = `
|
|
@@ -41172,7 +41448,7 @@ var init_tui_select = __esm({
|
|
|
41172
41448
|
});
|
|
41173
41449
|
|
|
41174
41450
|
// packages/cli/dist/tui/drop-panel.js
|
|
41175
|
-
import { existsSync as
|
|
41451
|
+
import { existsSync as existsSync38 } from "node:fs";
|
|
41176
41452
|
import { extname as extname10, resolve as resolve29 } from "node:path";
|
|
41177
41453
|
function ansi4(code, text) {
|
|
41178
41454
|
return isTTY4 ? `\x1B[${code}m${text}\x1B[0m` : text;
|
|
@@ -41287,7 +41563,7 @@ function showDropPanel(opts) {
|
|
|
41287
41563
|
filePath = decodeURIComponent(filePath.slice(7));
|
|
41288
41564
|
}
|
|
41289
41565
|
filePath = resolve29(filePath);
|
|
41290
|
-
if (!
|
|
41566
|
+
if (!existsSync38(filePath)) {
|
|
41291
41567
|
errorMsg = `File not found: ${filePath}`;
|
|
41292
41568
|
render();
|
|
41293
41569
|
return;
|
|
@@ -41358,10 +41634,10 @@ var init_drop_panel = __esm({
|
|
|
41358
41634
|
});
|
|
41359
41635
|
|
|
41360
41636
|
// packages/cli/dist/tui/neovim-mode.js
|
|
41361
|
-
import { existsSync as
|
|
41637
|
+
import { existsSync as existsSync39, unlinkSync as unlinkSync8 } from "node:fs";
|
|
41362
41638
|
import { tmpdir as tmpdir8 } from "node:os";
|
|
41363
|
-
import { join as
|
|
41364
|
-
import { execSync as
|
|
41639
|
+
import { join as join55 } from "node:path";
|
|
41640
|
+
import { execSync as execSync28 } from "node:child_process";
|
|
41365
41641
|
function isNeovimActive() {
|
|
41366
41642
|
return _state !== null && !_state.cleanedUp;
|
|
41367
41643
|
}
|
|
@@ -41379,7 +41655,7 @@ async function startNeovimMode(opts) {
|
|
|
41379
41655
|
}
|
|
41380
41656
|
let nvimPath;
|
|
41381
41657
|
try {
|
|
41382
|
-
nvimPath =
|
|
41658
|
+
nvimPath = execSync28("which nvim 2>/dev/null", { encoding: "utf8" }).trim();
|
|
41383
41659
|
if (!nvimPath)
|
|
41384
41660
|
throw new Error();
|
|
41385
41661
|
} catch {
|
|
@@ -41408,10 +41684,10 @@ async function startNeovimMode(opts) {
|
|
|
41408
41684
|
);
|
|
41409
41685
|
} catch {
|
|
41410
41686
|
}
|
|
41411
|
-
const socketPath =
|
|
41687
|
+
const socketPath = join55(tmpdir8(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
|
|
41412
41688
|
try {
|
|
41413
|
-
if (
|
|
41414
|
-
|
|
41689
|
+
if (existsSync39(socketPath))
|
|
41690
|
+
unlinkSync8(socketPath);
|
|
41415
41691
|
} catch {
|
|
41416
41692
|
}
|
|
41417
41693
|
const ptyCols = opts.cols;
|
|
@@ -41637,13 +41913,13 @@ function resizeNeovim(cols, contentRows) {
|
|
|
41637
41913
|
}
|
|
41638
41914
|
async function connectRPC(state, neovimPkg, cols) {
|
|
41639
41915
|
let attempts = 0;
|
|
41640
|
-
while (!
|
|
41916
|
+
while (!existsSync39(state.socketPath) && attempts < 30) {
|
|
41641
41917
|
await new Promise((r) => setTimeout(r, 200));
|
|
41642
41918
|
attempts++;
|
|
41643
41919
|
if (state.cleanedUp)
|
|
41644
41920
|
return;
|
|
41645
41921
|
}
|
|
41646
|
-
if (!
|
|
41922
|
+
if (!existsSync39(state.socketPath))
|
|
41647
41923
|
return;
|
|
41648
41924
|
const nvim = neovimPkg.attach({ socket: state.socketPath });
|
|
41649
41925
|
state.nvim = nvim;
|
|
@@ -41780,8 +42056,8 @@ function doCleanup(state) {
|
|
|
41780
42056
|
state.pty = null;
|
|
41781
42057
|
}
|
|
41782
42058
|
try {
|
|
41783
|
-
if (
|
|
41784
|
-
|
|
42059
|
+
if (existsSync39(state.socketPath))
|
|
42060
|
+
unlinkSync8(state.socketPath);
|
|
41785
42061
|
} catch {
|
|
41786
42062
|
}
|
|
41787
42063
|
if (state.stdinHandler) {
|
|
@@ -41837,10 +42113,10 @@ __export(voice_exports, {
|
|
|
41837
42113
|
registerCustomOnnxModel: () => registerCustomOnnxModel,
|
|
41838
42114
|
resetNarrationContext: () => resetNarrationContext
|
|
41839
42115
|
});
|
|
41840
|
-
import { existsSync as
|
|
41841
|
-
import { join as
|
|
42116
|
+
import { existsSync as existsSync40, mkdirSync as mkdirSync16, writeFileSync as writeFileSync17, readFileSync as readFileSync29, unlinkSync as unlinkSync9, readdirSync as readdirSync11, renameSync, statSync as statSync13 } from "node:fs";
|
|
42117
|
+
import { join as join56, dirname as dirname18 } from "node:path";
|
|
41842
42118
|
import { homedir as homedir13, tmpdir as tmpdir9, platform as platform3 } from "node:os";
|
|
41843
|
-
import { execSync as
|
|
42119
|
+
import { execSync as execSync29, spawn as nodeSpawn } from "node:child_process";
|
|
41844
42120
|
import { createRequire } from "node:module";
|
|
41845
42121
|
function sanitizeForTTS(text) {
|
|
41846
42122
|
return text.replace(/^#{1,6}\s+/gm, "").replace(/\*{1,3}([^*]+)\*{1,3}/g, "$1").replace(/_{1,3}([^_]+)_{1,3}/g, "$1").replace(/~~([^~]+)~~/g, "$1").replace(/`([^`]+)`/g, "$1").replace(/```[\s\S]*?```/g, "").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/!\[([^\]]*)\]\([^)]+\)/g, "$1").replace(/^[\s]*[-*+]\s+/gm, "").replace(/^[\s]*\d+\.\s+/gm, "").replace(/^>\s+/gm, "").replace(/^[-*_]{3,}$/gm, "").replace(/\[[ xX]\]\s*/g, "").replace(/[\u{1F600}-\u{1F64F}]/gu, "").replace(/[\u{1F300}-\u{1F5FF}]/gu, "").replace(/[\u{1F680}-\u{1F6FF}]/gu, "").replace(/[\u{1F1E0}-\u{1F1FF}]/gu, "").replace(/[\u{2600}-\u{26FF}]/gu, "").replace(/[\u{2700}-\u{27BF}]/gu, "").replace(/[\u{FE00}-\u{FE0F}]/gu, "").replace(/[\u{1F900}-\u{1F9FF}]/gu, "").replace(/[\u{1FA00}-\u{1FA6F}]/gu, "").replace(/[\u{1FA70}-\u{1FAFF}]/gu, "").replace(/[\u{200D}]/gu, "").replace(/[\u{20E3}]/gu, "").replace(/[✓✔✗✘✕✖⚠️⏸⏹⏵●○◆◇■□▪▫►▼▲◀⬆⬇⬅➡↑↓←→⇐⇒⇑⇓]/g, "").replace(/[─━│┃┌┐└┘├┤┬┴┼╔╗╚╝╠╣╦╩╬⎿⎾▕▏⏐░▒▓█⠀-⣿]/g, "").replace(/\s{2,}/g, " ").trim();
|
|
@@ -41863,40 +42139,40 @@ function listVoiceModels() {
|
|
|
41863
42139
|
}));
|
|
41864
42140
|
}
|
|
41865
42141
|
function voiceDir() {
|
|
41866
|
-
return
|
|
42142
|
+
return join56(homedir13(), ".open-agents", "voice");
|
|
41867
42143
|
}
|
|
41868
42144
|
function modelsDir() {
|
|
41869
|
-
return
|
|
42145
|
+
return join56(voiceDir(), "models");
|
|
41870
42146
|
}
|
|
41871
42147
|
function modelDir(id) {
|
|
41872
|
-
return
|
|
42148
|
+
return join56(modelsDir(), id);
|
|
41873
42149
|
}
|
|
41874
42150
|
function modelOnnxPath(id) {
|
|
41875
|
-
return
|
|
42151
|
+
return join56(modelDir(id), "model.onnx");
|
|
41876
42152
|
}
|
|
41877
42153
|
function modelConfigPath(id) {
|
|
41878
|
-
return
|
|
42154
|
+
return join56(modelDir(id), "config.json");
|
|
41879
42155
|
}
|
|
41880
42156
|
function luxttsVenvDir() {
|
|
41881
|
-
return
|
|
42157
|
+
return join56(voiceDir(), "luxtts-venv");
|
|
41882
42158
|
}
|
|
41883
42159
|
function luxttsVenvPy() {
|
|
41884
|
-
return platform3() === "win32" ?
|
|
42160
|
+
return platform3() === "win32" ? join56(luxttsVenvDir(), "Scripts", "python.exe") : join56(luxttsVenvDir(), "bin", "python3");
|
|
41885
42161
|
}
|
|
41886
42162
|
function luxttsRepoDir() {
|
|
41887
|
-
return
|
|
42163
|
+
return join56(voiceDir(), "LuxTTS");
|
|
41888
42164
|
}
|
|
41889
42165
|
function luxttsCloneRefsDir() {
|
|
41890
|
-
return
|
|
42166
|
+
return join56(voiceDir(), "clone-refs");
|
|
41891
42167
|
}
|
|
41892
42168
|
function luxttsInferScript() {
|
|
41893
|
-
return
|
|
42169
|
+
return join56(voiceDir(), "luxtts-infer.py");
|
|
41894
42170
|
}
|
|
41895
42171
|
function writeDetectTorchScript(targetPath) {
|
|
41896
|
-
if (
|
|
42172
|
+
if (existsSync40(targetPath))
|
|
41897
42173
|
return;
|
|
41898
42174
|
try {
|
|
41899
|
-
|
|
42175
|
+
mkdirSync16(dirname18(targetPath), { recursive: true });
|
|
41900
42176
|
} catch {
|
|
41901
42177
|
}
|
|
41902
42178
|
const script = `#!/usr/bin/env python3
|
|
@@ -41969,7 +42245,7 @@ def main():
|
|
|
41969
42245
|
if __name__ == "__main__": main()
|
|
41970
42246
|
`;
|
|
41971
42247
|
try {
|
|
41972
|
-
|
|
42248
|
+
writeFileSync17(targetPath, script, { mode: 493 });
|
|
41973
42249
|
} catch {
|
|
41974
42250
|
}
|
|
41975
42251
|
}
|
|
@@ -42779,8 +43055,8 @@ var init_voice = __esm({
|
|
|
42779
43055
|
const refsDir = luxttsCloneRefsDir();
|
|
42780
43056
|
const targets = ["glados", "overwatch"];
|
|
42781
43057
|
for (const modelId of targets) {
|
|
42782
|
-
const refFile =
|
|
42783
|
-
if (
|
|
43058
|
+
const refFile = join56(refsDir, `${modelId}-ref.wav`);
|
|
43059
|
+
if (existsSync40(refFile))
|
|
42784
43060
|
continue;
|
|
42785
43061
|
try {
|
|
42786
43062
|
await this.generateCloneRef(modelId);
|
|
@@ -42859,24 +43135,24 @@ var init_voice = __esm({
|
|
|
42859
43135
|
}
|
|
42860
43136
|
p = p.replace(/\\ /g, " ");
|
|
42861
43137
|
if (p.startsWith("~/") || p === "~") {
|
|
42862
|
-
p =
|
|
43138
|
+
p = join56(homedir13(), p.slice(1));
|
|
42863
43139
|
}
|
|
42864
|
-
if (!
|
|
43140
|
+
if (!existsSync40(p)) {
|
|
42865
43141
|
return `File not found: ${p}
|
|
42866
43142
|
(original input: ${audioPath})`;
|
|
42867
43143
|
}
|
|
42868
43144
|
audioPath = p;
|
|
42869
43145
|
const refsDir = luxttsCloneRefsDir();
|
|
42870
|
-
if (!
|
|
42871
|
-
|
|
43146
|
+
if (!existsSync40(refsDir))
|
|
43147
|
+
mkdirSync16(refsDir, { recursive: true });
|
|
42872
43148
|
const ext = audioPath.split(".").pop() || "wav";
|
|
42873
43149
|
const srcName = (audioPath.split("/").pop() ?? "clone").replace(/\.[^.]+$/, "").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
42874
43150
|
const ts = Date.now().toString(36);
|
|
42875
43151
|
const destFilename = `clone-${srcName}-${ts}.${ext}`;
|
|
42876
|
-
const destPath =
|
|
43152
|
+
const destPath = join56(refsDir, destFilename);
|
|
42877
43153
|
try {
|
|
42878
|
-
const data =
|
|
42879
|
-
|
|
43154
|
+
const data = readFileSync29(audioPath);
|
|
43155
|
+
writeFileSync17(destPath, data);
|
|
42880
43156
|
} catch (err) {
|
|
42881
43157
|
return `Failed to copy audio file: ${err instanceof Error ? err.message : String(err)}`;
|
|
42882
43158
|
}
|
|
@@ -42916,9 +43192,9 @@ var init_voice = __esm({
|
|
|
42916
43192
|
return `Failed to synthesize reference audio from ${source.label}.`;
|
|
42917
43193
|
}
|
|
42918
43194
|
const refsDir = luxttsCloneRefsDir();
|
|
42919
|
-
if (!
|
|
42920
|
-
|
|
42921
|
-
const destPath =
|
|
43195
|
+
if (!existsSync40(refsDir))
|
|
43196
|
+
mkdirSync16(refsDir, { recursive: true });
|
|
43197
|
+
const destPath = join56(refsDir, `${sourceModelId}-ref.wav`);
|
|
42922
43198
|
const sampleRate = this.config?.audio?.sample_rate ?? 22050;
|
|
42923
43199
|
this.writeWav(audioData, sampleRate, destPath);
|
|
42924
43200
|
this.luxttsCloneRef = destPath;
|
|
@@ -42934,23 +43210,23 @@ var init_voice = __esm({
|
|
|
42934
43210
|
// -------------------------------------------------------------------------
|
|
42935
43211
|
/** Metadata file for friendly names of clone refs */
|
|
42936
43212
|
static cloneMetaFile() {
|
|
42937
|
-
return
|
|
43213
|
+
return join56(luxttsCloneRefsDir(), "meta.json");
|
|
42938
43214
|
}
|
|
42939
43215
|
loadCloneMeta() {
|
|
42940
43216
|
const p = _VoiceEngine.cloneMetaFile();
|
|
42941
|
-
if (!
|
|
43217
|
+
if (!existsSync40(p))
|
|
42942
43218
|
return {};
|
|
42943
43219
|
try {
|
|
42944
|
-
return JSON.parse(
|
|
43220
|
+
return JSON.parse(readFileSync29(p, "utf8"));
|
|
42945
43221
|
} catch {
|
|
42946
43222
|
return {};
|
|
42947
43223
|
}
|
|
42948
43224
|
}
|
|
42949
43225
|
saveCloneMeta(meta) {
|
|
42950
43226
|
const dir = luxttsCloneRefsDir();
|
|
42951
|
-
if (!
|
|
42952
|
-
|
|
42953
|
-
|
|
43227
|
+
if (!existsSync40(dir))
|
|
43228
|
+
mkdirSync16(dir, { recursive: true });
|
|
43229
|
+
writeFileSync17(_VoiceEngine.cloneMetaFile(), JSON.stringify(meta, null, 2));
|
|
42954
43230
|
}
|
|
42955
43231
|
/** Audio file extensions recognized as clone references */
|
|
42956
43232
|
static AUDIO_EXTS = /* @__PURE__ */ new Set(["wav", "mp3", "ogg", "flac", "m4a", "opus", "aac"]);
|
|
@@ -42960,15 +43236,15 @@ var init_voice = __esm({
|
|
|
42960
43236
|
*/
|
|
42961
43237
|
listCloneRefs() {
|
|
42962
43238
|
const dir = luxttsCloneRefsDir();
|
|
42963
|
-
if (!
|
|
43239
|
+
if (!existsSync40(dir))
|
|
42964
43240
|
return [];
|
|
42965
43241
|
const meta = this.loadCloneMeta();
|
|
42966
|
-
const files =
|
|
43242
|
+
const files = readdirSync11(dir).filter((f) => {
|
|
42967
43243
|
const ext = f.split(".").pop()?.toLowerCase() ?? "";
|
|
42968
43244
|
return _VoiceEngine.AUDIO_EXTS.has(ext);
|
|
42969
43245
|
});
|
|
42970
43246
|
return files.map((f) => {
|
|
42971
|
-
const p =
|
|
43247
|
+
const p = join56(dir, f);
|
|
42972
43248
|
let size = 0;
|
|
42973
43249
|
try {
|
|
42974
43250
|
size = statSync13(p).size;
|
|
@@ -42985,11 +43261,11 @@ var init_voice = __esm({
|
|
|
42985
43261
|
}
|
|
42986
43262
|
/** Delete a clone reference file by filename. Returns true if deleted. */
|
|
42987
43263
|
deleteCloneRef(filename) {
|
|
42988
|
-
const p =
|
|
42989
|
-
if (!
|
|
43264
|
+
const p = join56(luxttsCloneRefsDir(), filename);
|
|
43265
|
+
if (!existsSync40(p))
|
|
42990
43266
|
return false;
|
|
42991
43267
|
try {
|
|
42992
|
-
|
|
43268
|
+
unlinkSync9(p);
|
|
42993
43269
|
const meta = this.loadCloneMeta();
|
|
42994
43270
|
delete meta[filename];
|
|
42995
43271
|
this.saveCloneMeta(meta);
|
|
@@ -43010,8 +43286,8 @@ var init_voice = __esm({
|
|
|
43010
43286
|
}
|
|
43011
43287
|
/** Set the active clone reference by filename. */
|
|
43012
43288
|
setActiveCloneRef(filename) {
|
|
43013
|
-
const p =
|
|
43014
|
-
if (!
|
|
43289
|
+
const p = join56(luxttsCloneRefsDir(), filename);
|
|
43290
|
+
if (!existsSync40(p))
|
|
43015
43291
|
return `File not found: ${filename}`;
|
|
43016
43292
|
this.luxttsCloneRef = p;
|
|
43017
43293
|
return `Active clone voice set to: ${filename}`;
|
|
@@ -43267,7 +43543,7 @@ var init_voice = __esm({
|
|
|
43267
43543
|
}
|
|
43268
43544
|
if (prefetchedWav) {
|
|
43269
43545
|
try {
|
|
43270
|
-
|
|
43546
|
+
unlinkSync9(prefetchedWav.path);
|
|
43271
43547
|
} catch {
|
|
43272
43548
|
}
|
|
43273
43549
|
}
|
|
@@ -43336,11 +43612,11 @@ var init_voice = __esm({
|
|
|
43336
43612
|
}
|
|
43337
43613
|
this.onPCMOutput(Buffer.from(int16.buffer), sampleRate);
|
|
43338
43614
|
}
|
|
43339
|
-
const wavPath =
|
|
43615
|
+
const wavPath = join56(tmpdir9(), `oa-voice-${Date.now()}.wav`);
|
|
43340
43616
|
this.writeStereoWav(stereo.left, stereo.right, sampleRate, wavPath);
|
|
43341
43617
|
await this.playWav(wavPath);
|
|
43342
43618
|
try {
|
|
43343
|
-
|
|
43619
|
+
unlinkSync9(wavPath);
|
|
43344
43620
|
} catch {
|
|
43345
43621
|
}
|
|
43346
43622
|
}
|
|
@@ -43453,7 +43729,7 @@ var init_voice = __esm({
|
|
|
43453
43729
|
buffer.writeInt16LE(rSample < 0 ? rSample * 32768 : rSample * 32767, pos);
|
|
43454
43730
|
pos += 2;
|
|
43455
43731
|
}
|
|
43456
|
-
|
|
43732
|
+
writeFileSync17(path, buffer);
|
|
43457
43733
|
}
|
|
43458
43734
|
// -------------------------------------------------------------------------
|
|
43459
43735
|
// Phonemization
|
|
@@ -43531,7 +43807,7 @@ var init_voice = __esm({
|
|
|
43531
43807
|
return buffer;
|
|
43532
43808
|
}
|
|
43533
43809
|
writeWav(samples, sampleRate, path) {
|
|
43534
|
-
|
|
43810
|
+
writeFileSync17(path, this.buildWavBuffer(samples, sampleRate));
|
|
43535
43811
|
}
|
|
43536
43812
|
// -------------------------------------------------------------------------
|
|
43537
43813
|
// Audio playback (system default speakers)
|
|
@@ -43581,7 +43857,7 @@ var init_voice = __esm({
|
|
|
43581
43857
|
}
|
|
43582
43858
|
for (const player of ["paplay", "pw-play", "aplay"]) {
|
|
43583
43859
|
try {
|
|
43584
|
-
|
|
43860
|
+
execSync29(`which ${player}`, { stdio: "pipe" });
|
|
43585
43861
|
return [player, path];
|
|
43586
43862
|
} catch {
|
|
43587
43863
|
}
|
|
@@ -43610,7 +43886,7 @@ var init_voice = __esm({
|
|
|
43610
43886
|
return this.python3Path;
|
|
43611
43887
|
for (const bin of ["python3", "python"]) {
|
|
43612
43888
|
try {
|
|
43613
|
-
const path =
|
|
43889
|
+
const path = execSync29(`which ${bin}`, { stdio: "pipe", timeout: 5e3 }).toString().trim();
|
|
43614
43890
|
if (path) {
|
|
43615
43891
|
this.python3Path = path;
|
|
43616
43892
|
return path;
|
|
@@ -43676,7 +43952,7 @@ var init_voice = __esm({
|
|
|
43676
43952
|
return false;
|
|
43677
43953
|
}
|
|
43678
43954
|
try {
|
|
43679
|
-
|
|
43955
|
+
execSync29(`${py} -c "import mlx_audio"`, { stdio: "pipe", timeout: 1e4 });
|
|
43680
43956
|
this.mlxInstalled = true;
|
|
43681
43957
|
return true;
|
|
43682
43958
|
} catch {
|
|
@@ -43729,7 +44005,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
43729
44005
|
const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
|
|
43730
44006
|
const mlxVoice = model.mlxVoice ?? "af_heart";
|
|
43731
44007
|
const mlxLangCode = model.mlxLangCode ?? "a";
|
|
43732
|
-
const wavPath =
|
|
44008
|
+
const wavPath = join56(tmpdir9(), `oa-mlx-${Date.now()}.wav`);
|
|
43733
44009
|
const pyScript = [
|
|
43734
44010
|
"import sys, json",
|
|
43735
44011
|
"from mlx_audio.tts import generate as tts_gen",
|
|
@@ -43737,20 +44013,20 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
43737
44013
|
`tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
|
|
43738
44014
|
].join("; ");
|
|
43739
44015
|
try {
|
|
43740
|
-
|
|
44016
|
+
execSync29(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
|
|
43741
44017
|
} catch (err) {
|
|
43742
44018
|
try {
|
|
43743
44019
|
const safeText = cleaned.replace(/'/g, "'\\''");
|
|
43744
|
-
|
|
44020
|
+
execSync29(`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
|
|
43745
44021
|
} catch (err2) {
|
|
43746
44022
|
return;
|
|
43747
44023
|
}
|
|
43748
44024
|
}
|
|
43749
|
-
if (!
|
|
44025
|
+
if (!existsSync40(wavPath))
|
|
43750
44026
|
return;
|
|
43751
44027
|
if (volume !== 1) {
|
|
43752
44028
|
try {
|
|
43753
|
-
const wavData =
|
|
44029
|
+
const wavData = readFileSync29(wavPath);
|
|
43754
44030
|
if (wavData.length > 44) {
|
|
43755
44031
|
const header = wavData.subarray(0, 44);
|
|
43756
44032
|
const samples = new Int16Array(wavData.buffer, wavData.byteOffset + 44, (wavData.length - 44) / 2);
|
|
@@ -43758,14 +44034,14 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
43758
44034
|
samples[i] = Math.round(samples[i] * volume);
|
|
43759
44035
|
}
|
|
43760
44036
|
const scaled = Buffer.concat([header, Buffer.from(samples.buffer, samples.byteOffset, samples.byteLength)]);
|
|
43761
|
-
|
|
44037
|
+
writeFileSync17(wavPath, scaled);
|
|
43762
44038
|
}
|
|
43763
44039
|
} catch {
|
|
43764
44040
|
}
|
|
43765
44041
|
}
|
|
43766
44042
|
if (this.onPCMOutput) {
|
|
43767
44043
|
try {
|
|
43768
|
-
const wavData =
|
|
44044
|
+
const wavData = readFileSync29(wavPath);
|
|
43769
44045
|
if (wavData.length > 44) {
|
|
43770
44046
|
const pcm = Buffer.from(wavData.buffer, wavData.byteOffset + 44, wavData.length - 44);
|
|
43771
44047
|
const sampleRate = wavData.readUInt32LE(24);
|
|
@@ -43776,7 +44052,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
43776
44052
|
}
|
|
43777
44053
|
await this.playWav(wavPath);
|
|
43778
44054
|
try {
|
|
43779
|
-
|
|
44055
|
+
unlinkSync9(wavPath);
|
|
43780
44056
|
} catch {
|
|
43781
44057
|
}
|
|
43782
44058
|
}
|
|
@@ -43797,7 +44073,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
43797
44073
|
const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
|
|
43798
44074
|
const mlxVoice = model.mlxVoice ?? "af_heart";
|
|
43799
44075
|
const mlxLangCode = model.mlxLangCode ?? "a";
|
|
43800
|
-
const wavPath =
|
|
44076
|
+
const wavPath = join56(tmpdir9(), `oa-mlx-buf-${Date.now()}.wav`);
|
|
43801
44077
|
const pyScript = [
|
|
43802
44078
|
"import sys, json",
|
|
43803
44079
|
"from mlx_audio.tts import generate as tts_gen",
|
|
@@ -43805,20 +44081,20 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
43805
44081
|
`tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
|
|
43806
44082
|
].join("; ");
|
|
43807
44083
|
try {
|
|
43808
|
-
|
|
44084
|
+
execSync29(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
|
|
43809
44085
|
} catch {
|
|
43810
44086
|
try {
|
|
43811
44087
|
const safeText = cleaned.replace(/'/g, "'\\''");
|
|
43812
|
-
|
|
44088
|
+
execSync29(`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
|
|
43813
44089
|
} catch {
|
|
43814
44090
|
return null;
|
|
43815
44091
|
}
|
|
43816
44092
|
}
|
|
43817
|
-
if (!
|
|
44093
|
+
if (!existsSync40(wavPath))
|
|
43818
44094
|
return null;
|
|
43819
44095
|
try {
|
|
43820
|
-
const data =
|
|
43821
|
-
|
|
44096
|
+
const data = readFileSync29(wavPath);
|
|
44097
|
+
unlinkSync9(wavPath);
|
|
43822
44098
|
return data;
|
|
43823
44099
|
} catch {
|
|
43824
44100
|
return null;
|
|
@@ -43840,7 +44116,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
43840
44116
|
}
|
|
43841
44117
|
const venvDir = luxttsVenvDir();
|
|
43842
44118
|
const venvPy = luxttsVenvPy();
|
|
43843
|
-
if (
|
|
44119
|
+
if (existsSync40(venvPy)) {
|
|
43844
44120
|
try {
|
|
43845
44121
|
await this.asyncShell(`${venvPy} -c "import sys; sys.path.insert(0, '${luxttsRepoDir()}'); from zipvoice.luxvoice import LuxTTS; print('ok')"`, 3e4);
|
|
43846
44122
|
let hasCudaSys = false;
|
|
@@ -43854,7 +44130,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
43854
44130
|
if (torchCheck === "cpu") {
|
|
43855
44131
|
renderWarning("GPU detected but PyTorch is CPU-only. Reinstalling with CUDA support in background...");
|
|
43856
44132
|
try {
|
|
43857
|
-
const detectScript =
|
|
44133
|
+
const detectScript = join56(voiceDir(), "detect-torch.py");
|
|
43858
44134
|
writeDetectTorchScript(detectScript);
|
|
43859
44135
|
let pipArgs = `torch torchaudio --index-url https://download.pytorch.org/whl/cu124`;
|
|
43860
44136
|
try {
|
|
@@ -43879,7 +44155,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
43879
44155
|
}
|
|
43880
44156
|
}
|
|
43881
44157
|
renderInfo("Setting up LuxTTS voice cloning (first-time setup, this takes several minutes)...");
|
|
43882
|
-
if (!
|
|
44158
|
+
if (!existsSync40(venvDir)) {
|
|
43883
44159
|
renderInfo(" Creating Python virtual environment...");
|
|
43884
44160
|
try {
|
|
43885
44161
|
await this.asyncShell(`${py} -m venv ${JSON.stringify(venvDir)}`, 6e4);
|
|
@@ -43888,7 +44164,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
43888
44164
|
}
|
|
43889
44165
|
}
|
|
43890
44166
|
{
|
|
43891
|
-
const detectScript =
|
|
44167
|
+
const detectScript = join56(voiceDir(), "detect-torch.py");
|
|
43892
44168
|
writeDetectTorchScript(detectScript);
|
|
43893
44169
|
let pipArgsStr = "torch torchaudio";
|
|
43894
44170
|
let torchDesc = "unknown platform";
|
|
@@ -43925,10 +44201,10 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
43925
44201
|
}
|
|
43926
44202
|
}
|
|
43927
44203
|
const repoDir = luxttsRepoDir();
|
|
43928
|
-
if (!
|
|
44204
|
+
if (!existsSync40(join56(repoDir, "zipvoice", "luxvoice.py"))) {
|
|
43929
44205
|
renderInfo(" Cloning LuxTTS repository...");
|
|
43930
44206
|
try {
|
|
43931
|
-
if (
|
|
44207
|
+
if (existsSync40(repoDir)) {
|
|
43932
44208
|
const rmCmd = process.platform === "win32" ? `rmdir /s /q ${JSON.stringify(repoDir)}` : `rm -rf ${JSON.stringify(repoDir)}`;
|
|
43933
44209
|
await this.asyncShell(rmCmd, 3e4);
|
|
43934
44210
|
}
|
|
@@ -43967,7 +44243,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
43967
44243
|
renderWarning(` Could not install system build deps: ${err instanceof Error ? err.message : String(err)}`);
|
|
43968
44244
|
}
|
|
43969
44245
|
}
|
|
43970
|
-
const isJetson = isArm && (
|
|
44246
|
+
const isJetson = isArm && (existsSync40("/etc/nv_tegra_release") || existsSync40("/usr/local/cuda/targets/aarch64-linux") || (process.env.JETSON_L4T_VERSION ?? "") !== "");
|
|
43971
44247
|
const installSteps = isArm ? [
|
|
43972
44248
|
// ARM: install individually so we get clear error messages per package.
|
|
43973
44249
|
// ALL are fatal because LuxTTS hard-imports them (no lazy/optional imports).
|
|
@@ -44035,14 +44311,14 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
44035
44311
|
}
|
|
44036
44312
|
/** Auto-detect an existing clone reference in the refs directory */
|
|
44037
44313
|
autoDetectCloneRef() {
|
|
44038
|
-
if (this.luxttsCloneRef &&
|
|
44314
|
+
if (this.luxttsCloneRef && existsSync40(this.luxttsCloneRef))
|
|
44039
44315
|
return;
|
|
44040
44316
|
const refsDir = luxttsCloneRefsDir();
|
|
44041
|
-
if (!
|
|
44317
|
+
if (!existsSync40(refsDir))
|
|
44042
44318
|
return;
|
|
44043
44319
|
for (const name of ["custom-clone.wav", "custom-clone.mp3", "glados-ref.wav", "overwatch-ref.wav"]) {
|
|
44044
|
-
const p =
|
|
44045
|
-
if (
|
|
44320
|
+
const p = join56(refsDir, name);
|
|
44321
|
+
if (existsSync40(p)) {
|
|
44046
44322
|
this.luxttsCloneRef = p;
|
|
44047
44323
|
return;
|
|
44048
44324
|
}
|
|
@@ -44142,15 +44418,15 @@ if __name__ == '__main__':
|
|
|
44142
44418
|
main()
|
|
44143
44419
|
`;
|
|
44144
44420
|
const scriptPath2 = luxttsInferScript();
|
|
44145
|
-
|
|
44146
|
-
|
|
44421
|
+
mkdirSync16(voiceDir(), { recursive: true });
|
|
44422
|
+
writeFileSync17(scriptPath2, script);
|
|
44147
44423
|
}
|
|
44148
44424
|
/** Ensure the LuxTTS daemon is running, spawn if needed */
|
|
44149
44425
|
async ensureLuxttsDaemon() {
|
|
44150
44426
|
if (this._luxttsDaemon && !this._luxttsDaemon.killed)
|
|
44151
44427
|
return true;
|
|
44152
44428
|
const venvPy = luxttsVenvPy();
|
|
44153
|
-
if (!
|
|
44429
|
+
if (!existsSync40(venvPy))
|
|
44154
44430
|
return false;
|
|
44155
44431
|
return new Promise((resolve34) => {
|
|
44156
44432
|
const env = { ...process.env, LUXTTS_REPO_PATH: luxttsRepoDir() };
|
|
@@ -44234,7 +44510,7 @@ if __name__ == '__main__':
|
|
|
44234
44510
|
* Used by drainQueue's pre-fetch pipeline for gapless back-to-back playback.
|
|
44235
44511
|
*/
|
|
44236
44512
|
async synthesizeLuxttsWav(text, speedFactor = 1) {
|
|
44237
|
-
if (!this.luxttsCloneRef || !
|
|
44513
|
+
if (!this.luxttsCloneRef || !existsSync40(this.luxttsCloneRef))
|
|
44238
44514
|
return null;
|
|
44239
44515
|
const cleaned = text.replace(/\*/g, "").trim();
|
|
44240
44516
|
if (!cleaned)
|
|
@@ -44242,7 +44518,7 @@ if __name__ == '__main__':
|
|
|
44242
44518
|
const ready = await this.ensureLuxttsDaemon();
|
|
44243
44519
|
if (!ready)
|
|
44244
44520
|
return null;
|
|
44245
|
-
const wavPath =
|
|
44521
|
+
const wavPath = join56(tmpdir9(), `oa-luxtts-${Date.now()}-${Math.random().toString(36).slice(2, 6)}.wav`);
|
|
44246
44522
|
try {
|
|
44247
44523
|
await this.luxttsRequest({
|
|
44248
44524
|
action: "synthesize",
|
|
@@ -44254,17 +44530,17 @@ if __name__ == '__main__':
|
|
|
44254
44530
|
} catch {
|
|
44255
44531
|
return null;
|
|
44256
44532
|
}
|
|
44257
|
-
return
|
|
44533
|
+
return existsSync40(wavPath) ? wavPath : null;
|
|
44258
44534
|
}
|
|
44259
44535
|
/**
|
|
44260
44536
|
* Post-process (fade-in, volume, pitch, stereo) and play a LuxTTS WAV file.
|
|
44261
44537
|
* Cleans up the WAV file after playback.
|
|
44262
44538
|
*/
|
|
44263
44539
|
async postProcessAndPlayLuxtts(wavPath, volume = 1, pitchFactor = 1, stereoDelayMs = 0.6) {
|
|
44264
|
-
if (!
|
|
44540
|
+
if (!existsSync40(wavPath))
|
|
44265
44541
|
return;
|
|
44266
44542
|
try {
|
|
44267
|
-
const wavData =
|
|
44543
|
+
const wavData = readFileSync29(wavPath);
|
|
44268
44544
|
if (wavData.length > 44) {
|
|
44269
44545
|
const sampleRate = wavData.readUInt32LE(24);
|
|
44270
44546
|
const samples = new Int16Array(wavData.buffer, wavData.byteOffset + 44, (wavData.length - 44) / 2);
|
|
@@ -44279,13 +44555,13 @@ if __name__ == '__main__':
|
|
|
44279
44555
|
}
|
|
44280
44556
|
const header = wavData.subarray(0, 44);
|
|
44281
44557
|
const scaled = Buffer.concat([header, Buffer.from(samples.buffer, samples.byteOffset, samples.byteLength)]);
|
|
44282
|
-
|
|
44558
|
+
writeFileSync17(wavPath, scaled);
|
|
44283
44559
|
}
|
|
44284
44560
|
} catch {
|
|
44285
44561
|
}
|
|
44286
44562
|
if (pitchFactor !== 1) {
|
|
44287
44563
|
try {
|
|
44288
|
-
const wavData =
|
|
44564
|
+
const wavData = readFileSync29(wavPath);
|
|
44289
44565
|
if (wavData.length > 44) {
|
|
44290
44566
|
const int16 = new Int16Array(wavData.buffer, wavData.byteOffset + 44, (wavData.length - 44) / 2);
|
|
44291
44567
|
const float32 = new Float32Array(int16.length);
|
|
@@ -44300,7 +44576,7 @@ if __name__ == '__main__':
|
|
|
44300
44576
|
}
|
|
44301
44577
|
if (this.onPCMOutput) {
|
|
44302
44578
|
try {
|
|
44303
|
-
const wavData =
|
|
44579
|
+
const wavData = readFileSync29(wavPath);
|
|
44304
44580
|
if (wavData.length > 44) {
|
|
44305
44581
|
const pcm = Buffer.from(wavData.buffer, wavData.byteOffset + 44, wavData.length - 44);
|
|
44306
44582
|
const sampleRate = wavData.readUInt32LE(24);
|
|
@@ -44311,7 +44587,7 @@ if __name__ == '__main__':
|
|
|
44311
44587
|
}
|
|
44312
44588
|
if (stereoDelayMs > 0) {
|
|
44313
44589
|
try {
|
|
44314
|
-
const wavData =
|
|
44590
|
+
const wavData = readFileSync29(wavPath);
|
|
44315
44591
|
if (wavData.length > 44) {
|
|
44316
44592
|
const sampleRate = wavData.readUInt32LE(24);
|
|
44317
44593
|
const numChannels = wavData.readUInt16LE(22);
|
|
@@ -44331,7 +44607,7 @@ if __name__ == '__main__':
|
|
|
44331
44607
|
await this.playWav(wavPath);
|
|
44332
44608
|
await this.sleep(150);
|
|
44333
44609
|
try {
|
|
44334
|
-
|
|
44610
|
+
unlinkSync9(wavPath);
|
|
44335
44611
|
} catch {
|
|
44336
44612
|
}
|
|
44337
44613
|
}
|
|
@@ -44347,7 +44623,7 @@ if __name__ == '__main__':
|
|
|
44347
44623
|
* Used for Telegram voice messages and WebSocket streaming.
|
|
44348
44624
|
*/
|
|
44349
44625
|
async synthesizeLuxttsToBuffer(text) {
|
|
44350
|
-
if (!this.luxttsCloneRef || !
|
|
44626
|
+
if (!this.luxttsCloneRef || !existsSync40(this.luxttsCloneRef))
|
|
44351
44627
|
return null;
|
|
44352
44628
|
const cleaned = text.replace(/\*/g, "").trim();
|
|
44353
44629
|
if (!cleaned)
|
|
@@ -44355,7 +44631,7 @@ if __name__ == '__main__':
|
|
|
44355
44631
|
const ready = await this.ensureLuxttsDaemon();
|
|
44356
44632
|
if (!ready)
|
|
44357
44633
|
return null;
|
|
44358
|
-
const wavPath =
|
|
44634
|
+
const wavPath = join56(tmpdir9(), `oa-luxtts-buf-${Date.now()}.wav`);
|
|
44359
44635
|
try {
|
|
44360
44636
|
await this.luxttsRequest({
|
|
44361
44637
|
action: "synthesize",
|
|
@@ -44367,11 +44643,11 @@ if __name__ == '__main__':
|
|
|
44367
44643
|
} catch {
|
|
44368
44644
|
return null;
|
|
44369
44645
|
}
|
|
44370
|
-
if (!
|
|
44646
|
+
if (!existsSync40(wavPath))
|
|
44371
44647
|
return null;
|
|
44372
44648
|
try {
|
|
44373
|
-
const data =
|
|
44374
|
-
|
|
44649
|
+
const data = readFileSync29(wavPath);
|
|
44650
|
+
unlinkSync9(wavPath);
|
|
44375
44651
|
return data;
|
|
44376
44652
|
} catch {
|
|
44377
44653
|
return null;
|
|
@@ -44384,40 +44660,40 @@ if __name__ == '__main__':
|
|
|
44384
44660
|
if (this.ort)
|
|
44385
44661
|
return;
|
|
44386
44662
|
const arch2 = process.arch;
|
|
44387
|
-
|
|
44388
|
-
const pkgPath =
|
|
44663
|
+
mkdirSync16(voiceDir(), { recursive: true });
|
|
44664
|
+
const pkgPath = join56(voiceDir(), "package.json");
|
|
44389
44665
|
const expectedDeps = {
|
|
44390
44666
|
"onnxruntime-node": "^1.21.0",
|
|
44391
44667
|
"phonemizer": "^1.2.1"
|
|
44392
44668
|
};
|
|
44393
|
-
if (
|
|
44669
|
+
if (existsSync40(pkgPath)) {
|
|
44394
44670
|
try {
|
|
44395
|
-
const existing = JSON.parse(
|
|
44671
|
+
const existing = JSON.parse(readFileSync29(pkgPath, "utf8"));
|
|
44396
44672
|
if (!existing.dependencies?.["phonemizer"]) {
|
|
44397
44673
|
existing.dependencies = { ...existing.dependencies, ...expectedDeps };
|
|
44398
|
-
|
|
44674
|
+
writeFileSync17(pkgPath, JSON.stringify(existing, null, 2));
|
|
44399
44675
|
}
|
|
44400
44676
|
} catch {
|
|
44401
44677
|
}
|
|
44402
44678
|
}
|
|
44403
|
-
if (!
|
|
44404
|
-
|
|
44679
|
+
if (!existsSync40(pkgPath)) {
|
|
44680
|
+
writeFileSync17(pkgPath, JSON.stringify({
|
|
44405
44681
|
name: "open-agents-voice",
|
|
44406
44682
|
private: true,
|
|
44407
44683
|
dependencies: expectedDeps
|
|
44408
44684
|
}, null, 2));
|
|
44409
44685
|
}
|
|
44410
|
-
const voiceRequire = createRequire(
|
|
44686
|
+
const voiceRequire = createRequire(join56(voiceDir(), "index.js"));
|
|
44411
44687
|
const probeOnnx = async () => {
|
|
44412
44688
|
try {
|
|
44413
|
-
const output = await this.asyncShell(`NODE_PATH="${
|
|
44689
|
+
const output = await this.asyncShell(`NODE_PATH="${join56(voiceDir(), "node_modules")}" node -e "try { require('onnxruntime-node'); console.log('OK'); } catch(e) { console.log('FAIL:' + e.message); }"`, 15e3);
|
|
44414
44690
|
return output.trim() === "OK";
|
|
44415
44691
|
} catch {
|
|
44416
44692
|
return false;
|
|
44417
44693
|
}
|
|
44418
44694
|
};
|
|
44419
|
-
const onnxNodeModules =
|
|
44420
|
-
const onnxInstalled =
|
|
44695
|
+
const onnxNodeModules = join56(voiceDir(), "node_modules", "onnxruntime-node");
|
|
44696
|
+
const onnxInstalled = existsSync40(onnxNodeModules);
|
|
44421
44697
|
if (onnxInstalled && !await probeOnnx()) {
|
|
44422
44698
|
throw new Error(`Voice synthesis unavailable: ONNX runtime crashes on this CPU (${process.platform}-${arch2}). This is a known issue with some ARM SoCs where the CPU vendor is not recognized. Voice feedback will be disabled but all other features work normally.`);
|
|
44423
44699
|
}
|
|
@@ -44467,18 +44743,18 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
44467
44743
|
const dir = modelDir(id);
|
|
44468
44744
|
const onnxPath = modelOnnxPath(id);
|
|
44469
44745
|
const configPath = modelConfigPath(id);
|
|
44470
|
-
if (
|
|
44746
|
+
if (existsSync40(onnxPath) && existsSync40(configPath))
|
|
44471
44747
|
return;
|
|
44472
|
-
|
|
44473
|
-
if (!
|
|
44748
|
+
mkdirSync16(dir, { recursive: true });
|
|
44749
|
+
if (!existsSync40(configPath)) {
|
|
44474
44750
|
renderInfo(`Downloading ${model.label} voice config...`);
|
|
44475
44751
|
const configResp = await fetch(model.configUrl);
|
|
44476
44752
|
if (!configResp.ok)
|
|
44477
44753
|
throw new Error(`Failed to download config: HTTP ${configResp.status}`);
|
|
44478
44754
|
const configText = await configResp.text();
|
|
44479
|
-
|
|
44755
|
+
writeFileSync17(configPath, configText);
|
|
44480
44756
|
}
|
|
44481
|
-
if (!
|
|
44757
|
+
if (!existsSync40(onnxPath)) {
|
|
44482
44758
|
renderInfo(`Downloading ${model.label} voice model (this may take a minute)...`);
|
|
44483
44759
|
const onnxResp = await fetch(model.onnxUrl);
|
|
44484
44760
|
if (!onnxResp.ok)
|
|
@@ -44503,7 +44779,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
44503
44779
|
}
|
|
44504
44780
|
}
|
|
44505
44781
|
const fullBuffer = Buffer.concat(chunks);
|
|
44506
|
-
|
|
44782
|
+
writeFileSync17(onnxPath, fullBuffer);
|
|
44507
44783
|
renderInfo(`${model.label} model downloaded (${formatBytes2(fullBuffer.length)}).`);
|
|
44508
44784
|
}
|
|
44509
44785
|
}
|
|
@@ -44515,10 +44791,10 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
44515
44791
|
throw new Error("ONNX runtime not loaded");
|
|
44516
44792
|
const onnxPath = modelOnnxPath(this.modelId);
|
|
44517
44793
|
const configPath = modelConfigPath(this.modelId);
|
|
44518
|
-
if (!
|
|
44794
|
+
if (!existsSync40(onnxPath) || !existsSync40(configPath)) {
|
|
44519
44795
|
throw new Error(`Model files not found for ${this.modelId}`);
|
|
44520
44796
|
}
|
|
44521
|
-
this.config = JSON.parse(
|
|
44797
|
+
this.config = JSON.parse(readFileSync29(configPath, "utf8"));
|
|
44522
44798
|
this.session = await this.ort.InferenceSession.create(onnxPath, {
|
|
44523
44799
|
executionProviders: ["cpu"],
|
|
44524
44800
|
graphOptimizationLevel: "all"
|
|
@@ -44545,8 +44821,8 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
44545
44821
|
// packages/cli/dist/tui/commands.js
|
|
44546
44822
|
import * as nodeOs from "node:os";
|
|
44547
44823
|
import { execSync as nodeExecSync } from "node:child_process";
|
|
44548
|
-
import { existsSync as
|
|
44549
|
-
import { join as
|
|
44824
|
+
import { existsSync as existsSync41, readFileSync as readFileSync30, writeFileSync as writeFileSync18, mkdirSync as mkdirSync17, readdirSync as readdirSync12, statSync as statSync14, rmSync } from "node:fs";
|
|
44825
|
+
import { join as join57 } from "node:path";
|
|
44550
44826
|
function safeLog(text) {
|
|
44551
44827
|
if (isNeovimActive()) {
|
|
44552
44828
|
writeToNeovimOutput(text + "\n");
|
|
@@ -45155,22 +45431,22 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45155
45431
|
let content = "";
|
|
45156
45432
|
let metadata = {};
|
|
45157
45433
|
if (shareType === "tool") {
|
|
45158
|
-
const toolDir =
|
|
45159
|
-
const toolFile =
|
|
45160
|
-
if (!
|
|
45434
|
+
const toolDir = join57(ctx.repoRoot, ".oa", "tools");
|
|
45435
|
+
const toolFile = join57(toolDir, shareName.endsWith(".json") ? shareName : `${shareName}.json`);
|
|
45436
|
+
if (!existsSync41(toolFile)) {
|
|
45161
45437
|
renderWarning(`Tool not found: ${toolFile}`);
|
|
45162
45438
|
return "handled";
|
|
45163
45439
|
}
|
|
45164
|
-
content =
|
|
45440
|
+
content = readFileSync30(toolFile, "utf8");
|
|
45165
45441
|
metadata = { type: "tool", name: shareName };
|
|
45166
45442
|
} else if (shareType === "skill") {
|
|
45167
|
-
const skillDir =
|
|
45168
|
-
const skillFile =
|
|
45169
|
-
if (!
|
|
45443
|
+
const skillDir = join57(ctx.repoRoot, ".oa", "skills", shareName);
|
|
45444
|
+
const skillFile = join57(skillDir, "SKILL.md");
|
|
45445
|
+
if (!existsSync41(skillFile)) {
|
|
45170
45446
|
renderWarning(`Skill not found: ${skillFile}`);
|
|
45171
45447
|
return "handled";
|
|
45172
45448
|
}
|
|
45173
|
-
content =
|
|
45449
|
+
content = readFileSync30(skillFile, "utf8");
|
|
45174
45450
|
metadata = { type: "skill", name: shareName };
|
|
45175
45451
|
} else {
|
|
45176
45452
|
renderWarning(`Unknown share type: ${shareType}. Use 'tool' or 'skill'.`);
|
|
@@ -45209,9 +45485,9 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45209
45485
|
const { NexusTool: NexusTool2 } = __require("@open-agents/execution");
|
|
45210
45486
|
const nexus = new NexusTool2(ctx.repoRoot);
|
|
45211
45487
|
await nexus.execute({ action: "ipfs_pin", cid: importCid, source: "import" });
|
|
45212
|
-
const regFile =
|
|
45213
|
-
if (
|
|
45214
|
-
const reg = JSON.parse(
|
|
45488
|
+
const regFile = join57(ctx.repoRoot, ".oa", "nexus", "ipfs", "cid-registry", "learning-cids.json");
|
|
45489
|
+
if (existsSync41(regFile)) {
|
|
45490
|
+
const reg = JSON.parse(readFileSync30(regFile, "utf8"));
|
|
45215
45491
|
const pinned = Object.values(reg).some((e) => e.cid === importCid && e.pinned);
|
|
45216
45492
|
if (pinned) {
|
|
45217
45493
|
renderInfo(`CID ${importCid.slice(0, 20)}... pinned successfully.`);
|
|
@@ -45264,33 +45540,33 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45264
45540
|
lines.push(`
|
|
45265
45541
|
${c2.bold("IPFS / Helia Status")}
|
|
45266
45542
|
`);
|
|
45267
|
-
const ipfsDir =
|
|
45268
|
-
const ipfsLocalDir =
|
|
45543
|
+
const ipfsDir = join57(ctx.repoRoot, ".oa", "ipfs");
|
|
45544
|
+
const ipfsLocalDir = join57(ipfsDir, "local");
|
|
45269
45545
|
let ipfsFiles = 0;
|
|
45270
45546
|
let ipfsBytes = 0;
|
|
45271
45547
|
let heliaBlocks = 0;
|
|
45272
45548
|
let heliaBytes = 0;
|
|
45273
45549
|
try {
|
|
45274
|
-
if (
|
|
45275
|
-
const files =
|
|
45550
|
+
if (existsSync41(ipfsLocalDir)) {
|
|
45551
|
+
const files = readdirSync12(ipfsLocalDir).filter((f) => f.endsWith(".json"));
|
|
45276
45552
|
ipfsFiles = files.length;
|
|
45277
45553
|
for (const f of files) {
|
|
45278
45554
|
try {
|
|
45279
|
-
ipfsBytes += statSync14(
|
|
45555
|
+
ipfsBytes += statSync14(join57(ipfsLocalDir, f)).size;
|
|
45280
45556
|
} catch {
|
|
45281
45557
|
}
|
|
45282
45558
|
}
|
|
45283
45559
|
}
|
|
45284
|
-
const heliaBlockDir =
|
|
45285
|
-
if (
|
|
45560
|
+
const heliaBlockDir = join57(ipfsDir, "blocks");
|
|
45561
|
+
if (existsSync41(heliaBlockDir)) {
|
|
45286
45562
|
const walkDir = (dir) => {
|
|
45287
|
-
for (const entry of
|
|
45563
|
+
for (const entry of readdirSync12(dir, { withFileTypes: true })) {
|
|
45288
45564
|
if (entry.isDirectory())
|
|
45289
|
-
walkDir(
|
|
45565
|
+
walkDir(join57(dir, entry.name));
|
|
45290
45566
|
else {
|
|
45291
45567
|
heliaBlocks++;
|
|
45292
45568
|
try {
|
|
45293
|
-
heliaBytes += statSync14(
|
|
45569
|
+
heliaBytes += statSync14(join57(dir, entry.name)).size;
|
|
45294
45570
|
} catch {
|
|
45295
45571
|
}
|
|
45296
45572
|
}
|
|
@@ -45306,9 +45582,9 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45306
45582
|
lines.push(` Blocks: ${c2.bold(String(heliaBlocks))} Size: ${c2.bold(formatFileSize(heliaBytes))}`);
|
|
45307
45583
|
lines.push(` Backend: ${heliaBlocks > 0 ? c2.green("helia-ipfs") : c2.yellow("sha256-local (Helia not initialized)")}`);
|
|
45308
45584
|
try {
|
|
45309
|
-
const statusFile =
|
|
45310
|
-
if (
|
|
45311
|
-
const status = JSON.parse(
|
|
45585
|
+
const statusFile = join57(ctx.repoRoot, ".oa", "nexus", "status.json");
|
|
45586
|
+
if (existsSync41(statusFile)) {
|
|
45587
|
+
const status = JSON.parse(readFileSync30(statusFile, "utf8"));
|
|
45312
45588
|
if (status.peerId) {
|
|
45313
45589
|
lines.push(`
|
|
45314
45590
|
${c2.bold("Peer Info")}`);
|
|
@@ -45327,11 +45603,11 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45327
45603
|
${c2.dim("Commands: /ipfs pin <CID> /ipfs publish /ipfs cids")}`);
|
|
45328
45604
|
lines.push(`
|
|
45329
45605
|
${c2.bold("Identity Kernel")}`);
|
|
45330
|
-
const idDir =
|
|
45606
|
+
const idDir = join57(ctx.repoRoot, ".oa", "identity");
|
|
45331
45607
|
try {
|
|
45332
|
-
const stateFile =
|
|
45333
|
-
if (
|
|
45334
|
-
const state = JSON.parse(
|
|
45608
|
+
const stateFile = join57(idDir, "self-state.json");
|
|
45609
|
+
if (existsSync41(stateFile)) {
|
|
45610
|
+
const state = JSON.parse(readFileSync30(stateFile, "utf8"));
|
|
45335
45611
|
lines.push(` Version: ${c2.bold("v" + (state.version ?? "?"))} Sessions: ${c2.bold(String(state.session_count ?? 0))}`);
|
|
45336
45612
|
if (state.narrative_summary) {
|
|
45337
45613
|
lines.push(` Narrative: ${c2.dim(state.narrative_summary.slice(0, 60))}${state.narrative_summary.length > 60 ? "..." : ""}`);
|
|
@@ -45340,9 +45616,9 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45340
45616
|
const traits = typeof state.personality_traits === "object" ? Object.entries(state.personality_traits).map(([k, v]) => `${k}:${v}`).join(", ") : String(state.personality_traits);
|
|
45341
45617
|
lines.push(` Traits: ${c2.dim(traits.slice(0, 60))}`);
|
|
45342
45618
|
}
|
|
45343
|
-
const cidFile =
|
|
45344
|
-
if (
|
|
45345
|
-
const cids = JSON.parse(
|
|
45619
|
+
const cidFile = join57(idDir, "cids.json");
|
|
45620
|
+
if (existsSync41(cidFile)) {
|
|
45621
|
+
const cids = JSON.parse(readFileSync30(cidFile, "utf8"));
|
|
45346
45622
|
const lastCid = Array.isArray(cids) ? cids[cids.length - 1] : cids.latest;
|
|
45347
45623
|
if (lastCid)
|
|
45348
45624
|
lines.push(` Last CID: ${c2.dim(String(lastCid).slice(0, 50))}`);
|
|
@@ -45355,9 +45631,9 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45355
45631
|
lines.push(`
|
|
45356
45632
|
${c2.bold("Memory Sentiment")}`);
|
|
45357
45633
|
try {
|
|
45358
|
-
const metaFile =
|
|
45359
|
-
if (
|
|
45360
|
-
const store = JSON.parse(
|
|
45634
|
+
const metaFile = join57(ctx.repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
45635
|
+
if (existsSync41(metaFile)) {
|
|
45636
|
+
const store = JSON.parse(readFileSync30(metaFile, "utf8"));
|
|
45361
45637
|
const active = store.filter((m) => m.type !== "quarantine");
|
|
45362
45638
|
const recoveries = active.filter((m) => m.content?.startsWith("[recovery]")).length;
|
|
45363
45639
|
const strategies = active.filter((m) => m.content?.startsWith("[strategy]")).length;
|
|
@@ -45375,8 +45651,8 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45375
45651
|
} catch {
|
|
45376
45652
|
}
|
|
45377
45653
|
try {
|
|
45378
|
-
const dbPath =
|
|
45379
|
-
if (
|
|
45654
|
+
const dbPath = join57(ctx.repoRoot, ".oa", "memory", "structured.db");
|
|
45655
|
+
if (existsSync41(dbPath)) {
|
|
45380
45656
|
const { initDb: initDb2, closeDb: cDb, ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
|
|
45381
45657
|
const db = initDb2(dbPath);
|
|
45382
45658
|
const memStore = new ProceduralMemoryStore2(db);
|
|
@@ -45397,8 +45673,8 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45397
45673
|
lines.push(`
|
|
45398
45674
|
${c2.bold("Storage Overview")}
|
|
45399
45675
|
`);
|
|
45400
|
-
const oaDir =
|
|
45401
|
-
if (!
|
|
45676
|
+
const oaDir = join57(ctx.repoRoot, ".oa");
|
|
45677
|
+
if (!existsSync41(oaDir)) {
|
|
45402
45678
|
lines.push(` ${c2.dim("No .oa/ directory found.")}`);
|
|
45403
45679
|
safeLog(lines.join("\n") + "\n");
|
|
45404
45680
|
return "handled";
|
|
@@ -45407,8 +45683,8 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45407
45683
|
const categories = {};
|
|
45408
45684
|
const walkStorage = (dir, category) => {
|
|
45409
45685
|
try {
|
|
45410
|
-
for (const entry of
|
|
45411
|
-
const full =
|
|
45686
|
+
for (const entry of readdirSync12(dir, { withFileTypes: true })) {
|
|
45687
|
+
const full = join57(dir, entry.name);
|
|
45412
45688
|
if (entry.isDirectory()) {
|
|
45413
45689
|
const subCat = category || entry.name;
|
|
45414
45690
|
walkStorage(full, subCat);
|
|
@@ -45441,13 +45717,13 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45441
45717
|
const sensitiveFound = [];
|
|
45442
45718
|
const checkSensitive = (dir) => {
|
|
45443
45719
|
try {
|
|
45444
|
-
for (const entry of
|
|
45720
|
+
for (const entry of readdirSync12(dir, { withFileTypes: true })) {
|
|
45445
45721
|
const name = entry.name.toLowerCase();
|
|
45446
45722
|
if (sensitivePatterns.some((p) => name.includes(p))) {
|
|
45447
|
-
sensitiveFound.push(
|
|
45723
|
+
sensitiveFound.push(join57(dir, entry.name).replace(oaDir + "/", ""));
|
|
45448
45724
|
}
|
|
45449
45725
|
if (entry.isDirectory())
|
|
45450
|
-
checkSensitive(
|
|
45726
|
+
checkSensitive(join57(dir, entry.name));
|
|
45451
45727
|
}
|
|
45452
45728
|
} catch {
|
|
45453
45729
|
}
|
|
@@ -45475,8 +45751,8 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45475
45751
|
renderInfo("Supported: .wav .mp3 .flac .ogg (audio\u2192transcribe) | .pdf .txt .md (text\u2192chunk)");
|
|
45476
45752
|
return "handled";
|
|
45477
45753
|
}
|
|
45478
|
-
const resolvedPath =
|
|
45479
|
-
if (!
|
|
45754
|
+
const resolvedPath = join57(ctx.repoRoot, filePath);
|
|
45755
|
+
if (!existsSync41(resolvedPath)) {
|
|
45480
45756
|
renderWarning(`File not found: ${resolvedPath}`);
|
|
45481
45757
|
return "handled";
|
|
45482
45758
|
}
|
|
@@ -45492,9 +45768,9 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45492
45768
|
}
|
|
45493
45769
|
try {
|
|
45494
45770
|
const { initDb: initDb2, closeDb: cDb, ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
|
|
45495
|
-
const dbDir =
|
|
45496
|
-
|
|
45497
|
-
const db = initDb2(
|
|
45771
|
+
const dbDir = join57(ctx.repoRoot, ".oa", "memory");
|
|
45772
|
+
mkdirSync17(dbDir, { recursive: true });
|
|
45773
|
+
const db = initDb2(join57(dbDir, "structured.db"));
|
|
45498
45774
|
const memStore = new ProceduralMemoryStore2(db);
|
|
45499
45775
|
if (isAudio) {
|
|
45500
45776
|
renderInfo(`Transcribing: ${filePath}...`);
|
|
@@ -45535,7 +45811,7 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45535
45811
|
return "handled";
|
|
45536
45812
|
}
|
|
45537
45813
|
} else {
|
|
45538
|
-
content =
|
|
45814
|
+
content = readFileSync30(resolvedPath, "utf8");
|
|
45539
45815
|
}
|
|
45540
45816
|
if (!content.trim()) {
|
|
45541
45817
|
renderWarning("No content extracted.");
|
|
@@ -45574,9 +45850,9 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45574
45850
|
}
|
|
45575
45851
|
case "fortemi": {
|
|
45576
45852
|
const fortemiSubCmd = (arg || "").trim().toLowerCase();
|
|
45577
|
-
const fortemiDir =
|
|
45578
|
-
const altFortemiDir =
|
|
45579
|
-
const fDir =
|
|
45853
|
+
const fortemiDir = join57(ctx.repoRoot, "..", "fortemi-react");
|
|
45854
|
+
const altFortemiDir = join57(nodeOs.homedir(), "fortemi-react");
|
|
45855
|
+
const fDir = existsSync41(fortemiDir) ? fortemiDir : existsSync41(altFortemiDir) ? altFortemiDir : null;
|
|
45580
45856
|
if (fortemiSubCmd === "start" || fortemiSubCmd === "") {
|
|
45581
45857
|
if (!fDir) {
|
|
45582
45858
|
renderWarning("fortemi-react not found adjacent or in home directory.");
|
|
@@ -45591,14 +45867,14 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45591
45867
|
// 24h
|
|
45592
45868
|
nonce: Math.random().toString(36).slice(2, 10)
|
|
45593
45869
|
};
|
|
45594
|
-
const jwtFile =
|
|
45595
|
-
|
|
45596
|
-
|
|
45870
|
+
const jwtFile = join57(ctx.repoRoot, ".oa", "fortemi-jwt.json");
|
|
45871
|
+
mkdirSync17(join57(ctx.repoRoot, ".oa"), { recursive: true });
|
|
45872
|
+
writeFileSync18(jwtFile, JSON.stringify(jwtPayload, null, 2));
|
|
45597
45873
|
renderInfo(`Launching fortemi-react from ${fDir}...`);
|
|
45598
45874
|
try {
|
|
45599
45875
|
const { spawn: spawn21 } = __require("node:child_process");
|
|
45600
45876
|
const child = spawn21("npx", ["vite", "dev", "--host", "0.0.0.0", "--port", "3000"], {
|
|
45601
|
-
cwd:
|
|
45877
|
+
cwd: join57(fDir, "apps", "standalone"),
|
|
45602
45878
|
stdio: "ignore",
|
|
45603
45879
|
detached: true,
|
|
45604
45880
|
env: { ...process.env, OA_JWT: JSON.stringify(jwtPayload) }
|
|
@@ -45607,8 +45883,8 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45607
45883
|
renderInfo("Fortemi-React starting on http://localhost:3000");
|
|
45608
45884
|
renderInfo(`JWT saved to ${jwtFile}`);
|
|
45609
45885
|
renderInfo("Memory operations will proxy to fortemi when available.");
|
|
45610
|
-
const bridgeFile =
|
|
45611
|
-
|
|
45886
|
+
const bridgeFile = join57(ctx.repoRoot, ".oa", "fortemi-bridge.json");
|
|
45887
|
+
writeFileSync18(bridgeFile, JSON.stringify({
|
|
45612
45888
|
url: "http://localhost:3000",
|
|
45613
45889
|
pid: child.pid,
|
|
45614
45890
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -45620,12 +45896,12 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45620
45896
|
return "handled";
|
|
45621
45897
|
}
|
|
45622
45898
|
if (fortemiSubCmd === "status") {
|
|
45623
|
-
const bridgeFile =
|
|
45624
|
-
if (!
|
|
45899
|
+
const bridgeFile = join57(ctx.repoRoot, ".oa", "fortemi-bridge.json");
|
|
45900
|
+
if (!existsSync41(bridgeFile)) {
|
|
45625
45901
|
renderInfo("Fortemi bridge: not connected. Run /fortemi start");
|
|
45626
45902
|
return "handled";
|
|
45627
45903
|
}
|
|
45628
|
-
const bridge = JSON.parse(
|
|
45904
|
+
const bridge = JSON.parse(readFileSync30(bridgeFile, "utf8"));
|
|
45629
45905
|
let alive = false;
|
|
45630
45906
|
try {
|
|
45631
45907
|
process.kill(bridge.pid, 0);
|
|
@@ -45645,15 +45921,15 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45645
45921
|
lines.push(` Process: ${alive ? c2.green("running") : c2.yellow("not running")} (PID ${bridge.pid})`);
|
|
45646
45922
|
lines.push(` HTTP: ${httpOk ? c2.green("connected") : c2.yellow("unreachable")}`);
|
|
45647
45923
|
lines.push(` Started: ${bridge.startedAt}`);
|
|
45648
|
-
lines.push(` JWT: ${
|
|
45924
|
+
lines.push(` JWT: ${existsSync41(bridge.jwtFile) ? c2.green("valid") : c2.yellow("missing")}`);
|
|
45649
45925
|
lines.push("");
|
|
45650
45926
|
safeLog(lines.join("\n"));
|
|
45651
45927
|
return "handled";
|
|
45652
45928
|
}
|
|
45653
45929
|
if (fortemiSubCmd === "stop") {
|
|
45654
|
-
const bridgeFile =
|
|
45655
|
-
if (
|
|
45656
|
-
const bridge = JSON.parse(
|
|
45930
|
+
const bridgeFile = join57(ctx.repoRoot, ".oa", "fortemi-bridge.json");
|
|
45931
|
+
if (existsSync41(bridgeFile)) {
|
|
45932
|
+
const bridge = JSON.parse(readFileSync30(bridgeFile, "utf8"));
|
|
45657
45933
|
try {
|
|
45658
45934
|
process.kill(bridge.pid, "SIGTERM");
|
|
45659
45935
|
} catch {
|
|
@@ -47032,13 +47308,13 @@ async function showCohereDashboard(ctx) {
|
|
|
47032
47308
|
} else if (idResult.key === "view") {
|
|
47033
47309
|
await ik.execute({ operation: "hydrate" });
|
|
47034
47310
|
} else if (idResult.key === "history") {
|
|
47035
|
-
const snapDir =
|
|
47036
|
-
if (
|
|
47037
|
-
const snaps =
|
|
47311
|
+
const snapDir = join57(ctx.repoRoot, ".oa", "identity", "snapshots");
|
|
47312
|
+
if (existsSync41(snapDir)) {
|
|
47313
|
+
const snaps = readdirSync12(snapDir).filter((f) => f.endsWith(".json")).sort().reverse();
|
|
47038
47314
|
const snapItems = snaps.slice(0, 20).map((f) => ({
|
|
47039
47315
|
key: f,
|
|
47040
47316
|
label: f.replace(".json", ""),
|
|
47041
|
-
detail: `${formatFileSize(statSync14(
|
|
47317
|
+
detail: `${formatFileSize(statSync14(join57(snapDir, f)).size)}`
|
|
47042
47318
|
}));
|
|
47043
47319
|
if (snapItems.length > 0) {
|
|
47044
47320
|
await tuiSelect({
|
|
@@ -47353,13 +47629,13 @@ async function handleVoiceMenu(ctx, save, hasLocal) {
|
|
|
47353
47629
|
if (!jsonDrop.confirmed || !jsonDrop.path) {
|
|
47354
47630
|
continue;
|
|
47355
47631
|
}
|
|
47356
|
-
const { basename:
|
|
47357
|
-
const { copyFileSync: copyFileSync2, mkdirSync:
|
|
47632
|
+
const { basename: basename18, join: pathJoin } = await import("node:path");
|
|
47633
|
+
const { copyFileSync: copyFileSync2, mkdirSync: mkdirSync25, existsSync: exists } = await import("node:fs");
|
|
47358
47634
|
const { homedir: homedir18 } = await import("node:os");
|
|
47359
|
-
const modelName =
|
|
47635
|
+
const modelName = basename18(onnxDrop.path, ".onnx").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
47360
47636
|
const destDir = pathJoin(homedir18(), ".open-agents", "voice", "models", modelName);
|
|
47361
47637
|
if (!exists(destDir))
|
|
47362
|
-
|
|
47638
|
+
mkdirSync25(destDir, { recursive: true });
|
|
47363
47639
|
copyFileSync2(onnxDrop.path, pathJoin(destDir, "model.onnx"));
|
|
47364
47640
|
copyFileSync2(jsonDrop.path, pathJoin(destDir, "config.json"));
|
|
47365
47641
|
const { registerCustomOnnxModel: registerCustomOnnxModel2 } = await Promise.resolve().then(() => (init_voice(), voice_exports));
|
|
@@ -47504,7 +47780,7 @@ async function handleVoiceList(ctx, focusFilename) {
|
|
|
47504
47780
|
const src = srcPath.trim();
|
|
47505
47781
|
try {
|
|
47506
47782
|
const { existsSync: fe, copyFileSync: cpf, mkdirSync: mkd } = __require("node:fs");
|
|
47507
|
-
const { basename:
|
|
47783
|
+
const { basename: basename18, join: pjoin } = __require("node:path");
|
|
47508
47784
|
if (!fe(src)) {
|
|
47509
47785
|
renderError(`File not found: ${src}`);
|
|
47510
47786
|
helpers.render();
|
|
@@ -47512,7 +47788,7 @@ async function handleVoiceList(ctx, focusFilename) {
|
|
|
47512
47788
|
}
|
|
47513
47789
|
const refsDir = pjoin(__require("node:os").homedir(), ".open-agents", "voice", "clone-refs");
|
|
47514
47790
|
mkd(refsDir, { recursive: true });
|
|
47515
|
-
const destName =
|
|
47791
|
+
const destName = basename18(src);
|
|
47516
47792
|
const dest = pjoin(refsDir, destName);
|
|
47517
47793
|
cpf(src, dest);
|
|
47518
47794
|
renderInfo(`Imported "${destName}" \u2192 ${dest}`);
|
|
@@ -47851,11 +48127,11 @@ async function handlePeerEndpoint(peerId, authKey, ctx, local) {
|
|
|
47851
48127
|
const models = await fetchModels(peerUrl, authKey);
|
|
47852
48128
|
if (models.length > 0) {
|
|
47853
48129
|
try {
|
|
47854
|
-
const { writeFileSync:
|
|
47855
|
-
const { join:
|
|
47856
|
-
const cachePath =
|
|
47857
|
-
|
|
47858
|
-
|
|
48130
|
+
const { writeFileSync: writeFileSync24, mkdirSync: mkdirSync25 } = await import("node:fs");
|
|
48131
|
+
const { join: join71, dirname: dirname22 } = await import("node:path");
|
|
48132
|
+
const cachePath = join71(ctx.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
|
|
48133
|
+
mkdirSync25(dirname22(cachePath), { recursive: true });
|
|
48134
|
+
writeFileSync24(cachePath, JSON.stringify({
|
|
47859
48135
|
peerId,
|
|
47860
48136
|
cachedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
47861
48137
|
models: models.map((m) => ({ name: m.name, size: m.size, parameterSize: m.parameterSize }))
|
|
@@ -47904,7 +48180,7 @@ async function handlePeerEndpoint(peerId, authKey, ctx, local) {
|
|
|
47904
48180
|
}
|
|
47905
48181
|
}
|
|
47906
48182
|
async function handleParallel(arg, ctx) {
|
|
47907
|
-
const { execSync:
|
|
48183
|
+
const { execSync: execSync34 } = await import("node:child_process");
|
|
47908
48184
|
const baseUrl = ctx.config.backendUrl || "http://localhost:11434";
|
|
47909
48185
|
const isRemote = ctx.config.backendType === "nexus";
|
|
47910
48186
|
if (isRemote) {
|
|
@@ -47928,7 +48204,7 @@ async function handleParallel(arg, ctx) {
|
|
|
47928
48204
|
}
|
|
47929
48205
|
let systemdVal = "";
|
|
47930
48206
|
try {
|
|
47931
|
-
const out =
|
|
48207
|
+
const out = execSync34("systemctl show ollama.service -p Environment 2>/dev/null || true", { encoding: "utf8" });
|
|
47932
48208
|
const match = out.match(/OLLAMA_NUM_PARALLEL=(\d+)/);
|
|
47933
48209
|
if (match)
|
|
47934
48210
|
systemdVal = match[1];
|
|
@@ -47957,7 +48233,7 @@ async function handleParallel(arg, ctx) {
|
|
|
47957
48233
|
}
|
|
47958
48234
|
const isSystemd = (() => {
|
|
47959
48235
|
try {
|
|
47960
|
-
const out =
|
|
48236
|
+
const out = execSync34("systemctl is-active ollama.service 2>/dev/null", { encoding: "utf8" }).trim();
|
|
47961
48237
|
return out === "active" || out === "inactive";
|
|
47962
48238
|
} catch {
|
|
47963
48239
|
return false;
|
|
@@ -47971,10 +48247,10 @@ async function handleParallel(arg, ctx) {
|
|
|
47971
48247
|
const overrideContent = `[Service]
|
|
47972
48248
|
Environment="OLLAMA_NUM_PARALLEL=${n}"
|
|
47973
48249
|
`;
|
|
47974
|
-
|
|
47975
|
-
|
|
47976
|
-
|
|
47977
|
-
|
|
48250
|
+
execSync34(`sudo mkdir -p ${overrideDir}`, { stdio: "pipe" });
|
|
48251
|
+
execSync34(`echo '${overrideContent}' | sudo tee ${overrideFile} > /dev/null`, { stdio: "pipe" });
|
|
48252
|
+
execSync34("sudo systemctl daemon-reload", { stdio: "pipe" });
|
|
48253
|
+
execSync34("sudo systemctl restart ollama.service", { stdio: "pipe" });
|
|
47978
48254
|
let ready = false;
|
|
47979
48255
|
for (let i = 0; i < 30 && !ready; i++) {
|
|
47980
48256
|
await new Promise((r) => setTimeout(r, 500));
|
|
@@ -48001,7 +48277,7 @@ Environment="OLLAMA_NUM_PARALLEL=${n}"
|
|
|
48001
48277
|
renderInfo(`Setting OLLAMA_NUM_PARALLEL=${n}...`);
|
|
48002
48278
|
try {
|
|
48003
48279
|
try {
|
|
48004
|
-
|
|
48280
|
+
execSync34("pkill -f 'ollama serve' 2>/dev/null || true", { stdio: "pipe" });
|
|
48005
48281
|
} catch {
|
|
48006
48282
|
}
|
|
48007
48283
|
await new Promise((r) => setTimeout(r, 1e3));
|
|
@@ -48054,17 +48330,17 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
48054
48330
|
try {
|
|
48055
48331
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
48056
48332
|
const { fileURLToPath: fileURLToPath14 } = await import("node:url");
|
|
48057
|
-
const { dirname: dirname22, join:
|
|
48058
|
-
const { existsSync:
|
|
48333
|
+
const { dirname: dirname22, join: join71 } = await import("node:path");
|
|
48334
|
+
const { existsSync: existsSync51 } = await import("node:fs");
|
|
48059
48335
|
const req = createRequire4(import.meta.url);
|
|
48060
48336
|
const thisDir = dirname22(fileURLToPath14(import.meta.url));
|
|
48061
48337
|
const candidates = [
|
|
48062
|
-
|
|
48063
|
-
|
|
48064
|
-
|
|
48338
|
+
join71(thisDir, "..", "package.json"),
|
|
48339
|
+
join71(thisDir, "..", "..", "package.json"),
|
|
48340
|
+
join71(thisDir, "..", "..", "..", "package.json")
|
|
48065
48341
|
];
|
|
48066
48342
|
for (const pkgPath of candidates) {
|
|
48067
|
-
if (
|
|
48343
|
+
if (existsSync51(pkgPath)) {
|
|
48068
48344
|
const pkg = req(pkgPath);
|
|
48069
48345
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
|
|
48070
48346
|
currentVersion = pkg.version ?? "0.0.0";
|
|
@@ -48804,18 +49080,18 @@ async function showExposeDashboard(gateway, rl, ctx) {
|
|
|
48804
49080
|
const cmd = `/endpoint ${id} --auth ${gateway.authKey ?? ""}`;
|
|
48805
49081
|
let copied = false;
|
|
48806
49082
|
try {
|
|
48807
|
-
const { execSync:
|
|
49083
|
+
const { execSync: execSync34 } = __require("node:child_process");
|
|
48808
49084
|
const platform6 = process.platform;
|
|
48809
49085
|
if (platform6 === "darwin") {
|
|
48810
|
-
|
|
49086
|
+
execSync34("pbcopy", { input: cmd, timeout: 3e3 });
|
|
48811
49087
|
copied = true;
|
|
48812
49088
|
} else if (platform6 === "win32") {
|
|
48813
|
-
|
|
49089
|
+
execSync34("clip", { input: cmd, timeout: 3e3 });
|
|
48814
49090
|
copied = true;
|
|
48815
49091
|
} else {
|
|
48816
49092
|
for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
|
|
48817
49093
|
try {
|
|
48818
|
-
|
|
49094
|
+
execSync34(tool, { input: cmd, timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] });
|
|
48819
49095
|
copied = true;
|
|
48820
49096
|
break;
|
|
48821
49097
|
} catch {
|
|
@@ -48902,9 +49178,9 @@ var init_commands = __esm({
|
|
|
48902
49178
|
});
|
|
48903
49179
|
|
|
48904
49180
|
// packages/cli/dist/tui/project-context.js
|
|
48905
|
-
import { existsSync as
|
|
48906
|
-
import { join as
|
|
48907
|
-
import { execSync as
|
|
49181
|
+
import { existsSync as existsSync42, readFileSync as readFileSync31, readdirSync as readdirSync13 } from "node:fs";
|
|
49182
|
+
import { join as join58, basename as basename12 } from "node:path";
|
|
49183
|
+
import { execSync as execSync30 } from "node:child_process";
|
|
48908
49184
|
import { homedir as homedir15, platform as platform4, release } from "node:os";
|
|
48909
49185
|
function getModelTier(modelName) {
|
|
48910
49186
|
const m = modelName.toLowerCase();
|
|
@@ -48938,10 +49214,10 @@ function loadProjectMap(repoRoot) {
|
|
|
48938
49214
|
if (!hasOaDirectory(repoRoot)) {
|
|
48939
49215
|
initOaDirectory(repoRoot);
|
|
48940
49216
|
}
|
|
48941
|
-
const mapPath2 =
|
|
48942
|
-
if (
|
|
49217
|
+
const mapPath2 = join58(repoRoot, OA_DIR, "context", "project-map.md");
|
|
49218
|
+
if (existsSync42(mapPath2)) {
|
|
48943
49219
|
try {
|
|
48944
|
-
const content =
|
|
49220
|
+
const content = readFileSync31(mapPath2, "utf-8");
|
|
48945
49221
|
return content;
|
|
48946
49222
|
} catch {
|
|
48947
49223
|
}
|
|
@@ -48950,19 +49226,19 @@ function loadProjectMap(repoRoot) {
|
|
|
48950
49226
|
}
|
|
48951
49227
|
function getGitInfo(repoRoot) {
|
|
48952
49228
|
try {
|
|
48953
|
-
|
|
49229
|
+
execSync30("git rev-parse --is-inside-work-tree", { cwd: repoRoot, stdio: "pipe" });
|
|
48954
49230
|
} catch {
|
|
48955
49231
|
return "";
|
|
48956
49232
|
}
|
|
48957
49233
|
const lines = [];
|
|
48958
49234
|
try {
|
|
48959
|
-
const branch =
|
|
49235
|
+
const branch = execSync30("git branch --show-current", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
48960
49236
|
if (branch)
|
|
48961
49237
|
lines.push(`Branch: ${branch}`);
|
|
48962
49238
|
} catch {
|
|
48963
49239
|
}
|
|
48964
49240
|
try {
|
|
48965
|
-
const status =
|
|
49241
|
+
const status = execSync30("git status --porcelain", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
48966
49242
|
if (status) {
|
|
48967
49243
|
const changed = status.split("\n").length;
|
|
48968
49244
|
lines.push(`Working tree: ${changed} changed file(s)`);
|
|
@@ -48972,7 +49248,7 @@ function getGitInfo(repoRoot) {
|
|
|
48972
49248
|
} catch {
|
|
48973
49249
|
}
|
|
48974
49250
|
try {
|
|
48975
|
-
const log =
|
|
49251
|
+
const log = execSync30("git log --oneline -5 --no-decorate", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
48976
49252
|
if (log)
|
|
48977
49253
|
lines.push(`Recent commits:
|
|
48978
49254
|
${log}`);
|
|
@@ -48982,33 +49258,33 @@ ${log}`);
|
|
|
48982
49258
|
}
|
|
48983
49259
|
function loadMemoryContext(repoRoot) {
|
|
48984
49260
|
const sections = [];
|
|
48985
|
-
const oaMemDir =
|
|
49261
|
+
const oaMemDir = join58(repoRoot, OA_DIR, "memory");
|
|
48986
49262
|
const oaEntries = loadMemoryDir(oaMemDir, "project");
|
|
48987
49263
|
if (oaEntries)
|
|
48988
49264
|
sections.push(oaEntries);
|
|
48989
|
-
const legacyMemDir =
|
|
48990
|
-
if (legacyMemDir !== oaMemDir &&
|
|
49265
|
+
const legacyMemDir = join58(repoRoot, ".open-agents", "memory");
|
|
49266
|
+
if (legacyMemDir !== oaMemDir && existsSync42(legacyMemDir)) {
|
|
48991
49267
|
const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
|
|
48992
49268
|
if (legacyEntries)
|
|
48993
49269
|
sections.push(legacyEntries);
|
|
48994
49270
|
}
|
|
48995
|
-
const globalMemDir =
|
|
49271
|
+
const globalMemDir = join58(homedir15(), ".open-agents", "memory");
|
|
48996
49272
|
const globalEntries = loadMemoryDir(globalMemDir, "global");
|
|
48997
49273
|
if (globalEntries)
|
|
48998
49274
|
sections.push(globalEntries);
|
|
48999
49275
|
return sections.join("\n\n");
|
|
49000
49276
|
}
|
|
49001
49277
|
function loadMemoryDir(memDir, scope) {
|
|
49002
|
-
if (!
|
|
49278
|
+
if (!existsSync42(memDir))
|
|
49003
49279
|
return "";
|
|
49004
49280
|
const lines = [];
|
|
49005
49281
|
try {
|
|
49006
|
-
const files =
|
|
49282
|
+
const files = readdirSync13(memDir).filter((f) => f.endsWith(".json"));
|
|
49007
49283
|
for (const file of files.slice(0, 10)) {
|
|
49008
49284
|
try {
|
|
49009
|
-
const raw =
|
|
49285
|
+
const raw = readFileSync31(join58(memDir, file), "utf-8");
|
|
49010
49286
|
const entries = JSON.parse(raw);
|
|
49011
|
-
const topic =
|
|
49287
|
+
const topic = basename12(file, ".json");
|
|
49012
49288
|
const keys = Object.keys(entries);
|
|
49013
49289
|
if (keys.length === 0)
|
|
49014
49290
|
continue;
|
|
@@ -50525,22 +50801,22 @@ var init_banner = __esm({
|
|
|
50525
50801
|
});
|
|
50526
50802
|
|
|
50527
50803
|
// packages/cli/dist/tui/carousel-descriptors.js
|
|
50528
|
-
import { existsSync as
|
|
50529
|
-
import { join as
|
|
50804
|
+
import { existsSync as existsSync43, readFileSync as readFileSync32, writeFileSync as writeFileSync19, mkdirSync as mkdirSync18, readdirSync as readdirSync14 } from "node:fs";
|
|
50805
|
+
import { join as join59, basename as basename13 } from "node:path";
|
|
50530
50806
|
function loadToolProfile(repoRoot) {
|
|
50531
|
-
const filePath =
|
|
50807
|
+
const filePath = join59(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
|
|
50532
50808
|
try {
|
|
50533
|
-
if (!
|
|
50809
|
+
if (!existsSync43(filePath))
|
|
50534
50810
|
return null;
|
|
50535
|
-
return JSON.parse(
|
|
50811
|
+
return JSON.parse(readFileSync32(filePath, "utf-8"));
|
|
50536
50812
|
} catch {
|
|
50537
50813
|
return null;
|
|
50538
50814
|
}
|
|
50539
50815
|
}
|
|
50540
50816
|
function saveToolProfile(repoRoot, profile) {
|
|
50541
|
-
const contextDir =
|
|
50542
|
-
|
|
50543
|
-
|
|
50817
|
+
const contextDir = join59(repoRoot, OA_DIR, "context");
|
|
50818
|
+
mkdirSync18(contextDir, { recursive: true });
|
|
50819
|
+
writeFileSync19(join59(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
|
|
50544
50820
|
}
|
|
50545
50821
|
function categorizeToolCall(toolName) {
|
|
50546
50822
|
for (const cat of TOOL_CATEGORIES) {
|
|
@@ -50598,25 +50874,25 @@ function weightedColor(profile) {
|
|
|
50598
50874
|
return selectedCat.colors[Math.floor(Math.random() * selectedCat.colors.length)];
|
|
50599
50875
|
}
|
|
50600
50876
|
function loadCachedDescriptors(repoRoot) {
|
|
50601
|
-
const filePath =
|
|
50877
|
+
const filePath = join59(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
|
|
50602
50878
|
try {
|
|
50603
|
-
if (!
|
|
50879
|
+
if (!existsSync43(filePath))
|
|
50604
50880
|
return null;
|
|
50605
|
-
const cached = JSON.parse(
|
|
50881
|
+
const cached = JSON.parse(readFileSync32(filePath, "utf-8"));
|
|
50606
50882
|
return cached.phrases.length > 0 ? cached.phrases : null;
|
|
50607
50883
|
} catch {
|
|
50608
50884
|
return null;
|
|
50609
50885
|
}
|
|
50610
50886
|
}
|
|
50611
50887
|
function saveCachedDescriptors(repoRoot, phrases, sourceHash) {
|
|
50612
|
-
const contextDir =
|
|
50613
|
-
|
|
50888
|
+
const contextDir = join59(repoRoot, OA_DIR, "context");
|
|
50889
|
+
mkdirSync18(contextDir, { recursive: true });
|
|
50614
50890
|
const cached = {
|
|
50615
50891
|
phrases,
|
|
50616
50892
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
50617
50893
|
sourceHash
|
|
50618
50894
|
};
|
|
50619
|
-
|
|
50895
|
+
writeFileSync19(join59(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
|
|
50620
50896
|
}
|
|
50621
50897
|
function generateDescriptors(repoRoot) {
|
|
50622
50898
|
const profile = loadToolProfile(repoRoot);
|
|
@@ -50627,7 +50903,7 @@ function generateDescriptors(repoRoot) {
|
|
|
50627
50903
|
extractFromSessions(repoRoot, tags);
|
|
50628
50904
|
extractFromMemory(repoRoot, tags);
|
|
50629
50905
|
extractFromToolProfile(profile, tags);
|
|
50630
|
-
const repoName2 =
|
|
50906
|
+
const repoName2 = basename13(repoRoot);
|
|
50631
50907
|
if (repoName2 && !tags.includes(repoName2)) {
|
|
50632
50908
|
tags.push(repoName2);
|
|
50633
50909
|
}
|
|
@@ -50664,11 +50940,11 @@ function generateDescriptors(repoRoot) {
|
|
|
50664
50940
|
return phrases;
|
|
50665
50941
|
}
|
|
50666
50942
|
function extractFromPackageJson(repoRoot, tags) {
|
|
50667
|
-
const pkgPath =
|
|
50943
|
+
const pkgPath = join59(repoRoot, "package.json");
|
|
50668
50944
|
try {
|
|
50669
|
-
if (!
|
|
50945
|
+
if (!existsSync43(pkgPath))
|
|
50670
50946
|
return;
|
|
50671
|
-
const pkg = JSON.parse(
|
|
50947
|
+
const pkg = JSON.parse(readFileSync32(pkgPath, "utf-8"));
|
|
50672
50948
|
if (pkg.name && typeof pkg.name === "string") {
|
|
50673
50949
|
const parts = pkg.name.replace(/^@/, "").split("/");
|
|
50674
50950
|
for (const p of parts)
|
|
@@ -50712,7 +50988,7 @@ function extractFromManifests(repoRoot, tags) {
|
|
|
50712
50988
|
{ file: ".github/workflows", tag: "ci/cd" }
|
|
50713
50989
|
];
|
|
50714
50990
|
for (const check of manifestChecks) {
|
|
50715
|
-
if (
|
|
50991
|
+
if (existsSync43(join59(repoRoot, check.file))) {
|
|
50716
50992
|
tags.push(check.tag);
|
|
50717
50993
|
}
|
|
50718
50994
|
}
|
|
@@ -50734,16 +51010,16 @@ function extractFromSessions(repoRoot, tags) {
|
|
|
50734
51010
|
}
|
|
50735
51011
|
}
|
|
50736
51012
|
function extractFromMemory(repoRoot, tags) {
|
|
50737
|
-
const memoryDir =
|
|
51013
|
+
const memoryDir = join59(repoRoot, OA_DIR, "memory");
|
|
50738
51014
|
try {
|
|
50739
|
-
if (!
|
|
51015
|
+
if (!existsSync43(memoryDir))
|
|
50740
51016
|
return;
|
|
50741
|
-
const files =
|
|
51017
|
+
const files = readdirSync14(memoryDir).filter((f) => f.endsWith(".json"));
|
|
50742
51018
|
for (const file of files) {
|
|
50743
51019
|
const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
|
|
50744
51020
|
tags.push(topic);
|
|
50745
51021
|
try {
|
|
50746
|
-
const data = JSON.parse(
|
|
51022
|
+
const data = JSON.parse(readFileSync32(join59(memoryDir, file), "utf-8"));
|
|
50747
51023
|
if (data && typeof data === "object") {
|
|
50748
51024
|
const keys = Object.keys(data).slice(0, 3);
|
|
50749
51025
|
for (const key of keys) {
|
|
@@ -51376,13 +51652,13 @@ var init_stream_renderer = __esm({
|
|
|
51376
51652
|
});
|
|
51377
51653
|
|
|
51378
51654
|
// packages/cli/dist/tui/edit-history.js
|
|
51379
|
-
import { appendFileSync as appendFileSync3, mkdirSync as
|
|
51380
|
-
import { join as
|
|
51655
|
+
import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync19 } from "node:fs";
|
|
51656
|
+
import { join as join60 } from "node:path";
|
|
51381
51657
|
function createEditHistoryLogger(repoRoot, sessionId) {
|
|
51382
|
-
const historyDir =
|
|
51383
|
-
const logPath2 =
|
|
51658
|
+
const historyDir = join60(repoRoot, ".oa", "history");
|
|
51659
|
+
const logPath2 = join60(historyDir, "edits.jsonl");
|
|
51384
51660
|
try {
|
|
51385
|
-
|
|
51661
|
+
mkdirSync19(historyDir, { recursive: true });
|
|
51386
51662
|
} catch {
|
|
51387
51663
|
}
|
|
51388
51664
|
function logToolCall(toolName, toolArgs, success) {
|
|
@@ -51491,17 +51767,17 @@ var init_edit_history = __esm({
|
|
|
51491
51767
|
});
|
|
51492
51768
|
|
|
51493
51769
|
// packages/cli/dist/tui/promptLoader.js
|
|
51494
|
-
import { readFileSync as
|
|
51495
|
-
import { join as
|
|
51770
|
+
import { readFileSync as readFileSync33, existsSync as existsSync44 } from "node:fs";
|
|
51771
|
+
import { join as join61, dirname as dirname19 } from "node:path";
|
|
51496
51772
|
import { fileURLToPath as fileURLToPath11 } from "node:url";
|
|
51497
51773
|
function loadPrompt3(promptPath, vars) {
|
|
51498
51774
|
let content = cache3.get(promptPath);
|
|
51499
51775
|
if (content === void 0) {
|
|
51500
|
-
const fullPath =
|
|
51501
|
-
if (!
|
|
51776
|
+
const fullPath = join61(PROMPTS_DIR3, promptPath);
|
|
51777
|
+
if (!existsSync44(fullPath)) {
|
|
51502
51778
|
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
51503
51779
|
}
|
|
51504
|
-
content =
|
|
51780
|
+
content = readFileSync33(fullPath, "utf-8");
|
|
51505
51781
|
cache3.set(promptPath, content);
|
|
51506
51782
|
}
|
|
51507
51783
|
if (!vars)
|
|
@@ -51514,23 +51790,23 @@ var init_promptLoader3 = __esm({
|
|
|
51514
51790
|
"use strict";
|
|
51515
51791
|
__filename3 = fileURLToPath11(import.meta.url);
|
|
51516
51792
|
__dirname6 = dirname19(__filename3);
|
|
51517
|
-
devPath2 =
|
|
51518
|
-
publishedPath2 =
|
|
51519
|
-
PROMPTS_DIR3 =
|
|
51793
|
+
devPath2 = join61(__dirname6, "..", "..", "prompts");
|
|
51794
|
+
publishedPath2 = join61(__dirname6, "..", "prompts");
|
|
51795
|
+
PROMPTS_DIR3 = existsSync44(devPath2) ? devPath2 : publishedPath2;
|
|
51520
51796
|
cache3 = /* @__PURE__ */ new Map();
|
|
51521
51797
|
}
|
|
51522
51798
|
});
|
|
51523
51799
|
|
|
51524
51800
|
// packages/cli/dist/tui/dream-engine.js
|
|
51525
|
-
import { mkdirSync as
|
|
51526
|
-
import { join as
|
|
51527
|
-
import { execSync as
|
|
51801
|
+
import { mkdirSync as mkdirSync20, writeFileSync as writeFileSync20, readFileSync as readFileSync34, existsSync as existsSync45, cpSync, rmSync as rmSync2, readdirSync as readdirSync15 } from "node:fs";
|
|
51802
|
+
import { join as join62, basename as basename14 } from "node:path";
|
|
51803
|
+
import { execSync as execSync31 } from "node:child_process";
|
|
51528
51804
|
function loadAutoresearchMemory(repoRoot) {
|
|
51529
|
-
const memoryPath =
|
|
51530
|
-
if (!
|
|
51805
|
+
const memoryPath = join62(repoRoot, ".oa", "memory", "autoresearch.json");
|
|
51806
|
+
if (!existsSync45(memoryPath))
|
|
51531
51807
|
return "";
|
|
51532
51808
|
try {
|
|
51533
|
-
const raw =
|
|
51809
|
+
const raw = readFileSync34(memoryPath, "utf-8");
|
|
51534
51810
|
const data = JSON.parse(raw);
|
|
51535
51811
|
const sections = [];
|
|
51536
51812
|
for (const key of AUTORESEARCH_MEMORY_KEYS) {
|
|
@@ -51720,14 +51996,14 @@ var init_dream_engine = __esm({
|
|
|
51720
51996
|
const content = String(args["content"] ?? "");
|
|
51721
51997
|
if (!rawPath)
|
|
51722
51998
|
return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
|
|
51723
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ?
|
|
51999
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join62(this.autoresearchDir, basename14(rawPath)) : join62(this.autoresearchDir, rawPath);
|
|
51724
52000
|
if (!targetPath.startsWith(this.autoresearchDir)) {
|
|
51725
52001
|
return { success: false, output: "", error: "Autoresearch mode: writes are confined to .oa/autoresearch/", durationMs: Date.now() - start };
|
|
51726
52002
|
}
|
|
51727
52003
|
try {
|
|
51728
|
-
const dir =
|
|
51729
|
-
|
|
51730
|
-
|
|
52004
|
+
const dir = join62(targetPath, "..");
|
|
52005
|
+
mkdirSync20(dir, { recursive: true });
|
|
52006
|
+
writeFileSync20(targetPath, content, "utf-8");
|
|
51731
52007
|
return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
|
|
51732
52008
|
} catch (err) {
|
|
51733
52009
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
|
|
@@ -51755,20 +52031,20 @@ var init_dream_engine = __esm({
|
|
|
51755
52031
|
const rawPath = String(args["path"] ?? "");
|
|
51756
52032
|
const oldStr = String(args["old_string"] ?? "");
|
|
51757
52033
|
const newStr = String(args["new_string"] ?? "");
|
|
51758
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ?
|
|
52034
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join62(this.autoresearchDir, basename14(rawPath)) : join62(this.autoresearchDir, rawPath);
|
|
51759
52035
|
if (!targetPath.startsWith(this.autoresearchDir)) {
|
|
51760
52036
|
return { success: false, output: "", error: "Autoresearch mode: edits are confined to .oa/autoresearch/", durationMs: Date.now() - start };
|
|
51761
52037
|
}
|
|
51762
52038
|
try {
|
|
51763
|
-
if (!
|
|
52039
|
+
if (!existsSync45(targetPath)) {
|
|
51764
52040
|
return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
|
|
51765
52041
|
}
|
|
51766
|
-
let content =
|
|
52042
|
+
let content = readFileSync34(targetPath, "utf-8");
|
|
51767
52043
|
if (!content.includes(oldStr)) {
|
|
51768
52044
|
return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start };
|
|
51769
52045
|
}
|
|
51770
52046
|
content = content.replace(oldStr, newStr);
|
|
51771
|
-
|
|
52047
|
+
writeFileSync20(targetPath, content, "utf-8");
|
|
51772
52048
|
return { success: true, output: `Edited ${rawPath}`, durationMs: Date.now() - start };
|
|
51773
52049
|
} catch (err) {
|
|
51774
52050
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
|
|
@@ -51809,14 +52085,14 @@ var init_dream_engine = __esm({
|
|
|
51809
52085
|
const content = String(args["content"] ?? "");
|
|
51810
52086
|
if (!rawPath)
|
|
51811
52087
|
return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
|
|
51812
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ?
|
|
52088
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join62(this.dreamsDir, basename14(rawPath)) : join62(this.dreamsDir, rawPath);
|
|
51813
52089
|
if (!targetPath.startsWith(this.dreamsDir)) {
|
|
51814
52090
|
return { success: false, output: "", error: "Dream mode: writes are confined to .oa/dreams/", durationMs: Date.now() - start };
|
|
51815
52091
|
}
|
|
51816
52092
|
try {
|
|
51817
|
-
const dir =
|
|
51818
|
-
|
|
51819
|
-
|
|
52093
|
+
const dir = join62(targetPath, "..");
|
|
52094
|
+
mkdirSync20(dir, { recursive: true });
|
|
52095
|
+
writeFileSync20(targetPath, content, "utf-8");
|
|
51820
52096
|
return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
|
|
51821
52097
|
} catch (err) {
|
|
51822
52098
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
|
|
@@ -51844,20 +52120,20 @@ var init_dream_engine = __esm({
|
|
|
51844
52120
|
const rawPath = String(args["path"] ?? "");
|
|
51845
52121
|
const oldStr = String(args["old_string"] ?? "");
|
|
51846
52122
|
const newStr = String(args["new_string"] ?? "");
|
|
51847
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ?
|
|
52123
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join62(this.dreamsDir, basename14(rawPath)) : join62(this.dreamsDir, rawPath);
|
|
51848
52124
|
if (!targetPath.startsWith(this.dreamsDir)) {
|
|
51849
52125
|
return { success: false, output: "", error: "Dream mode: edits are confined to .oa/dreams/", durationMs: Date.now() - start };
|
|
51850
52126
|
}
|
|
51851
52127
|
try {
|
|
51852
|
-
if (!
|
|
52128
|
+
if (!existsSync45(targetPath)) {
|
|
51853
52129
|
return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
|
|
51854
52130
|
}
|
|
51855
|
-
let content =
|
|
52131
|
+
let content = readFileSync34(targetPath, "utf-8");
|
|
51856
52132
|
if (!content.includes(oldStr)) {
|
|
51857
52133
|
return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start };
|
|
51858
52134
|
}
|
|
51859
52135
|
content = content.replace(oldStr, newStr);
|
|
51860
|
-
|
|
52136
|
+
writeFileSync20(targetPath, content, "utf-8");
|
|
51861
52137
|
return { success: true, output: `Edited ${rawPath}`, durationMs: Date.now() - start };
|
|
51862
52138
|
} catch (err) {
|
|
51863
52139
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
|
|
@@ -51888,7 +52164,7 @@ var init_dream_engine = __esm({
|
|
|
51888
52164
|
}
|
|
51889
52165
|
}
|
|
51890
52166
|
try {
|
|
51891
|
-
const output =
|
|
52167
|
+
const output = execSync31(cmd, {
|
|
51892
52168
|
cwd: this.repoRoot,
|
|
51893
52169
|
timeout: 3e4,
|
|
51894
52170
|
encoding: "utf-8",
|
|
@@ -51911,7 +52187,7 @@ var init_dream_engine = __esm({
|
|
|
51911
52187
|
constructor(config, repoRoot) {
|
|
51912
52188
|
this.config = config;
|
|
51913
52189
|
this.repoRoot = repoRoot;
|
|
51914
|
-
this.dreamsDir =
|
|
52190
|
+
this.dreamsDir = join62(repoRoot, ".oa", "dreams");
|
|
51915
52191
|
this.state = {
|
|
51916
52192
|
mode: "default",
|
|
51917
52193
|
active: false,
|
|
@@ -51942,7 +52218,7 @@ var init_dream_engine = __esm({
|
|
|
51942
52218
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
51943
52219
|
results: []
|
|
51944
52220
|
};
|
|
51945
|
-
|
|
52221
|
+
mkdirSync20(this.dreamsDir, { recursive: true });
|
|
51946
52222
|
this.saveDreamState();
|
|
51947
52223
|
try {
|
|
51948
52224
|
for (let cycle = 1; cycle <= totalCycles; cycle++) {
|
|
@@ -51995,8 +52271,8 @@ ${result.summary}`;
|
|
|
51995
52271
|
if (mode !== "default" || cycle === totalCycles) {
|
|
51996
52272
|
renderDreamContraction(cycle);
|
|
51997
52273
|
const cycleSummary = this.buildCycleSummary(cycle, previousFindings);
|
|
51998
|
-
const summaryPath =
|
|
51999
|
-
|
|
52274
|
+
const summaryPath = join62(this.dreamsDir, `cycle-${cycle}-summary.md`);
|
|
52275
|
+
writeFileSync20(summaryPath, cycleSummary, "utf-8");
|
|
52000
52276
|
}
|
|
52001
52277
|
if (mode === "lucid" && !this.abortController.signal.aborted) {
|
|
52002
52278
|
this.saveVersionCheckpoint(cycle);
|
|
@@ -52208,7 +52484,7 @@ After synthesis, call task_complete with the final prioritized summary.`, toolMo
|
|
|
52208
52484
|
}
|
|
52209
52485
|
/** Build role-specific tool sets for swarm agents */
|
|
52210
52486
|
buildSwarmTools(role, _workspace) {
|
|
52211
|
-
const autoresearchDir =
|
|
52487
|
+
const autoresearchDir = join62(this.repoRoot, ".oa", "autoresearch");
|
|
52212
52488
|
const taskComplete = this.createSwarmTaskCompleteTool(role);
|
|
52213
52489
|
switch (role) {
|
|
52214
52490
|
case "researcher": {
|
|
@@ -52572,7 +52848,7 @@ INSTRUCTIONS:
|
|
|
52572
52848
|
2. Summarize the key learnings and next steps
|
|
52573
52849
|
|
|
52574
52850
|
Call task_complete with a human-readable summary of the autoresearch session.`, workspace, onEvent);
|
|
52575
|
-
const reportPath =
|
|
52851
|
+
const reportPath = join62(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
|
|
52576
52852
|
const report = `# Autoresearch Swarm Report \u2014 Cycle ${cycleNum}
|
|
52577
52853
|
|
|
52578
52854
|
**Date**: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
|
|
@@ -52594,8 +52870,8 @@ ${summaryResult}
|
|
|
52594
52870
|
*Generated by open-agents autoresearch swarm*
|
|
52595
52871
|
`;
|
|
52596
52872
|
try {
|
|
52597
|
-
|
|
52598
|
-
|
|
52873
|
+
mkdirSync20(this.dreamsDir, { recursive: true });
|
|
52874
|
+
writeFileSync20(reportPath, report, "utf-8");
|
|
52599
52875
|
} catch {
|
|
52600
52876
|
}
|
|
52601
52877
|
renderSwarmComplete(workspace);
|
|
@@ -52661,29 +52937,29 @@ ${summaryResult}
|
|
|
52661
52937
|
}
|
|
52662
52938
|
/** Save workspace backup for lucid mode */
|
|
52663
52939
|
saveVersionCheckpoint(cycle) {
|
|
52664
|
-
const checkpointDir =
|
|
52940
|
+
const checkpointDir = join62(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
|
|
52665
52941
|
try {
|
|
52666
|
-
|
|
52942
|
+
mkdirSync20(checkpointDir, { recursive: true });
|
|
52667
52943
|
try {
|
|
52668
|
-
const gitStatus =
|
|
52944
|
+
const gitStatus = execSync31("git status --porcelain", {
|
|
52669
52945
|
cwd: this.repoRoot,
|
|
52670
52946
|
encoding: "utf-8",
|
|
52671
52947
|
timeout: 1e4
|
|
52672
52948
|
});
|
|
52673
|
-
const gitDiff =
|
|
52949
|
+
const gitDiff = execSync31("git diff", {
|
|
52674
52950
|
cwd: this.repoRoot,
|
|
52675
52951
|
encoding: "utf-8",
|
|
52676
52952
|
timeout: 1e4
|
|
52677
52953
|
});
|
|
52678
|
-
const gitHash =
|
|
52954
|
+
const gitHash = execSync31("git rev-parse HEAD 2>/dev/null || echo 'no-git'", {
|
|
52679
52955
|
cwd: this.repoRoot,
|
|
52680
52956
|
encoding: "utf-8",
|
|
52681
52957
|
timeout: 5e3
|
|
52682
52958
|
}).trim();
|
|
52683
|
-
|
|
52684
|
-
|
|
52685
|
-
|
|
52686
|
-
|
|
52959
|
+
writeFileSync20(join62(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
|
|
52960
|
+
writeFileSync20(join62(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
|
|
52961
|
+
writeFileSync20(join62(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
|
|
52962
|
+
writeFileSync20(join62(checkpointDir, "checkpoint.json"), JSON.stringify({
|
|
52687
52963
|
cycle,
|
|
52688
52964
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
52689
52965
|
gitHash,
|
|
@@ -52691,7 +52967,7 @@ ${summaryResult}
|
|
|
52691
52967
|
}, null, 2), "utf-8");
|
|
52692
52968
|
renderInfo(`Checkpoint saved: cycle ${cycle} (${gitHash.slice(0, 8)})`);
|
|
52693
52969
|
} catch {
|
|
52694
|
-
|
|
52970
|
+
writeFileSync20(join62(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
|
|
52695
52971
|
renderInfo(`Checkpoint saved: cycle ${cycle} (no git)`);
|
|
52696
52972
|
}
|
|
52697
52973
|
} catch (err) {
|
|
@@ -52728,7 +53004,7 @@ Each proposal includes implementation entrypoints and estimated effort.
|
|
|
52728
53004
|
/** Update the master proposal index */
|
|
52729
53005
|
updateProposalIndex() {
|
|
52730
53006
|
try {
|
|
52731
|
-
const files =
|
|
53007
|
+
const files = readdirSync15(this.dreamsDir).filter((f) => f.endsWith(".md") && f !== "PROPOSAL-INDEX.md" && f !== "dream-state.json").sort();
|
|
52732
53008
|
const index = `# Dream Proposals Index
|
|
52733
53009
|
|
|
52734
53010
|
**Last updated**: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
|
|
@@ -52749,14 +53025,14 @@ ${files.map((f) => `- [\`${f}\`](./${f})`).join("\n")}
|
|
|
52749
53025
|
---
|
|
52750
53026
|
*Auto-generated by open-agents dream engine*
|
|
52751
53027
|
`;
|
|
52752
|
-
|
|
53028
|
+
writeFileSync20(join62(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
|
|
52753
53029
|
} catch {
|
|
52754
53030
|
}
|
|
52755
53031
|
}
|
|
52756
53032
|
/** Save dream state for resume/inspection */
|
|
52757
53033
|
saveDreamState() {
|
|
52758
53034
|
try {
|
|
52759
|
-
|
|
53035
|
+
writeFileSync20(join62(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
|
|
52760
53036
|
} catch {
|
|
52761
53037
|
}
|
|
52762
53038
|
}
|
|
@@ -53130,8 +53406,8 @@ var init_bless_engine = __esm({
|
|
|
53130
53406
|
});
|
|
53131
53407
|
|
|
53132
53408
|
// packages/cli/dist/tui/dmn-engine.js
|
|
53133
|
-
import { existsSync as
|
|
53134
|
-
import { join as
|
|
53409
|
+
import { existsSync as existsSync46, readFileSync as readFileSync35, writeFileSync as writeFileSync21, mkdirSync as mkdirSync21, readdirSync as readdirSync16, unlinkSync as unlinkSync10 } from "node:fs";
|
|
53410
|
+
import { join as join63, basename as basename15 } from "node:path";
|
|
53135
53411
|
function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
|
|
53136
53412
|
const competenceReport = competence.length > 0 ? competence.map((c3) => {
|
|
53137
53413
|
const rate = c3.attempts > 0 ? Math.round(c3.successes / c3.attempts * 100) : 0;
|
|
@@ -53251,9 +53527,9 @@ var init_dmn_engine = __esm({
|
|
|
53251
53527
|
constructor(config, repoRoot) {
|
|
53252
53528
|
this.config = config;
|
|
53253
53529
|
this.repoRoot = repoRoot;
|
|
53254
|
-
this.stateDir =
|
|
53255
|
-
this.historyDir =
|
|
53256
|
-
|
|
53530
|
+
this.stateDir = join63(repoRoot, ".oa", "dmn");
|
|
53531
|
+
this.historyDir = join63(repoRoot, ".oa", "dmn", "cycles");
|
|
53532
|
+
mkdirSync21(this.historyDir, { recursive: true });
|
|
53257
53533
|
this.loadState();
|
|
53258
53534
|
}
|
|
53259
53535
|
get stats() {
|
|
@@ -53842,16 +54118,16 @@ OUTPUT: Call task_complete with JSON:
|
|
|
53842
54118
|
async gatherMemoryTopics() {
|
|
53843
54119
|
const topics = [];
|
|
53844
54120
|
const dirs = [
|
|
53845
|
-
|
|
53846
|
-
|
|
54121
|
+
join63(this.repoRoot, ".oa", "memory"),
|
|
54122
|
+
join63(this.repoRoot, ".open-agents", "memory")
|
|
53847
54123
|
];
|
|
53848
54124
|
for (const dir of dirs) {
|
|
53849
|
-
if (!
|
|
54125
|
+
if (!existsSync46(dir))
|
|
53850
54126
|
continue;
|
|
53851
54127
|
try {
|
|
53852
|
-
const files =
|
|
54128
|
+
const files = readdirSync16(dir).filter((f) => f.endsWith(".json"));
|
|
53853
54129
|
for (const f of files) {
|
|
53854
|
-
const topic =
|
|
54130
|
+
const topic = basename15(f, ".json");
|
|
53855
54131
|
if (!topics.includes(topic))
|
|
53856
54132
|
topics.push(topic);
|
|
53857
54133
|
}
|
|
@@ -53862,29 +54138,29 @@ OUTPUT: Call task_complete with JSON:
|
|
|
53862
54138
|
}
|
|
53863
54139
|
// ── State persistence ─────────────────────────────────────────────────
|
|
53864
54140
|
loadState() {
|
|
53865
|
-
const path =
|
|
53866
|
-
if (
|
|
54141
|
+
const path = join63(this.stateDir, "state.json");
|
|
54142
|
+
if (existsSync46(path)) {
|
|
53867
54143
|
try {
|
|
53868
|
-
this.state = JSON.parse(
|
|
54144
|
+
this.state = JSON.parse(readFileSync35(path, "utf-8"));
|
|
53869
54145
|
} catch {
|
|
53870
54146
|
}
|
|
53871
54147
|
}
|
|
53872
54148
|
}
|
|
53873
54149
|
saveState() {
|
|
53874
54150
|
try {
|
|
53875
|
-
|
|
54151
|
+
writeFileSync21(join63(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
|
|
53876
54152
|
} catch {
|
|
53877
54153
|
}
|
|
53878
54154
|
}
|
|
53879
54155
|
saveCycleResult(result) {
|
|
53880
54156
|
try {
|
|
53881
54157
|
const filename = `cycle-${result.cycleNumber}-${Date.now()}.json`;
|
|
53882
|
-
|
|
53883
|
-
const files =
|
|
54158
|
+
writeFileSync21(join63(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
|
|
54159
|
+
const files = readdirSync16(this.historyDir).filter((f) => f.startsWith("cycle-") && f.endsWith(".json")).sort();
|
|
53884
54160
|
if (files.length > 50) {
|
|
53885
54161
|
for (const old of files.slice(0, files.length - 50)) {
|
|
53886
54162
|
try {
|
|
53887
|
-
|
|
54163
|
+
unlinkSync10(join63(this.historyDir, old));
|
|
53888
54164
|
} catch {
|
|
53889
54165
|
}
|
|
53890
54166
|
}
|
|
@@ -53897,8 +54173,8 @@ OUTPUT: Call task_complete with JSON:
|
|
|
53897
54173
|
});
|
|
53898
54174
|
|
|
53899
54175
|
// packages/cli/dist/tui/snr-engine.js
|
|
53900
|
-
import { existsSync as
|
|
53901
|
-
import { join as
|
|
54176
|
+
import { existsSync as existsSync47, readdirSync as readdirSync17, readFileSync as readFileSync36 } from "node:fs";
|
|
54177
|
+
import { join as join64, basename as basename16 } from "node:path";
|
|
53902
54178
|
function computeDPrime(signalScores, noiseScores) {
|
|
53903
54179
|
if (signalScores.length === 0 || noiseScores.length === 0)
|
|
53904
54180
|
return 0;
|
|
@@ -54138,20 +54414,20 @@ Call task_complete with the JSON array when done.`, onEvent)
|
|
|
54138
54414
|
loadMemoryEntries(topics) {
|
|
54139
54415
|
const entries = [];
|
|
54140
54416
|
const dirs = [
|
|
54141
|
-
|
|
54142
|
-
|
|
54417
|
+
join64(this.repoRoot, ".oa", "memory"),
|
|
54418
|
+
join64(this.repoRoot, ".open-agents", "memory")
|
|
54143
54419
|
];
|
|
54144
54420
|
for (const dir of dirs) {
|
|
54145
|
-
if (!
|
|
54421
|
+
if (!existsSync47(dir))
|
|
54146
54422
|
continue;
|
|
54147
54423
|
try {
|
|
54148
|
-
const files =
|
|
54424
|
+
const files = readdirSync17(dir).filter((f) => f.endsWith(".json"));
|
|
54149
54425
|
for (const f of files) {
|
|
54150
|
-
const topic =
|
|
54426
|
+
const topic = basename16(f, ".json");
|
|
54151
54427
|
if (topics.length > 0 && !topics.includes(topic))
|
|
54152
54428
|
continue;
|
|
54153
54429
|
try {
|
|
54154
|
-
const data = JSON.parse(
|
|
54430
|
+
const data = JSON.parse(readFileSync36(join64(dir, f), "utf-8"));
|
|
54155
54431
|
for (const [key, val] of Object.entries(data)) {
|
|
54156
54432
|
const value = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
54157
54433
|
entries.push({ topic, key, value });
|
|
@@ -54718,8 +54994,8 @@ var init_tool_policy = __esm({
|
|
|
54718
54994
|
});
|
|
54719
54995
|
|
|
54720
54996
|
// packages/cli/dist/tui/telegram-bridge.js
|
|
54721
|
-
import { mkdirSync as
|
|
54722
|
-
import { join as
|
|
54997
|
+
import { mkdirSync as mkdirSync22, existsSync as existsSync48, unlinkSync as unlinkSync11, readdirSync as readdirSync18, statSync as statSync15 } from "node:fs";
|
|
54998
|
+
import { join as join65, resolve as resolve30 } from "node:path";
|
|
54723
54999
|
import { writeFile as writeFileAsync } from "node:fs/promises";
|
|
54724
55000
|
function convertMarkdownToTelegramHTML(md) {
|
|
54725
55001
|
let html = md;
|
|
@@ -55047,7 +55323,7 @@ with summary "no_reply" to silently skip without responding.
|
|
|
55047
55323
|
this.polling = true;
|
|
55048
55324
|
this.abortController = new AbortController();
|
|
55049
55325
|
try {
|
|
55050
|
-
|
|
55326
|
+
mkdirSync22(this.mediaCacheDir, { recursive: true });
|
|
55051
55327
|
} catch {
|
|
55052
55328
|
}
|
|
55053
55329
|
this.mediaCacheCleanupTimer = setInterval(() => this.cleanupMediaCache(), 5 * 60 * 1e3);
|
|
@@ -55484,7 +55760,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
|
|
|
55484
55760
|
return null;
|
|
55485
55761
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
55486
55762
|
const fileName = `${Date.now()}-${fileId.slice(0, 8)}${extension}`;
|
|
55487
|
-
const localPath =
|
|
55763
|
+
const localPath = join65(this.mediaCacheDir, fileName);
|
|
55488
55764
|
await writeFileAsync(localPath, buffer);
|
|
55489
55765
|
return localPath;
|
|
55490
55766
|
} catch {
|
|
@@ -55572,7 +55848,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
|
|
|
55572
55848
|
for (const [key, entry] of this.mediaCache) {
|
|
55573
55849
|
if (now - entry.cachedAt > MEDIA_CACHE_TTL_MS) {
|
|
55574
55850
|
try {
|
|
55575
|
-
|
|
55851
|
+
unlinkSync11(entry.localPath);
|
|
55576
55852
|
} catch {
|
|
55577
55853
|
}
|
|
55578
55854
|
this.mediaCache.delete(key);
|
|
@@ -56500,7 +56776,7 @@ __export(text_selection_exports, {
|
|
|
56500
56776
|
stripAnsi: () => stripAnsi3,
|
|
56501
56777
|
visibleLength: () => visibleLength
|
|
56502
56778
|
});
|
|
56503
|
-
import { execSync as
|
|
56779
|
+
import { execSync as execSync32 } from "node:child_process";
|
|
56504
56780
|
function stripAnsi3(s) {
|
|
56505
56781
|
return s.replace(/\x1B\[[0-9;]*[A-Za-z]|\x1B\].*?(?:\x07|\x1B\\)/g, "");
|
|
56506
56782
|
}
|
|
@@ -56511,16 +56787,16 @@ function copyText(text) {
|
|
|
56511
56787
|
try {
|
|
56512
56788
|
const platform6 = process.platform;
|
|
56513
56789
|
if (platform6 === "darwin") {
|
|
56514
|
-
|
|
56790
|
+
execSync32("pbcopy", { input: text, timeout: 3e3 });
|
|
56515
56791
|
return true;
|
|
56516
56792
|
}
|
|
56517
56793
|
if (platform6 === "win32") {
|
|
56518
|
-
|
|
56794
|
+
execSync32("clip", { input: text, timeout: 3e3 });
|
|
56519
56795
|
return true;
|
|
56520
56796
|
}
|
|
56521
56797
|
for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
|
|
56522
56798
|
try {
|
|
56523
|
-
|
|
56799
|
+
execSync32(tool, { input: text, timeout: 3e3 });
|
|
56524
56800
|
return true;
|
|
56525
56801
|
} catch {
|
|
56526
56802
|
continue;
|
|
@@ -56529,10 +56805,10 @@ function copyText(text) {
|
|
|
56529
56805
|
if (!_clipboardAutoInstallAttempted) {
|
|
56530
56806
|
_clipboardAutoInstallAttempted = true;
|
|
56531
56807
|
try {
|
|
56532
|
-
|
|
56808
|
+
execSync32("which apt-get", { timeout: 2e3, stdio: "pipe" });
|
|
56533
56809
|
try {
|
|
56534
|
-
|
|
56535
|
-
|
|
56810
|
+
execSync32("sudo -n apt-get install -y xclip 2>/dev/null", { timeout: 15e3, stdio: "pipe" });
|
|
56811
|
+
execSync32("xclip -selection clipboard", { input: text, timeout: 3e3 });
|
|
56536
56812
|
return true;
|
|
56537
56813
|
} catch {
|
|
56538
56814
|
}
|
|
@@ -56840,7 +57116,7 @@ var init_text_selection = __esm({
|
|
|
56840
57116
|
});
|
|
56841
57117
|
|
|
56842
57118
|
// packages/cli/dist/tui/status-bar.js
|
|
56843
|
-
import { readFileSync as
|
|
57119
|
+
import { readFileSync as readFileSync37 } from "node:fs";
|
|
56844
57120
|
function setTerminalTitle(task, version) {
|
|
56845
57121
|
if (!process.stdout.isTTY)
|
|
56846
57122
|
return;
|
|
@@ -57522,7 +57798,7 @@ var init_status_bar = __esm({
|
|
|
57522
57798
|
if (nexusDir) {
|
|
57523
57799
|
try {
|
|
57524
57800
|
const metricsPath = nexusDir + "/remote-metrics.json";
|
|
57525
|
-
const raw =
|
|
57801
|
+
const raw = readFileSync37(metricsPath, "utf8");
|
|
57526
57802
|
const cached = JSON.parse(raw);
|
|
57527
57803
|
if (cached && cached.ts && Date.now() - cached.ts < 6e4) {
|
|
57528
57804
|
const m = cached.data;
|
|
@@ -59121,12 +59397,12 @@ var init_mouse_filter = __esm({
|
|
|
59121
59397
|
import * as readline2 from "node:readline";
|
|
59122
59398
|
import { Writable } from "node:stream";
|
|
59123
59399
|
import { cwd } from "node:process";
|
|
59124
|
-
import { resolve as resolve31, join as
|
|
59400
|
+
import { resolve as resolve31, join as join66, dirname as dirname20, extname as extname11 } from "node:path";
|
|
59125
59401
|
import { createRequire as createRequire2 } from "node:module";
|
|
59126
59402
|
import { fileURLToPath as fileURLToPath12 } from "node:url";
|
|
59127
|
-
import { readFileSync as
|
|
59128
|
-
import { existsSync as
|
|
59129
|
-
import { execSync as
|
|
59403
|
+
import { readFileSync as readFileSync38, writeFileSync as writeFileSync22, appendFileSync as appendFileSync4, rmSync as rmSync3, readdirSync as readdirSync19, mkdirSync as mkdirSync23 } from "node:fs";
|
|
59404
|
+
import { existsSync as existsSync49 } from "node:fs";
|
|
59405
|
+
import { execSync as execSync33 } from "node:child_process";
|
|
59130
59406
|
import { homedir as homedir16 } from "node:os";
|
|
59131
59407
|
function formatTimeAgo(date) {
|
|
59132
59408
|
const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
|
|
@@ -59146,12 +59422,12 @@ function getVersion3() {
|
|
|
59146
59422
|
const require2 = createRequire2(import.meta.url);
|
|
59147
59423
|
const thisDir = dirname20(fileURLToPath12(import.meta.url));
|
|
59148
59424
|
const candidates = [
|
|
59149
|
-
|
|
59150
|
-
|
|
59151
|
-
|
|
59425
|
+
join66(thisDir, "..", "package.json"),
|
|
59426
|
+
join66(thisDir, "..", "..", "package.json"),
|
|
59427
|
+
join66(thisDir, "..", "..", "..", "package.json")
|
|
59152
59428
|
];
|
|
59153
59429
|
for (const pkgPath of candidates) {
|
|
59154
|
-
if (
|
|
59430
|
+
if (existsSync49(pkgPath)) {
|
|
59155
59431
|
const pkg = require2(pkgPath);
|
|
59156
59432
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
|
|
59157
59433
|
return pkg.version ?? "0.0.0";
|
|
@@ -59284,6 +59560,7 @@ function buildTools(repoRoot, config, contextWindowSize) {
|
|
|
59284
59560
|
new SemanticMapTool(repoRoot),
|
|
59285
59561
|
new RepoMapTool(repoRoot),
|
|
59286
59562
|
new ProcessHealthTool(),
|
|
59563
|
+
new VideoUnderstandTool(repoRoot),
|
|
59287
59564
|
// Full OA sub-process — callbacks wired after runner + statusBar created
|
|
59288
59565
|
(() => {
|
|
59289
59566
|
_fullSubAgentToolRef = new FullSubAgentTool(repoRoot, config.model, config.backendUrl);
|
|
@@ -59385,15 +59662,15 @@ Use task_status("${taskId}") or task_output("${taskId}") to check progress.`
|
|
|
59385
59662
|
function gatherMemorySnippets(root) {
|
|
59386
59663
|
const snippets = [];
|
|
59387
59664
|
const dirs = [
|
|
59388
|
-
|
|
59389
|
-
|
|
59665
|
+
join66(root, ".oa", "memory"),
|
|
59666
|
+
join66(root, ".open-agents", "memory")
|
|
59390
59667
|
];
|
|
59391
59668
|
for (const dir of dirs) {
|
|
59392
|
-
if (!
|
|
59669
|
+
if (!existsSync49(dir))
|
|
59393
59670
|
continue;
|
|
59394
59671
|
try {
|
|
59395
|
-
for (const f of
|
|
59396
|
-
const data = JSON.parse(
|
|
59672
|
+
for (const f of readdirSync19(dir).filter((f2) => f2.endsWith(".json"))) {
|
|
59673
|
+
const data = JSON.parse(readFileSync38(join66(dir, f), "utf-8"));
|
|
59397
59674
|
for (const val of Object.values(data)) {
|
|
59398
59675
|
const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
59399
59676
|
if (v.length > 10)
|
|
@@ -59550,9 +59827,9 @@ ${metabolismMemories}
|
|
|
59550
59827
|
} catch {
|
|
59551
59828
|
}
|
|
59552
59829
|
try {
|
|
59553
|
-
const archeFile =
|
|
59554
|
-
if (
|
|
59555
|
-
const variants = JSON.parse(
|
|
59830
|
+
const archeFile = join66(repoRoot, ".oa", "arche", "variants.json");
|
|
59831
|
+
if (existsSync49(archeFile)) {
|
|
59832
|
+
const variants = JSON.parse(readFileSync38(archeFile, "utf8"));
|
|
59556
59833
|
if (variants.length > 0) {
|
|
59557
59834
|
let filtered = variants;
|
|
59558
59835
|
if (taskType) {
|
|
@@ -59689,9 +59966,9 @@ ${lines.join("\n")}
|
|
|
59689
59966
|
const compactionThreshold = modelTier === "small" ? 12e3 : modelTier === "medium" ? 24e3 : 4e4;
|
|
59690
59967
|
let identityInjection = "";
|
|
59691
59968
|
try {
|
|
59692
|
-
const ikStateFile =
|
|
59693
|
-
if (
|
|
59694
|
-
const selfState = JSON.parse(
|
|
59969
|
+
const ikStateFile = join66(repoRoot, ".oa", "identity", "self-state.json");
|
|
59970
|
+
if (existsSync49(ikStateFile)) {
|
|
59971
|
+
const selfState = JSON.parse(readFileSync38(ikStateFile, "utf8"));
|
|
59695
59972
|
const lines = [
|
|
59696
59973
|
`[Identity State v${selfState.version}]`,
|
|
59697
59974
|
`Self: ${selfState.narrative_summary}`,
|
|
@@ -60330,13 +60607,13 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
60330
60607
|
});
|
|
60331
60608
|
}
|
|
60332
60609
|
try {
|
|
60333
|
-
const ikDir =
|
|
60334
|
-
const ikFile =
|
|
60610
|
+
const ikDir = join66(repoRoot, ".oa", "identity");
|
|
60611
|
+
const ikFile = join66(ikDir, "self-state.json");
|
|
60335
60612
|
let ikState;
|
|
60336
|
-
if (
|
|
60337
|
-
ikState = JSON.parse(
|
|
60613
|
+
if (existsSync49(ikFile)) {
|
|
60614
|
+
ikState = JSON.parse(readFileSync38(ikFile, "utf8"));
|
|
60338
60615
|
} else {
|
|
60339
|
-
|
|
60616
|
+
mkdirSync23(ikDir, { recursive: true });
|
|
60340
60617
|
const machineId = Date.now().toString(36) + Math.random().toString(36).slice(2, 8);
|
|
60341
60618
|
ikState = {
|
|
60342
60619
|
self_id: `oa-${machineId}`,
|
|
@@ -60362,7 +60639,7 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
60362
60639
|
}
|
|
60363
60640
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
60364
60641
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
60365
|
-
|
|
60642
|
+
writeFileSync22(ikFile, JSON.stringify(ikState, null, 2));
|
|
60366
60643
|
} catch (ikErr) {
|
|
60367
60644
|
try {
|
|
60368
60645
|
console.error("[IK-OBSERVE]", ikErr);
|
|
@@ -60377,14 +60654,14 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
60377
60654
|
} else {
|
|
60378
60655
|
renderTaskIncomplete(result.turns, result.toolCalls, result.durationMs, tokens);
|
|
60379
60656
|
try {
|
|
60380
|
-
const ikFile =
|
|
60381
|
-
if (
|
|
60382
|
-
const ikState = JSON.parse(
|
|
60657
|
+
const ikFile = join66(repoRoot, ".oa", "identity", "self-state.json");
|
|
60658
|
+
if (existsSync49(ikFile)) {
|
|
60659
|
+
const ikState = JSON.parse(readFileSync38(ikFile, "utf8"));
|
|
60383
60660
|
ikState.homeostasis.uncertainty = Math.min(1, ikState.homeostasis.uncertainty + 0.1);
|
|
60384
60661
|
ikState.homeostasis.coherence = Math.max(0, ikState.homeostasis.coherence - 0.05);
|
|
60385
60662
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
60386
60663
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
60387
|
-
|
|
60664
|
+
writeFileSync22(ikFile, JSON.stringify(ikState, null, 2));
|
|
60388
60665
|
}
|
|
60389
60666
|
} catch {
|
|
60390
60667
|
}
|
|
@@ -60727,7 +61004,7 @@ Review its full output in the [${id}] tab or via full_sub_agent(action='output',
|
|
|
60727
61004
|
let p2pGateway = null;
|
|
60728
61005
|
let peerMesh = null;
|
|
60729
61006
|
let inferenceRouter = null;
|
|
60730
|
-
const secretVault = new SecretVault(
|
|
61007
|
+
const secretVault = new SecretVault(join66(repoRoot, ".oa", "vault.enc"));
|
|
60731
61008
|
let adminSessionKey = null;
|
|
60732
61009
|
const callSubAgents = /* @__PURE__ */ new Map();
|
|
60733
61010
|
const streamRenderer = new StreamRenderer();
|
|
@@ -60947,13 +61224,13 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
60947
61224
|
const hits = allCompletions.filter((c3) => c3.toLowerCase().startsWith(lower));
|
|
60948
61225
|
return [hits, line];
|
|
60949
61226
|
}
|
|
60950
|
-
const HISTORY_DIR =
|
|
60951
|
-
const HISTORY_FILE =
|
|
61227
|
+
const HISTORY_DIR = join66(homedir16(), ".open-agents");
|
|
61228
|
+
const HISTORY_FILE = join66(HISTORY_DIR, "repl-history");
|
|
60952
61229
|
const MAX_HISTORY_LINES = 500;
|
|
60953
61230
|
let savedHistory = [];
|
|
60954
61231
|
try {
|
|
60955
|
-
if (
|
|
60956
|
-
const raw =
|
|
61232
|
+
if (existsSync49(HISTORY_FILE)) {
|
|
61233
|
+
const raw = readFileSync38(HISTORY_FILE, "utf8").trim();
|
|
60957
61234
|
if (raw)
|
|
60958
61235
|
savedHistory = raw.split("\n").reverse();
|
|
60959
61236
|
}
|
|
@@ -61033,12 +61310,12 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
61033
61310
|
if (!line.trim())
|
|
61034
61311
|
return;
|
|
61035
61312
|
try {
|
|
61036
|
-
|
|
61313
|
+
mkdirSync23(HISTORY_DIR, { recursive: true });
|
|
61037
61314
|
appendFileSync4(HISTORY_FILE, line + "\n", "utf8");
|
|
61038
61315
|
if (Math.random() < 0.02) {
|
|
61039
|
-
const all =
|
|
61316
|
+
const all = readFileSync38(HISTORY_FILE, "utf8").trim().split("\n");
|
|
61040
61317
|
if (all.length > MAX_HISTORY_LINES) {
|
|
61041
|
-
|
|
61318
|
+
writeFileSync22(HISTORY_FILE, all.slice(-MAX_HISTORY_LINES).join("\n") + "\n", "utf8");
|
|
61042
61319
|
}
|
|
61043
61320
|
}
|
|
61044
61321
|
} catch {
|
|
@@ -61214,7 +61491,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
61214
61491
|
} catch {
|
|
61215
61492
|
}
|
|
61216
61493
|
try {
|
|
61217
|
-
const oaDir =
|
|
61494
|
+
const oaDir = join66(repoRoot, ".oa");
|
|
61218
61495
|
const reconnected = await ExposeGateway.checkAndReconnect(oaDir, {
|
|
61219
61496
|
onInfo: (msg) => writeContent(() => renderInfo(msg)),
|
|
61220
61497
|
onError: (msg) => writeContent(() => renderWarning(msg))
|
|
@@ -61237,7 +61514,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
61237
61514
|
} catch {
|
|
61238
61515
|
}
|
|
61239
61516
|
try {
|
|
61240
|
-
const oaDir =
|
|
61517
|
+
const oaDir = join66(repoRoot, ".oa");
|
|
61241
61518
|
const reconnectedP2P = await ExposeP2PGateway.checkAndReconnect(oaDir, new NexusTool(repoRoot), {
|
|
61242
61519
|
onInfo: (msg) => writeContent(() => renderInfo(msg)),
|
|
61243
61520
|
onError: (msg) => writeContent(() => renderWarning(msg))
|
|
@@ -62121,7 +62398,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
62121
62398
|
kind,
|
|
62122
62399
|
targetUrl,
|
|
62123
62400
|
authKey,
|
|
62124
|
-
stateDir:
|
|
62401
|
+
stateDir: join66(repoRoot, ".oa"),
|
|
62125
62402
|
passthrough: passthrough ?? false,
|
|
62126
62403
|
loadbalance: loadbalance ?? false,
|
|
62127
62404
|
endpointAuth: passthrough ? currentConfig.apiKey : void 0,
|
|
@@ -62169,7 +62446,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
62169
62446
|
await tunnelGateway.stop();
|
|
62170
62447
|
tunnelGateway = null;
|
|
62171
62448
|
}
|
|
62172
|
-
const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir:
|
|
62449
|
+
const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join66(repoRoot, ".oa") });
|
|
62173
62450
|
newTunnel.on("stats", (stats) => {
|
|
62174
62451
|
statusBar.setExposeStatus({
|
|
62175
62452
|
status: stats.status,
|
|
@@ -62438,15 +62715,15 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
62438
62715
|
writeContent(() => renderInfo(`Killed ${bgKilled} background task(s).`));
|
|
62439
62716
|
}
|
|
62440
62717
|
try {
|
|
62441
|
-
const nexusDir =
|
|
62442
|
-
const pidFile =
|
|
62443
|
-
if (
|
|
62444
|
-
const pid = parseInt(
|
|
62718
|
+
const nexusDir = join66(repoRoot, OA_DIR, "nexus");
|
|
62719
|
+
const pidFile = join66(nexusDir, "daemon.pid");
|
|
62720
|
+
if (existsSync49(pidFile)) {
|
|
62721
|
+
const pid = parseInt(readFileSync38(pidFile, "utf8").trim(), 10);
|
|
62445
62722
|
if (pid > 0) {
|
|
62446
62723
|
try {
|
|
62447
62724
|
if (process.platform === "win32") {
|
|
62448
62725
|
try {
|
|
62449
|
-
|
|
62726
|
+
execSync33(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
|
|
62450
62727
|
} catch {
|
|
62451
62728
|
}
|
|
62452
62729
|
} else {
|
|
@@ -62463,17 +62740,17 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
62463
62740
|
} catch {
|
|
62464
62741
|
}
|
|
62465
62742
|
try {
|
|
62466
|
-
const voiceDir2 =
|
|
62743
|
+
const voiceDir2 = join66(homedir16(), ".open-agents", "voice");
|
|
62467
62744
|
const voicePidFiles = ["luxtts-daemon.pid", "piper-daemon.pid"];
|
|
62468
62745
|
for (const pf of voicePidFiles) {
|
|
62469
|
-
const pidPath =
|
|
62470
|
-
if (
|
|
62746
|
+
const pidPath = join66(voiceDir2, pf);
|
|
62747
|
+
if (existsSync49(pidPath)) {
|
|
62471
62748
|
try {
|
|
62472
|
-
const pid = parseInt(
|
|
62749
|
+
const pid = parseInt(readFileSync38(pidPath, "utf8").trim(), 10);
|
|
62473
62750
|
if (pid > 0) {
|
|
62474
62751
|
if (process.platform === "win32") {
|
|
62475
62752
|
try {
|
|
62476
|
-
|
|
62753
|
+
execSync33(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
|
|
62477
62754
|
} catch {
|
|
62478
62755
|
}
|
|
62479
62756
|
} else {
|
|
@@ -62490,11 +62767,11 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
62490
62767
|
} catch {
|
|
62491
62768
|
}
|
|
62492
62769
|
try {
|
|
62493
|
-
|
|
62770
|
+
execSync33(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.5", { timeout: 3e3, stdio: "ignore" });
|
|
62494
62771
|
} catch {
|
|
62495
62772
|
}
|
|
62496
|
-
const oaPath =
|
|
62497
|
-
if (
|
|
62773
|
+
const oaPath = join66(repoRoot, OA_DIR);
|
|
62774
|
+
if (existsSync49(oaPath)) {
|
|
62498
62775
|
let deleted = false;
|
|
62499
62776
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
62500
62777
|
try {
|
|
@@ -62504,14 +62781,14 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
62504
62781
|
} catch (err) {
|
|
62505
62782
|
if (attempt < 2) {
|
|
62506
62783
|
try {
|
|
62507
|
-
|
|
62784
|
+
execSync33(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.3", { timeout: 3e3, stdio: "ignore" });
|
|
62508
62785
|
} catch {
|
|
62509
62786
|
}
|
|
62510
62787
|
} else {
|
|
62511
62788
|
writeContent(() => renderWarning(`Could not fully remove ${OA_DIR}/: ${err instanceof Error ? err.message : String(err)}`));
|
|
62512
62789
|
if (process.platform === "win32") {
|
|
62513
62790
|
try {
|
|
62514
|
-
|
|
62791
|
+
execSync33(`rd /s /q "${oaPath}"`, { timeout: 1e4, stdio: "ignore" });
|
|
62515
62792
|
deleted = true;
|
|
62516
62793
|
} catch {
|
|
62517
62794
|
}
|
|
@@ -62866,8 +63143,8 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
62866
63143
|
}
|
|
62867
63144
|
}
|
|
62868
63145
|
const cleanPath = input.replace(/^['"]|['"]$/g, "").trim();
|
|
62869
|
-
const isImage = isImagePath(cleanPath) &&
|
|
62870
|
-
const isMedia = !isImage && isTranscribablePath(cleanPath) &&
|
|
63146
|
+
const isImage = isImagePath(cleanPath) && existsSync49(resolve31(repoRoot, cleanPath));
|
|
63147
|
+
const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync49(resolve31(repoRoot, cleanPath));
|
|
62871
63148
|
if (activeTask) {
|
|
62872
63149
|
if (activeTask.runner.isPaused) {
|
|
62873
63150
|
activeTask.runner.resume();
|
|
@@ -62876,7 +63153,7 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
62876
63153
|
if (isImage) {
|
|
62877
63154
|
try {
|
|
62878
63155
|
const imgPath = resolve31(repoRoot, cleanPath);
|
|
62879
|
-
const imgBuffer =
|
|
63156
|
+
const imgBuffer = readFileSync38(imgPath);
|
|
62880
63157
|
const base64 = imgBuffer.toString("base64");
|
|
62881
63158
|
const ext = extname11(cleanPath).toLowerCase();
|
|
62882
63159
|
const mime = ext === ".png" ? "image/png" : ext === ".gif" ? "image/gif" : ext === ".webp" ? "image/webp" : "image/jpeg";
|
|
@@ -63113,13 +63390,13 @@ NEW TASK: ${fullInput}`;
|
|
|
63113
63390
|
writeContent(() => renderError(errMsg));
|
|
63114
63391
|
if (failureStore) {
|
|
63115
63392
|
try {
|
|
63116
|
-
const { createHash:
|
|
63393
|
+
const { createHash: createHash6 } = await import("node:crypto");
|
|
63117
63394
|
failureStore.insert({
|
|
63118
63395
|
taskId: "",
|
|
63119
63396
|
sessionId: `${Date.now()}`,
|
|
63120
63397
|
repoRoot,
|
|
63121
63398
|
failureType: "runtime-error",
|
|
63122
|
-
fingerprint:
|
|
63399
|
+
fingerprint: createHash6("sha256").update(errMsg.slice(0, 200)).digest("hex").slice(0, 16),
|
|
63123
63400
|
filePath: null,
|
|
63124
63401
|
errorMessage: errMsg.slice(0, 500),
|
|
63125
63402
|
context: null,
|
|
@@ -63375,13 +63652,13 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
63375
63652
|
const handle = startTask(task, config, repoRoot);
|
|
63376
63653
|
await handle.promise;
|
|
63377
63654
|
try {
|
|
63378
|
-
const ikDir =
|
|
63379
|
-
const ikFile =
|
|
63655
|
+
const ikDir = join66(repoRoot, ".oa", "identity");
|
|
63656
|
+
const ikFile = join66(ikDir, "self-state.json");
|
|
63380
63657
|
let ikState;
|
|
63381
|
-
if (
|
|
63382
|
-
ikState = JSON.parse(
|
|
63658
|
+
if (existsSync49(ikFile)) {
|
|
63659
|
+
ikState = JSON.parse(readFileSync38(ikFile, "utf8"));
|
|
63383
63660
|
} else {
|
|
63384
|
-
|
|
63661
|
+
mkdirSync23(ikDir, { recursive: true });
|
|
63385
63662
|
ikState = {
|
|
63386
63663
|
self_id: `oa-${Date.now().toString(36)}`,
|
|
63387
63664
|
version: 1,
|
|
@@ -63403,7 +63680,7 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
63403
63680
|
ikState.homeostasis.coherence = Math.min(1, ikState.homeostasis.coherence + 0.05);
|
|
63404
63681
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
63405
63682
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
63406
|
-
|
|
63683
|
+
writeFileSync22(ikFile, JSON.stringify(ikState, null, 2));
|
|
63407
63684
|
} catch (ikErr) {
|
|
63408
63685
|
}
|
|
63409
63686
|
try {
|
|
@@ -63412,12 +63689,12 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
63412
63689
|
ec.archiveVariantSync(`Task: ${task.slice(0, 200)}`, "success \u2014 completed", ["general"]);
|
|
63413
63690
|
} catch {
|
|
63414
63691
|
try {
|
|
63415
|
-
const archeDir =
|
|
63416
|
-
const archeFile =
|
|
63692
|
+
const archeDir = join66(repoRoot, ".oa", "arche");
|
|
63693
|
+
const archeFile = join66(archeDir, "variants.json");
|
|
63417
63694
|
let variants = [];
|
|
63418
63695
|
try {
|
|
63419
|
-
if (
|
|
63420
|
-
variants = JSON.parse(
|
|
63696
|
+
if (existsSync49(archeFile))
|
|
63697
|
+
variants = JSON.parse(readFileSync38(archeFile, "utf8"));
|
|
63421
63698
|
} catch {
|
|
63422
63699
|
}
|
|
63423
63700
|
variants.push({
|
|
@@ -63432,15 +63709,15 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
63432
63709
|
});
|
|
63433
63710
|
if (variants.length > 50)
|
|
63434
63711
|
variants = variants.slice(-50);
|
|
63435
|
-
|
|
63436
|
-
|
|
63712
|
+
mkdirSync23(archeDir, { recursive: true });
|
|
63713
|
+
writeFileSync22(archeFile, JSON.stringify(variants, null, 2));
|
|
63437
63714
|
} catch {
|
|
63438
63715
|
}
|
|
63439
63716
|
}
|
|
63440
63717
|
try {
|
|
63441
|
-
const metaFile =
|
|
63442
|
-
if (
|
|
63443
|
-
const store = JSON.parse(
|
|
63718
|
+
const metaFile = join66(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
63719
|
+
if (existsSync49(metaFile)) {
|
|
63720
|
+
const store = JSON.parse(readFileSync38(metaFile, "utf8"));
|
|
63444
63721
|
const surfaced = store.filter((m) => m.type !== "quarantine" && m.scores?.confidence > 0.15).sort((a, b) => b.scores.utility * b.scores.confidence - a.scores.utility * a.scores.confidence).slice(0, 5);
|
|
63445
63722
|
let updated = false;
|
|
63446
63723
|
for (const item of surfaced) {
|
|
@@ -63451,7 +63728,7 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
63451
63728
|
updated = true;
|
|
63452
63729
|
}
|
|
63453
63730
|
if (updated) {
|
|
63454
|
-
|
|
63731
|
+
writeFileSync22(metaFile, JSON.stringify(store, null, 2));
|
|
63455
63732
|
}
|
|
63456
63733
|
}
|
|
63457
63734
|
} catch {
|
|
@@ -63504,9 +63781,9 @@ Rules:
|
|
|
63504
63781
|
try {
|
|
63505
63782
|
const { initDb: initDb2 } = __require("@open-agents/memory");
|
|
63506
63783
|
const { ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
|
|
63507
|
-
const dbDir =
|
|
63508
|
-
|
|
63509
|
-
const db = initDb2(
|
|
63784
|
+
const dbDir = join66(repoRoot, ".oa", "memory");
|
|
63785
|
+
mkdirSync23(dbDir, { recursive: true });
|
|
63786
|
+
const db = initDb2(join66(dbDir, "structured.db"));
|
|
63510
63787
|
const memStore = new ProceduralMemoryStore2(db);
|
|
63511
63788
|
memStore.createWithEmbedding({
|
|
63512
63789
|
content: content.slice(0, 600),
|
|
@@ -63521,12 +63798,12 @@ Rules:
|
|
|
63521
63798
|
db.close();
|
|
63522
63799
|
} catch {
|
|
63523
63800
|
}
|
|
63524
|
-
const metaDir =
|
|
63525
|
-
const storeFile =
|
|
63801
|
+
const metaDir = join66(repoRoot, ".oa", "memory", "metabolism");
|
|
63802
|
+
const storeFile = join66(metaDir, "store.json");
|
|
63526
63803
|
let store = [];
|
|
63527
63804
|
try {
|
|
63528
|
-
if (
|
|
63529
|
-
store = JSON.parse(
|
|
63805
|
+
if (existsSync49(storeFile))
|
|
63806
|
+
store = JSON.parse(readFileSync38(storeFile, "utf8"));
|
|
63530
63807
|
} catch {
|
|
63531
63808
|
}
|
|
63532
63809
|
store.push({
|
|
@@ -63542,26 +63819,26 @@ Rules:
|
|
|
63542
63819
|
});
|
|
63543
63820
|
if (store.length > 100)
|
|
63544
63821
|
store = store.slice(-100);
|
|
63545
|
-
|
|
63546
|
-
|
|
63822
|
+
mkdirSync23(metaDir, { recursive: true });
|
|
63823
|
+
writeFileSync22(storeFile, JSON.stringify(store, null, 2));
|
|
63547
63824
|
}
|
|
63548
63825
|
}
|
|
63549
63826
|
} catch {
|
|
63550
63827
|
}
|
|
63551
63828
|
try {
|
|
63552
|
-
const cohereSettingsFile =
|
|
63829
|
+
const cohereSettingsFile = join66(repoRoot, ".oa", "settings.json");
|
|
63553
63830
|
let cohereActive = false;
|
|
63554
63831
|
try {
|
|
63555
|
-
if (
|
|
63556
|
-
const settings = JSON.parse(
|
|
63832
|
+
if (existsSync49(cohereSettingsFile)) {
|
|
63833
|
+
const settings = JSON.parse(readFileSync38(cohereSettingsFile, "utf8"));
|
|
63557
63834
|
cohereActive = settings.cohere === true;
|
|
63558
63835
|
}
|
|
63559
63836
|
} catch {
|
|
63560
63837
|
}
|
|
63561
63838
|
if (cohereActive) {
|
|
63562
|
-
const metaFile =
|
|
63563
|
-
if (
|
|
63564
|
-
const store = JSON.parse(
|
|
63839
|
+
const metaFile = join66(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
63840
|
+
if (existsSync49(metaFile)) {
|
|
63841
|
+
const store = JSON.parse(readFileSync38(metaFile, "utf8"));
|
|
63565
63842
|
const latest = store.filter((m) => m.sourceTrace === "trajectory-extraction" || m.sourceTrace === "llm-trajectory-extraction").slice(-1)[0];
|
|
63566
63843
|
if (latest && latest.scores?.confidence >= 0.6) {
|
|
63567
63844
|
try {
|
|
@@ -63586,18 +63863,18 @@ Rules:
|
|
|
63586
63863
|
}
|
|
63587
63864
|
} catch (err) {
|
|
63588
63865
|
try {
|
|
63589
|
-
const ikFile =
|
|
63590
|
-
if (
|
|
63591
|
-
const ikState = JSON.parse(
|
|
63866
|
+
const ikFile = join66(repoRoot, ".oa", "identity", "self-state.json");
|
|
63867
|
+
if (existsSync49(ikFile)) {
|
|
63868
|
+
const ikState = JSON.parse(readFileSync38(ikFile, "utf8"));
|
|
63592
63869
|
ikState.homeostasis.uncertainty = Math.min(1, ikState.homeostasis.uncertainty + 0.1);
|
|
63593
63870
|
ikState.homeostasis.coherence = Math.max(0, ikState.homeostasis.coherence - 0.05);
|
|
63594
63871
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
63595
63872
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
63596
|
-
|
|
63873
|
+
writeFileSync22(ikFile, JSON.stringify(ikState, null, 2));
|
|
63597
63874
|
}
|
|
63598
|
-
const metaFile =
|
|
63599
|
-
if (
|
|
63600
|
-
const store = JSON.parse(
|
|
63875
|
+
const metaFile = join66(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
63876
|
+
if (existsSync49(metaFile)) {
|
|
63877
|
+
const store = JSON.parse(readFileSync38(metaFile, "utf8"));
|
|
63601
63878
|
const surfaced = store.filter((m) => m.type !== "quarantine" && m.scores?.confidence > 0.15).sort((a, b) => b.scores.utility * b.scores.confidence - a.scores.utility * a.scores.confidence).slice(0, 5);
|
|
63602
63879
|
for (const item of surfaced) {
|
|
63603
63880
|
item.accessCount = (item.accessCount || 0) + 1;
|
|
@@ -63605,15 +63882,15 @@ Rules:
|
|
|
63605
63882
|
item.scores.utility = Math.max(0, (item.scores.utility || 0.5) - 0.05);
|
|
63606
63883
|
item.scores.confidence = Math.max(0, (item.scores.confidence || 0.5) - 0.02);
|
|
63607
63884
|
}
|
|
63608
|
-
|
|
63885
|
+
writeFileSync22(metaFile, JSON.stringify(store, null, 2));
|
|
63609
63886
|
}
|
|
63610
63887
|
try {
|
|
63611
|
-
const archeDir =
|
|
63612
|
-
const archeFile =
|
|
63888
|
+
const archeDir = join66(repoRoot, ".oa", "arche");
|
|
63889
|
+
const archeFile = join66(archeDir, "variants.json");
|
|
63613
63890
|
let variants = [];
|
|
63614
63891
|
try {
|
|
63615
|
-
if (
|
|
63616
|
-
variants = JSON.parse(
|
|
63892
|
+
if (existsSync49(archeFile))
|
|
63893
|
+
variants = JSON.parse(readFileSync38(archeFile, "utf8"));
|
|
63617
63894
|
} catch {
|
|
63618
63895
|
}
|
|
63619
63896
|
variants.push({
|
|
@@ -63628,8 +63905,8 @@ Rules:
|
|
|
63628
63905
|
});
|
|
63629
63906
|
if (variants.length > 50)
|
|
63630
63907
|
variants = variants.slice(-50);
|
|
63631
|
-
|
|
63632
|
-
|
|
63908
|
+
mkdirSync23(archeDir, { recursive: true });
|
|
63909
|
+
writeFileSync22(archeFile, JSON.stringify(variants, null, 2));
|
|
63633
63910
|
} catch {
|
|
63634
63911
|
}
|
|
63635
63912
|
} catch {
|
|
@@ -63717,8 +63994,8 @@ var init_run = __esm({
|
|
|
63717
63994
|
import { glob } from "glob";
|
|
63718
63995
|
import ignore from "ignore";
|
|
63719
63996
|
import { readFile as readFile23, stat as stat4 } from "node:fs/promises";
|
|
63720
|
-
import { createHash as
|
|
63721
|
-
import { join as
|
|
63997
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
63998
|
+
import { join as join67, relative as relative4, extname as extname12, basename as basename17 } from "node:path";
|
|
63722
63999
|
var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
|
|
63723
64000
|
var init_codebase_indexer = __esm({
|
|
63724
64001
|
"packages/indexer/dist/codebase-indexer.js"() {
|
|
@@ -63762,7 +64039,7 @@ var init_codebase_indexer = __esm({
|
|
|
63762
64039
|
const ig = ignore.default();
|
|
63763
64040
|
if (this.config.respectGitignore) {
|
|
63764
64041
|
try {
|
|
63765
|
-
const gitignoreContent = await readFile23(
|
|
64042
|
+
const gitignoreContent = await readFile23(join67(this.config.rootDir, ".gitignore"), "utf-8");
|
|
63766
64043
|
ig.add(gitignoreContent);
|
|
63767
64044
|
} catch {
|
|
63768
64045
|
}
|
|
@@ -63777,13 +64054,13 @@ var init_codebase_indexer = __esm({
|
|
|
63777
64054
|
for (const relativePath of files) {
|
|
63778
64055
|
if (ig.ignores(relativePath))
|
|
63779
64056
|
continue;
|
|
63780
|
-
const fullPath =
|
|
64057
|
+
const fullPath = join67(this.config.rootDir, relativePath);
|
|
63781
64058
|
try {
|
|
63782
64059
|
const fileStat = await stat4(fullPath);
|
|
63783
64060
|
if (fileStat.size > this.config.maxFileSize)
|
|
63784
64061
|
continue;
|
|
63785
64062
|
const content = await readFile23(fullPath);
|
|
63786
|
-
const hash =
|
|
64063
|
+
const hash = createHash5("sha256").update(content).digest("hex");
|
|
63787
64064
|
const ext = extname12(relativePath);
|
|
63788
64065
|
indexed.push({
|
|
63789
64066
|
path: fullPath,
|
|
@@ -63800,7 +64077,7 @@ var init_codebase_indexer = __esm({
|
|
|
63800
64077
|
}
|
|
63801
64078
|
buildTree(files) {
|
|
63802
64079
|
const root = {
|
|
63803
|
-
name:
|
|
64080
|
+
name: basename17(this.config.rootDir),
|
|
63804
64081
|
path: this.config.rootDir,
|
|
63805
64082
|
type: "directory",
|
|
63806
64083
|
children: []
|
|
@@ -63823,7 +64100,7 @@ var init_codebase_indexer = __esm({
|
|
|
63823
64100
|
if (!child) {
|
|
63824
64101
|
child = {
|
|
63825
64102
|
name: part,
|
|
63826
|
-
path:
|
|
64103
|
+
path: join67(current.path, part),
|
|
63827
64104
|
type: "directory",
|
|
63828
64105
|
children: []
|
|
63829
64106
|
};
|
|
@@ -63906,13 +64183,13 @@ __export(index_repo_exports, {
|
|
|
63906
64183
|
indexRepoCommand: () => indexRepoCommand
|
|
63907
64184
|
});
|
|
63908
64185
|
import { resolve as resolve32 } from "node:path";
|
|
63909
|
-
import { existsSync as
|
|
64186
|
+
import { existsSync as existsSync50, statSync as statSync16 } from "node:fs";
|
|
63910
64187
|
import { cwd as cwd2 } from "node:process";
|
|
63911
64188
|
async function indexRepoCommand(opts, _config) {
|
|
63912
64189
|
const repoRoot = resolve32(opts.repoPath ?? cwd2());
|
|
63913
64190
|
printHeader("Index Repository");
|
|
63914
64191
|
printInfo(`Indexing: ${repoRoot}`);
|
|
63915
|
-
if (!
|
|
64192
|
+
if (!existsSync50(repoRoot)) {
|
|
63916
64193
|
printError(`Path does not exist: ${repoRoot}`);
|
|
63917
64194
|
process.exit(1);
|
|
63918
64195
|
}
|
|
@@ -64164,7 +64441,7 @@ var config_exports = {};
|
|
|
64164
64441
|
__export(config_exports, {
|
|
64165
64442
|
configCommand: () => configCommand
|
|
64166
64443
|
});
|
|
64167
|
-
import { join as
|
|
64444
|
+
import { join as join68, resolve as resolve33 } from "node:path";
|
|
64168
64445
|
import { homedir as homedir17 } from "node:os";
|
|
64169
64446
|
import { cwd as cwd3 } from "node:process";
|
|
64170
64447
|
function redactIfSensitive(key, value) {
|
|
@@ -64247,7 +64524,7 @@ function handleShow(opts, config) {
|
|
|
64247
64524
|
}
|
|
64248
64525
|
}
|
|
64249
64526
|
printSection("Config File");
|
|
64250
|
-
printInfo(`~/.open-agents/config.json (${
|
|
64527
|
+
printInfo(`~/.open-agents/config.json (${join68(homedir17(), ".open-agents", "config.json")})`);
|
|
64251
64528
|
printSection("Priority Chain");
|
|
64252
64529
|
printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
|
|
64253
64530
|
printInfo(" 2. Project .oa/settings.json (--local)");
|
|
@@ -64286,7 +64563,7 @@ function handleSet(opts, _config) {
|
|
|
64286
64563
|
const coerced = coerceForSettings(key, value);
|
|
64287
64564
|
saveProjectSettings(repoRoot, { [key]: coerced });
|
|
64288
64565
|
printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value)}`);
|
|
64289
|
-
printInfo(`Saved to ${
|
|
64566
|
+
printInfo(`Saved to ${join68(repoRoot, ".oa", "settings.json")}`);
|
|
64290
64567
|
printInfo("This override applies only when running in this workspace.");
|
|
64291
64568
|
} catch (err) {
|
|
64292
64569
|
printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -64544,8 +64821,8 @@ __export(eval_exports, {
|
|
|
64544
64821
|
evalCommand: () => evalCommand
|
|
64545
64822
|
});
|
|
64546
64823
|
import { tmpdir as tmpdir10 } from "node:os";
|
|
64547
|
-
import { mkdirSync as
|
|
64548
|
-
import { join as
|
|
64824
|
+
import { mkdirSync as mkdirSync24, writeFileSync as writeFileSync23 } from "node:fs";
|
|
64825
|
+
import { join as join69 } from "node:path";
|
|
64549
64826
|
async function evalCommand(opts, config) {
|
|
64550
64827
|
const suiteName = opts.suite ?? "basic";
|
|
64551
64828
|
const suite = SUITES[suiteName];
|
|
@@ -64670,9 +64947,9 @@ async function evalCommand(opts, config) {
|
|
|
64670
64947
|
process.exit(failed > 0 ? 1 : 0);
|
|
64671
64948
|
}
|
|
64672
64949
|
function createTempEvalRepo() {
|
|
64673
|
-
const dir =
|
|
64674
|
-
|
|
64675
|
-
|
|
64950
|
+
const dir = join69(tmpdir10(), `open-agents-eval-${Date.now()}`);
|
|
64951
|
+
mkdirSync24(dir, { recursive: true });
|
|
64952
|
+
writeFileSync23(join69(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
|
|
64676
64953
|
return dir;
|
|
64677
64954
|
}
|
|
64678
64955
|
var BASIC_SUITE, FULL_SUITE, SUITES;
|
|
@@ -64732,7 +65009,7 @@ init_updater();
|
|
|
64732
65009
|
import { parseArgs as nodeParseArgs2 } from "node:util";
|
|
64733
65010
|
import { createRequire as createRequire3 } from "node:module";
|
|
64734
65011
|
import { fileURLToPath as fileURLToPath13 } from "node:url";
|
|
64735
|
-
import { dirname as dirname21, join as
|
|
65012
|
+
import { dirname as dirname21, join as join70 } from "node:path";
|
|
64736
65013
|
|
|
64737
65014
|
// packages/cli/dist/cli.js
|
|
64738
65015
|
import { createInterface } from "node:readline";
|
|
@@ -64839,7 +65116,7 @@ init_output();
|
|
|
64839
65116
|
function getVersion4() {
|
|
64840
65117
|
try {
|
|
64841
65118
|
const require2 = createRequire3(import.meta.url);
|
|
64842
|
-
const pkgPath =
|
|
65119
|
+
const pkgPath = join70(dirname21(fileURLToPath13(import.meta.url)), "..", "package.json");
|
|
64843
65120
|
const pkg = require2(pkgPath);
|
|
64844
65121
|
return pkg.version;
|
|
64845
65122
|
} catch {
|