open-agents-ai 0.187.536 → 0.187.538
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 +879 -475
- package/dist/scripts/tor/UPSTREAM-README.md +148 -0
- package/dist/scripts/tor/destroy_tor.sh +29 -0
- package/dist/scripts/tor/tor_setup.sh +163 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -247827,9 +247827,9 @@ print("${sentinel}")
|
|
|
247827
247827
|
if (!this.proc || this.proc.killed) {
|
|
247828
247828
|
return { success: false, path: "" };
|
|
247829
247829
|
}
|
|
247830
|
-
const { mkdirSync:
|
|
247830
|
+
const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = await import("node:fs");
|
|
247831
247831
|
const sessionDir = join28(this.cwd, ".oa", "rlm");
|
|
247832
|
-
|
|
247832
|
+
mkdirSync68(sessionDir, { recursive: true });
|
|
247833
247833
|
const sessionPath2 = join28(sessionDir, "session.json");
|
|
247834
247834
|
try {
|
|
247835
247835
|
const inspectCode = `
|
|
@@ -247853,7 +247853,7 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
|
|
|
247853
247853
|
trajectoryCount: this.trajectory.length,
|
|
247854
247854
|
subCallCount: this.subCallCount
|
|
247855
247855
|
};
|
|
247856
|
-
|
|
247856
|
+
writeFileSync60(sessionPath2, JSON.stringify(sessionData, null, 2), "utf8");
|
|
247857
247857
|
return { success: true, path: sessionPath2 };
|
|
247858
247858
|
}
|
|
247859
247859
|
} catch {
|
|
@@ -247865,9 +247865,9 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
|
|
|
247865
247865
|
* what was previously computed. */
|
|
247866
247866
|
async loadSessionInfo() {
|
|
247867
247867
|
try {
|
|
247868
|
-
const { readFileSync: readFileSync89, existsSync:
|
|
247868
|
+
const { readFileSync: readFileSync89, existsSync: existsSync111 } = await import("node:fs");
|
|
247869
247869
|
const sessionPath2 = join28(this.cwd, ".oa", "rlm", "session.json");
|
|
247870
|
-
if (!
|
|
247870
|
+
if (!existsSync111(sessionPath2))
|
|
247871
247871
|
return null;
|
|
247872
247872
|
return JSON.parse(readFileSync89(sessionPath2, "utf8"));
|
|
247873
247873
|
} catch {
|
|
@@ -248433,10 +248433,10 @@ ${issues.map((i2) => ` - ${i2}`).join("\n")}` : " No issues found."),
|
|
|
248433
248433
|
* Optionally filter by task type for phase-aware context (FSM paper insight).
|
|
248434
248434
|
*/
|
|
248435
248435
|
getTopMemoriesSync(k = 5, taskType) {
|
|
248436
|
-
const { readFileSync: readFileSync89, existsSync:
|
|
248436
|
+
const { readFileSync: readFileSync89, existsSync: existsSync111 } = __require("node:fs");
|
|
248437
248437
|
const metaDir = join29(this.cwd, ".oa", "memory", "metabolism");
|
|
248438
248438
|
const storeFile = join29(metaDir, "store.json");
|
|
248439
|
-
if (!
|
|
248439
|
+
if (!existsSync111(storeFile))
|
|
248440
248440
|
return "";
|
|
248441
248441
|
let store2 = [];
|
|
248442
248442
|
try {
|
|
@@ -248462,10 +248462,10 @@ ${issues.map((i2) => ` - ${i2}`).join("\n")}` : " No issues found."),
|
|
|
248462
248462
|
/** Update memory scores based on task outcome. Called after task completion.
|
|
248463
248463
|
* Memories used in successful tasks get boosted. Memories present during failures get decayed. */
|
|
248464
248464
|
updateFromOutcomeSync(surfacedMemoryText, succeeded) {
|
|
248465
|
-
const { readFileSync: readFileSync89, writeFileSync:
|
|
248465
|
+
const { readFileSync: readFileSync89, writeFileSync: writeFileSync60, existsSync: existsSync111, mkdirSync: mkdirSync68 } = __require("node:fs");
|
|
248466
248466
|
const metaDir = join29(this.cwd, ".oa", "memory", "metabolism");
|
|
248467
248467
|
const storeFile = join29(metaDir, "store.json");
|
|
248468
|
-
if (!
|
|
248468
|
+
if (!existsSync111(storeFile))
|
|
248469
248469
|
return;
|
|
248470
248470
|
let store2 = [];
|
|
248471
248471
|
try {
|
|
@@ -248493,8 +248493,8 @@ ${issues.map((i2) => ` - ${i2}`).join("\n")}` : " No issues found."),
|
|
|
248493
248493
|
updated = true;
|
|
248494
248494
|
}
|
|
248495
248495
|
if (updated) {
|
|
248496
|
-
|
|
248497
|
-
|
|
248496
|
+
mkdirSync68(metaDir, { recursive: true });
|
|
248497
|
+
writeFileSync60(storeFile, JSON.stringify(store2, null, 2));
|
|
248498
248498
|
}
|
|
248499
248499
|
}
|
|
248500
248500
|
// ── Storage ──────────────────────────────────────────────────────────
|
|
@@ -248916,9 +248916,9 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
248916
248916
|
// Per EvoSkill (arXiv:2603.02766): retrieve relevant strategies from archive.
|
|
248917
248917
|
/** Retrieve top-K strategies for context injection. Returns "" if none. */
|
|
248918
248918
|
getRelevantStrategiesSync(k = 3, taskType) {
|
|
248919
|
-
const { readFileSync: readFileSync89, existsSync:
|
|
248919
|
+
const { readFileSync: readFileSync89, existsSync: existsSync111 } = __require("node:fs");
|
|
248920
248920
|
const archiveFile = join31(this.cwd, ".oa", "arche", "variants.json");
|
|
248921
|
-
if (!
|
|
248921
|
+
if (!existsSync111(archiveFile))
|
|
248922
248922
|
return "";
|
|
248923
248923
|
let variants = [];
|
|
248924
248924
|
try {
|
|
@@ -248940,12 +248940,12 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
248940
248940
|
}
|
|
248941
248941
|
/** Archive a strategy variant synchronously (for task completion path) */
|
|
248942
248942
|
archiveVariantSync(strategy, outcome, tags = []) {
|
|
248943
|
-
const { readFileSync: readFileSync89, writeFileSync:
|
|
248943
|
+
const { readFileSync: readFileSync89, writeFileSync: writeFileSync60, existsSync: existsSync111, mkdirSync: mkdirSync68 } = __require("node:fs");
|
|
248944
248944
|
const dir = join31(this.cwd, ".oa", "arche");
|
|
248945
248945
|
const archiveFile = join31(dir, "variants.json");
|
|
248946
248946
|
let variants = [];
|
|
248947
248947
|
try {
|
|
248948
|
-
if (
|
|
248948
|
+
if (existsSync111(archiveFile))
|
|
248949
248949
|
variants = JSON.parse(readFileSync89(archiveFile, "utf8"));
|
|
248950
248950
|
} catch {
|
|
248951
248951
|
}
|
|
@@ -248961,8 +248961,8 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
248961
248961
|
});
|
|
248962
248962
|
if (variants.length > 50)
|
|
248963
248963
|
variants = variants.slice(-50);
|
|
248964
|
-
|
|
248965
|
-
|
|
248964
|
+
mkdirSync68(dir, { recursive: true });
|
|
248965
|
+
writeFileSync60(archiveFile, JSON.stringify(variants, null, 2));
|
|
248966
248966
|
}
|
|
248967
248967
|
async saveArchive(variants) {
|
|
248968
248968
|
const dir = join31(this.cwd, ".oa", "arche");
|
|
@@ -257226,7 +257226,7 @@ var require_util9 = __commonJS({
|
|
|
257226
257226
|
return path8;
|
|
257227
257227
|
}
|
|
257228
257228
|
exports.normalize = normalize2;
|
|
257229
|
-
function
|
|
257229
|
+
function join129(aRoot, aPath) {
|
|
257230
257230
|
if (aRoot === "") {
|
|
257231
257231
|
aRoot = ".";
|
|
257232
257232
|
}
|
|
@@ -257258,7 +257258,7 @@ var require_util9 = __commonJS({
|
|
|
257258
257258
|
}
|
|
257259
257259
|
return joined;
|
|
257260
257260
|
}
|
|
257261
|
-
exports.join =
|
|
257261
|
+
exports.join = join129;
|
|
257262
257262
|
exports.isAbsolute = function(aPath) {
|
|
257263
257263
|
return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
|
|
257264
257264
|
};
|
|
@@ -257431,7 +257431,7 @@ var require_util9 = __commonJS({
|
|
|
257431
257431
|
parsed.path = parsed.path.substring(0, index + 1);
|
|
257432
257432
|
}
|
|
257433
257433
|
}
|
|
257434
|
-
sourceURL =
|
|
257434
|
+
sourceURL = join129(urlGenerate(parsed), sourceURL);
|
|
257435
257435
|
}
|
|
257436
257436
|
return normalize2(sourceURL);
|
|
257437
257437
|
}
|
|
@@ -472334,10 +472334,10 @@ var require_commonjs3 = __commonJS({
|
|
|
472334
472334
|
let ai = 0;
|
|
472335
472335
|
let bi = 0;
|
|
472336
472336
|
let result = [];
|
|
472337
|
-
let
|
|
472337
|
+
let which2 = "";
|
|
472338
472338
|
while (ai < a2.length && bi < b.length) {
|
|
472339
472339
|
if (a2[ai] === b[bi]) {
|
|
472340
|
-
result.push(
|
|
472340
|
+
result.push(which2 === "b" ? b[bi] : a2[ai]);
|
|
472341
472341
|
ai++;
|
|
472342
472342
|
bi++;
|
|
472343
472343
|
} else if (emptyGSMatch && a2[ai] === "**" && b[bi] === a2[ai + 1]) {
|
|
@@ -472347,16 +472347,16 @@ var require_commonjs3 = __commonJS({
|
|
|
472347
472347
|
result.push(b[bi]);
|
|
472348
472348
|
bi++;
|
|
472349
472349
|
} else if (a2[ai] === "*" && b[bi] && (this.options.dot || !b[bi].startsWith(".")) && b[bi] !== "**") {
|
|
472350
|
-
if (
|
|
472350
|
+
if (which2 === "b")
|
|
472351
472351
|
return false;
|
|
472352
|
-
|
|
472352
|
+
which2 = "a";
|
|
472353
472353
|
result.push(a2[ai]);
|
|
472354
472354
|
ai++;
|
|
472355
472355
|
bi++;
|
|
472356
472356
|
} else if (b[bi] === "*" && a2[ai] && (this.options.dot || !a2[ai].startsWith(".")) && a2[ai] !== "**") {
|
|
472357
|
-
if (
|
|
472357
|
+
if (which2 === "a")
|
|
472358
472358
|
return false;
|
|
472359
|
-
|
|
472359
|
+
which2 = "b";
|
|
472360
472360
|
result.push(b[bi]);
|
|
472361
472361
|
ai++;
|
|
472362
472362
|
bi++;
|
|
@@ -472851,7 +472851,7 @@ var require_path_browserify = __commonJS({
|
|
|
472851
472851
|
assertPath(path8);
|
|
472852
472852
|
return path8.length > 0 && path8.charCodeAt(0) === 47;
|
|
472853
472853
|
},
|
|
472854
|
-
join: function
|
|
472854
|
+
join: function join129() {
|
|
472855
472855
|
if (arguments.length === 0)
|
|
472856
472856
|
return ".";
|
|
472857
472857
|
var joined;
|
|
@@ -507839,7 +507839,7 @@ var init_agent_tool = __esm({
|
|
|
507839
507839
|
})();
|
|
507840
507840
|
if (isolation === "worktree") {
|
|
507841
507841
|
this.callbacks.onViewRegister?.(agentId, label);
|
|
507842
|
-
const
|
|
507842
|
+
const spawn28 = this.callbacks.spawnSubprocess({
|
|
507843
507843
|
id: agentId,
|
|
507844
507844
|
task: composedPrompt,
|
|
507845
507845
|
model,
|
|
@@ -507849,7 +507849,7 @@ var init_agent_tool = __esm({
|
|
|
507849
507849
|
success: true,
|
|
507850
507850
|
output: `Agent spawned (subprocess, worktree): ${agentId}
|
|
507851
507851
|
Type: ${subagentType}
|
|
507852
|
-
PID: ${
|
|
507852
|
+
PID: ${spawn28.pid}
|
|
507853
507853
|
Task: ${prompt.slice(0, 100)}
|
|
507854
507854
|
Use task_status("${agentId}") to check progress.`,
|
|
507855
507855
|
durationMs: performance.now() - start2
|
|
@@ -522965,8 +522965,8 @@ var init_reflectionBuffer = __esm({
|
|
|
522965
522965
|
this.persistPath = persistPath ?? null;
|
|
522966
522966
|
if (this.persistPath) {
|
|
522967
522967
|
try {
|
|
522968
|
-
const { readFileSync: readFileSync89, existsSync:
|
|
522969
|
-
if (
|
|
522968
|
+
const { readFileSync: readFileSync89, existsSync: existsSync111 } = __require("node:fs");
|
|
522969
|
+
if (existsSync111(this.persistPath)) {
|
|
522970
522970
|
this.state = JSON.parse(readFileSync89(this.persistPath, "utf-8"));
|
|
522971
522971
|
return;
|
|
522972
522972
|
}
|
|
@@ -523200,12 +523200,12 @@ var init_reflectionBuffer = __esm({
|
|
|
523200
523200
|
if (!this.persistPath)
|
|
523201
523201
|
return;
|
|
523202
523202
|
try {
|
|
523203
|
-
const { writeFileSync:
|
|
523204
|
-
const { join:
|
|
523205
|
-
const dir =
|
|
523206
|
-
if (!
|
|
523207
|
-
|
|
523208
|
-
|
|
523203
|
+
const { writeFileSync: writeFileSync60, mkdirSync: mkdirSync68, existsSync: existsSync111 } = __require("node:fs");
|
|
523204
|
+
const { join: join129 } = __require("node:path");
|
|
523205
|
+
const dir = join129(this.persistPath, "..");
|
|
523206
|
+
if (!existsSync111(dir))
|
|
523207
|
+
mkdirSync68(dir, { recursive: true });
|
|
523208
|
+
writeFileSync60(this.persistPath, JSON.stringify(this.state, null, 2));
|
|
523209
523209
|
} catch {
|
|
523210
523210
|
}
|
|
523211
523211
|
}
|
|
@@ -533745,10 +533745,10 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
|
|
|
533745
533745
|
if (nodes > 0) {
|
|
533746
533746
|
this.emit({ type: "status", content: `Knowledge graph: ${nodes} nodes, ${edges} active edges`, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
533747
533747
|
try {
|
|
533748
|
-
const { mkdirSync:
|
|
533749
|
-
const { join:
|
|
533750
|
-
const contextDir =
|
|
533751
|
-
|
|
533748
|
+
const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = __require("node:fs");
|
|
533749
|
+
const { join: join129 } = __require("node:path");
|
|
533750
|
+
const contextDir = join129(this._workingDirectory || process.cwd(), ".oa", "context");
|
|
533751
|
+
mkdirSync68(contextDir, { recursive: true });
|
|
533752
533752
|
const topEntities = this._temporalGraph.nodesByType("entity", 3);
|
|
533753
533753
|
const topFiles = this._temporalGraph.nodesByType("file", 3);
|
|
533754
533754
|
const topConcepts = this._temporalGraph.nodesByType("concept", 3);
|
|
@@ -533788,9 +533788,9 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
|
|
|
533788
533788
|
section("Top Files", topFiles);
|
|
533789
533789
|
section("Top Concepts", topConcepts);
|
|
533790
533790
|
lines.push("(Use file_read on this file for quick recall. See provenance JSON for full edge detail.)");
|
|
533791
|
-
const outPath =
|
|
533792
|
-
|
|
533793
|
-
|
|
533791
|
+
const outPath = join129(contextDir, `kg-summary-${this._sessionId}.md`);
|
|
533792
|
+
writeFileSync60(outPath, lines.join("\n"), "utf-8");
|
|
533793
|
+
writeFileSync60(join129(contextDir, `kg-summary-latest.md`), lines.join("\n"), "utf-8");
|
|
533794
533794
|
} catch {
|
|
533795
533795
|
}
|
|
533796
533796
|
}
|
|
@@ -533958,11 +533958,11 @@ ${errOutput}`;
|
|
|
533958
533958
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
533959
533959
|
});
|
|
533960
533960
|
try {
|
|
533961
|
-
const { mkdirSync:
|
|
533962
|
-
const { join:
|
|
533963
|
-
const resultsDir =
|
|
533964
|
-
|
|
533965
|
-
|
|
533961
|
+
const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = __require("node:fs");
|
|
533962
|
+
const { join: join129 } = __require("node:path");
|
|
533963
|
+
const resultsDir = join129(process.cwd(), ".oa", "tool-results");
|
|
533964
|
+
mkdirSync68(resultsDir, { recursive: true });
|
|
533965
|
+
writeFileSync60(join129(resultsDir, `${handleId}.txt`), `# Tool: ${toolName}
|
|
533966
533966
|
# Turn: ${turn}
|
|
533967
533967
|
# Timestamp: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
533968
533968
|
# Size: ${result.output.length} chars, ${lineCount} lines
|
|
@@ -534178,10 +534178,10 @@ Actions: (1) list_directory on the parent directory to see what's there, (2) Che
|
|
|
534178
534178
|
if (!this._workingDirectory)
|
|
534179
534179
|
return;
|
|
534180
534180
|
try {
|
|
534181
|
-
const { mkdirSync:
|
|
534182
|
-
const { join:
|
|
534183
|
-
const sessionDir =
|
|
534184
|
-
|
|
534181
|
+
const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = __require("node:fs");
|
|
534182
|
+
const { join: join129 } = __require("node:path");
|
|
534183
|
+
const sessionDir = join129(this._workingDirectory, ".oa", "session", this._sessionId);
|
|
534184
|
+
mkdirSync68(sessionDir, { recursive: true });
|
|
534185
534185
|
const checkpoint = {
|
|
534186
534186
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
534187
534187
|
sessionId: this._sessionId,
|
|
@@ -534193,7 +534193,7 @@ Actions: (1) list_directory on the parent directory to see what's there, (2) Che
|
|
|
534193
534193
|
memexEntryCount: this._memexArchive.size,
|
|
534194
534194
|
fileRegistrySize: this._fileRegistry.size
|
|
534195
534195
|
};
|
|
534196
|
-
|
|
534196
|
+
writeFileSync60(join129(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
|
|
534197
534197
|
} catch {
|
|
534198
534198
|
}
|
|
534199
534199
|
}
|
|
@@ -536020,12 +536020,12 @@ ${result}`
|
|
|
536020
536020
|
let resizedBase64 = null;
|
|
536021
536021
|
try {
|
|
536022
536022
|
const { execSync: execSync59 } = await import("node:child_process");
|
|
536023
|
-
const { writeFileSync:
|
|
536024
|
-
const { join:
|
|
536025
|
-
const { tmpdir:
|
|
536026
|
-
const tmpIn =
|
|
536027
|
-
const tmpOut =
|
|
536028
|
-
|
|
536023
|
+
const { writeFileSync: writeFileSync60, readFileSync: readFileSync89, unlinkSync: unlinkSync25 } = await import("node:fs");
|
|
536024
|
+
const { join: join129 } = await import("node:path");
|
|
536025
|
+
const { tmpdir: tmpdir23 } = await import("node:os");
|
|
536026
|
+
const tmpIn = join129(tmpdir23(), `oa_img_in_${Date.now()}.png`);
|
|
536027
|
+
const tmpOut = join129(tmpdir23(), `oa_img_out_${Date.now()}.jpg`);
|
|
536028
|
+
writeFileSync60(tmpIn, buffer2);
|
|
536029
536029
|
const pyBin = process.platform === "win32" ? "python" : "python3";
|
|
536030
536030
|
const escapedIn = tmpIn.replace(/\\/g, "\\\\");
|
|
536031
536031
|
const escapedOut = tmpOut.replace(/\\/g, "\\\\");
|
|
@@ -544570,23 +544570,23 @@ async function fetchOpenAIModels(baseUrl, apiKey) {
|
|
|
544570
544570
|
async function fetchPeerModels(peerId, authKey) {
|
|
544571
544571
|
try {
|
|
544572
544572
|
const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist5(), dist_exports));
|
|
544573
|
-
const { existsSync:
|
|
544574
|
-
const { join:
|
|
544573
|
+
const { existsSync: existsSync111, readFileSync: readFileSync89 } = await import("node:fs");
|
|
544574
|
+
const { join: join129 } = await import("node:path");
|
|
544575
544575
|
const cwd4 = process.cwd();
|
|
544576
544576
|
const nexusTool = new NexusTool2(cwd4);
|
|
544577
544577
|
const nexusDir = nexusTool.getNexusDir();
|
|
544578
544578
|
let isLocalPeer = false;
|
|
544579
544579
|
try {
|
|
544580
|
-
const statusPath =
|
|
544581
|
-
if (
|
|
544580
|
+
const statusPath = join129(nexusDir, "status.json");
|
|
544581
|
+
if (existsSync111(statusPath)) {
|
|
544582
544582
|
const status = JSON.parse(readFileSync89(statusPath, "utf8"));
|
|
544583
544583
|
if (status.peerId === peerId) isLocalPeer = true;
|
|
544584
544584
|
}
|
|
544585
544585
|
} catch {
|
|
544586
544586
|
}
|
|
544587
544587
|
if (isLocalPeer) {
|
|
544588
|
-
const pricingPath =
|
|
544589
|
-
if (
|
|
544588
|
+
const pricingPath = join129(nexusDir, "pricing.json");
|
|
544589
|
+
if (existsSync111(pricingPath)) {
|
|
544590
544590
|
try {
|
|
544591
544591
|
const pricing = JSON.parse(readFileSync89(pricingPath, "utf8"));
|
|
544592
544592
|
const localModels = (pricing.models || []).map((m2) => ({
|
|
@@ -544601,8 +544601,8 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
544601
544601
|
}
|
|
544602
544602
|
}
|
|
544603
544603
|
}
|
|
544604
|
-
const cachePath =
|
|
544605
|
-
if (
|
|
544604
|
+
const cachePath = join129(nexusDir, "peer-models-cache.json");
|
|
544605
|
+
if (existsSync111(cachePath)) {
|
|
544606
544606
|
try {
|
|
544607
544607
|
const cache8 = JSON.parse(readFileSync89(cachePath, "utf8"));
|
|
544608
544608
|
if (cache8.peerId === peerId && cache8.models?.length > 0) {
|
|
@@ -544716,8 +544716,8 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
544716
544716
|
} catch {
|
|
544717
544717
|
}
|
|
544718
544718
|
if (isLocalPeer) {
|
|
544719
|
-
const pricingPath =
|
|
544720
|
-
if (
|
|
544719
|
+
const pricingPath = join129(nexusDir, "pricing.json");
|
|
544720
|
+
if (existsSync111(pricingPath)) {
|
|
544721
544721
|
try {
|
|
544722
544722
|
const pricing = JSON.parse(readFileSync89(pricingPath, "utf8"));
|
|
544723
544723
|
return (pricing.models || []).map((m2) => ({
|
|
@@ -562498,13 +562498,13 @@ async function runSudoScript(ctx3, script) {
|
|
|
562498
562498
|
} catch {
|
|
562499
562499
|
}
|
|
562500
562500
|
try {
|
|
562501
|
-
const { spawn:
|
|
562501
|
+
const { spawn: spawn28 } = await import("node:child_process");
|
|
562502
562502
|
const full = `set -e; ${script}`;
|
|
562503
562503
|
await new Promise((resolve43) => {
|
|
562504
562504
|
const usePkexec = process.platform === "linux";
|
|
562505
562505
|
const cmd = usePkexec ? "pkexec" : "sudo";
|
|
562506
562506
|
const args = usePkexec ? ["bash", "-lc", full] : ["-n", "bash", "-lc", full];
|
|
562507
|
-
const child =
|
|
562507
|
+
const child = spawn28(cmd, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
562508
562508
|
let stdout = "";
|
|
562509
562509
|
let stderr = "";
|
|
562510
562510
|
child.stdout?.on("data", (data) => {
|
|
@@ -562538,9 +562538,9 @@ async function ensureVoiceDeps(ctx3) {
|
|
|
562538
562538
|
}
|
|
562539
562539
|
if (typeof mod2.getVenvPython === "function") {
|
|
562540
562540
|
const { dirname: dirname39 } = await import("node:path");
|
|
562541
|
-
const { existsSync:
|
|
562541
|
+
const { existsSync: existsSync111 } = await import("node:fs");
|
|
562542
562542
|
const venvPy = mod2.getVenvPython();
|
|
562543
|
-
if (
|
|
562543
|
+
if (existsSync111(venvPy)) {
|
|
562544
562544
|
process.env.TRANSCRIBE_PYTHON = venvPy;
|
|
562545
562545
|
const venvBin = dirname39(venvPy);
|
|
562546
562546
|
const sep2 = process.platform === "win32" ? ";" : ":";
|
|
@@ -562859,10 +562859,10 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
562859
562859
|
if (!key) {
|
|
562860
562860
|
try {
|
|
562861
562861
|
const { homedir: homedir46 } = await import("node:os");
|
|
562862
|
-
const { readFileSync: readFileSync89, existsSync:
|
|
562863
|
-
const { join:
|
|
562864
|
-
const p2 =
|
|
562865
|
-
if (
|
|
562862
|
+
const { readFileSync: readFileSync89, existsSync: existsSync111 } = await import("node:fs");
|
|
562863
|
+
const { join: join129 } = await import("node:path");
|
|
562864
|
+
const p2 = join129(homedir46(), ".open-agents", "api.key");
|
|
562865
|
+
if (existsSync111(p2)) key = readFileSync89(p2, "utf8").trim();
|
|
562866
562866
|
} catch {
|
|
562867
562867
|
}
|
|
562868
562868
|
}
|
|
@@ -562901,13 +562901,13 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
562901
562901
|
try {
|
|
562902
562902
|
const { randomBytes: randomBytes25 } = await import("node:crypto");
|
|
562903
562903
|
const { homedir: homedir46 } = await import("node:os");
|
|
562904
|
-
const { mkdirSync:
|
|
562905
|
-
const { join:
|
|
562904
|
+
const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = await import("node:fs");
|
|
562905
|
+
const { join: join129 } = await import("node:path");
|
|
562906
562906
|
const newKey = randomBytes25(16).toString("hex");
|
|
562907
562907
|
process.env["OA_API_KEY"] = newKey;
|
|
562908
|
-
const dir =
|
|
562909
|
-
|
|
562910
|
-
|
|
562908
|
+
const dir = join129(homedir46(), ".open-agents");
|
|
562909
|
+
mkdirSync68(dir, { recursive: true });
|
|
562910
|
+
writeFileSync60(join129(dir, "api.key"), newKey + "\n", "utf8");
|
|
562911
562911
|
renderInfo2(`New API key: ${c3.bold(c3.yellow(newKey))}`);
|
|
562912
562912
|
renderInfo2("Restart the daemon to apply if needed. Use /access any to restart quickly.");
|
|
562913
562913
|
} catch (e2) {
|
|
@@ -563095,11 +563095,11 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
563095
563095
|
renderInfo2("Use the Web UI ‘key’ button to paste this token, or set Authorization: Bearer <key> in your client.");
|
|
563096
563096
|
try {
|
|
563097
563097
|
const { homedir: homedir47 } = await import("node:os");
|
|
563098
|
-
const { mkdirSync:
|
|
563099
|
-
const { join:
|
|
563100
|
-
const dir =
|
|
563101
|
-
|
|
563102
|
-
|
|
563098
|
+
const { mkdirSync: mkdirSync69, writeFileSync: writeFileSync61 } = await import("node:fs");
|
|
563099
|
+
const { join: join130 } = await import("node:path");
|
|
563100
|
+
const dir = join130(homedir47(), ".open-agents");
|
|
563101
|
+
mkdirSync69(dir, { recursive: true });
|
|
563102
|
+
writeFileSync61(join130(dir, "api.key"), apiKey + "\n", "utf8");
|
|
563103
563103
|
} catch {
|
|
563104
563104
|
}
|
|
563105
563105
|
}
|
|
@@ -563111,11 +563111,11 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
563111
563111
|
const port2 = parseInt(process.env["OA_PORT"] || "11435", 10);
|
|
563112
563112
|
try {
|
|
563113
563113
|
const { homedir: homedir47 } = await import("node:os");
|
|
563114
|
-
const { mkdirSync:
|
|
563115
|
-
const { join:
|
|
563116
|
-
const dir =
|
|
563117
|
-
|
|
563118
|
-
|
|
563114
|
+
const { mkdirSync: mkdirSync69, writeFileSync: writeFileSync61 } = await import("node:fs");
|
|
563115
|
+
const { join: join130 } = await import("node:path");
|
|
563116
|
+
const dir = join130(homedir47(), ".open-agents");
|
|
563117
|
+
mkdirSync69(dir, { recursive: true });
|
|
563118
|
+
writeFileSync61(join130(dir, "access"), `${val2}
|
|
563119
563119
|
`, "utf8");
|
|
563120
563120
|
} catch {
|
|
563121
563121
|
}
|
|
@@ -563197,11 +563197,11 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
563197
563197
|
renderInfo2("Use the Web UI ‘key’ button to paste this token, or set Authorization: Bearer <key> in your client.");
|
|
563198
563198
|
try {
|
|
563199
563199
|
const { homedir: homedir47 } = await import("node:os");
|
|
563200
|
-
const { mkdirSync:
|
|
563201
|
-
const { join:
|
|
563202
|
-
const dir =
|
|
563203
|
-
|
|
563204
|
-
|
|
563200
|
+
const { mkdirSync: mkdirSync69, writeFileSync: writeFileSync61 } = await import("node:fs");
|
|
563201
|
+
const { join: join130 } = await import("node:path");
|
|
563202
|
+
const dir = join130(homedir47(), ".open-agents");
|
|
563203
|
+
mkdirSync69(dir, { recursive: true });
|
|
563204
|
+
writeFileSync61(join130(dir, "api.key"), apiKey + "\n", "utf8");
|
|
563205
563205
|
} catch {
|
|
563206
563206
|
}
|
|
563207
563207
|
}
|
|
@@ -563212,12 +563212,12 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
563212
563212
|
}
|
|
563213
563213
|
const port = parseInt(process.env["OA_PORT"] || "11435", 10);
|
|
563214
563214
|
const { homedir: homedir46 } = await import("node:os");
|
|
563215
|
-
const { mkdirSync:
|
|
563216
|
-
const { join:
|
|
563215
|
+
const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = await import("node:fs");
|
|
563216
|
+
const { join: join129 } = await import("node:path");
|
|
563217
563217
|
try {
|
|
563218
|
-
const dir =
|
|
563219
|
-
|
|
563220
|
-
|
|
563218
|
+
const dir = join129(homedir46(), ".open-agents");
|
|
563219
|
+
mkdirSync68(dir, { recursive: true });
|
|
563220
|
+
writeFileSync60(join129(dir, "access"), `${val}
|
|
563221
563221
|
`, "utf8");
|
|
563222
563222
|
} catch (e2) {
|
|
563223
563223
|
renderWarning2(`Could not persist ~/.open-agents/access: ${e2 instanceof Error ? e2.message : String(e2)}`);
|
|
@@ -564269,8 +564269,8 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
564269
564269
|
writeFileSync41(jwtFile, JSON.stringify(jwtPayload, null, 2));
|
|
564270
564270
|
renderInfo2(`Launching fortemi-react from ${fDir}...`);
|
|
564271
564271
|
try {
|
|
564272
|
-
const { spawn:
|
|
564273
|
-
const child =
|
|
564272
|
+
const { spawn: spawn28 } = __require("node:child_process");
|
|
564273
|
+
const child = spawn28("npx", ["vite", "dev", "--host", "0.0.0.0", "--port", "3000"], {
|
|
564274
564274
|
cwd: join99(fDir, "apps", "standalone"),
|
|
564275
564275
|
stdio: "ignore",
|
|
564276
564276
|
detached: true,
|
|
@@ -564995,9 +564995,9 @@ systemctl --user daemon-reload || true
|
|
|
564995
564995
|
systemctl --user enable --now open-agents-daemon.service || true
|
|
564996
564996
|
sleep 1
|
|
564997
564997
|
`;
|
|
564998
|
-
const { spawn:
|
|
564998
|
+
const { spawn: spawn28 } = await import("node:child_process");
|
|
564999
564999
|
await new Promise((resolve43) => {
|
|
565000
|
-
const child =
|
|
565000
|
+
const child = spawn28("bash", ["-lc", takeover], { stdio: "inherit" });
|
|
565001
565001
|
onChildExit(child, () => resolve43());
|
|
565002
565002
|
});
|
|
565003
565003
|
renderInfo2("Daemon takeover complete.");
|
|
@@ -567434,11 +567434,11 @@ async function handleVoiceMenu(ctx3, save2, hasLocal) {
|
|
|
567434
567434
|
continue;
|
|
567435
567435
|
}
|
|
567436
567436
|
const { basename: basename21, join: pathJoin } = await import("node:path");
|
|
567437
|
-
const { copyFileSync: copyFileSync3, mkdirSync:
|
|
567437
|
+
const { copyFileSync: copyFileSync3, mkdirSync: mkdirSync68, existsSync: exists2 } = await import("node:fs");
|
|
567438
567438
|
const { homedir: homedir46 } = await import("node:os");
|
|
567439
567439
|
const modelName = basename21(onnxDrop.path, ".onnx").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
567440
567440
|
const destDir = pathJoin(homedir46(), ".open-agents", "voice", "models", modelName);
|
|
567441
|
-
if (!exists2(destDir))
|
|
567441
|
+
if (!exists2(destDir)) mkdirSync68(destDir, { recursive: true });
|
|
567442
567442
|
copyFileSync3(onnxDrop.path, pathJoin(destDir, "model.onnx"));
|
|
567443
567443
|
copyFileSync3(jsonDrop.path, pathJoin(destDir, "config.json"));
|
|
567444
567444
|
const { registerCustomOnnxModel: registerCustomOnnxModel2 } = await Promise.resolve().then(() => (init_voice(), voice_exports));
|
|
@@ -568188,10 +568188,10 @@ async function handleSponsoredEndpoint(ctx3, local) {
|
|
|
568188
568188
|
sponsors.push(...verified);
|
|
568189
568189
|
if (verified.length > 0) {
|
|
568190
568190
|
try {
|
|
568191
|
-
const { mkdirSync:
|
|
568192
|
-
|
|
568191
|
+
const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = __require("node:fs");
|
|
568192
|
+
mkdirSync68(sponsorDir2, { recursive: true });
|
|
568193
568193
|
const cached = verified.map((s2) => ({ ...s2, lastVerified: Date.now() }));
|
|
568194
|
-
|
|
568194
|
+
writeFileSync60(knownFile, JSON.stringify(cached, null, 2));
|
|
568195
568195
|
} catch {
|
|
568196
568196
|
}
|
|
568197
568197
|
}
|
|
@@ -568364,11 +568364,11 @@ async function handlePeerEndpoint(peerId, authKey, ctx3, local) {
|
|
|
568364
568364
|
const models = await fetchModels(peerUrl, authKey);
|
|
568365
568365
|
if (models.length > 0) {
|
|
568366
568366
|
try {
|
|
568367
|
-
const { writeFileSync:
|
|
568368
|
-
const { join:
|
|
568369
|
-
const cachePath =
|
|
568370
|
-
|
|
568371
|
-
|
|
568367
|
+
const { writeFileSync: writeFileSync60, mkdirSync: mkdirSync68 } = await import("node:fs");
|
|
568368
|
+
const { join: join129, dirname: dirname39 } = await import("node:path");
|
|
568369
|
+
const cachePath = join129(ctx3.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
|
|
568370
|
+
mkdirSync68(dirname39(cachePath), { recursive: true });
|
|
568371
|
+
writeFileSync60(cachePath, JSON.stringify({
|
|
568372
568372
|
peerId,
|
|
568373
568373
|
cachedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
568374
568374
|
models: models.map((m2) => ({ name: m2.name, size: m2.size, parameterSize: m2.parameterSize }))
|
|
@@ -568520,8 +568520,8 @@ ${escapedContent}EOF'`, { timeoutMs: 3e4 });
|
|
|
568520
568520
|
}
|
|
568521
568521
|
await new Promise((r2) => setTimeout(r2, 1e3));
|
|
568522
568522
|
process.env.OLLAMA_NUM_PARALLEL = String(n2);
|
|
568523
|
-
const { spawn:
|
|
568524
|
-
const child =
|
|
568523
|
+
const { spawn: spawn28 } = await import("node:child_process");
|
|
568524
|
+
const child = spawn28("ollama", ["serve"], {
|
|
568525
568525
|
stdio: "ignore",
|
|
568526
568526
|
detached: true,
|
|
568527
568527
|
env: { ...process.env, OLLAMA_NUM_PARALLEL: String(n2) }
|
|
@@ -568937,17 +568937,17 @@ async function handleUpdate(subcommand, ctx3) {
|
|
|
568937
568937
|
try {
|
|
568938
568938
|
const { createRequire: createRequire8 } = await import("node:module");
|
|
568939
568939
|
const { fileURLToPath: fileURLToPath20 } = await import("node:url");
|
|
568940
|
-
const { dirname: dirname39, join:
|
|
568941
|
-
const { existsSync:
|
|
568940
|
+
const { dirname: dirname39, join: join129 } = await import("node:path");
|
|
568941
|
+
const { existsSync: existsSync111 } = await import("node:fs");
|
|
568942
568942
|
const req2 = createRequire8(import.meta.url);
|
|
568943
568943
|
const thisDir = dirname39(fileURLToPath20(import.meta.url));
|
|
568944
568944
|
const candidates = [
|
|
568945
|
-
|
|
568946
|
-
|
|
568947
|
-
|
|
568945
|
+
join129(thisDir, "..", "package.json"),
|
|
568946
|
+
join129(thisDir, "..", "..", "package.json"),
|
|
568947
|
+
join129(thisDir, "..", "..", "..", "package.json")
|
|
568948
568948
|
];
|
|
568949
568949
|
for (const pkgPath of candidates) {
|
|
568950
|
-
if (
|
|
568950
|
+
if (existsSync111(pkgPath)) {
|
|
568951
568951
|
const pkg = req2(pkgPath);
|
|
568952
568952
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
|
|
568953
568953
|
currentVersion = pkg.version ?? "0.0.0";
|
|
@@ -570095,13 +570095,13 @@ var init_commands = __esm({
|
|
|
570095
570095
|
try {
|
|
570096
570096
|
const { randomBytes: randomBytes25 } = await import("node:crypto");
|
|
570097
570097
|
const { homedir: homedir46 } = await import("node:os");
|
|
570098
|
-
const { mkdirSync:
|
|
570099
|
-
const { join:
|
|
570098
|
+
const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = await import("node:fs");
|
|
570099
|
+
const { join: join129 } = await import("node:path");
|
|
570100
570100
|
const apiKey = randomBytes25(16).toString("hex");
|
|
570101
570101
|
process.env["OA_API_KEY"] = apiKey;
|
|
570102
|
-
const dir =
|
|
570103
|
-
|
|
570104
|
-
|
|
570102
|
+
const dir = join129(homedir46(), ".open-agents");
|
|
570103
|
+
mkdirSync68(dir, { recursive: true });
|
|
570104
|
+
writeFileSync60(join129(dir, "api.key"), apiKey + "\n", "utf8");
|
|
570105
570105
|
renderInfo2(`Generated API key: ${c3.bold(c3.yellow(apiKey))}`);
|
|
570106
570106
|
renderInfo2("Use Authorization: Bearer <key> or click 'key' in the Web UI header to paste it.");
|
|
570107
570107
|
} catch (e2) {
|
|
@@ -570116,11 +570116,11 @@ var init_commands = __esm({
|
|
|
570116
570116
|
const port = parseInt(process.env["OA_PORT"] || "11435", 10);
|
|
570117
570117
|
try {
|
|
570118
570118
|
const { homedir: homedir46 } = await import("node:os");
|
|
570119
|
-
const { mkdirSync:
|
|
570120
|
-
const { join:
|
|
570121
|
-
const dir =
|
|
570122
|
-
|
|
570123
|
-
|
|
570119
|
+
const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = await import("node:fs");
|
|
570120
|
+
const { join: join129 } = await import("node:path");
|
|
570121
|
+
const dir = join129(homedir46(), ".open-agents");
|
|
570122
|
+
mkdirSync68(dir, { recursive: true });
|
|
570123
|
+
writeFileSync60(join129(dir, "access"), `${val}
|
|
570124
570124
|
`, "utf8");
|
|
570125
570125
|
} catch {
|
|
570126
570126
|
}
|
|
@@ -581932,11 +581932,11 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
|
|
|
581932
581932
|
let mimeType = "audio/wav";
|
|
581933
581933
|
try {
|
|
581934
581934
|
const { execSync: execSyncLocal } = await import("node:child_process");
|
|
581935
|
-
const { tmpdir:
|
|
581935
|
+
const { tmpdir: tmpdir23 } = await import("node:os");
|
|
581936
581936
|
const { join: joinPath } = await import("node:path");
|
|
581937
581937
|
const { writeFileSync: writeFs, readFileSync: readFs, unlinkSync: unlinkFs } = await import("node:fs");
|
|
581938
|
-
const tmpWav = joinPath(
|
|
581939
|
-
const tmpOgg = joinPath(
|
|
581938
|
+
const tmpWav = joinPath(tmpdir23(), `oa-tg-voice-${Date.now()}.wav`);
|
|
581939
|
+
const tmpOgg = joinPath(tmpdir23(), `oa-tg-voice-${Date.now()}.ogg`);
|
|
581940
581940
|
writeFs(tmpWav, wavBuffer);
|
|
581941
581941
|
execSyncLocal(`ffmpeg -i "${tmpWav}" -c:a libopus -b:a 48k -ar 48000 -ac 1 "${tmpOgg}" -y 2>/dev/null`, {
|
|
581942
581942
|
timeout: 15e3,
|
|
@@ -585811,9 +585811,131 @@ var init_tor_fallback = __esm({
|
|
|
585811
585811
|
}
|
|
585812
585812
|
});
|
|
585813
585813
|
|
|
585814
|
+
// packages/cli/src/api/graphical-sudo.ts
|
|
585815
|
+
var graphical_sudo_exports = {};
|
|
585816
|
+
__export(graphical_sudo_exports, {
|
|
585817
|
+
detectSudoHelper: () => detectSudoHelper,
|
|
585818
|
+
runGraphicalSudo: () => runGraphicalSudo
|
|
585819
|
+
});
|
|
585820
|
+
import { spawn as spawn24 } from "node:child_process";
|
|
585821
|
+
import { existsSync as existsSync102, mkdirSync as mkdirSync60, writeFileSync as writeFileSync52, chmodSync as chmodSync2 } from "node:fs";
|
|
585822
|
+
import { join as join118 } from "node:path";
|
|
585823
|
+
import { tmpdir as tmpdir21 } from "node:os";
|
|
585824
|
+
function detectSudoHelper() {
|
|
585825
|
+
if (process.platform === "win32") return null;
|
|
585826
|
+
if (process.platform === "darwin") return "osascript";
|
|
585827
|
+
if (which("pkexec")) return "pkexec";
|
|
585828
|
+
if (which("ssh-askpass")) return "ssh-askpass";
|
|
585829
|
+
if (which("zenity")) return "zenity";
|
|
585830
|
+
if (which("kdialog")) return "kdialog";
|
|
585831
|
+
if (which("sudo")) return "sudo-tty";
|
|
585832
|
+
return null;
|
|
585833
|
+
}
|
|
585834
|
+
function which(cmd) {
|
|
585835
|
+
const path8 = process.env["PATH"] || "/usr/bin:/bin:/usr/local/bin";
|
|
585836
|
+
for (const dir of path8.split(":")) {
|
|
585837
|
+
if (!dir) continue;
|
|
585838
|
+
const full = join118(dir, cmd);
|
|
585839
|
+
if (existsSync102(full)) return full;
|
|
585840
|
+
}
|
|
585841
|
+
return null;
|
|
585842
|
+
}
|
|
585843
|
+
function ensureAskpassShim(helper, description) {
|
|
585844
|
+
const shimDir = join118(tmpdir21(), "oa-askpass");
|
|
585845
|
+
mkdirSync60(shimDir, { recursive: true });
|
|
585846
|
+
const shim = join118(shimDir, `${helper}.sh`);
|
|
585847
|
+
let body;
|
|
585848
|
+
if (helper === "zenity") {
|
|
585849
|
+
body = `#!/bin/sh
|
|
585850
|
+
exec zenity --password --title="OA needs sudo" --text="${description.replace(/"/g, '\\"')}" 2>/dev/null
|
|
585851
|
+
`;
|
|
585852
|
+
} else {
|
|
585853
|
+
body = `#!/bin/sh
|
|
585854
|
+
exec kdialog --password "${description.replace(/"/g, '\\"')}" 2>/dev/null
|
|
585855
|
+
`;
|
|
585856
|
+
}
|
|
585857
|
+
writeFileSync52(shim, body, "utf-8");
|
|
585858
|
+
chmodSync2(shim, 493);
|
|
585859
|
+
return shim;
|
|
585860
|
+
}
|
|
585861
|
+
async function runGraphicalSudo(opts) {
|
|
585862
|
+
const helper = detectSudoHelper();
|
|
585863
|
+
const description = opts.description || "Open Agents needs admin access to set up Tor (.onion hidden service)";
|
|
585864
|
+
const timeoutMs = opts.timeoutMs ?? 5 * 6e4;
|
|
585865
|
+
if (!helper) throw new Error("No suitable sudo helper found (pkexec, zenity, kdialog, ssh-askpass).");
|
|
585866
|
+
let cmd;
|
|
585867
|
+
let args;
|
|
585868
|
+
let extraEnv = {};
|
|
585869
|
+
const envFlags = [];
|
|
585870
|
+
for (const [k, v] of Object.entries(opts.env || {})) envFlags.push(`${k}=${v}`);
|
|
585871
|
+
if (helper === "pkexec") {
|
|
585872
|
+
cmd = "pkexec";
|
|
585873
|
+
args = [];
|
|
585874
|
+
if (envFlags.length) args.push(...envFlags.flatMap((e2) => ["--user", "root", "env", e2]));
|
|
585875
|
+
args = ["env", ...envFlags, "/bin/bash", opts.scriptPath, ...opts.args ?? []];
|
|
585876
|
+
} else if (helper === "osascript") {
|
|
585877
|
+
const inner = `${envFlags.map((e2) => `${e2}`).join(" ")} /bin/bash ${shellQuote(opts.scriptPath)} ${shellQuote((opts.args ?? []).join(" "))}`.trim();
|
|
585878
|
+
cmd = "osascript";
|
|
585879
|
+
args = ["-e", `do shell script "${inner.replace(/"/g, '\\"')}" with administrator privileges`];
|
|
585880
|
+
} else if (helper === "ssh-askpass" || helper === "zenity" || helper === "kdialog") {
|
|
585881
|
+
const shim = helper === "ssh-askpass" ? which("ssh-askpass") : ensureAskpassShim(helper, description);
|
|
585882
|
+
extraEnv = { ...extraEnv, SUDO_ASKPASS: shim, DISPLAY: process.env["DISPLAY"] || ":0" };
|
|
585883
|
+
cmd = "sudo";
|
|
585884
|
+
args = ["-A", "-E", "/bin/bash", opts.scriptPath, ...opts.args ?? []];
|
|
585885
|
+
} else {
|
|
585886
|
+
cmd = "sudo";
|
|
585887
|
+
args = ["/bin/bash", opts.scriptPath, ...opts.args ?? []];
|
|
585888
|
+
}
|
|
585889
|
+
return new Promise((resolve43, reject) => {
|
|
585890
|
+
const child = spawn24(cmd, args, {
|
|
585891
|
+
env: { ...process.env, ...opts.env || {}, ...extraEnv },
|
|
585892
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
585893
|
+
});
|
|
585894
|
+
let stdout = "";
|
|
585895
|
+
let stderr = "";
|
|
585896
|
+
let timedOut = false;
|
|
585897
|
+
const timer = setTimeout(() => {
|
|
585898
|
+
timedOut = true;
|
|
585899
|
+
try {
|
|
585900
|
+
child.kill("SIGTERM");
|
|
585901
|
+
} catch {
|
|
585902
|
+
}
|
|
585903
|
+
setTimeout(() => {
|
|
585904
|
+
try {
|
|
585905
|
+
child.kill("SIGKILL");
|
|
585906
|
+
} catch {
|
|
585907
|
+
}
|
|
585908
|
+
}, 2e3);
|
|
585909
|
+
}, timeoutMs);
|
|
585910
|
+
child.stdout.on("data", (d2) => {
|
|
585911
|
+
stdout += d2.toString("utf-8");
|
|
585912
|
+
});
|
|
585913
|
+
child.stderr.on("data", (d2) => {
|
|
585914
|
+
stderr += d2.toString("utf-8");
|
|
585915
|
+
});
|
|
585916
|
+
child.on("error", (e2) => {
|
|
585917
|
+
clearTimeout(timer);
|
|
585918
|
+
reject(e2);
|
|
585919
|
+
});
|
|
585920
|
+
child.on("close", (code8) => {
|
|
585921
|
+
clearTimeout(timer);
|
|
585922
|
+
if (timedOut) return reject(new Error(`graphical sudo timed out after ${timeoutMs}ms`));
|
|
585923
|
+
resolve43({ code: code8 ?? -1, stdout, stderr, helper });
|
|
585924
|
+
});
|
|
585925
|
+
});
|
|
585926
|
+
}
|
|
585927
|
+
function shellQuote(s2) {
|
|
585928
|
+
return "'" + s2.replace(/'/g, "'\\''") + "'";
|
|
585929
|
+
}
|
|
585930
|
+
var init_graphical_sudo = __esm({
|
|
585931
|
+
"packages/cli/src/api/graphical-sudo.ts"() {
|
|
585932
|
+
"use strict";
|
|
585933
|
+
}
|
|
585934
|
+
});
|
|
585935
|
+
|
|
585814
585936
|
// packages/cli/src/api/routes-v1.ts
|
|
585815
|
-
import { existsSync as
|
|
585816
|
-
import { join as
|
|
585937
|
+
import { existsSync as existsSync103, readFileSync as readFileSync83, readdirSync as readdirSync34, statSync as statSync34 } from "node:fs";
|
|
585938
|
+
import { join as join119, resolve as pathResolve2 } from "node:path";
|
|
585817
585939
|
import { homedir as homedir40 } from "node:os";
|
|
585818
585940
|
async function tryRouteV1(ctx3) {
|
|
585819
585941
|
const { pathname, method } = ctx3;
|
|
@@ -585898,6 +586020,9 @@ async function tryRouteV1(ctx3) {
|
|
|
585898
586020
|
}
|
|
585899
586021
|
if (pathname === "/v1/share/generate" && method === "POST") return handleGenerateShare(ctx3);
|
|
585900
586022
|
if (pathname === "/v1/remote-proxy" && method === "POST") return handleRemoteProxy(ctx3);
|
|
586023
|
+
if (pathname === "/v1/tor/status" && method === "GET") return handleTorStatus(ctx3);
|
|
586024
|
+
if (pathname === "/v1/tor/enable" && method === "POST") return handleTorEnable(ctx3);
|
|
586025
|
+
if (pathname === "/v1/tor/disable" && method === "POST") return handleTorDisable(ctx3);
|
|
585901
586026
|
if (pathname === "/v1/tools" && method === "GET") {
|
|
585902
586027
|
return handleListTools(ctx3);
|
|
585903
586028
|
}
|
|
@@ -586044,11 +586169,11 @@ async function handleGetSkill(ctx3, name10) {
|
|
|
586044
586169
|
async function fallbackDiscoverSkills() {
|
|
586045
586170
|
return (_root) => {
|
|
586046
586171
|
const roots = [
|
|
586047
|
-
|
|
586172
|
+
join119(homedir40(), ".local", "share", "ai-writing-guide")
|
|
586048
586173
|
];
|
|
586049
586174
|
const out = [];
|
|
586050
586175
|
for (const root of roots) {
|
|
586051
|
-
if (!
|
|
586176
|
+
if (!existsSync103(root)) continue;
|
|
586052
586177
|
walkForSkills(root, out, 0);
|
|
586053
586178
|
}
|
|
586054
586179
|
return out;
|
|
@@ -586059,7 +586184,7 @@ function walkForSkills(dir, out, depth) {
|
|
|
586059
586184
|
try {
|
|
586060
586185
|
for (const e2 of readdirSync34(dir, { withFileTypes: true })) {
|
|
586061
586186
|
if (e2.name.startsWith(".") || e2.name === "node_modules") continue;
|
|
586062
|
-
const p2 =
|
|
586187
|
+
const p2 = join119(dir, e2.name);
|
|
586063
586188
|
if (e2.isDirectory()) {
|
|
586064
586189
|
walkForSkills(p2, out, depth + 1);
|
|
586065
586190
|
} else if (e2.isFile() && e2.name === "SKILL.md") {
|
|
@@ -586248,7 +586373,7 @@ async function getMemoryStores() {
|
|
|
586248
586373
|
if (memoryInitTried) return null;
|
|
586249
586374
|
memoryInitTried = true;
|
|
586250
586375
|
try {
|
|
586251
|
-
const dbPath =
|
|
586376
|
+
const dbPath = join119(homedir40(), ".open-agents", "memory.db");
|
|
586252
586377
|
const sharedDb = initDb(dbPath);
|
|
586253
586378
|
memoryStoresCache = {
|
|
586254
586379
|
episode: new EpisodeStore(dbPath),
|
|
@@ -586506,7 +586631,7 @@ async function handleFilesRead(ctx3) {
|
|
|
586506
586631
|
}));
|
|
586507
586632
|
return true;
|
|
586508
586633
|
}
|
|
586509
|
-
if (!
|
|
586634
|
+
if (!existsSync103(resolved)) {
|
|
586510
586635
|
sendProblem(res, problemDetails({
|
|
586511
586636
|
type: P.notFound,
|
|
586512
586637
|
status: 404,
|
|
@@ -586771,12 +586896,12 @@ async function handleNexusStatus(ctx3) {
|
|
|
586771
586896
|
const { res, requestId } = ctx3;
|
|
586772
586897
|
try {
|
|
586773
586898
|
const statePaths = [
|
|
586774
|
-
|
|
586775
|
-
|
|
586899
|
+
join119(process.cwd(), ".oa", "nexus-peer-state.json"),
|
|
586900
|
+
join119(homedir40(), ".open-agents", "nexus-peer-cache.json")
|
|
586776
586901
|
];
|
|
586777
586902
|
const states = [];
|
|
586778
586903
|
for (const p2 of statePaths) {
|
|
586779
|
-
if (!
|
|
586904
|
+
if (!existsSync103(p2)) continue;
|
|
586780
586905
|
try {
|
|
586781
586906
|
const raw = readFileSync83(p2, "utf-8");
|
|
586782
586907
|
states.push({ source: p2, data: JSON.parse(raw) });
|
|
@@ -586805,8 +586930,8 @@ async function handleNexusStatus(ctx3) {
|
|
|
586805
586930
|
}
|
|
586806
586931
|
function loadAgentName() {
|
|
586807
586932
|
try {
|
|
586808
|
-
const p2 =
|
|
586809
|
-
if (
|
|
586933
|
+
const p2 = join119(homedir40(), ".open-agents", "agent-name");
|
|
586934
|
+
if (existsSync103(p2)) return readFileSync83(p2, "utf-8").trim();
|
|
586810
586935
|
} catch {
|
|
586811
586936
|
}
|
|
586812
586937
|
return null;
|
|
@@ -586815,12 +586940,12 @@ async function handleSponsors(ctx3) {
|
|
|
586815
586940
|
const { req: req2, res, url, requestId } = ctx3;
|
|
586816
586941
|
try {
|
|
586817
586942
|
const candidates = [
|
|
586818
|
-
|
|
586819
|
-
|
|
586943
|
+
join119(homedir40(), ".open-agents", "sponsor-cache.json"),
|
|
586944
|
+
join119(homedir40(), ".open-agents", "sponsors.json")
|
|
586820
586945
|
];
|
|
586821
586946
|
let sponsors = [];
|
|
586822
586947
|
for (const p2 of candidates) {
|
|
586823
|
-
if (!
|
|
586948
|
+
if (!existsSync103(p2)) continue;
|
|
586824
586949
|
try {
|
|
586825
586950
|
const raw = JSON.parse(readFileSync83(p2, "utf-8"));
|
|
586826
586951
|
if (Array.isArray(raw)) {
|
|
@@ -586891,8 +587016,8 @@ async function handleEvaluate(ctx3) {
|
|
|
586891
587016
|
}));
|
|
586892
587017
|
return true;
|
|
586893
587018
|
}
|
|
586894
|
-
const jobPath =
|
|
586895
|
-
if (!
|
|
587019
|
+
const jobPath = join119(process.cwd(), ".oa", "jobs", `${runId}.json`);
|
|
587020
|
+
if (!existsSync103(jobPath)) {
|
|
586896
587021
|
sendProblem(res, problemDetails({
|
|
586897
587022
|
type: P.notFound,
|
|
586898
587023
|
status: 404,
|
|
@@ -587040,7 +587165,7 @@ async function handleMintKey(ctx3) {
|
|
|
587040
587165
|
return true;
|
|
587041
587166
|
}
|
|
587042
587167
|
function _readStatusFile(p2) {
|
|
587043
|
-
if (!
|
|
587168
|
+
if (!existsSync103(p2)) return null;
|
|
587044
587169
|
try {
|
|
587045
587170
|
const data = JSON.parse(readFileSync83(p2, "utf-8"));
|
|
587046
587171
|
if (data?.connected && typeof data.peerId === "string" && data.peerId.length > 10) {
|
|
@@ -587057,18 +587182,18 @@ function _readStatusFile(p2) {
|
|
|
587057
587182
|
function resolveLocalPeerId() {
|
|
587058
587183
|
const override = process.env["OA_NEXUS_DIR"];
|
|
587059
587184
|
if (override) {
|
|
587060
|
-
const r2 = _readStatusFile(
|
|
587185
|
+
const r2 = _readStatusFile(join119(override, "status.json"));
|
|
587061
587186
|
if (r2) return r2;
|
|
587062
587187
|
}
|
|
587063
587188
|
try {
|
|
587064
|
-
const regPath =
|
|
587065
|
-
if (
|
|
587189
|
+
const regPath = join119(homedir40(), ".open-agents", "nexus-registry.json");
|
|
587190
|
+
if (existsSync103(regPath)) {
|
|
587066
587191
|
const reg = JSON.parse(readFileSync83(regPath, "utf-8"));
|
|
587067
587192
|
const entries = Array.isArray(reg?.dirs) ? reg.dirs : [];
|
|
587068
587193
|
for (const entry of entries) {
|
|
587069
587194
|
const dir = typeof entry === "string" ? entry : entry?.dir;
|
|
587070
587195
|
if (typeof dir === "string") {
|
|
587071
|
-
const r2 = _readStatusFile(
|
|
587196
|
+
const r2 = _readStatusFile(join119(dir, "status.json"));
|
|
587072
587197
|
if (r2) return r2;
|
|
587073
587198
|
}
|
|
587074
587199
|
}
|
|
@@ -587076,9 +587201,9 @@ function resolveLocalPeerId() {
|
|
|
587076
587201
|
} catch {
|
|
587077
587202
|
}
|
|
587078
587203
|
const candidates = [
|
|
587079
|
-
|
|
587080
|
-
|
|
587081
|
-
|
|
587204
|
+
join119(process.cwd(), ".oa", "nexus", "status.json"),
|
|
587205
|
+
join119(homedir40(), ".oa", "nexus", "status.json"),
|
|
587206
|
+
join119(homedir40(), ".open-agents", "nexus", "status.json")
|
|
587082
587207
|
];
|
|
587083
587208
|
for (const p2 of candidates) {
|
|
587084
587209
|
const r2 = _readStatusFile(p2);
|
|
@@ -587107,6 +587232,136 @@ function resolveLocalPeerId() {
|
|
|
587107
587232
|
_peerIdScanCache = { ts: now, result: scanResult };
|
|
587108
587233
|
return scanResult;
|
|
587109
587234
|
}
|
|
587235
|
+
function locateTorScript(filename) {
|
|
587236
|
+
const candidates = [
|
|
587237
|
+
// npm-installed layout: scripts get copied to dist/scripts/tor/ by
|
|
587238
|
+
// scripts/build-publish.mjs. __dirname at runtime points at dist/api.
|
|
587239
|
+
join119(__dirname, "..", "scripts", "tor", filename),
|
|
587240
|
+
// Workspace dev: cli package's source tree.
|
|
587241
|
+
join119(__dirname, "..", "..", "scripts", "tor", filename),
|
|
587242
|
+
// Workspace dev (from cwd at repo root):
|
|
587243
|
+
join119(process.cwd(), "packages", "cli", "scripts", "tor", filename),
|
|
587244
|
+
join119(process.cwd(), "scripts", "tor", filename)
|
|
587245
|
+
];
|
|
587246
|
+
for (const p2 of candidates) {
|
|
587247
|
+
if (existsSync103(p2)) return p2;
|
|
587248
|
+
}
|
|
587249
|
+
try {
|
|
587250
|
+
const { execSync: execSync59 } = __require("node:child_process");
|
|
587251
|
+
const root = execSync59("npm root -g", { encoding: "utf-8", timeout: 5e3 }).trim();
|
|
587252
|
+
const p2 = join119(root, "open-agents-ai", "dist", "scripts", "tor", filename);
|
|
587253
|
+
if (existsSync103(p2)) return p2;
|
|
587254
|
+
} catch {
|
|
587255
|
+
}
|
|
587256
|
+
return null;
|
|
587257
|
+
}
|
|
587258
|
+
async function handleTorStatus(ctx3) {
|
|
587259
|
+
const { res } = ctx3;
|
|
587260
|
+
const { getLocalOnion: getLocalOnion2, torIsReachable: torIsReachable2 } = await Promise.resolve().then(() => (init_tor_fallback(), tor_fallback_exports));
|
|
587261
|
+
const { detectSudoHelper: detectSudoHelper2 } = await Promise.resolve().then(() => (init_graphical_sudo(), graphical_sudo_exports));
|
|
587262
|
+
const onion = getLocalOnion2();
|
|
587263
|
+
const reachable = await torIsReachable2();
|
|
587264
|
+
sendJson(res, 200, {
|
|
587265
|
+
onion,
|
|
587266
|
+
socks5_reachable: reachable,
|
|
587267
|
+
sudo_helper: detectSudoHelper2()
|
|
587268
|
+
});
|
|
587269
|
+
return true;
|
|
587270
|
+
}
|
|
587271
|
+
async function handleTorEnable(ctx3) {
|
|
587272
|
+
const { req: req2, res, requestId } = ctx3;
|
|
587273
|
+
const reqAuth = req2;
|
|
587274
|
+
if (reqAuth._authScope !== "admin") {
|
|
587275
|
+
sendProblem(res, problemDetails({
|
|
587276
|
+
type: P.forbidden,
|
|
587277
|
+
status: 403,
|
|
587278
|
+
title: "Admin scope required",
|
|
587279
|
+
detail: "Tor setup requires elevated privileges; only admin keys can request it.",
|
|
587280
|
+
instance: requestId
|
|
587281
|
+
}));
|
|
587282
|
+
return true;
|
|
587283
|
+
}
|
|
587284
|
+
const { getLocalOnion: getLocalOnion2 } = await Promise.resolve().then(() => (init_tor_fallback(), tor_fallback_exports));
|
|
587285
|
+
if (getLocalOnion2()) {
|
|
587286
|
+
sendJson(res, 409, {
|
|
587287
|
+
status: "already_configured",
|
|
587288
|
+
onion: getLocalOnion2(),
|
|
587289
|
+
_note: "Tor hidden service already exists. Use /v1/tor/disable to remove."
|
|
587290
|
+
});
|
|
587291
|
+
return true;
|
|
587292
|
+
}
|
|
587293
|
+
const scriptPath2 = locateTorScript("tor_setup.sh");
|
|
587294
|
+
if (!scriptPath2) {
|
|
587295
|
+
sendProblem(res, problemDetails({
|
|
587296
|
+
type: P.internalError,
|
|
587297
|
+
status: 500,
|
|
587298
|
+
title: "tor_setup.sh not found",
|
|
587299
|
+
detail: "Could not locate the bundled Tor setup script.",
|
|
587300
|
+
instance: requestId
|
|
587301
|
+
}));
|
|
587302
|
+
return true;
|
|
587303
|
+
}
|
|
587304
|
+
const { detectSudoHelper: detectSudoHelper2, runGraphicalSudo: runGraphicalSudo2 } = await Promise.resolve().then(() => (init_graphical_sudo(), graphical_sudo_exports));
|
|
587305
|
+
const helper = detectSudoHelper2();
|
|
587306
|
+
if (!helper) {
|
|
587307
|
+
sendProblem(res, problemDetails({
|
|
587308
|
+
type: P.internalError,
|
|
587309
|
+
status: 503,
|
|
587310
|
+
title: "No graphical sudo helper",
|
|
587311
|
+
detail: "Install one of: pkexec (PolKit), zenity, kdialog, or ssh-askpass — then retry.",
|
|
587312
|
+
instance: requestId
|
|
587313
|
+
}));
|
|
587314
|
+
return true;
|
|
587315
|
+
}
|
|
587316
|
+
sendJson(res, 202, {
|
|
587317
|
+
status: "accepted",
|
|
587318
|
+
helper,
|
|
587319
|
+
script: scriptPath2,
|
|
587320
|
+
poll: "/v1/tor/status"
|
|
587321
|
+
});
|
|
587322
|
+
const apiPort = req2.socket?.localPort || parseInt(process.env["OA_API_PORT"] || "11435", 10);
|
|
587323
|
+
runGraphicalSudo2({
|
|
587324
|
+
scriptPath: scriptPath2,
|
|
587325
|
+
env: { OA_API_PORT: String(apiPort) },
|
|
587326
|
+
description: "Open Agents needs admin access to install Tor and configure a hidden service"
|
|
587327
|
+
}).then((r2) => {
|
|
587328
|
+
if (r2.code !== 0) {
|
|
587329
|
+
console.warn(`[tor-enable] sudo helper ${r2.helper} exited ${r2.code}: ${r2.stderr.slice(-300)}`);
|
|
587330
|
+
}
|
|
587331
|
+
}).catch((e2) => {
|
|
587332
|
+
console.warn(`[tor-enable] failed: ${e2 instanceof Error ? e2.message : String(e2)}`);
|
|
587333
|
+
});
|
|
587334
|
+
return true;
|
|
587335
|
+
}
|
|
587336
|
+
async function handleTorDisable(ctx3) {
|
|
587337
|
+
const { req: req2, res, requestId } = ctx3;
|
|
587338
|
+
const reqAuth = req2;
|
|
587339
|
+
if (reqAuth._authScope !== "admin") {
|
|
587340
|
+
sendProblem(res, problemDetails({
|
|
587341
|
+
type: P.forbidden,
|
|
587342
|
+
status: 403,
|
|
587343
|
+
title: "Admin scope required",
|
|
587344
|
+
detail: "Tor teardown requires admin scope.",
|
|
587345
|
+
instance: requestId
|
|
587346
|
+
}));
|
|
587347
|
+
return true;
|
|
587348
|
+
}
|
|
587349
|
+
const scriptPath2 = locateTorScript("destroy_tor.sh");
|
|
587350
|
+
if (!scriptPath2) {
|
|
587351
|
+
sendProblem(res, problemDetails({
|
|
587352
|
+
type: P.internalError,
|
|
587353
|
+
status: 500,
|
|
587354
|
+
title: "destroy_tor.sh not found",
|
|
587355
|
+
detail: "Bundled teardown script missing.",
|
|
587356
|
+
instance: requestId
|
|
587357
|
+
}));
|
|
587358
|
+
return true;
|
|
587359
|
+
}
|
|
587360
|
+
const { runGraphicalSudo: runGraphicalSudo2 } = await Promise.resolve().then(() => (init_graphical_sudo(), graphical_sudo_exports));
|
|
587361
|
+
sendJson(res, 202, { status: "accepted", script: scriptPath2 });
|
|
587362
|
+
runGraphicalSudo2({ scriptPath: scriptPath2, description: "Open Agents needs admin access to remove the Tor hidden service" }).catch((e2) => console.warn(`[tor-disable] failed: ${e2 instanceof Error ? e2.message : String(e2)}`));
|
|
587363
|
+
return true;
|
|
587364
|
+
}
|
|
587110
587365
|
async function handleGenerateShare(ctx3) {
|
|
587111
587366
|
const { req: req2, res, requestId } = ctx3;
|
|
587112
587367
|
const reqAuth = req2;
|
|
@@ -587174,9 +587429,11 @@ async function handleGenerateShare(ctx3) {
|
|
|
587174
587429
|
if (onion) plainParams.push(`oa-onion=${encodeURIComponent(onion)}`);
|
|
587175
587430
|
plainParams.push(`oa-share-label=${encodeURIComponent(label)}`);
|
|
587176
587431
|
const plainUrl = `${scheme}://${hostPort}/?${plainParams.join("&")}`;
|
|
587432
|
+
const torShareUrl = onion ? `oa-share-tor://${onion}#${fullKey}` : null;
|
|
587177
587433
|
sendJson(res, 201, {
|
|
587178
587434
|
shareUrl,
|
|
587179
587435
|
plainUrl,
|
|
587436
|
+
torShareUrl,
|
|
587180
587437
|
mode,
|
|
587181
587438
|
peerId: peerInfo?.peerId || null,
|
|
587182
587439
|
onion: onion || null,
|
|
@@ -587192,7 +587449,7 @@ async function handleGenerateShare(ctx3) {
|
|
|
587192
587449
|
tor: !!onion,
|
|
587193
587450
|
direct: !peerInfo
|
|
587194
587451
|
},
|
|
587195
|
-
_note: peerInfo && onion ? "Globally reachable via libp2p (primary) and Tor (.onion fallback)." : peerInfo ? "Globally reachable via libp2p. For maximum reach add Tor:
|
|
587452
|
+
_note: peerInfo && onion ? "Globally reachable via libp2p (primary) and Tor (.onion fallback)." : peerInfo ? "Globally reachable via libp2p. For maximum reach add Tor: run `oa tor enable`." : onion ? "Globally reachable via Tor only (.onion). Start nexus for libp2p tier." : "Nexus offline + no Tor — URL is direct-HTTP only (LAN/VPN reach)."
|
|
587196
587453
|
});
|
|
587197
587454
|
} catch (err) {
|
|
587198
587455
|
sendProblem(res, problemDetails({
|
|
@@ -587250,13 +587507,13 @@ async function handleRemoteProxy(ctx3) {
|
|
|
587250
587507
|
return true;
|
|
587251
587508
|
}
|
|
587252
587509
|
const nexusCandidates = [
|
|
587253
|
-
|
|
587254
|
-
|
|
587255
|
-
|
|
587510
|
+
join119(process.cwd(), ".oa", "nexus"),
|
|
587511
|
+
join119(homedir40(), ".oa", "nexus"),
|
|
587512
|
+
join119(homedir40(), ".open-agents", "nexus")
|
|
587256
587513
|
];
|
|
587257
587514
|
let nexusDirPath = null;
|
|
587258
587515
|
for (const p2 of nexusCandidates) {
|
|
587259
|
-
if (
|
|
587516
|
+
if (existsSync103(join119(p2, "status.json"))) {
|
|
587260
587517
|
nexusDirPath = p2;
|
|
587261
587518
|
break;
|
|
587262
587519
|
}
|
|
@@ -587352,7 +587609,7 @@ async function handleRemoteProxy(ctx3) {
|
|
|
587352
587609
|
}));
|
|
587353
587610
|
return true;
|
|
587354
587611
|
}
|
|
587355
|
-
const streamFile =
|
|
587612
|
+
const streamFile = join119(nexusDirPath, `tunnel-${requestId}-${Date.now()}.jsonl`);
|
|
587356
587613
|
try {
|
|
587357
587614
|
const { writeFileSync: _wfs } = await import("node:fs");
|
|
587358
587615
|
_wfs(streamFile, "");
|
|
@@ -587795,14 +588052,14 @@ async function handleListEngines(ctx3) {
|
|
|
587795
588052
|
const home = homedir40();
|
|
587796
588053
|
sendJson(res, 200, {
|
|
587797
588054
|
engines: [
|
|
587798
|
-
{ name: "dream", state_file:
|
|
587799
|
-
{ name: "bless", state_file:
|
|
587800
|
-
{ name: "call", state_file:
|
|
587801
|
-
{ name: "listen", state_file:
|
|
587802
|
-
{ name: "telegram", state_file:
|
|
587803
|
-
{ name: "expose", state_file:
|
|
587804
|
-
{ name: "nexus", state_file:
|
|
587805
|
-
{ name: "ipfs", state_file:
|
|
588055
|
+
{ name: "dream", state_file: join119(process.cwd(), ".oa", "dreams"), controllable_via: "SSE + slash commands" },
|
|
588056
|
+
{ name: "bless", state_file: join119(process.cwd(), ".oa", "bless-state.json"), controllable_via: "slash commands" },
|
|
588057
|
+
{ name: "call", state_file: join119(process.cwd(), ".oa", "call-state.json"), controllable_via: "slash commands" },
|
|
588058
|
+
{ name: "listen", state_file: join119(process.cwd(), ".oa", "listen-state.json"), controllable_via: "slash commands" },
|
|
588059
|
+
{ name: "telegram", state_file: join119(home, ".open-agents", "telegram-state.json"), controllable_via: "slash commands" },
|
|
588060
|
+
{ name: "expose", state_file: join119(process.cwd(), ".oa", "expose-state.json"), controllable_via: "/expose commands" },
|
|
588061
|
+
{ name: "nexus", state_file: join119(home, ".open-agents", "nexus-peer-cache.json"), controllable_via: "/nexus commands" },
|
|
588062
|
+
{ name: "ipfs", state_file: join119(process.cwd(), ".oa", "ipfs"), controllable_via: "slash commands" }
|
|
587806
588063
|
],
|
|
587807
588064
|
note: "Engine instrumentation lives in the running TUI process. Full status + control requires the daemon↔TUI bridge (PT-07). See parity audit WO-PARITY-04."
|
|
587808
588065
|
});
|
|
@@ -587885,21 +588142,21 @@ async function tryAimsRoute(ctx3) {
|
|
|
587885
588142
|
return false;
|
|
587886
588143
|
}
|
|
587887
588144
|
function aimsDir() {
|
|
587888
|
-
return
|
|
588145
|
+
return join119(homedir40(), ".open-agents", "aims");
|
|
587889
588146
|
}
|
|
587890
588147
|
function readAimsFile(name10, fallback) {
|
|
587891
588148
|
try {
|
|
587892
|
-
const p2 =
|
|
587893
|
-
if (
|
|
588149
|
+
const p2 = join119(aimsDir(), name10);
|
|
588150
|
+
if (existsSync103(p2)) return JSON.parse(readFileSync83(p2, "utf-8"));
|
|
587894
588151
|
} catch {
|
|
587895
588152
|
}
|
|
587896
588153
|
return fallback;
|
|
587897
588154
|
}
|
|
587898
588155
|
function writeAimsFile(name10, data) {
|
|
587899
588156
|
const dir = aimsDir();
|
|
587900
|
-
const { mkdirSync:
|
|
587901
|
-
|
|
587902
|
-
const finalPath =
|
|
588157
|
+
const { mkdirSync: mkdirSync68, writeFileSync: wf, renameSync: rn } = __require("node:fs");
|
|
588158
|
+
mkdirSync68(dir, { recursive: true });
|
|
588159
|
+
const finalPath = join119(dir, name10);
|
|
587903
588160
|
const tmpPath = `${finalPath}.tmp.${process.pid}.${Date.now()}`;
|
|
587904
588161
|
try {
|
|
587905
588162
|
wf(tmpPath, JSON.stringify(data, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
@@ -588229,10 +588486,10 @@ async function handleAimsSuppliers(ctx3) {
|
|
|
588229
588486
|
}
|
|
588230
588487
|
];
|
|
588231
588488
|
const sponsorPaths = [
|
|
588232
|
-
|
|
588489
|
+
join119(homedir40(), ".open-agents", "sponsor-cache.json")
|
|
588233
588490
|
];
|
|
588234
588491
|
for (const p2 of sponsorPaths) {
|
|
588235
|
-
if (!
|
|
588492
|
+
if (!existsSync103(p2)) continue;
|
|
588236
588493
|
try {
|
|
588237
588494
|
const raw = JSON.parse(readFileSync83(p2, "utf-8"));
|
|
588238
588495
|
const list = Array.isArray(raw) ? raw : raw?.sponsors ?? [];
|
|
@@ -591759,6 +592016,19 @@ function _looksLikePeerId(s) {
|
|
|
591759
592016
|
function parseShareInput(raw) {
|
|
591760
592017
|
const v = String(raw || '').trim();
|
|
591761
592018
|
if (!v) return null;
|
|
592019
|
+
// oa-share-tor scheme — Tor-only routing via SOCKS5 to <onion>:80
|
|
592020
|
+
if (v.toLowerCase().startsWith('oa-share-tor://')) {
|
|
592021
|
+
const after = v.slice('oa-share-tor://'.length);
|
|
592022
|
+
const hashIdx = after.indexOf('#');
|
|
592023
|
+
if (hashIdx < 0) return null;
|
|
592024
|
+
const onionRaw = after.slice(0, hashIdx);
|
|
592025
|
+
// Strip optional :port suffix; we always dial 80 since hidden services
|
|
592026
|
+
// are configured to forward 80 → local API per the leek_messenger setup.
|
|
592027
|
+
const onion = onionRaw.split(':')[0];
|
|
592028
|
+
const key = after.slice(hashIdx + 1);
|
|
592029
|
+
if (!onion.endsWith('.onion') || !key) return null;
|
|
592030
|
+
return { peerId: null, onion, host: null, key, scheme: 'tor' };
|
|
592031
|
+
}
|
|
591762
592032
|
// oa-share scheme — custom parser since URL() doesn't always honor it.
|
|
591763
592033
|
if (v.toLowerCase().startsWith('oa-share://')) {
|
|
591764
592034
|
const after = v.slice('oa-share://'.length);
|
|
@@ -591919,10 +592189,25 @@ async function generateShareUrl() {
|
|
|
591919
592189
|
const j = await r.json();
|
|
591920
592190
|
const safeShare = escapeHtml(j.shareUrl || '');
|
|
591921
592191
|
const safePlain = escapeHtml(j.plainUrl || '');
|
|
592192
|
+
const safeTor = escapeHtml(j.torShareUrl || '');
|
|
592193
|
+
const torRow = j.torShareUrl
|
|
592194
|
+
? '<div style="margin:6px 0">' +
|
|
592195
|
+
'<label style="display:block;font-size:0.7rem;color:var(--color-fg-muted);margin-bottom:2px">tor-only URL (.onion routed via SOCKS5 — works through any firewall)</label>' +
|
|
592196
|
+
'<div style="display:flex;gap:6px;align-items:center">' +
|
|
592197
|
+
'<input readonly value="' + safeTor + '" style="flex:1;background:var(--color-bg-input);border:1px solid var(--color-border);color:var(--color-fg);padding:5px 8px;border-radius:var(--radius-sm);font-family:var(--font-mono);font-size:0.74rem">' +
|
|
592198
|
+
'<button type="button" onclick="copyShareUrl(\\'tor\\')" style="font-size:0.74rem">copy</button>' +
|
|
592199
|
+
'</div>' +
|
|
592200
|
+
'</div>'
|
|
592201
|
+
: '<div style="margin:8px 0;padding:8px;background:var(--color-bg-input);border:1px dashed var(--color-border);border-radius:var(--radius-sm)">' +
|
|
592202
|
+
'<div style="font-size:0.74rem;margin-bottom:4px">Tor (.onion) is not configured on this OA.</div>' +
|
|
592203
|
+
'<div style="font-size:0.68rem;color:var(--color-fg-muted);margin-bottom:6px">Enable Tor for global reach when libp2p fails. Asks for sudo via your system password dialog.</div>' +
|
|
592204
|
+
'<button type="button" onclick="enableTorShare()" style="font-size:0.74rem;background:var(--color-accent);color:#fff;border:none;padding:4px 12px;border-radius:var(--radius-sm);cursor:pointer">enable Tor</button>' +
|
|
592205
|
+
'<span id="enable-tor-status" style="font-size:0.68rem;margin-left:8px;color:var(--color-fg-muted)"></span>' +
|
|
592206
|
+
'</div>';
|
|
591922
592207
|
out.innerHTML =
|
|
591923
592208
|
'<div style="font-weight:500;margin-bottom:6px;color:var(--color-success)">✓ Share URL generated — hand off to remote</div>' +
|
|
591924
592209
|
'<div style="margin:6px 0">' +
|
|
591925
|
-
'<label style="display:block;font-size:0.7rem;color:var(--color-fg-muted);margin-bottom:2px">oa-share URL (compact, recommended for OA-to-OA)</label>' +
|
|
592210
|
+
'<label style="display:block;font-size:0.7rem;color:var(--color-fg-muted);margin-bottom:2px">oa-share URL (libp2p, compact, recommended for OA-to-OA)</label>' +
|
|
591926
592211
|
'<div style="display:flex;gap:6px;align-items:center">' +
|
|
591927
592212
|
'<input readonly value="' + safeShare + '" style="flex:1;background:var(--color-bg-input);border:1px solid var(--color-border);color:var(--color-fg);padding:5px 8px;border-radius:var(--radius-sm);font-family:var(--font-mono);font-size:0.74rem">' +
|
|
591928
592213
|
'<button type="button" onclick="copyShareUrl(\\'oa-share\\')" style="font-size:0.74rem">copy</button>' +
|
|
@@ -591935,17 +592220,22 @@ async function generateShareUrl() {
|
|
|
591935
592220
|
'<button type="button" onclick="copyShareUrl(\\'plain\\')" style="font-size:0.74rem">copy</button>' +
|
|
591936
592221
|
'</div>' +
|
|
591937
592222
|
'</div>' +
|
|
591938
|
-
|
|
592223
|
+
torRow +
|
|
592224
|
+
'<p style="font-size:0.68rem;color:var(--color-fg-muted);margin:6px 0 0">Note: these URLs contain the full secret. Anyone with one can use this OA. To revoke: Advanced settings → keys → revoke prefix <code>' + escapeHtml(j.keyPrefix || '') + '</code>.</p>';
|
|
591939
592225
|
// Stash for the copy buttons + add to recent.
|
|
591940
592226
|
window.__oaLastShareUrl = j.shareUrl;
|
|
591941
592227
|
window.__oaLastPlainUrl = j.plainUrl;
|
|
592228
|
+
window.__oaLastTorUrl = j.torShareUrl || null;
|
|
591942
592229
|
saveRecentKey({ key: j.key, host: j.host + ':' + j.port, label: j.label || ('shared ' + j.host) });
|
|
591943
592230
|
} catch (e) {
|
|
591944
592231
|
out.innerHTML = '<div style="color:var(--color-error)">✗ ' + escapeHtml(e && e.message ? e.message : String(e)) + '</div>';
|
|
591945
592232
|
}
|
|
591946
592233
|
}
|
|
591947
592234
|
function copyShareUrl(which) {
|
|
591948
|
-
|
|
592235
|
+
let v;
|
|
592236
|
+
if (which === 'plain') v = window.__oaLastPlainUrl;
|
|
592237
|
+
else if (which === 'tor') v = window.__oaLastTorUrl;
|
|
592238
|
+
else v = window.__oaLastShareUrl;
|
|
591949
592239
|
if (!v) return;
|
|
591950
592240
|
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
591951
592241
|
navigator.clipboard.writeText(v).then(
|
|
@@ -591965,6 +592255,46 @@ function fallbackCopy(v) {
|
|
|
591965
592255
|
window.generateShareUrl = generateShareUrl;
|
|
591966
592256
|
window.copyShareUrl = copyShareUrl;
|
|
591967
592257
|
|
|
592258
|
+
// ─── Enable Tor (graphical sudo) ────────────────────────────────────────
|
|
592259
|
+
async function enableTorShare() {
|
|
592260
|
+
const status = document.getElementById('enable-tor-status');
|
|
592261
|
+
if (status) { status.textContent = 'launching graphical sudo prompt…'; status.style.color = 'var(--color-fg-muted)'; }
|
|
592262
|
+
try {
|
|
592263
|
+
const r = await fetch('/v1/tor/enable', {
|
|
592264
|
+
method: 'POST',
|
|
592265
|
+
headers: { ...headers(), 'Content-Type': 'application/json' },
|
|
592266
|
+
body: '{}',
|
|
592267
|
+
});
|
|
592268
|
+
const j = await r.json().catch(() => ({}));
|
|
592269
|
+
if (r.status === 202) {
|
|
592270
|
+
if (status) {
|
|
592271
|
+
status.textContent = 'started — waiting for hidden service…';
|
|
592272
|
+
status.style.color = 'var(--color-accent)';
|
|
592273
|
+
}
|
|
592274
|
+
// Poll up to 90s for the .onion to appear
|
|
592275
|
+
for (let i = 0; i < 30; i++) {
|
|
592276
|
+
await new Promise(r => setTimeout(r, 3000));
|
|
592277
|
+
const s = await fetch('/v1/tor/status', { headers: headers() }).then(x => x.json()).catch(() => ({}));
|
|
592278
|
+
if (s.onion) {
|
|
592279
|
+
if (status) { status.textContent = '✓ Tor enabled: ' + s.onion; status.style.color = 'var(--color-success)'; }
|
|
592280
|
+
// Re-generate share URL to pick up the .onion field
|
|
592281
|
+
setTimeout(() => generateShareUrl(), 500);
|
|
592282
|
+
return;
|
|
592283
|
+
}
|
|
592284
|
+
}
|
|
592285
|
+
if (status) { status.textContent = '⚠ setup ran but no .onion appeared. Check journalctl -u tor for errors.'; status.style.color = 'var(--color-warning)'; }
|
|
592286
|
+
} else if (r.status === 409) {
|
|
592287
|
+
if (status) { status.textContent = '✓ already enabled — re-generating'; status.style.color = 'var(--color-success)'; }
|
|
592288
|
+
setTimeout(() => generateShareUrl(), 500);
|
|
592289
|
+
} else {
|
|
592290
|
+
if (status) { status.textContent = '✗ ' + (j.detail || ('HTTP ' + r.status)); status.style.color = 'var(--color-error)'; }
|
|
592291
|
+
}
|
|
592292
|
+
} catch (e) {
|
|
592293
|
+
if (status) { status.textContent = '✗ ' + (e && e.message ? e.message : String(e)); status.style.color = 'var(--color-error)'; }
|
|
592294
|
+
}
|
|
592295
|
+
}
|
|
592296
|
+
window.enableTorShare = enableTorShare;
|
|
592297
|
+
|
|
591968
592298
|
// ─── Remote-state helpers (visual indicator on the key button) ───────
|
|
591969
592299
|
// When localStorage carries oa.remoteHost we are in REMOTE mode: the
|
|
591970
592300
|
// key was loaded from an oa-share URL or via on-load ?oa-key=. The key
|
|
@@ -596842,14 +597172,14 @@ var init_auth_oidc = __esm({
|
|
|
596842
597172
|
});
|
|
596843
597173
|
|
|
596844
597174
|
// packages/cli/src/api/usage-tracker.ts
|
|
596845
|
-
import { mkdirSync as
|
|
596846
|
-
import { join as
|
|
597175
|
+
import { mkdirSync as mkdirSync61, readFileSync as readFileSync84, writeFileSync as writeFileSync53, existsSync as existsSync104 } from "node:fs";
|
|
597176
|
+
import { join as join120 } from "node:path";
|
|
596847
597177
|
function initUsageTracker(oaDir) {
|
|
596848
|
-
const dir =
|
|
596849
|
-
|
|
596850
|
-
usageFile =
|
|
597178
|
+
const dir = join120(oaDir, "usage");
|
|
597179
|
+
mkdirSync61(dir, { recursive: true });
|
|
597180
|
+
usageFile = join120(dir, "token-usage.json");
|
|
596851
597181
|
try {
|
|
596852
|
-
if (
|
|
597182
|
+
if (existsSync104(usageFile)) {
|
|
596853
597183
|
store = JSON.parse(readFileSync84(usageFile, "utf-8"));
|
|
596854
597184
|
}
|
|
596855
597185
|
} catch {
|
|
@@ -596886,7 +597216,7 @@ function flush2() {
|
|
|
596886
597216
|
if (!initialized2 || !dirty) return;
|
|
596887
597217
|
try {
|
|
596888
597218
|
store.lastSaved = (/* @__PURE__ */ new Date()).toISOString();
|
|
596889
|
-
|
|
597219
|
+
writeFileSync53(usageFile, JSON.stringify(store, null, 2), "utf-8");
|
|
596890
597220
|
dirty = false;
|
|
596891
597221
|
} catch {
|
|
596892
597222
|
}
|
|
@@ -596914,24 +597244,24 @@ var init_usage_tracker = __esm({
|
|
|
596914
597244
|
});
|
|
596915
597245
|
|
|
596916
597246
|
// packages/cli/src/api/profiles.ts
|
|
596917
|
-
import { existsSync as
|
|
596918
|
-
import { join as
|
|
597247
|
+
import { existsSync as existsSync105, readFileSync as readFileSync85, writeFileSync as writeFileSync54, mkdirSync as mkdirSync62, readdirSync as readdirSync35, unlinkSync as unlinkSync23 } from "node:fs";
|
|
597248
|
+
import { join as join121 } from "node:path";
|
|
596919
597249
|
import { homedir as homedir41 } from "node:os";
|
|
596920
597250
|
import { createCipheriv as createCipheriv4, createDecipheriv as createDecipheriv4, randomBytes as randomBytes22, scryptSync as scryptSync3 } from "node:crypto";
|
|
596921
597251
|
function globalProfileDir() {
|
|
596922
|
-
return
|
|
597252
|
+
return join121(homedir41(), ".open-agents", "profiles");
|
|
596923
597253
|
}
|
|
596924
597254
|
function projectProfileDir(projectDir2) {
|
|
596925
|
-
return
|
|
597255
|
+
return join121(projectDir2 || process.cwd(), ".oa", "profiles");
|
|
596926
597256
|
}
|
|
596927
597257
|
function listProfiles(projectDir2) {
|
|
596928
597258
|
const result = [];
|
|
596929
597259
|
const seen = /* @__PURE__ */ new Set();
|
|
596930
597260
|
const projDir = projectProfileDir(projectDir2);
|
|
596931
|
-
if (
|
|
597261
|
+
if (existsSync105(projDir)) {
|
|
596932
597262
|
for (const f2 of readdirSync35(projDir).filter((f3) => f3.endsWith(".json"))) {
|
|
596933
597263
|
try {
|
|
596934
|
-
const raw = JSON.parse(readFileSync85(
|
|
597264
|
+
const raw = JSON.parse(readFileSync85(join121(projDir, f2), "utf8"));
|
|
596935
597265
|
const name10 = f2.replace(".json", "");
|
|
596936
597266
|
seen.add(name10);
|
|
596937
597267
|
result.push({
|
|
@@ -596945,12 +597275,12 @@ function listProfiles(projectDir2) {
|
|
|
596945
597275
|
}
|
|
596946
597276
|
}
|
|
596947
597277
|
const globDir = globalProfileDir();
|
|
596948
|
-
if (
|
|
597278
|
+
if (existsSync105(globDir)) {
|
|
596949
597279
|
for (const f2 of readdirSync35(globDir).filter((f3) => f3.endsWith(".json"))) {
|
|
596950
597280
|
const name10 = f2.replace(".json", "");
|
|
596951
597281
|
if (seen.has(name10)) continue;
|
|
596952
597282
|
try {
|
|
596953
|
-
const raw = JSON.parse(readFileSync85(
|
|
597283
|
+
const raw = JSON.parse(readFileSync85(join121(globDir, f2), "utf8"));
|
|
596954
597284
|
result.push({
|
|
596955
597285
|
name: name10,
|
|
596956
597286
|
description: raw.description || "",
|
|
@@ -596965,9 +597295,9 @@ function listProfiles(projectDir2) {
|
|
|
596965
597295
|
}
|
|
596966
597296
|
function loadProfile(name10, password, projectDir2) {
|
|
596967
597297
|
const sanitized = name10.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
596968
|
-
const projPath =
|
|
596969
|
-
const globPath =
|
|
596970
|
-
const filePath =
|
|
597298
|
+
const projPath = join121(projectProfileDir(projectDir2), `${sanitized}.json`);
|
|
597299
|
+
const globPath = join121(globalProfileDir(), `${sanitized}.json`);
|
|
597300
|
+
const filePath = existsSync105(projPath) ? projPath : existsSync105(globPath) ? globPath : null;
|
|
596971
597301
|
if (!filePath) return null;
|
|
596972
597302
|
const raw = JSON.parse(readFileSync85(filePath, "utf8"));
|
|
596973
597303
|
if (raw.encrypted === true) {
|
|
@@ -596978,23 +597308,23 @@ function loadProfile(name10, password, projectDir2) {
|
|
|
596978
597308
|
}
|
|
596979
597309
|
function saveProfile(profile, password, scope = "global", projectDir2) {
|
|
596980
597310
|
const dir = scope === "project" ? projectProfileDir(projectDir2) : globalProfileDir();
|
|
596981
|
-
|
|
597311
|
+
mkdirSync62(dir, { recursive: true });
|
|
596982
597312
|
const sanitized = profile.name.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
596983
|
-
const filePath =
|
|
597313
|
+
const filePath = join121(dir, `${sanitized}.json`);
|
|
596984
597314
|
profile.modified = (/* @__PURE__ */ new Date()).toISOString();
|
|
596985
597315
|
if (password) {
|
|
596986
597316
|
const encrypted = encryptProfile(profile, password);
|
|
596987
|
-
|
|
597317
|
+
writeFileSync54(filePath, JSON.stringify(encrypted, null, 2), { mode: 384 });
|
|
596988
597318
|
} else {
|
|
596989
597319
|
profile.encrypted = false;
|
|
596990
|
-
|
|
597320
|
+
writeFileSync54(filePath, JSON.stringify(profile, null, 2), { mode: 420 });
|
|
596991
597321
|
}
|
|
596992
597322
|
}
|
|
596993
597323
|
function deleteProfile(name10, scope = "global", projectDir2) {
|
|
596994
597324
|
const sanitized = name10.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
596995
597325
|
const dir = scope === "project" ? projectProfileDir(projectDir2) : globalProfileDir();
|
|
596996
|
-
const filePath =
|
|
596997
|
-
if (
|
|
597326
|
+
const filePath = join121(dir, `${sanitized}.json`);
|
|
597327
|
+
if (existsSync105(filePath)) {
|
|
596998
597328
|
unlinkSync23(filePath);
|
|
596999
597329
|
return true;
|
|
597000
597330
|
}
|
|
@@ -597108,24 +597438,24 @@ var init_profiles = __esm({
|
|
|
597108
597438
|
});
|
|
597109
597439
|
|
|
597110
597440
|
// packages/cli/src/docker.ts
|
|
597111
|
-
import { execSync as execSync56, spawn as
|
|
597112
|
-
import { existsSync as
|
|
597113
|
-
import { join as
|
|
597441
|
+
import { execSync as execSync56, spawn as spawn25 } from "node:child_process";
|
|
597442
|
+
import { existsSync as existsSync106, mkdirSync as mkdirSync63, writeFileSync as writeFileSync55 } from "node:fs";
|
|
597443
|
+
import { join as join122, resolve as resolve37, dirname as dirname35 } from "node:path";
|
|
597114
597444
|
import { homedir as homedir42 } from "node:os";
|
|
597115
597445
|
import { fileURLToPath as fileURLToPath16 } from "node:url";
|
|
597116
597446
|
function getDockerDir() {
|
|
597117
597447
|
try {
|
|
597118
597448
|
if (typeof __dirname !== "undefined") {
|
|
597119
|
-
return
|
|
597449
|
+
return join122(__dirname, "..", "..", "..", "docker");
|
|
597120
597450
|
}
|
|
597121
597451
|
} catch {
|
|
597122
597452
|
}
|
|
597123
597453
|
try {
|
|
597124
597454
|
const thisDir = dirname35(fileURLToPath16(import.meta.url));
|
|
597125
|
-
return
|
|
597455
|
+
return join122(thisDir, "..", "..", "..", "docker");
|
|
597126
597456
|
} catch {
|
|
597127
597457
|
}
|
|
597128
|
-
return
|
|
597458
|
+
return join122(process.cwd(), "docker");
|
|
597129
597459
|
}
|
|
597130
597460
|
function isDockerAvailable() {
|
|
597131
597461
|
try {
|
|
@@ -597256,11 +597586,11 @@ async function ensureOaImage(force = false) {
|
|
|
597256
597586
|
}
|
|
597257
597587
|
let buildContext;
|
|
597258
597588
|
const dockerDir = getDockerDir();
|
|
597259
|
-
if (
|
|
597589
|
+
if (existsSync106(join122(dockerDir, "Dockerfile"))) {
|
|
597260
597590
|
buildContext = dockerDir;
|
|
597261
597591
|
} else {
|
|
597262
|
-
buildContext =
|
|
597263
|
-
|
|
597592
|
+
buildContext = join122(homedir42(), ".oa", "docker-build");
|
|
597593
|
+
mkdirSync63(buildContext, { recursive: true });
|
|
597264
597594
|
writeDockerfiles(buildContext);
|
|
597265
597595
|
}
|
|
597266
597596
|
try {
|
|
@@ -597334,8 +597664,8 @@ chown -R node:node /workspace /home/node/.oa /home/node/.open-agents 2>/dev/null
|
|
|
597334
597664
|
if [ "$1" = "oa" ]; then shift; exec su - node -c "cd /workspace && oa $*"; fi
|
|
597335
597665
|
exec "$@"
|
|
597336
597666
|
`;
|
|
597337
|
-
|
|
597338
|
-
|
|
597667
|
+
writeFileSync55(join122(dir, "Dockerfile"), dockerfile);
|
|
597668
|
+
writeFileSync55(join122(dir, "docker-entrypoint.sh"), entrypoint, { mode: 493 });
|
|
597339
597669
|
}
|
|
597340
597670
|
function hasNvidiaGpu() {
|
|
597341
597671
|
try {
|
|
@@ -597389,7 +597719,7 @@ function runInContainer(opts) {
|
|
|
597389
597719
|
if (opts.maxTurns) oaArgs.push("--max-turns", String(opts.maxTurns));
|
|
597390
597720
|
if (opts.timeoutS) oaArgs.push("--timeout", String(opts.timeoutS));
|
|
597391
597721
|
args.push(...oaArgs);
|
|
597392
|
-
return
|
|
597722
|
+
return spawn25("docker", args, {
|
|
597393
597723
|
stdio: ["ignore", "pipe", "pipe"]
|
|
597394
597724
|
});
|
|
597395
597725
|
}
|
|
@@ -597588,23 +597918,23 @@ import * as http5 from "node:http";
|
|
|
597588
597918
|
import * as https3 from "node:https";
|
|
597589
597919
|
import { createRequire as createRequire5 } from "node:module";
|
|
597590
597920
|
import { fileURLToPath as fileURLToPath17 } from "node:url";
|
|
597591
|
-
import { dirname as dirname36, join as
|
|
597921
|
+
import { dirname as dirname36, join as join123, resolve as resolve38 } from "node:path";
|
|
597592
597922
|
import { homedir as homedir43 } from "node:os";
|
|
597593
|
-
import { spawn as
|
|
597594
|
-
import { mkdirSync as
|
|
597923
|
+
import { spawn as spawn26, execSync as execSync57 } from "node:child_process";
|
|
597924
|
+
import { mkdirSync as mkdirSync64, writeFileSync as writeFileSync56, readFileSync as readFileSync86, readdirSync as readdirSync36, existsSync as existsSync107, watch as fsWatch3, renameSync as renameSync8, unlinkSync as unlinkSync24 } from "node:fs";
|
|
597595
597925
|
import { randomBytes as randomBytes23, randomUUID as randomUUID16 } from "node:crypto";
|
|
597596
597926
|
import { createHash as createHash19 } from "node:crypto";
|
|
597597
597927
|
function getVersion3() {
|
|
597598
597928
|
try {
|
|
597599
597929
|
const thisDir = dirname36(fileURLToPath17(import.meta.url));
|
|
597600
597930
|
const candidates = [
|
|
597601
|
-
|
|
597602
|
-
|
|
597603
|
-
|
|
597931
|
+
join123(thisDir, "..", "package.json"),
|
|
597932
|
+
join123(thisDir, "..", "..", "package.json"),
|
|
597933
|
+
join123(thisDir, "..", "..", "..", "package.json")
|
|
597604
597934
|
];
|
|
597605
597935
|
for (const pkgPath of candidates) {
|
|
597606
597936
|
try {
|
|
597607
|
-
if (!
|
|
597937
|
+
if (!existsSync107(pkgPath)) continue;
|
|
597608
597938
|
const pkg = require3(pkgPath);
|
|
597609
597939
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli" || pkg.name === "@open-agents/monorepo") {
|
|
597610
597940
|
return pkg.version ?? "0.0.0";
|
|
@@ -597806,8 +598136,8 @@ function isOriginAllowed(origin) {
|
|
|
597806
598136
|
if (!origin) return true;
|
|
597807
598137
|
let accessMode = (process.env["OA_ACCESS"] || "").toLowerCase().trim();
|
|
597808
598138
|
try {
|
|
597809
|
-
const accessFile =
|
|
597810
|
-
if (
|
|
598139
|
+
const accessFile = join123(homedir43(), ".open-agents", "access");
|
|
598140
|
+
if (existsSync107(accessFile)) {
|
|
597811
598141
|
const persisted = readFileSync86(accessFile, "utf8").trim().toLowerCase();
|
|
597812
598142
|
if (persisted === "any" || persisted === "lan" || persisted === "loopback") {
|
|
597813
598143
|
accessMode = persisted;
|
|
@@ -597868,7 +598198,7 @@ async function retrieveMemoryContext(userMessage, sessionId, maxEpisodes = 5) {
|
|
|
597868
598198
|
if (!memMod || !memMod.EpisodeStore) {
|
|
597869
598199
|
return { contextBlock: "", retrieved: [] };
|
|
597870
598200
|
}
|
|
597871
|
-
const dbPath =
|
|
598201
|
+
const dbPath = join123(homedir43(), ".open-agents", "memory.db");
|
|
597872
598202
|
const store2 = new memMod.EpisodeStore(dbPath);
|
|
597873
598203
|
const recent = store2.search({ limit: 30, sessionId: void 0 }) ?? [];
|
|
597874
598204
|
const qLower = userMessage.toLowerCase();
|
|
@@ -597911,7 +598241,7 @@ async function writeMemoryEpisodes(sessionId, userMessage, assistantContent, too
|
|
|
597911
598241
|
try {
|
|
597912
598242
|
const memMod = await Promise.resolve().then(() => (init_dist7(), dist_exports2)).catch(() => null);
|
|
597913
598243
|
if (!memMod || !memMod.EpisodeStore) return 0;
|
|
597914
|
-
const dbPath =
|
|
598244
|
+
const dbPath = join123(homedir43(), ".open-agents", "memory.db");
|
|
597915
598245
|
const store2 = new memMod.EpisodeStore(dbPath);
|
|
597916
598246
|
let written = 0;
|
|
597917
598247
|
try {
|
|
@@ -598233,13 +598563,13 @@ function ollamaStream(ollamaUrl, path8, method, body, onData, onEnd, onError, ti
|
|
|
598233
598563
|
}
|
|
598234
598564
|
function jobsDir() {
|
|
598235
598565
|
const root = resolve38(process.cwd());
|
|
598236
|
-
const dir =
|
|
598237
|
-
|
|
598566
|
+
const dir = join123(root, ".oa", "jobs");
|
|
598567
|
+
mkdirSync64(dir, { recursive: true });
|
|
598238
598568
|
return dir;
|
|
598239
598569
|
}
|
|
598240
598570
|
function loadJob(id) {
|
|
598241
|
-
const file =
|
|
598242
|
-
if (!
|
|
598571
|
+
const file = join123(jobsDir(), `${id}.json`);
|
|
598572
|
+
if (!existsSync107(file)) return null;
|
|
598243
598573
|
try {
|
|
598244
598574
|
return JSON.parse(readFileSync86(file, "utf-8"));
|
|
598245
598575
|
} catch {
|
|
@@ -598248,12 +598578,12 @@ function loadJob(id) {
|
|
|
598248
598578
|
}
|
|
598249
598579
|
function listJobs() {
|
|
598250
598580
|
const dir = jobsDir();
|
|
598251
|
-
if (!
|
|
598581
|
+
if (!existsSync107(dir)) return [];
|
|
598252
598582
|
const files = readdirSync36(dir).filter((f2) => f2.endsWith(".json")).sort();
|
|
598253
598583
|
const jobs = [];
|
|
598254
598584
|
for (const file of files) {
|
|
598255
598585
|
try {
|
|
598256
|
-
jobs.push(JSON.parse(readFileSync86(
|
|
598586
|
+
jobs.push(JSON.parse(readFileSync86(join123(dir, file), "utf-8")));
|
|
598257
598587
|
} catch {
|
|
598258
598588
|
}
|
|
598259
598589
|
}
|
|
@@ -598263,12 +598593,12 @@ function pruneOldJobs() {
|
|
|
598263
598593
|
const retentionH = parseFloat(process.env["OA_RUN_RETENTION_H"] || "24");
|
|
598264
598594
|
const cutoffMs = Date.now() - (Number.isFinite(retentionH) && retentionH > 0 ? retentionH : 24) * 36e5;
|
|
598265
598595
|
const dir = jobsDir();
|
|
598266
|
-
if (!
|
|
598596
|
+
if (!existsSync107(dir)) return { pruned: 0, kept: 0 };
|
|
598267
598597
|
let pruned = 0;
|
|
598268
598598
|
let kept = 0;
|
|
598269
598599
|
for (const file of readdirSync36(dir)) {
|
|
598270
598600
|
if (!file.endsWith(".json")) continue;
|
|
598271
|
-
const path8 =
|
|
598601
|
+
const path8 = join123(dir, file);
|
|
598272
598602
|
try {
|
|
598273
598603
|
const job = JSON.parse(readFileSync86(path8, "utf-8"));
|
|
598274
598604
|
if (job.status === "running") {
|
|
@@ -598283,7 +598613,7 @@ function pruneOldJobs() {
|
|
|
598283
598613
|
} catch {
|
|
598284
598614
|
}
|
|
598285
598615
|
const outFile = path8.replace(/\.json$/, ".output");
|
|
598286
|
-
if (
|
|
598616
|
+
if (existsSync107(outFile)) {
|
|
598287
598617
|
try {
|
|
598288
598618
|
unlinkSync24(outFile);
|
|
598289
598619
|
} catch {
|
|
@@ -598576,14 +598906,14 @@ function autoSeedTodosFromPrompt(prompt) {
|
|
|
598576
598906
|
return [];
|
|
598577
598907
|
}
|
|
598578
598908
|
function atomicJobWrite(dir, id, job) {
|
|
598579
|
-
const finalPath =
|
|
598909
|
+
const finalPath = join123(dir, `${id}.json`);
|
|
598580
598910
|
const tmpPath = `${finalPath}.tmp.${process.pid}.${Date.now()}`;
|
|
598581
598911
|
try {
|
|
598582
|
-
|
|
598912
|
+
writeFileSync56(tmpPath, JSON.stringify(job, null, 2), "utf-8");
|
|
598583
598913
|
renameSync8(tmpPath, finalPath);
|
|
598584
598914
|
} catch {
|
|
598585
598915
|
try {
|
|
598586
|
-
|
|
598916
|
+
writeFileSync56(finalPath, JSON.stringify(job, null, 2), "utf-8");
|
|
598587
598917
|
} catch {
|
|
598588
598918
|
}
|
|
598589
598919
|
try {
|
|
@@ -599785,7 +600115,7 @@ ${task}` : task;
|
|
|
599785
600115
|
runEnv["OA_RUN_SCOPE"] = req2._authScope || "admin";
|
|
599786
600116
|
runEnv["OLLAMA_HOST"] = currentCfg.backendUrl || process.env["OLLAMA_HOST"] || "http://127.0.0.1:11434";
|
|
599787
600117
|
if (currentCfg.apiKey) runEnv["OA_API_KEY_INHERIT"] = currentCfg.apiKey;
|
|
599788
|
-
const child =
|
|
600118
|
+
const child = spawn26(process.execPath, [oaBin, ...args], {
|
|
599789
600119
|
cwd: resolve38(process.cwd()),
|
|
599790
600120
|
env: runEnv,
|
|
599791
600121
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -600002,15 +600332,15 @@ ${task}` : task;
|
|
|
600002
600332
|
});
|
|
600003
600333
|
}
|
|
600004
600334
|
function updateStateFile() {
|
|
600005
|
-
return
|
|
600335
|
+
return join123(homedir43(), ".open-agents", "update-state.json");
|
|
600006
600336
|
}
|
|
600007
600337
|
function updateLogPath() {
|
|
600008
|
-
return
|
|
600338
|
+
return join123(homedir43(), ".open-agents", "update.log");
|
|
600009
600339
|
}
|
|
600010
600340
|
function readUpdateState() {
|
|
600011
600341
|
try {
|
|
600012
600342
|
const p2 = updateStateFile();
|
|
600013
|
-
if (!
|
|
600343
|
+
if (!existsSync107(p2)) return null;
|
|
600014
600344
|
return JSON.parse(readFileSync86(p2, "utf-8"));
|
|
600015
600345
|
} catch {
|
|
600016
600346
|
return null;
|
|
@@ -600018,11 +600348,11 @@ function readUpdateState() {
|
|
|
600018
600348
|
}
|
|
600019
600349
|
function writeUpdateState(state) {
|
|
600020
600350
|
try {
|
|
600021
|
-
const dir =
|
|
600022
|
-
|
|
600351
|
+
const dir = join123(homedir43(), ".open-agents");
|
|
600352
|
+
mkdirSync64(dir, { recursive: true });
|
|
600023
600353
|
const finalPath = updateStateFile();
|
|
600024
600354
|
const tmpPath = `${finalPath}.tmp.${process.pid}`;
|
|
600025
|
-
|
|
600355
|
+
writeFileSync56(tmpPath, JSON.stringify(state, null, 2), "utf-8");
|
|
600026
600356
|
renameSync8(tmpPath, finalPath);
|
|
600027
600357
|
} catch {
|
|
600028
600358
|
}
|
|
@@ -600066,15 +600396,15 @@ async function handleV1Update(req2, res, requestId) {
|
|
|
600066
600396
|
const { execSync: es } = require3("node:child_process");
|
|
600067
600397
|
const isWin2 = process.platform === "win32";
|
|
600068
600398
|
let npmBin = "";
|
|
600069
|
-
for (const candidate of isWin2 ? [
|
|
600070
|
-
if (
|
|
600399
|
+
for (const candidate of isWin2 ? [join123(nodeDir, "npm.cmd"), join123(nodeDir, "npm")] : [join123(nodeDir, "npm"), "/usr/local/bin/npm", "/usr/bin/npm"]) {
|
|
600400
|
+
if (existsSync107(candidate)) {
|
|
600071
600401
|
npmBin = candidate;
|
|
600072
600402
|
break;
|
|
600073
600403
|
}
|
|
600074
600404
|
}
|
|
600075
600405
|
if (!npmBin) npmBin = isWin2 ? "npm.cmd" : "npm";
|
|
600076
600406
|
const pkgSpec = `open-agents-ai@${targetVersion}`;
|
|
600077
|
-
const dir =
|
|
600407
|
+
const dir = join123(homedir43(), ".open-agents");
|
|
600078
600408
|
fs7.mkdirSync(dir, { recursive: true });
|
|
600079
600409
|
const logFd = fs7.openSync(logPath3, "w");
|
|
600080
600410
|
const npmPrefix = dirname36(nodeDir);
|
|
@@ -600084,13 +600414,13 @@ async function handleV1Update(req2, res, requestId) {
|
|
|
600084
600414
|
globalBinDir = es(`${npmBin} bin -g`, { encoding: "utf8", timeout: 5e3, stdio: "pipe" }).trim();
|
|
600085
600415
|
} else {
|
|
600086
600416
|
const npmCliCandidates = [
|
|
600087
|
-
|
|
600088
|
-
|
|
600417
|
+
join123(nodeDir, "..", "lib", "node_modules", "npm", "bin", "npm-cli.js"),
|
|
600418
|
+
join123(npmBin, "..", "..", "lib", "node_modules", "npm", "bin", "npm-cli.js")
|
|
600089
600419
|
];
|
|
600090
600420
|
let npmCli = "";
|
|
600091
600421
|
for (const c9 of npmCliCandidates) {
|
|
600092
600422
|
try {
|
|
600093
|
-
if (
|
|
600423
|
+
if (existsSync107(c9)) {
|
|
600094
600424
|
npmCli = c9;
|
|
600095
600425
|
break;
|
|
600096
600426
|
}
|
|
@@ -600114,7 +600444,7 @@ async function handleV1Update(req2, res, requestId) {
|
|
|
600114
600444
|
cleanEnv.PATH = pathParts.join(":");
|
|
600115
600445
|
let child;
|
|
600116
600446
|
if (isWin2) {
|
|
600117
|
-
child =
|
|
600447
|
+
child = spawn26(npmBin, ["install", "-g", pkgSpec, "--no-audit", "--no-fund", "--no-progress"], {
|
|
600118
600448
|
detached: true,
|
|
600119
600449
|
stdio: ["ignore", logFd, logFd],
|
|
600120
600450
|
windowsHide: true,
|
|
@@ -600122,13 +600452,13 @@ async function handleV1Update(req2, res, requestId) {
|
|
|
600122
600452
|
});
|
|
600123
600453
|
} else {
|
|
600124
600454
|
const npmCliCandidates = [
|
|
600125
|
-
|
|
600126
|
-
|
|
600455
|
+
join123(nodeDir, "..", "lib", "node_modules", "npm", "bin", "npm-cli.js"),
|
|
600456
|
+
join123(npmBin, "..", "..", "lib", "node_modules", "npm", "bin", "npm-cli.js")
|
|
600127
600457
|
];
|
|
600128
600458
|
let npmCli = "";
|
|
600129
600459
|
for (const c9 of npmCliCandidates) {
|
|
600130
600460
|
try {
|
|
600131
|
-
if (
|
|
600461
|
+
if (existsSync107(c9)) {
|
|
600132
600462
|
npmCli = c9;
|
|
600133
600463
|
break;
|
|
600134
600464
|
}
|
|
@@ -600136,13 +600466,13 @@ async function handleV1Update(req2, res, requestId) {
|
|
|
600136
600466
|
}
|
|
600137
600467
|
}
|
|
600138
600468
|
if (npmCli) {
|
|
600139
|
-
child =
|
|
600469
|
+
child = spawn26(nodeBin, [npmCli, "install", "-g", pkgSpec, "--no-audit", "--no-fund", "--no-progress"], {
|
|
600140
600470
|
detached: true,
|
|
600141
600471
|
stdio: ["ignore", logFd, logFd],
|
|
600142
600472
|
env: cleanEnv
|
|
600143
600473
|
});
|
|
600144
600474
|
} else {
|
|
600145
|
-
child =
|
|
600475
|
+
child = spawn26(npmBin, ["install", "-g", pkgSpec, "--no-audit", "--no-fund", "--no-progress"], {
|
|
600146
600476
|
detached: true,
|
|
600147
600477
|
stdio: ["ignore", logFd, logFd],
|
|
600148
600478
|
env: cleanEnv
|
|
@@ -600153,7 +600483,7 @@ async function handleV1Update(req2, res, requestId) {
|
|
|
600153
600483
|
const installPid = child.pid ?? 0;
|
|
600154
600484
|
if (installPid > 0 && !isWin2) {
|
|
600155
600485
|
try {
|
|
600156
|
-
const follower =
|
|
600486
|
+
const follower = spawn26("bash", ["-c", `while kill -0 ${installPid} 2>/dev/null; do sleep 1; done; echo "__EXIT_CODE=0" >> "${logPath3}"`], {
|
|
600157
600487
|
detached: true,
|
|
600158
600488
|
stdio: "ignore"
|
|
600159
600489
|
});
|
|
@@ -600166,8 +600496,8 @@ async function handleV1Update(req2, res, requestId) {
|
|
|
600166
600496
|
}
|
|
600167
600497
|
let oaAbs = "oa";
|
|
600168
600498
|
try {
|
|
600169
|
-
const
|
|
600170
|
-
if (
|
|
600499
|
+
const which2 = es("command -v oa 2>/dev/null || which oa 2>/dev/null", { encoding: "utf8", timeout: 2e3, stdio: "pipe", env: cleanEnv }).trim();
|
|
600500
|
+
if (which2) oaAbs = which2;
|
|
600171
600501
|
} catch {
|
|
600172
600502
|
}
|
|
600173
600503
|
const relaunchScript = [
|
|
@@ -600176,7 +600506,7 @@ async function handleV1Update(req2, res, requestId) {
|
|
|
600176
600506
|
hasSystemdUnit ? `systemctl --user restart open-agents-daemon.service >/dev/null 2>&1 || true` : `${JSON.stringify(oaAbs)} serve --quiet --daemon >/dev/null 2>&1 & disown`,
|
|
600177
600507
|
`kill -TERM ${process.pid} >/dev/null 2>&1 || true`
|
|
600178
600508
|
].join("; ");
|
|
600179
|
-
const relauncher =
|
|
600509
|
+
const relauncher = spawn26("bash", ["-c", relaunchScript], {
|
|
600180
600510
|
detached: true,
|
|
600181
600511
|
stdio: "ignore",
|
|
600182
600512
|
env: cleanEnv
|
|
@@ -600225,7 +600555,7 @@ function handleV1UpdateStatus(res) {
|
|
|
600225
600555
|
let logTail = "";
|
|
600226
600556
|
let exitCode = null;
|
|
600227
600557
|
try {
|
|
600228
|
-
if (
|
|
600558
|
+
if (existsSync107(logPath3)) {
|
|
600229
600559
|
const raw = readFileSync86(logPath3, "utf-8");
|
|
600230
600560
|
const m2 = raw.match(/__EXIT_CODE=(\d+)/);
|
|
600231
600561
|
if (m2) exitCode = parseInt(m2[1], 10);
|
|
@@ -600322,8 +600652,8 @@ async function handleV1Run(req2, res) {
|
|
|
600322
600652
|
if (workingDir) {
|
|
600323
600653
|
cwd4 = resolve38(workingDir);
|
|
600324
600654
|
} else if (isolate) {
|
|
600325
|
-
const wsDir =
|
|
600326
|
-
|
|
600655
|
+
const wsDir = join123(dir, "..", "workspaces", id);
|
|
600656
|
+
mkdirSync64(wsDir, { recursive: true });
|
|
600327
600657
|
cwd4 = wsDir;
|
|
600328
600658
|
} else {
|
|
600329
600659
|
cwd4 = resolve38(process.cwd());
|
|
@@ -600398,7 +600728,7 @@ async function handleV1Run(req2, res) {
|
|
|
600398
600728
|
});
|
|
600399
600729
|
job.sandbox = "container";
|
|
600400
600730
|
} else {
|
|
600401
|
-
child =
|
|
600731
|
+
child = spawn26(process.execPath, [oaBin, ...args], {
|
|
600402
600732
|
cwd: cwd4,
|
|
600403
600733
|
env: runEnv,
|
|
600404
600734
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -600509,7 +600839,7 @@ async function handleV1Run(req2, res) {
|
|
|
600509
600839
|
let output = "";
|
|
600510
600840
|
let tailBytes = 0;
|
|
600511
600841
|
const TAIL_BUDGET = 1048576;
|
|
600512
|
-
const outputWriter = new DiskTaskOutput(
|
|
600842
|
+
const outputWriter = new DiskTaskOutput(join123(dir, `${id}.output`));
|
|
600513
600843
|
job.outputFile = outputWriter.path;
|
|
600514
600844
|
atomicJobWrite(dir, id, job);
|
|
600515
600845
|
child.stdout?.on("data", (chunk) => {
|
|
@@ -600908,7 +601238,7 @@ async function handlePostCommand(res, cmd) {
|
|
|
600908
601238
|
return;
|
|
600909
601239
|
}
|
|
600910
601240
|
try {
|
|
600911
|
-
const child =
|
|
601241
|
+
const child = spawn26("node", [oaBin, "run", `/${cmd}`, "--json"], {
|
|
600912
601242
|
env: { ...process.env, __OPEN_AGENTS_NO_AUTO_RUN: "" },
|
|
600913
601243
|
stdio: ["ignore", "pipe", "pipe"],
|
|
600914
601244
|
timeout: 3e4
|
|
@@ -601425,11 +601755,11 @@ async function handleRequest(req2, res, ollamaUrl, verbose) {
|
|
|
601425
601755
|
jsonResponse(res, 400, { error: "audio_too_small", message: "Reference audio must be at least ~4 KB" });
|
|
601426
601756
|
return;
|
|
601427
601757
|
}
|
|
601428
|
-
const { tmpdir:
|
|
601429
|
-
const { writeFileSync:
|
|
601758
|
+
const { tmpdir: tmpdir23 } = await import("node:os");
|
|
601759
|
+
const { writeFileSync: writeFileSync60, unlinkSync: unlinkSync25 } = await import("node:fs");
|
|
601430
601760
|
const { join: pjoin } = await import("node:path");
|
|
601431
|
-
const tmpPath = pjoin(
|
|
601432
|
-
|
|
601761
|
+
const tmpPath = pjoin(tmpdir23(), `oa-clone-upload-${Date.now()}-${safeName}`);
|
|
601762
|
+
writeFileSync60(tmpPath, buf);
|
|
601433
601763
|
try {
|
|
601434
601764
|
const ve = getVoiceEngine();
|
|
601435
601765
|
const msg = await ve.setCloneVoice(tmpPath);
|
|
@@ -601979,7 +602309,7 @@ data: ${JSON.stringify(data)}
|
|
|
601979
602309
|
}
|
|
601980
602310
|
for (const f2 of seenFiles) {
|
|
601981
602311
|
try {
|
|
601982
|
-
|
|
602312
|
+
writeFileSync56(f2, JSON.stringify({ tasks: [] }, null, 2));
|
|
601983
602313
|
deleted++;
|
|
601984
602314
|
} catch {
|
|
601985
602315
|
}
|
|
@@ -602280,7 +602610,7 @@ ${historyLines}
|
|
|
602280
602610
|
}
|
|
602281
602611
|
runEnv["OLLAMA_HOST"] = currentCfg.backendUrl || process.env["OLLAMA_HOST"] || "http://127.0.0.1:11434";
|
|
602282
602612
|
if (currentCfg.apiKey) runEnv["OA_API_KEY_INHERIT"] = currentCfg.apiKey;
|
|
602283
|
-
const child =
|
|
602613
|
+
const child = spawn26(process.execPath, [oaBin, ...args], {
|
|
602284
602614
|
cwd: cwdPath,
|
|
602285
602615
|
env: runEnv,
|
|
602286
602616
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -603083,7 +603413,7 @@ ${steering}`;
|
|
|
603083
603413
|
function getScheduleRoots() {
|
|
603084
603414
|
const rootsEnv = process.env["OA_SCHEDULE_ROOTS"] || "";
|
|
603085
603415
|
const roots = rootsEnv.split(rootsEnv.includes(";") ? ";" : ":").filter(Boolean);
|
|
603086
|
-
const defaults3 = [process.cwd(),
|
|
603416
|
+
const defaults3 = [process.cwd(), join123(homedir43(), "Documents")];
|
|
603087
603417
|
const set = /* @__PURE__ */ new Set([...defaults3, ...roots]);
|
|
603088
603418
|
return [...set];
|
|
603089
603419
|
}
|
|
@@ -603095,8 +603425,8 @@ function listScheduledTasks() {
|
|
|
603095
603425
|
for (const root of roots) {
|
|
603096
603426
|
try {
|
|
603097
603427
|
walk(root, 0, (dir) => {
|
|
603098
|
-
if (dir.endsWith(`${
|
|
603099
|
-
const file =
|
|
603428
|
+
if (dir.endsWith(`${join123(".oa", "scheduled")}`) || dir.includes(`${join123(".oa", "scheduled")}`)) {
|
|
603429
|
+
const file = join123(dir, "tasks.json");
|
|
603100
603430
|
try {
|
|
603101
603431
|
const raw = readFileSync86(file, "utf-8");
|
|
603102
603432
|
const json = JSON.parse(raw);
|
|
@@ -603163,7 +603493,7 @@ function walk(dir, depth, onDir, maxDepth) {
|
|
|
603163
603493
|
if (e2.name === "node_modules" || e2.name.startsWith(".")) {
|
|
603164
603494
|
if (e2.name !== ".oa") continue;
|
|
603165
603495
|
}
|
|
603166
|
-
const child =
|
|
603496
|
+
const child = join123(dir, e2.name);
|
|
603167
603497
|
walk(child, depth + 1, onDir, maxDepth);
|
|
603168
603498
|
}
|
|
603169
603499
|
}
|
|
@@ -603179,11 +603509,11 @@ function setScheduledEnabled(id, enabled2) {
|
|
|
603179
603509
|
arr[target.index].enabled = enabled2;
|
|
603180
603510
|
if (Array.isArray(json?.tasks)) {
|
|
603181
603511
|
json.tasks = arr;
|
|
603182
|
-
|
|
603512
|
+
writeFileSync56(target.file, JSON.stringify(json, null, 2));
|
|
603183
603513
|
} else if (Array.isArray(json)) {
|
|
603184
|
-
|
|
603514
|
+
writeFileSync56(target.file, JSON.stringify(arr, null, 2));
|
|
603185
603515
|
} else {
|
|
603186
|
-
|
|
603516
|
+
writeFileSync56(target.file, JSON.stringify({ tasks: arr }, null, 2));
|
|
603187
603517
|
}
|
|
603188
603518
|
if (!enabled2) {
|
|
603189
603519
|
try {
|
|
@@ -603213,11 +603543,11 @@ function deleteScheduledById(id) {
|
|
|
603213
603543
|
arr.splice(target.index, 1);
|
|
603214
603544
|
if (Array.isArray(json?.tasks)) {
|
|
603215
603545
|
json.tasks = arr;
|
|
603216
|
-
|
|
603546
|
+
writeFileSync56(target.file, JSON.stringify(json, null, 2));
|
|
603217
603547
|
} else if (Array.isArray(json)) {
|
|
603218
|
-
|
|
603548
|
+
writeFileSync56(target.file, JSON.stringify(arr, null, 2));
|
|
603219
603549
|
} else {
|
|
603220
|
-
|
|
603550
|
+
writeFileSync56(target.file, JSON.stringify({ tasks: arr }, null, 2));
|
|
603221
603551
|
}
|
|
603222
603552
|
const candidates = [];
|
|
603223
603553
|
if (id) candidates.push(id);
|
|
@@ -603470,7 +603800,7 @@ function reconcileScheduledTasks(apply) {
|
|
|
603470
603800
|
const errors = [];
|
|
603471
603801
|
for (const f2 of found) {
|
|
603472
603802
|
const wdir = f2.workingDir || process.cwd();
|
|
603473
|
-
const file =
|
|
603803
|
+
const file = join123(wdir, ".oa", "scheduled", "tasks.json");
|
|
603474
603804
|
try {
|
|
603475
603805
|
let json = { tasks: [] };
|
|
603476
603806
|
try {
|
|
@@ -603485,9 +603815,9 @@ function reconcileScheduledTasks(apply) {
|
|
|
603485
603815
|
const entry = { task: f2.task || `legacy ${f2.id}`, schedule: f2.cron, enabled: true };
|
|
603486
603816
|
arr.push(entry);
|
|
603487
603817
|
const toWrite = Array.isArray(json?.tasks) ? { ...json, tasks: arr } : Array.isArray(json) ? arr : { tasks: arr };
|
|
603488
|
-
|
|
603489
|
-
|
|
603490
|
-
|
|
603818
|
+
mkdirSync64(join123(wdir, ".oa", "scheduled"), { recursive: true });
|
|
603819
|
+
mkdirSync64(join123(wdir, ".oa", "scheduled", "logs"), { recursive: true });
|
|
603820
|
+
writeFileSync56(file, JSON.stringify(toWrite, null, 2));
|
|
603491
603821
|
adopted.push({ file, index: arr.length - 1 });
|
|
603492
603822
|
}
|
|
603493
603823
|
} else {
|
|
@@ -603531,32 +603861,32 @@ function writeCrontabLines(lines) {
|
|
|
603531
603861
|
}
|
|
603532
603862
|
function canonicalCronLine(rec) {
|
|
603533
603863
|
const oaBin = findOaBinary4();
|
|
603534
|
-
const logDir =
|
|
603535
|
-
const logFile =
|
|
603536
|
-
const storeFile =
|
|
603864
|
+
const logDir = join123(rec.workingDir, ".oa", "scheduled", "logs");
|
|
603865
|
+
const logFile = join123(logDir, `${rec.id}.log`);
|
|
603866
|
+
const storeFile = join123(rec.workingDir, ".oa", "scheduled", "tasks.json");
|
|
603537
603867
|
const taskEsc = rec.task.replace(/'/g, "'\\''");
|
|
603538
|
-
const lockDir =
|
|
603539
|
-
const lockPath =
|
|
603868
|
+
const lockDir = join123(rec.workingDir, ".oa", "run");
|
|
603869
|
+
const lockPath = join123(lockDir, `${rec.id}.lock`);
|
|
603540
603870
|
const wrapper = [
|
|
603541
603871
|
`cd ${JSON.stringify(rec.workingDir)}`,
|
|
603542
603872
|
`mkdir -p ${JSON.stringify(logDir)}`,
|
|
603543
603873
|
`mkdir -p ${JSON.stringify(lockDir)}`,
|
|
603544
603874
|
`if mkdir ${JSON.stringify(lockPath)} 2>/dev/null; then`,
|
|
603545
|
-
` echo $$ > ${JSON.stringify(
|
|
603875
|
+
` echo $$ > ${JSON.stringify(join123(lockPath, "pid"))}`,
|
|
603546
603876
|
` trap 'rm -rf ${lockPath}' EXIT`,
|
|
603547
603877
|
`else`,
|
|
603548
|
-
` if [ -f ${JSON.stringify(
|
|
603549
|
-
` oldpid=$(cat ${JSON.stringify(
|
|
603878
|
+
` if [ -f ${JSON.stringify(join123(lockPath, "pid"))} ]; then`,
|
|
603879
|
+
` oldpid=$(cat ${JSON.stringify(join123(lockPath, "pid"))} 2>/dev/null || echo)`,
|
|
603550
603880
|
` if [ -n "$oldpid" ] && kill -0 "$oldpid" 2>/dev/null; then`,
|
|
603551
603881
|
` echo "[oa-scheduler] ${rec.id} already running as PID $oldpid; skipping" >> ${JSON.stringify(logFile)}`,
|
|
603552
603882
|
` exit 0`,
|
|
603553
603883
|
` else`,
|
|
603554
603884
|
` rm -rf ${JSON.stringify(lockPath)} 2>/dev/null || true`,
|
|
603555
|
-
` mkdir -p ${JSON.stringify(lockPath)} && echo $$ > ${JSON.stringify(
|
|
603885
|
+
` mkdir -p ${JSON.stringify(lockPath)} && echo $$ > ${JSON.stringify(join123(lockPath, "pid"))} && trap 'rm -rf ${lockPath}' EXIT`,
|
|
603556
603886
|
` fi`,
|
|
603557
603887
|
` else`,
|
|
603558
603888
|
` rm -rf ${JSON.stringify(lockPath)} 2>/dev/null || true`,
|
|
603559
|
-
` mkdir -p ${JSON.stringify(lockPath)} && echo $$ > ${JSON.stringify(
|
|
603889
|
+
` mkdir -p ${JSON.stringify(lockPath)} && echo $$ > ${JSON.stringify(join123(lockPath, "pid"))} && trap 'rm -rf ${lockPath}' EXIT`,
|
|
603560
603890
|
` fi`,
|
|
603561
603891
|
`fi`,
|
|
603562
603892
|
`${oaBin} '${taskEsc}' >> ${JSON.stringify(logFile)} 2>&1; _oa_exit=$?`,
|
|
@@ -603588,9 +603918,9 @@ function fixupOrMigrateScheduled(mode, dryRun) {
|
|
|
603588
603918
|
try {
|
|
603589
603919
|
if (!f2.workingDir || !f2.task) continue;
|
|
603590
603920
|
const unitBase = `oa-${f2.id}`;
|
|
603591
|
-
const unitDir =
|
|
603592
|
-
const svc =
|
|
603593
|
-
const tim =
|
|
603921
|
+
const unitDir = join123(homedir43(), ".config", "systemd", "user");
|
|
603922
|
+
const svc = join123(unitDir, `${unitBase}.service`);
|
|
603923
|
+
const tim = join123(unitDir, `${unitBase}.timer`);
|
|
603594
603924
|
const oaBin = findOaBinary4();
|
|
603595
603925
|
const rec = { id: f2.id, cron: f2.cron, workingDir: f2.workingDir, task: f2.task };
|
|
603596
603926
|
const cmd = canonicalCronLine(rec).split(" ").slice(5).join(" ");
|
|
@@ -603620,9 +603950,9 @@ Persistent=true
|
|
|
603620
603950
|
WantedBy=timers.target
|
|
603621
603951
|
`;
|
|
603622
603952
|
if (!dryRun) {
|
|
603623
|
-
|
|
603624
|
-
|
|
603625
|
-
|
|
603953
|
+
mkdirSync64(unitDir, { recursive: true });
|
|
603954
|
+
writeFileSync56(svc, svcText);
|
|
603955
|
+
writeFileSync56(tim, timText);
|
|
603626
603956
|
try {
|
|
603627
603957
|
const { execSync: es } = require3("node:child_process");
|
|
603628
603958
|
es("systemctl --user daemon-reload", { stdio: "pipe" });
|
|
@@ -603716,8 +604046,8 @@ function startApiServer(options2 = {}) {
|
|
|
603716
604046
|
const config = loadConfig();
|
|
603717
604047
|
const ollamaUrl = options2.ollamaUrl ?? config.backendUrl;
|
|
603718
604048
|
const cwd4 = process.cwd();
|
|
603719
|
-
initAuditLog(
|
|
603720
|
-
initUsageTracker(
|
|
604049
|
+
initAuditLog(join123(cwd4, ".oa"));
|
|
604050
|
+
initUsageTracker(join123(cwd4, ".oa"));
|
|
603721
604051
|
try {
|
|
603722
604052
|
const taskMgr = getSharedTaskManager();
|
|
603723
604053
|
taskMgr.setEventPublisher((type, data, opts) => {
|
|
@@ -603759,7 +604089,7 @@ function startApiServer(options2 = {}) {
|
|
|
603759
604089
|
try {
|
|
603760
604090
|
const dir = todoDir();
|
|
603761
604091
|
try {
|
|
603762
|
-
|
|
604092
|
+
mkdirSync64(dir, { recursive: true });
|
|
603763
604093
|
} catch {
|
|
603764
604094
|
}
|
|
603765
604095
|
const cache8 = /* @__PURE__ */ new Map();
|
|
@@ -603768,7 +604098,7 @@ function startApiServer(options2 = {}) {
|
|
|
603768
604098
|
if (!f2.endsWith(".json") || f2.includes(".tmp.")) continue;
|
|
603769
604099
|
const sid = f2.replace(/\.json$/, "");
|
|
603770
604100
|
try {
|
|
603771
|
-
const items = JSON.parse(readFileSync86(
|
|
604101
|
+
const items = JSON.parse(readFileSync86(join123(dir, f2), "utf-8"));
|
|
603772
604102
|
if (Array.isArray(items)) {
|
|
603773
604103
|
cache8.set(sid, new Map(items.map((t2) => [t2.id, t2])));
|
|
603774
604104
|
}
|
|
@@ -603780,10 +604110,10 @@ function startApiServer(options2 = {}) {
|
|
|
603780
604110
|
const watcher = fsWatch3(dir, (_evt, fname) => {
|
|
603781
604111
|
if (!fname || !fname.endsWith(".json") || fname.includes(".tmp.")) return;
|
|
603782
604112
|
const sid = fname.replace(/\.json$/, "");
|
|
603783
|
-
const fp =
|
|
604113
|
+
const fp = join123(dir, fname);
|
|
603784
604114
|
let next = [];
|
|
603785
604115
|
try {
|
|
603786
|
-
if (!
|
|
604116
|
+
if (!existsSync107(fp)) {
|
|
603787
604117
|
const old = cache8.get(sid);
|
|
603788
604118
|
if (old) {
|
|
603789
604119
|
for (const t2 of old.values()) {
|
|
@@ -603835,13 +604165,13 @@ function startApiServer(options2 = {}) {
|
|
|
603835
604165
|
const retentionDays = parseInt(process.env["OA_JOB_RETENTION_DAYS"] ?? "30", 10);
|
|
603836
604166
|
if (retentionDays > 0) {
|
|
603837
604167
|
try {
|
|
603838
|
-
const jobsDir3 =
|
|
603839
|
-
if (
|
|
604168
|
+
const jobsDir3 = join123(cwd4, ".oa", "jobs");
|
|
604169
|
+
if (existsSync107(jobsDir3)) {
|
|
603840
604170
|
const cutoff = Date.now() - retentionDays * 864e5;
|
|
603841
604171
|
for (const f2 of readdirSync36(jobsDir3)) {
|
|
603842
604172
|
if (!f2.endsWith(".json")) continue;
|
|
603843
604173
|
try {
|
|
603844
|
-
const jobPath =
|
|
604174
|
+
const jobPath = join123(jobsDir3, f2);
|
|
603845
604175
|
const job = JSON.parse(readFileSync86(jobPath, "utf-8"));
|
|
603846
604176
|
const jobTime = new Date(job.startedAt ?? job.completedAt ?? 0).getTime();
|
|
603847
604177
|
if (jobTime > 0 && jobTime < cutoff && job.status !== "running") {
|
|
@@ -603874,8 +604204,8 @@ function startApiServer(options2 = {}) {
|
|
|
603874
604204
|
}
|
|
603875
604205
|
let runtimeAccessMode = resolveAccessMode(process.env["OA_ACCESS"], host);
|
|
603876
604206
|
try {
|
|
603877
|
-
const accessFile =
|
|
603878
|
-
if (
|
|
604207
|
+
const accessFile = join123(homedir43(), ".open-agents", "access");
|
|
604208
|
+
if (existsSync107(accessFile)) {
|
|
603879
604209
|
const persisted = readFileSync86(accessFile, "utf8").trim();
|
|
603880
604210
|
const resolved = resolveAccessMode(persisted, host);
|
|
603881
604211
|
if (resolved) runtimeAccessMode = resolved;
|
|
@@ -603929,9 +604259,9 @@ function startApiServer(options2 = {}) {
|
|
|
603929
604259
|
const previous = runtimeAccessMode;
|
|
603930
604260
|
runtimeAccessMode = requested;
|
|
603931
604261
|
try {
|
|
603932
|
-
const dir =
|
|
603933
|
-
|
|
603934
|
-
|
|
604262
|
+
const dir = join123(homedir43(), ".open-agents");
|
|
604263
|
+
mkdirSync64(dir, { recursive: true });
|
|
604264
|
+
writeFileSync56(join123(dir, "access"), `${runtimeAccessMode}
|
|
603935
604265
|
`, "utf8");
|
|
603936
604266
|
} catch {
|
|
603937
604267
|
}
|
|
@@ -604144,9 +604474,9 @@ function startApiServer(options2 = {}) {
|
|
|
604144
604474
|
try {
|
|
604145
604475
|
const { startEmbeddingWorkers: startEmbeddingWorkers2 } = await Promise.resolve().then(() => (init_embedding_workers(), embedding_workers_exports));
|
|
604146
604476
|
const { ensureEmbedDeps: ensureEmbedDeps2, runEmbedImage: runEmbedImage2, runEmbedAudio: runEmbedAudio2 } = await Promise.resolve().then(() => (init_py_embed(), py_embed_exports));
|
|
604147
|
-
const dbBase =
|
|
604148
|
-
const epStore = new mem.EpisodeStore(
|
|
604149
|
-
const kg = new mem.TemporalGraph(
|
|
604477
|
+
const dbBase = join123(cwd4, ".oa");
|
|
604478
|
+
const epStore = new mem.EpisodeStore(join123(dbBase, "memory.db"));
|
|
604479
|
+
const kg = new mem.TemporalGraph(join123(dbBase, "kg.db"));
|
|
604150
604480
|
try {
|
|
604151
604481
|
ensureEmbedDeps2();
|
|
604152
604482
|
} catch {
|
|
@@ -604224,7 +604554,7 @@ function startApiServer(options2 = {}) {
|
|
|
604224
604554
|
log22(` Primary: ${config.backendUrl} (${config.backendType || "ollama"})
|
|
604225
604555
|
`);
|
|
604226
604556
|
try {
|
|
604227
|
-
const { writeFileSync:
|
|
604557
|
+
const { writeFileSync: writeFileSync60, mkdirSync: mkdirSync68, existsSync: _exists, readFileSync: _rfs } = require3("node:fs");
|
|
604228
604558
|
const { join: _join } = require3("node:path");
|
|
604229
604559
|
const { homedir: _homedir } = require3("node:os");
|
|
604230
604560
|
const apiHint = JSON.stringify({
|
|
@@ -604254,8 +604584,8 @@ function startApiServer(options2 = {}) {
|
|
|
604254
604584
|
let written = 0;
|
|
604255
604585
|
for (const dir of dirSet) {
|
|
604256
604586
|
try {
|
|
604257
|
-
if (!_exists(dir))
|
|
604258
|
-
|
|
604587
|
+
if (!_exists(dir)) mkdirSync68(dir, { recursive: true });
|
|
604588
|
+
writeFileSync60(_join(dir, "api-port.json"), apiHint);
|
|
604259
604589
|
written++;
|
|
604260
604590
|
} catch {
|
|
604261
604591
|
}
|
|
@@ -604266,6 +604596,80 @@ function startApiServer(options2 = {}) {
|
|
|
604266
604596
|
log22(` WARN: api-port hint write failed: ${e2.message}
|
|
604267
604597
|
`);
|
|
604268
604598
|
}
|
|
604599
|
+
if (process.env["OA_AUTO_NEXUS"] !== "0") {
|
|
604600
|
+
(async () => {
|
|
604601
|
+
try {
|
|
604602
|
+
const { join: _j } = require3("node:path");
|
|
604603
|
+
const { homedir: _hd } = require3("node:os");
|
|
604604
|
+
const { existsSync: _ex, readFileSync: _rf, statSync: _st } = require3("node:fs");
|
|
604605
|
+
const { execSync: _ex2 } = require3("node:child_process");
|
|
604606
|
+
let chosenNexusDir = null;
|
|
604607
|
+
if (process.env["OA_NEXUS_DIR"]) chosenNexusDir = process.env["OA_NEXUS_DIR"];
|
|
604608
|
+
if (!chosenNexusDir) {
|
|
604609
|
+
try {
|
|
604610
|
+
const regPath = _j(_hd(), ".open-agents", "nexus-registry.json");
|
|
604611
|
+
if (_ex(regPath)) {
|
|
604612
|
+
const reg = JSON.parse(_rf(regPath, "utf-8"));
|
|
604613
|
+
for (const e2 of reg?.dirs || []) {
|
|
604614
|
+
const d2 = typeof e2 === "string" ? e2 : e2?.dir;
|
|
604615
|
+
if (typeof d2 === "string" && _ex(d2)) {
|
|
604616
|
+
chosenNexusDir = d2;
|
|
604617
|
+
break;
|
|
604618
|
+
}
|
|
604619
|
+
}
|
|
604620
|
+
}
|
|
604621
|
+
} catch {
|
|
604622
|
+
}
|
|
604623
|
+
}
|
|
604624
|
+
if (!chosenNexusDir) {
|
|
604625
|
+
try {
|
|
604626
|
+
const cmd = `find "${_hd()}" -maxdepth 4 -path '*/.oa/nexus' -type d 2>/dev/null | head -10`;
|
|
604627
|
+
const out = _ex2(cmd, { encoding: "utf-8", timeout: 2e3 }).trim();
|
|
604628
|
+
for (const ln of out.split("\n").filter(Boolean)) {
|
|
604629
|
+
if (_ex(_j(ln, "status.json"))) {
|
|
604630
|
+
chosenNexusDir = ln;
|
|
604631
|
+
break;
|
|
604632
|
+
}
|
|
604633
|
+
}
|
|
604634
|
+
if (!chosenNexusDir && out) chosenNexusDir = out.split("\n")[0]?.trim() || null;
|
|
604635
|
+
} catch {
|
|
604636
|
+
}
|
|
604637
|
+
}
|
|
604638
|
+
const finalNexusDir = chosenNexusDir ?? _j(_hd(), ".oa", "nexus");
|
|
604639
|
+
chosenNexusDir = finalNexusDir;
|
|
604640
|
+
const repoRoot = finalNexusDir.replace(/[\\/]\.oa[\\/]nexus$/, "");
|
|
604641
|
+
log22(` Nexus auto-recover: target ${finalNexusDir}
|
|
604642
|
+
`);
|
|
604643
|
+
const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist5(), dist_exports));
|
|
604644
|
+
const tool = new NexusTool2(repoRoot);
|
|
604645
|
+
const result = await tool.execute({ action: "connect" });
|
|
604646
|
+
const status = result?.success ? "ok" : "fail";
|
|
604647
|
+
const detail = result?.output || result?.error || "";
|
|
604648
|
+
log22(` Nexus auto-recover: ${status}${detail ? " — " + String(detail).split("\n")[0].slice(0, 120) : ""}
|
|
604649
|
+
`);
|
|
604650
|
+
if (status === "ok") {
|
|
604651
|
+
try {
|
|
604652
|
+
const { writeFileSync: _wfs2, mkdirSync: _mks, existsSync: _exf } = require3("node:fs");
|
|
604653
|
+
const apiHint2 = JSON.stringify({
|
|
604654
|
+
port,
|
|
604655
|
+
host: host === "0.0.0.0" ? "127.0.0.1" : host,
|
|
604656
|
+
scheme: proto,
|
|
604657
|
+
pid: process.pid,
|
|
604658
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
604659
|
+
version: version4
|
|
604660
|
+
}, null, 2);
|
|
604661
|
+
const dirOut = chosenNexusDir;
|
|
604662
|
+
if (!_exf(dirOut)) _mks(dirOut, { recursive: true });
|
|
604663
|
+
_wfs2(_j(dirOut, "api-port.json"), apiHint2);
|
|
604664
|
+
} catch {
|
|
604665
|
+
}
|
|
604666
|
+
}
|
|
604667
|
+
} catch (e2) {
|
|
604668
|
+
log22(` Nexus auto-recover: skipped (${e2.message.slice(0, 80)})
|
|
604669
|
+
`);
|
|
604670
|
+
}
|
|
604671
|
+
})();
|
|
604672
|
+
}
|
|
604269
604673
|
try {
|
|
604270
604674
|
adoptHandoffRuns();
|
|
604271
604675
|
} catch (e2) {
|
|
@@ -604499,10 +604903,10 @@ async function handleMemoryIngest(req2, res, ollamaUrl) {
|
|
|
604499
604903
|
const labels = Array.isArray(b.labels) ? b.labels : [];
|
|
604500
604904
|
const mediaPath = typeof b.media_path === "string" ? b.media_path : void 0;
|
|
604501
604905
|
const cwd4 = process.cwd();
|
|
604502
|
-
const dbBase =
|
|
604906
|
+
const dbBase = join123(cwd4, ".oa");
|
|
604503
604907
|
const { EpisodeStore: EpisodeStore3, TemporalGraph: TemporalGraph3 } = await Promise.resolve().then(() => (init_dist7(), dist_exports2));
|
|
604504
|
-
const epStore = new EpisodeStore3(
|
|
604505
|
-
const kg = new TemporalGraph3(
|
|
604908
|
+
const epStore = new EpisodeStore3(join123(dbBase, "memory.db"));
|
|
604909
|
+
const kg = new TemporalGraph3(join123(dbBase, "kg.db"));
|
|
604506
604910
|
const meta = {};
|
|
604507
604911
|
if (mediaPath) meta.media_path = mediaPath;
|
|
604508
604912
|
const epId = epStore.insert({ modality, content: content || (mediaPath || ""), metadata: meta, toolName: "memory_ingest" });
|
|
@@ -604569,7 +604973,7 @@ async function handleEntitiesList(req2, res) {
|
|
|
604569
604973
|
const type = url.searchParams.get("type") || "person";
|
|
604570
604974
|
const limit = Math.max(1, Math.min(1e3, parseInt(url.searchParams.get("limit") || "100", 10)));
|
|
604571
604975
|
const { TemporalGraph: TemporalGraph3 } = await Promise.resolve().then(() => (init_dist7(), dist_exports2));
|
|
604572
|
-
const kg = new TemporalGraph3(
|
|
604976
|
+
const kg = new TemporalGraph3(join123(process.cwd(), ".oa", "kg.db"));
|
|
604573
604977
|
const nodes = kg.nodesByType(type, limit).map((n2) => ({ id: n2.id, text: n2.text, mentionCount: n2.mentionCount, firstSeen: n2.firstSeen, lastSeen: n2.lastSeen }));
|
|
604574
604978
|
jsonResponse(res, 200, { object: "list", data: nodes });
|
|
604575
604979
|
} catch (err) {
|
|
@@ -604591,7 +604995,7 @@ async function handleMemorySearch2(req2, res) {
|
|
|
604591
604995
|
const wLex = typeof b.lexical_weight === "number" ? b.lexical_weight : 1;
|
|
604592
604996
|
const wEmb = typeof b.embedding_weight === "number" ? b.embedding_weight : 1;
|
|
604593
604997
|
const { EpisodeStore: EpisodeStore3 } = await Promise.resolve().then(() => (init_dist7(), dist_exports2));
|
|
604594
|
-
const epStore = new EpisodeStore3(
|
|
604998
|
+
const epStore = new EpisodeStore3(join123(process.cwd(), ".oa", "memory.db"));
|
|
604595
604999
|
const results = epStore.search({ query, modality, limit }, { queryEmbedding: qEmb, lexicalWeight: wLex, embeddingWeight: wEmb });
|
|
604596
605000
|
jsonResponse(res, 200, { object: "list", data: results.map((e2) => ({ id: e2.id, modality: e2.modality, content: e2.content, timestamp: e2.timestamp })) });
|
|
604597
605001
|
} catch (err) {
|
|
@@ -604708,11 +605112,11 @@ var init_serve = __esm({
|
|
|
604708
605112
|
|
|
604709
605113
|
// packages/cli/src/tui/interactive.ts
|
|
604710
605114
|
import { cwd } from "node:process";
|
|
604711
|
-
import { resolve as resolve39, join as
|
|
605115
|
+
import { resolve as resolve39, join as join124, dirname as dirname37, extname as extname12 } from "node:path";
|
|
604712
605116
|
import { createRequire as createRequire6 } from "node:module";
|
|
604713
605117
|
import { fileURLToPath as fileURLToPath18 } from "node:url";
|
|
604714
|
-
import { readFileSync as readFileSync87, writeFileSync as
|
|
604715
|
-
import { existsSync as
|
|
605118
|
+
import { readFileSync as readFileSync87, writeFileSync as writeFileSync57, appendFileSync as appendFileSync8, rmSync as rmSync5, readdirSync as readdirSync37, mkdirSync as mkdirSync65 } from "node:fs";
|
|
605119
|
+
import { existsSync as existsSync108 } from "node:fs";
|
|
604716
605120
|
import { execSync as execSync58 } from "node:child_process";
|
|
604717
605121
|
import { homedir as homedir44 } from "node:os";
|
|
604718
605122
|
function formatTimeAgo2(date) {
|
|
@@ -604730,12 +605134,12 @@ function getVersion4() {
|
|
|
604730
605134
|
const require4 = createRequire6(import.meta.url);
|
|
604731
605135
|
const thisDir = dirname37(fileURLToPath18(import.meta.url));
|
|
604732
605136
|
const candidates = [
|
|
604733
|
-
|
|
604734
|
-
|
|
604735
|
-
|
|
605137
|
+
join124(thisDir, "..", "package.json"),
|
|
605138
|
+
join124(thisDir, "..", "..", "package.json"),
|
|
605139
|
+
join124(thisDir, "..", "..", "..", "package.json")
|
|
604736
605140
|
];
|
|
604737
605141
|
for (const pkgPath of candidates) {
|
|
604738
|
-
if (
|
|
605142
|
+
if (existsSync108(pkgPath)) {
|
|
604739
605143
|
const pkg = require4(pkgPath);
|
|
604740
605144
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli" || pkg.name === "@open-agents/monorepo") {
|
|
604741
605145
|
return pkg.version ?? "0.0.0";
|
|
@@ -605541,14 +605945,14 @@ Meta-critique: quality ${meta.quality}/5, thorough: ${meta.thorough}`;
|
|
|
605541
605945
|
function gatherMemorySnippets(root) {
|
|
605542
605946
|
const snippets = [];
|
|
605543
605947
|
const dirs = [
|
|
605544
|
-
|
|
605545
|
-
|
|
605948
|
+
join124(root, ".oa", "memory"),
|
|
605949
|
+
join124(root, ".open-agents", "memory")
|
|
605546
605950
|
];
|
|
605547
605951
|
for (const dir of dirs) {
|
|
605548
|
-
if (!
|
|
605952
|
+
if (!existsSync108(dir)) continue;
|
|
605549
605953
|
try {
|
|
605550
605954
|
for (const f2 of readdirSync37(dir).filter((f3) => f3.endsWith(".json"))) {
|
|
605551
|
-
const data = JSON.parse(readFileSync87(
|
|
605955
|
+
const data = JSON.parse(readFileSync87(join124(dir, f2), "utf-8"));
|
|
605552
605956
|
for (const val of Object.values(data)) {
|
|
605553
605957
|
const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
605554
605958
|
if (v.length > 10) snippets.push(v);
|
|
@@ -605702,8 +606106,8 @@ ${metabolismMemories}
|
|
|
605702
606106
|
} catch {
|
|
605703
606107
|
}
|
|
605704
606108
|
try {
|
|
605705
|
-
const archeFile =
|
|
605706
|
-
if (
|
|
606109
|
+
const archeFile = join124(repoRoot, ".oa", "arche", "variants.json");
|
|
606110
|
+
if (existsSync108(archeFile)) {
|
|
605707
606111
|
const variants = JSON.parse(readFileSync87(archeFile, "utf8"));
|
|
605708
606112
|
if (variants.length > 0) {
|
|
605709
606113
|
let filtered = variants;
|
|
@@ -605876,8 +606280,8 @@ RULES:
|
|
|
605876
606280
|
const compactionThreshold = Number.isFinite(envOverride) && envOverride > 0 ? envOverride : modelTier === "small" ? 12e3 : modelTier === "medium" ? 24e3 : 4e4;
|
|
605877
606281
|
let identityInjection = "";
|
|
605878
606282
|
try {
|
|
605879
|
-
const ikStateFile =
|
|
605880
|
-
if (
|
|
606283
|
+
const ikStateFile = join124(repoRoot, ".oa", "identity", "self-state.json");
|
|
606284
|
+
if (existsSync108(ikStateFile)) {
|
|
605881
606285
|
const selfState = JSON.parse(readFileSync87(ikStateFile, "utf8"));
|
|
605882
606286
|
const lines = [
|
|
605883
606287
|
`[Identity State v${selfState.version}]`,
|
|
@@ -606740,13 +607144,13 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
606740
607144
|
});
|
|
606741
607145
|
}
|
|
606742
607146
|
try {
|
|
606743
|
-
const ikDir =
|
|
606744
|
-
const ikFile =
|
|
607147
|
+
const ikDir = join124(repoRoot, ".oa", "identity");
|
|
607148
|
+
const ikFile = join124(ikDir, "self-state.json");
|
|
606745
607149
|
let ikState;
|
|
606746
|
-
if (
|
|
607150
|
+
if (existsSync108(ikFile)) {
|
|
606747
607151
|
ikState = JSON.parse(readFileSync87(ikFile, "utf8"));
|
|
606748
607152
|
} else {
|
|
606749
|
-
|
|
607153
|
+
mkdirSync65(ikDir, { recursive: true });
|
|
606750
607154
|
const machineId = Date.now().toString(36) + Math.random().toString(36).slice(2, 8);
|
|
606751
607155
|
ikState = {
|
|
606752
607156
|
self_id: `oa-${machineId}`,
|
|
@@ -606802,7 +607206,7 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
606802
607206
|
}
|
|
606803
607207
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
606804
607208
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
606805
|
-
|
|
607209
|
+
writeFileSync57(ikFile, JSON.stringify(ikState, null, 2));
|
|
606806
607210
|
} catch (ikErr) {
|
|
606807
607211
|
try {
|
|
606808
607212
|
console.error("[IK-OBSERVE]", ikErr);
|
|
@@ -606821,8 +607225,8 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
606821
607225
|
} else {
|
|
606822
607226
|
renderTaskIncomplete(result.turns, result.toolCalls, result.durationMs, tokens);
|
|
606823
607227
|
try {
|
|
606824
|
-
const ikFile =
|
|
606825
|
-
if (
|
|
607228
|
+
const ikFile = join124(repoRoot, ".oa", "identity", "self-state.json");
|
|
607229
|
+
if (existsSync108(ikFile)) {
|
|
606826
607230
|
const ikState = JSON.parse(readFileSync87(ikFile, "utf8"));
|
|
606827
607231
|
if (!ikState.stats) ikState.stats = { queries_served: 0 };
|
|
606828
607232
|
ikState.stats.queries_served = (ikState.stats.queries_served || 0) + 1;
|
|
@@ -606834,7 +607238,7 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
606834
607238
|
if (ikState.version_history.length > 200) ikState.version_history = ikState.version_history.slice(-200);
|
|
606835
607239
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
606836
607240
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
606837
|
-
|
|
607241
|
+
writeFileSync57(ikFile, JSON.stringify(ikState, null, 2));
|
|
606838
607242
|
}
|
|
606839
607243
|
} catch {
|
|
606840
607244
|
}
|
|
@@ -607079,9 +607483,9 @@ async function startInteractive(config, repoPath) {
|
|
|
607079
607483
|
process.stdin.pause();
|
|
607080
607484
|
}
|
|
607081
607485
|
try {
|
|
607082
|
-
const oaDir =
|
|
607083
|
-
const nexusPidFile =
|
|
607084
|
-
if (
|
|
607486
|
+
const oaDir = join124(repoRoot, ".oa");
|
|
607487
|
+
const nexusPidFile = join124(oaDir, "nexus", "daemon.pid");
|
|
607488
|
+
if (existsSync108(nexusPidFile)) {
|
|
607085
607489
|
const pid = parseInt(readFileSync87(nexusPidFile, "utf8").trim(), 10);
|
|
607086
607490
|
if (pid > 0) {
|
|
607087
607491
|
try {
|
|
@@ -607742,7 +608146,7 @@ ${result.summary}`
|
|
|
607742
608146
|
let p2pGateway = null;
|
|
607743
608147
|
let peerMesh = null;
|
|
607744
608148
|
let inferenceRouter = null;
|
|
607745
|
-
const secretVault = new SecretVault(
|
|
608149
|
+
const secretVault = new SecretVault(join124(repoRoot, ".oa", "vault.enc"));
|
|
607746
608150
|
let adminSessionKey = null;
|
|
607747
608151
|
const callSubAgents = /* @__PURE__ */ new Map();
|
|
607748
608152
|
const streamRenderer = new StreamRenderer();
|
|
@@ -607973,12 +608377,12 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
607973
608377
|
const hits = allCompletions.filter((c9) => c9.toLowerCase().startsWith(lower));
|
|
607974
608378
|
return [hits, line];
|
|
607975
608379
|
}
|
|
607976
|
-
const HISTORY_DIR =
|
|
607977
|
-
const HISTORY_FILE =
|
|
608380
|
+
const HISTORY_DIR = join124(homedir44(), ".open-agents");
|
|
608381
|
+
const HISTORY_FILE = join124(HISTORY_DIR, "repl-history");
|
|
607978
608382
|
const MAX_HISTORY_LINES = 500;
|
|
607979
608383
|
let savedHistory = [];
|
|
607980
608384
|
try {
|
|
607981
|
-
if (
|
|
608385
|
+
if (existsSync108(HISTORY_FILE)) {
|
|
607982
608386
|
const raw = readFileSync87(HISTORY_FILE, "utf8").trim();
|
|
607983
608387
|
if (raw) savedHistory = raw.split("\n").reverse();
|
|
607984
608388
|
}
|
|
@@ -608126,12 +608530,12 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
608126
608530
|
function persistHistoryLine(line) {
|
|
608127
608531
|
if (!line.trim()) return;
|
|
608128
608532
|
try {
|
|
608129
|
-
|
|
608533
|
+
mkdirSync65(HISTORY_DIR, { recursive: true });
|
|
608130
608534
|
appendFileSync8(HISTORY_FILE, line + "\n", "utf8");
|
|
608131
608535
|
if (Math.random() < 0.02) {
|
|
608132
608536
|
const all2 = readFileSync87(HISTORY_FILE, "utf8").trim().split("\n");
|
|
608133
608537
|
if (all2.length > MAX_HISTORY_LINES) {
|
|
608134
|
-
|
|
608538
|
+
writeFileSync57(HISTORY_FILE, all2.slice(-MAX_HISTORY_LINES).join("\n") + "\n", "utf8");
|
|
608135
608539
|
}
|
|
608136
608540
|
}
|
|
608137
608541
|
} catch {
|
|
@@ -608316,10 +608720,10 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
608316
608720
|
const { unlinkSync: _rmStale } = await import("node:fs");
|
|
608317
608721
|
const { homedir: _hdir } = await import("node:os");
|
|
608318
608722
|
for (const dp of [
|
|
608319
|
-
|
|
608320
|
-
|
|
608723
|
+
join124(repoRoot, ".oa", "nexus", "nexus-daemon.mjs"),
|
|
608724
|
+
join124(_hdir(), ".open-agents", ".oa", "nexus", "nexus-daemon.mjs")
|
|
608321
608725
|
]) {
|
|
608322
|
-
if (
|
|
608726
|
+
if (existsSync108(dp)) try {
|
|
608323
608727
|
_rmStale(dp);
|
|
608324
608728
|
} catch {
|
|
608325
608729
|
}
|
|
@@ -608330,8 +608734,8 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
608330
608734
|
const autoNexus = new NexusTool(repoRoot);
|
|
608331
608735
|
const _registerNexusDaemon = () => {
|
|
608332
608736
|
try {
|
|
608333
|
-
const nexusPidFile =
|
|
608334
|
-
if (
|
|
608737
|
+
const nexusPidFile = join124(repoRoot, ".oa", "nexus", "daemon.pid");
|
|
608738
|
+
if (existsSync108(nexusPidFile)) {
|
|
608335
608739
|
const nPid = parseInt(readFileSync87(nexusPidFile, "utf8").trim(), 10);
|
|
608336
608740
|
if (nPid > 0 && !registry2.daemons.has("Nexus")) {
|
|
608337
608741
|
registry2.register({ name: "Nexus", pid: nPid, startedAt: Date.now(), status: "running" });
|
|
@@ -608389,7 +608793,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
608389
608793
|
} catch {
|
|
608390
608794
|
}
|
|
608391
608795
|
try {
|
|
608392
|
-
const oaDir =
|
|
608796
|
+
const oaDir = join124(repoRoot, ".oa");
|
|
608393
608797
|
const reconnected = await ExposeGateway.checkAndReconnect(oaDir, {
|
|
608394
608798
|
onInfo: (msg) => writeContent(() => renderInfo2(msg)),
|
|
608395
608799
|
onError: (msg) => writeContent(() => renderWarning2(msg))
|
|
@@ -608421,7 +608825,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
608421
608825
|
} catch {
|
|
608422
608826
|
}
|
|
608423
608827
|
try {
|
|
608424
|
-
const oaDir =
|
|
608828
|
+
const oaDir = join124(repoRoot, ".oa");
|
|
608425
608829
|
const reconnectedP2P = await ExposeP2PGateway.checkAndReconnect(oaDir, new NexusTool(repoRoot), {
|
|
608426
608830
|
onInfo: (msg) => writeContent(() => renderInfo2(msg)),
|
|
608427
608831
|
onError: (msg) => writeContent(() => renderWarning2(msg))
|
|
@@ -608462,10 +608866,10 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
608462
608866
|
}
|
|
608463
608867
|
try {
|
|
608464
608868
|
const { homedir: _hd, hostname: _hn, userInfo: _ui } = await import("node:os");
|
|
608465
|
-
const globalNamePath =
|
|
608869
|
+
const globalNamePath = join124(_hd(), ".open-agents", "agent-name");
|
|
608466
608870
|
let agName = "";
|
|
608467
608871
|
try {
|
|
608468
|
-
if (
|
|
608872
|
+
if (existsSync108(globalNamePath)) agName = readFileSync87(globalNamePath, "utf8").trim();
|
|
608469
608873
|
} catch {
|
|
608470
608874
|
}
|
|
608471
608875
|
if (!agName) {
|
|
@@ -608494,10 +608898,10 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
608494
608898
|
}
|
|
608495
608899
|
if (!ollamaAlive) {
|
|
608496
608900
|
try {
|
|
608497
|
-
const savedSponsorsPath =
|
|
608901
|
+
const savedSponsorsPath = join124(repoRoot, ".oa", "sponsor", "known-sponsors.json");
|
|
608498
608902
|
let savedSponsors = [];
|
|
608499
608903
|
try {
|
|
608500
|
-
if (
|
|
608904
|
+
if (existsSync108(savedSponsorsPath)) {
|
|
608501
608905
|
savedSponsors = JSON.parse(readFileSync87(savedSponsorsPath, "utf8"));
|
|
608502
608906
|
const oneHourAgo = Date.now() - 36e5;
|
|
608503
608907
|
savedSponsors = savedSponsors.filter((s2) => (s2.lastVerified || 0) > oneHourAgo);
|
|
@@ -609590,10 +609994,10 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
609590
609994
|
if (name10 === "voice_list_files") {
|
|
609591
609995
|
const baseDir = String(args?.dir ?? ".");
|
|
609592
609996
|
const { readdirSync: readdirSync39, statSync: statSync36 } = __require("node:fs");
|
|
609593
|
-
const { join:
|
|
609594
|
-
const base3 = baseDir.startsWith("/") ? baseDir : resolve43(
|
|
609997
|
+
const { join: join129, resolve: resolve43 } = __require("node:path");
|
|
609998
|
+
const base3 = baseDir.startsWith("/") ? baseDir : resolve43(join129(repoRoot, baseDir));
|
|
609595
609999
|
const items = readdirSync39(base3).slice(0, 200).map((f2) => {
|
|
609596
|
-
const s2 = statSync36(
|
|
610000
|
+
const s2 = statSync36(join129(base3, f2));
|
|
609597
610001
|
return { name: f2, dir: s2.isDirectory(), size: s2.size };
|
|
609598
610002
|
});
|
|
609599
610003
|
return JSON.stringify({ dir: base3, items }, null, 2);
|
|
@@ -609681,7 +610085,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
609681
610085
|
kind,
|
|
609682
610086
|
targetUrl,
|
|
609683
610087
|
authKey,
|
|
609684
|
-
stateDir:
|
|
610088
|
+
stateDir: join124(repoRoot, ".oa"),
|
|
609685
610089
|
passthrough: passthrough ?? false,
|
|
609686
610090
|
loadbalance: loadbalance ?? false,
|
|
609687
610091
|
endpointAuth: passthrough ? currentConfig.apiKey : void 0,
|
|
@@ -609727,7 +610131,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
609727
610131
|
await tunnelGateway.stop();
|
|
609728
610132
|
tunnelGateway = null;
|
|
609729
610133
|
}
|
|
609730
|
-
const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir:
|
|
610134
|
+
const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join124(repoRoot, ".oa") });
|
|
609731
610135
|
newTunnel.on("stats", (stats) => {
|
|
609732
610136
|
statusBar.setExposeStatus({
|
|
609733
610137
|
status: stats.status,
|
|
@@ -609748,14 +610152,14 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
609748
610152
|
throw err;
|
|
609749
610153
|
}
|
|
609750
610154
|
},
|
|
609751
|
-
async exposeStop(
|
|
609752
|
-
if (!
|
|
610155
|
+
async exposeStop(which2) {
|
|
610156
|
+
if (!which2 || which2 === "tunnel") {
|
|
609753
610157
|
if (tunnelGateway) {
|
|
609754
610158
|
await tunnelGateway.stop();
|
|
609755
610159
|
tunnelGateway = null;
|
|
609756
610160
|
}
|
|
609757
610161
|
}
|
|
609758
|
-
if (!
|
|
610162
|
+
if (!which2 || which2 === "libp2p") {
|
|
609759
610163
|
if (p2pGateway) {
|
|
609760
610164
|
await p2pGateway.stop();
|
|
609761
610165
|
p2pGateway = null;
|
|
@@ -609814,8 +610218,8 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
609814
610218
|
});
|
|
609815
610219
|
if (!result.success) throw new Error(result.error || "Connect failed");
|
|
609816
610220
|
try {
|
|
609817
|
-
const nexusPidFile =
|
|
609818
|
-
if (
|
|
610221
|
+
const nexusPidFile = join124(repoRoot, ".oa", "nexus", "daemon.pid");
|
|
610222
|
+
if (existsSync108(nexusPidFile)) {
|
|
609819
610223
|
const pid = parseInt(readFileSync87(nexusPidFile, "utf8").trim(), 10);
|
|
609820
610224
|
if (pid > 0) {
|
|
609821
610225
|
registry2.register({
|
|
@@ -610004,9 +610408,9 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
610004
610408
|
writeContent(() => renderInfo2(`Killed ${bgKilled} background task(s).`));
|
|
610005
610409
|
}
|
|
610006
610410
|
try {
|
|
610007
|
-
const nexusDir =
|
|
610008
|
-
const pidFile =
|
|
610009
|
-
if (
|
|
610411
|
+
const nexusDir = join124(repoRoot, OA_DIR, "nexus");
|
|
610412
|
+
const pidFile = join124(nexusDir, "daemon.pid");
|
|
610413
|
+
if (existsSync108(pidFile)) {
|
|
610010
610414
|
const pid = parseInt(readFileSync87(pidFile, "utf8").trim(), 10);
|
|
610011
610415
|
if (pid > 0) {
|
|
610012
610416
|
try {
|
|
@@ -610029,11 +610433,11 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
610029
610433
|
} catch {
|
|
610030
610434
|
}
|
|
610031
610435
|
try {
|
|
610032
|
-
const voiceDir2 =
|
|
610436
|
+
const voiceDir2 = join124(homedir44(), ".open-agents", "voice");
|
|
610033
610437
|
const voicePidFiles = ["luxtts-daemon.pid", "piper-daemon.pid"];
|
|
610034
610438
|
for (const pf of voicePidFiles) {
|
|
610035
|
-
const pidPath =
|
|
610036
|
-
if (
|
|
610439
|
+
const pidPath = join124(voiceDir2, pf);
|
|
610440
|
+
if (existsSync108(pidPath)) {
|
|
610037
610441
|
try {
|
|
610038
610442
|
const pid = parseInt(readFileSync87(pidPath, "utf8").trim(), 10);
|
|
610039
610443
|
if (pid > 0) {
|
|
@@ -610059,8 +610463,8 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
610059
610463
|
execSync58(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.5", { timeout: 3e3, stdio: "ignore" });
|
|
610060
610464
|
} catch {
|
|
610061
610465
|
}
|
|
610062
|
-
const oaPath =
|
|
610063
|
-
if (
|
|
610466
|
+
const oaPath = join124(repoRoot, OA_DIR);
|
|
610467
|
+
if (existsSync108(oaPath)) {
|
|
610064
610468
|
let deleted = false;
|
|
610065
610469
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
610066
610470
|
try {
|
|
@@ -610144,18 +610548,18 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
610144
610548
|
try {
|
|
610145
610549
|
const { isPersonaPlexRunning: isPersonaPlexRunning2 } = await Promise.resolve().then(() => (init_personaplex(), personaplex_exports));
|
|
610146
610550
|
if (isPersonaPlexRunning2()) {
|
|
610147
|
-
const ppPidFile =
|
|
610148
|
-
const ppPortFile =
|
|
610149
|
-
if (
|
|
610551
|
+
const ppPidFile = join124(homedir44(), ".open-agents", "voice", "personaplex", "daemon.pid");
|
|
610552
|
+
const ppPortFile = join124(homedir44(), ".open-agents", "voice", "personaplex", "daemon.port");
|
|
610553
|
+
if (existsSync108(ppPidFile)) {
|
|
610150
610554
|
const ppPid = parseInt(readFileSync87(ppPidFile, "utf8").trim(), 10);
|
|
610151
|
-
const ppPort =
|
|
610555
|
+
const ppPort = existsSync108(ppPortFile) ? parseInt(readFileSync87(ppPortFile, "utf8").trim(), 10) : void 0;
|
|
610152
610556
|
if (ppPid > 0 && !registry2.daemons.has("PersonaPlex")) {
|
|
610153
610557
|
registry2.register({ name: "PersonaPlex", pid: ppPid, port: ppPort, startedAt: Date.now(), status: "running" });
|
|
610154
610558
|
}
|
|
610155
610559
|
}
|
|
610156
610560
|
}
|
|
610157
|
-
const nexusPidFile =
|
|
610158
|
-
if (
|
|
610561
|
+
const nexusPidFile = join124(repoRoot, ".oa", "nexus", "daemon.pid");
|
|
610562
|
+
if (existsSync108(nexusPidFile)) {
|
|
610159
610563
|
const nPid = parseInt(readFileSync87(nexusPidFile, "utf8").trim(), 10);
|
|
610160
610564
|
if (nPid > 0 && !registry2.daemons.has("Nexus")) {
|
|
610161
610565
|
try {
|
|
@@ -610523,9 +610927,9 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
610523
610927
|
}
|
|
610524
610928
|
}
|
|
610525
610929
|
const cleanPath = input.replace(/^['"]|['"]$/g, "").trim();
|
|
610526
|
-
const isImage = isImagePath(cleanPath) &&
|
|
610527
|
-
const isMedia = !isImage && isTranscribablePath(cleanPath) &&
|
|
610528
|
-
const isMarkdown = !isImage && !isMedia && /\.(md|markdown)$/i.test(cleanPath) &&
|
|
610930
|
+
const isImage = isImagePath(cleanPath) && existsSync108(resolve39(repoRoot, cleanPath));
|
|
610931
|
+
const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync108(resolve39(repoRoot, cleanPath));
|
|
610932
|
+
const isMarkdown = !isImage && !isMedia && /\.(md|markdown)$/i.test(cleanPath) && existsSync108(resolve39(repoRoot, cleanPath));
|
|
610529
610933
|
if (activeTask) {
|
|
610530
610934
|
if (activeTask.runner.isPaused) {
|
|
610531
610935
|
activeTask.runner.resume();
|
|
@@ -611112,13 +611516,13 @@ async function runWithTUI(task, config, repoPath, callbacks) {
|
|
|
611112
611516
|
const handle2 = startTask(task, config, repoRoot);
|
|
611113
611517
|
await handle2.promise;
|
|
611114
611518
|
try {
|
|
611115
|
-
const ikDir =
|
|
611116
|
-
const ikFile =
|
|
611519
|
+
const ikDir = join124(repoRoot, ".oa", "identity");
|
|
611520
|
+
const ikFile = join124(ikDir, "self-state.json");
|
|
611117
611521
|
let ikState;
|
|
611118
|
-
if (
|
|
611522
|
+
if (existsSync108(ikFile)) {
|
|
611119
611523
|
ikState = JSON.parse(readFileSync87(ikFile, "utf8"));
|
|
611120
611524
|
} else {
|
|
611121
|
-
|
|
611525
|
+
mkdirSync65(ikDir, { recursive: true });
|
|
611122
611526
|
ikState = {
|
|
611123
611527
|
self_id: `oa-${Date.now().toString(36)}`,
|
|
611124
611528
|
version: 1,
|
|
@@ -611140,7 +611544,7 @@ async function runWithTUI(task, config, repoPath, callbacks) {
|
|
|
611140
611544
|
ikState.homeostasis.coherence = Math.min(1, ikState.homeostasis.coherence + 0.05);
|
|
611141
611545
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
611142
611546
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
611143
|
-
|
|
611547
|
+
writeFileSync57(ikFile, JSON.stringify(ikState, null, 2));
|
|
611144
611548
|
} catch (ikErr) {
|
|
611145
611549
|
}
|
|
611146
611550
|
try {
|
|
@@ -611153,11 +611557,11 @@ async function runWithTUI(task, config, repoPath, callbacks) {
|
|
|
611153
611557
|
);
|
|
611154
611558
|
} catch {
|
|
611155
611559
|
try {
|
|
611156
|
-
const archeDir =
|
|
611157
|
-
const archeFile =
|
|
611560
|
+
const archeDir = join124(repoRoot, ".oa", "arche");
|
|
611561
|
+
const archeFile = join124(archeDir, "variants.json");
|
|
611158
611562
|
let variants = [];
|
|
611159
611563
|
try {
|
|
611160
|
-
if (
|
|
611564
|
+
if (existsSync108(archeFile)) variants = JSON.parse(readFileSync87(archeFile, "utf8"));
|
|
611161
611565
|
} catch {
|
|
611162
611566
|
}
|
|
611163
611567
|
variants.push({
|
|
@@ -611171,14 +611575,14 @@ async function runWithTUI(task, config, repoPath, callbacks) {
|
|
|
611171
611575
|
tags: ["general"]
|
|
611172
611576
|
});
|
|
611173
611577
|
if (variants.length > 50) variants = variants.slice(-50);
|
|
611174
|
-
|
|
611175
|
-
|
|
611578
|
+
mkdirSync65(archeDir, { recursive: true });
|
|
611579
|
+
writeFileSync57(archeFile, JSON.stringify(variants, null, 2));
|
|
611176
611580
|
} catch {
|
|
611177
611581
|
}
|
|
611178
611582
|
}
|
|
611179
611583
|
try {
|
|
611180
|
-
const metaFile =
|
|
611181
|
-
if (
|
|
611584
|
+
const metaFile = join124(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
611585
|
+
if (existsSync108(metaFile)) {
|
|
611182
611586
|
const store2 = JSON.parse(readFileSync87(metaFile, "utf8"));
|
|
611183
611587
|
const surfaced = store2.filter((m2) => m2.type !== "quarantine" && m2.scores?.confidence > 0.15).sort((a2, b) => b.scores.utility * b.scores.confidence - a2.scores.utility * a2.scores.confidence).slice(0, 5);
|
|
611184
611588
|
let updated = false;
|
|
@@ -611190,7 +611594,7 @@ async function runWithTUI(task, config, repoPath, callbacks) {
|
|
|
611190
611594
|
updated = true;
|
|
611191
611595
|
}
|
|
611192
611596
|
if (updated) {
|
|
611193
|
-
|
|
611597
|
+
writeFileSync57(metaFile, JSON.stringify(store2, null, 2));
|
|
611194
611598
|
}
|
|
611195
611599
|
}
|
|
611196
611600
|
} catch {
|
|
@@ -611243,9 +611647,9 @@ Rules:
|
|
|
611243
611647
|
try {
|
|
611244
611648
|
const { initDb: initDb2 } = __require("@open-agents/memory");
|
|
611245
611649
|
const { ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
|
|
611246
|
-
const dbDir =
|
|
611247
|
-
|
|
611248
|
-
const db = initDb2(
|
|
611650
|
+
const dbDir = join124(repoRoot, ".oa", "memory");
|
|
611651
|
+
mkdirSync65(dbDir, { recursive: true });
|
|
611652
|
+
const db = initDb2(join124(dbDir, "structured.db"));
|
|
611249
611653
|
const memStore = new ProceduralMemoryStore2(db);
|
|
611250
611654
|
memStore.createWithEmbedding({
|
|
611251
611655
|
content: content.slice(0, 600),
|
|
@@ -611260,11 +611664,11 @@ Rules:
|
|
|
611260
611664
|
db.close();
|
|
611261
611665
|
} catch {
|
|
611262
611666
|
}
|
|
611263
|
-
const metaDir =
|
|
611264
|
-
const storeFile =
|
|
611667
|
+
const metaDir = join124(repoRoot, ".oa", "memory", "metabolism");
|
|
611668
|
+
const storeFile = join124(metaDir, "store.json");
|
|
611265
611669
|
let store2 = [];
|
|
611266
611670
|
try {
|
|
611267
|
-
if (
|
|
611671
|
+
if (existsSync108(storeFile)) store2 = JSON.parse(readFileSync87(storeFile, "utf8"));
|
|
611268
611672
|
} catch {
|
|
611269
611673
|
}
|
|
611270
611674
|
store2.push({
|
|
@@ -611279,25 +611683,25 @@ Rules:
|
|
|
611279
611683
|
accessCount: 0
|
|
611280
611684
|
});
|
|
611281
611685
|
if (store2.length > 100) store2 = store2.slice(-100);
|
|
611282
|
-
|
|
611283
|
-
|
|
611686
|
+
mkdirSync65(metaDir, { recursive: true });
|
|
611687
|
+
writeFileSync57(storeFile, JSON.stringify(store2, null, 2));
|
|
611284
611688
|
}
|
|
611285
611689
|
}
|
|
611286
611690
|
} catch {
|
|
611287
611691
|
}
|
|
611288
611692
|
try {
|
|
611289
|
-
const cohereSettingsFile =
|
|
611693
|
+
const cohereSettingsFile = join124(repoRoot, ".oa", "settings.json");
|
|
611290
611694
|
let cohereActive = false;
|
|
611291
611695
|
try {
|
|
611292
|
-
if (
|
|
611696
|
+
if (existsSync108(cohereSettingsFile)) {
|
|
611293
611697
|
const settings = JSON.parse(readFileSync87(cohereSettingsFile, "utf8"));
|
|
611294
611698
|
cohereActive = settings.cohere === true;
|
|
611295
611699
|
}
|
|
611296
611700
|
} catch {
|
|
611297
611701
|
}
|
|
611298
611702
|
if (cohereActive) {
|
|
611299
|
-
const metaFile =
|
|
611300
|
-
if (
|
|
611703
|
+
const metaFile = join124(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
611704
|
+
if (existsSync108(metaFile)) {
|
|
611301
611705
|
const store2 = JSON.parse(readFileSync87(metaFile, "utf8"));
|
|
611302
611706
|
const latest = store2.filter((m2) => m2.sourceTrace === "trajectory-extraction" || m2.sourceTrace === "llm-trajectory-extraction").slice(-1)[0];
|
|
611303
611707
|
if (latest && latest.scores?.confidence >= 0.6) {
|
|
@@ -611323,17 +611727,17 @@ Rules:
|
|
|
611323
611727
|
}
|
|
611324
611728
|
} catch (err) {
|
|
611325
611729
|
try {
|
|
611326
|
-
const ikFile =
|
|
611327
|
-
if (
|
|
611730
|
+
const ikFile = join124(repoRoot, ".oa", "identity", "self-state.json");
|
|
611731
|
+
if (existsSync108(ikFile)) {
|
|
611328
611732
|
const ikState = JSON.parse(readFileSync87(ikFile, "utf8"));
|
|
611329
611733
|
ikState.homeostasis.uncertainty = Math.min(1, ikState.homeostasis.uncertainty + 0.1);
|
|
611330
611734
|
ikState.homeostasis.coherence = Math.max(0, ikState.homeostasis.coherence - 0.05);
|
|
611331
611735
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
611332
611736
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
611333
|
-
|
|
611737
|
+
writeFileSync57(ikFile, JSON.stringify(ikState, null, 2));
|
|
611334
611738
|
}
|
|
611335
|
-
const metaFile =
|
|
611336
|
-
if (
|
|
611739
|
+
const metaFile = join124(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
611740
|
+
if (existsSync108(metaFile)) {
|
|
611337
611741
|
const store2 = JSON.parse(readFileSync87(metaFile, "utf8"));
|
|
611338
611742
|
const surfaced = store2.filter((m2) => m2.type !== "quarantine" && m2.scores?.confidence > 0.15).sort((a2, b) => b.scores.utility * b.scores.confidence - a2.scores.utility * a2.scores.confidence).slice(0, 5);
|
|
611339
611743
|
for (const item of surfaced) {
|
|
@@ -611342,14 +611746,14 @@ Rules:
|
|
|
611342
611746
|
item.scores.utility = Math.max(0, (item.scores.utility || 0.5) - 0.05);
|
|
611343
611747
|
item.scores.confidence = Math.max(0, (item.scores.confidence || 0.5) - 0.02);
|
|
611344
611748
|
}
|
|
611345
|
-
|
|
611749
|
+
writeFileSync57(metaFile, JSON.stringify(store2, null, 2));
|
|
611346
611750
|
}
|
|
611347
611751
|
try {
|
|
611348
|
-
const archeDir =
|
|
611349
|
-
const archeFile =
|
|
611752
|
+
const archeDir = join124(repoRoot, ".oa", "arche");
|
|
611753
|
+
const archeFile = join124(archeDir, "variants.json");
|
|
611350
611754
|
let variants = [];
|
|
611351
611755
|
try {
|
|
611352
|
-
if (
|
|
611756
|
+
if (existsSync108(archeFile)) variants = JSON.parse(readFileSync87(archeFile, "utf8"));
|
|
611353
611757
|
} catch {
|
|
611354
611758
|
}
|
|
611355
611759
|
variants.push({
|
|
@@ -611363,8 +611767,8 @@ Rules:
|
|
|
611363
611767
|
tags: ["general"]
|
|
611364
611768
|
});
|
|
611365
611769
|
if (variants.length > 50) variants = variants.slice(-50);
|
|
611366
|
-
|
|
611367
|
-
|
|
611770
|
+
mkdirSync65(archeDir, { recursive: true });
|
|
611771
|
+
writeFileSync57(archeFile, JSON.stringify(variants, null, 2));
|
|
611368
611772
|
} catch {
|
|
611369
611773
|
}
|
|
611370
611774
|
} catch {
|
|
@@ -611452,14 +611856,14 @@ __export(run_exports, {
|
|
|
611452
611856
|
statusCommand: () => statusCommand
|
|
611453
611857
|
});
|
|
611454
611858
|
import { resolve as resolve40 } from "node:path";
|
|
611455
|
-
import { spawn as
|
|
611456
|
-
import { mkdirSync as
|
|
611859
|
+
import { spawn as spawn27 } from "node:child_process";
|
|
611860
|
+
import { mkdirSync as mkdirSync66, writeFileSync as writeFileSync58, readFileSync as readFileSync88, readdirSync as readdirSync38, existsSync as existsSync109 } from "node:fs";
|
|
611457
611861
|
import { randomBytes as randomBytes24 } from "node:crypto";
|
|
611458
|
-
import { join as
|
|
611862
|
+
import { join as join125 } from "node:path";
|
|
611459
611863
|
function jobsDir2(repoPath) {
|
|
611460
611864
|
const root = resolve40(repoPath ?? process.cwd());
|
|
611461
|
-
const dir =
|
|
611462
|
-
|
|
611865
|
+
const dir = join125(root, ".oa", "jobs");
|
|
611866
|
+
mkdirSync66(dir, { recursive: true });
|
|
611463
611867
|
return dir;
|
|
611464
611868
|
}
|
|
611465
611869
|
async function runCommand(opts, config) {
|
|
@@ -611565,7 +611969,7 @@ async function runBackground(task, config, opts) {
|
|
|
611565
611969
|
const oaBin = process.argv[1] || "oa";
|
|
611566
611970
|
const args = [task, "--json"];
|
|
611567
611971
|
if (config.model) args.push("--model", config.model);
|
|
611568
|
-
const child =
|
|
611972
|
+
const child = spawn27(process.execPath, [oaBin, ...args], {
|
|
611569
611973
|
cwd: repoRoot,
|
|
611570
611974
|
env: { ...process.env, OA_JOB_ID: id },
|
|
611571
611975
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -611581,7 +611985,7 @@ async function runBackground(task, config, opts) {
|
|
|
611581
611985
|
}
|
|
611582
611986
|
});
|
|
611583
611987
|
job.pid = child.pid ?? 0;
|
|
611584
|
-
|
|
611988
|
+
writeFileSync58(join125(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
611585
611989
|
let output = "";
|
|
611586
611990
|
child.stdout?.on("data", (chunk) => {
|
|
611587
611991
|
output += chunk.toString();
|
|
@@ -611597,7 +612001,7 @@ async function runBackground(task, config, opts) {
|
|
|
611597
612001
|
job.summary = result.summary;
|
|
611598
612002
|
job.durationMs = result.durationMs;
|
|
611599
612003
|
job.error = result.error;
|
|
611600
|
-
|
|
612004
|
+
writeFileSync58(join125(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
611601
612005
|
} catch {
|
|
611602
612006
|
}
|
|
611603
612007
|
});
|
|
@@ -611613,8 +612017,8 @@ async function runBackground(task, config, opts) {
|
|
|
611613
612017
|
}
|
|
611614
612018
|
function statusCommand(jobId, repoPath) {
|
|
611615
612019
|
const dir = jobsDir2(repoPath);
|
|
611616
|
-
const file =
|
|
611617
|
-
if (!
|
|
612020
|
+
const file = join125(dir, `${jobId}.json`);
|
|
612021
|
+
if (!existsSync109(file)) {
|
|
611618
612022
|
console.error(`Job not found: ${jobId}`);
|
|
611619
612023
|
console.log(`Available jobs: oa jobs`);
|
|
611620
612024
|
process.exit(1);
|
|
@@ -611640,7 +612044,7 @@ function jobsCommand(repoPath) {
|
|
|
611640
612044
|
console.log("Jobs:");
|
|
611641
612045
|
for (const file of files) {
|
|
611642
612046
|
try {
|
|
611643
|
-
const job = JSON.parse(readFileSync88(
|
|
612047
|
+
const job = JSON.parse(readFileSync88(join125(dir, file), "utf-8"));
|
|
611644
612048
|
const icon = job.status === "completed" ? "✓" : job.status === "failed" ? "✗" : "●";
|
|
611645
612049
|
const runtime = job.completedAt ? `${((new Date(job.completedAt).getTime() - new Date(job.startedAt).getTime()) / 1e3).toFixed(0)}s` : `${((Date.now() - new Date(job.startedAt).getTime()) / 1e3).toFixed(0)}s`;
|
|
611646
612050
|
const cleanListTask = cleanForStorage(job.task) || job.task;
|
|
@@ -611664,13 +612068,13 @@ __export(index_repo_exports, {
|
|
|
611664
612068
|
indexRepoCommand: () => indexRepoCommand
|
|
611665
612069
|
});
|
|
611666
612070
|
import { resolve as resolve41 } from "node:path";
|
|
611667
|
-
import { existsSync as
|
|
612071
|
+
import { existsSync as existsSync110, statSync as statSync35 } from "node:fs";
|
|
611668
612072
|
import { cwd as cwd2 } from "node:process";
|
|
611669
612073
|
async function indexRepoCommand(opts, _config3) {
|
|
611670
612074
|
const repoRoot = resolve41(opts.repoPath ?? cwd2());
|
|
611671
612075
|
printHeader("Index Repository");
|
|
611672
612076
|
printInfo(`Indexing: ${repoRoot}`);
|
|
611673
|
-
if (!
|
|
612077
|
+
if (!existsSync110(repoRoot)) {
|
|
611674
612078
|
printError(`Path does not exist: ${repoRoot}`);
|
|
611675
612079
|
process.exit(1);
|
|
611676
612080
|
}
|
|
@@ -611922,7 +612326,7 @@ var config_exports2 = {};
|
|
|
611922
612326
|
__export(config_exports2, {
|
|
611923
612327
|
configCommand: () => configCommand
|
|
611924
612328
|
});
|
|
611925
|
-
import { join as
|
|
612329
|
+
import { join as join126, resolve as resolve42 } from "node:path";
|
|
611926
612330
|
import { homedir as homedir45 } from "node:os";
|
|
611927
612331
|
import { cwd as cwd3 } from "node:process";
|
|
611928
612332
|
function redactIfSensitive(key, value2) {
|
|
@@ -612004,7 +612408,7 @@ function handleShow(opts, config) {
|
|
|
612004
612408
|
}
|
|
612005
612409
|
}
|
|
612006
612410
|
printSection("Config File");
|
|
612007
|
-
printInfo(`~/.open-agents/config.json (${
|
|
612411
|
+
printInfo(`~/.open-agents/config.json (${join126(homedir45(), ".open-agents", "config.json")})`);
|
|
612008
612412
|
printSection("Priority Chain");
|
|
612009
612413
|
printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
|
|
612010
612414
|
printInfo(" 2. Project .oa/settings.json (--local)");
|
|
@@ -612043,7 +612447,7 @@ function handleSet(opts, _config3) {
|
|
|
612043
612447
|
const coerced = coerceForSettings(key, value2);
|
|
612044
612448
|
saveProjectSettings(repoRoot, { [key]: coerced });
|
|
612045
612449
|
printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value2)}`);
|
|
612046
|
-
printInfo(`Saved to ${
|
|
612450
|
+
printInfo(`Saved to ${join126(repoRoot, ".oa", "settings.json")}`);
|
|
612047
612451
|
printInfo("This override applies only when running in this workspace.");
|
|
612048
612452
|
} catch (err) {
|
|
612049
612453
|
printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -612226,9 +612630,9 @@ var eval_exports = {};
|
|
|
612226
612630
|
__export(eval_exports, {
|
|
612227
612631
|
evalCommand: () => evalCommand
|
|
612228
612632
|
});
|
|
612229
|
-
import { tmpdir as
|
|
612230
|
-
import { mkdirSync as
|
|
612231
|
-
import { join as
|
|
612633
|
+
import { tmpdir as tmpdir22 } from "node:os";
|
|
612634
|
+
import { mkdirSync as mkdirSync67, writeFileSync as writeFileSync59 } from "node:fs";
|
|
612635
|
+
import { join as join127 } from "node:path";
|
|
612232
612636
|
async function evalCommand(opts, config) {
|
|
612233
612637
|
const suiteName = opts.suite ?? "basic";
|
|
612234
612638
|
const suite = SUITES[suiteName];
|
|
@@ -612357,10 +612761,10 @@ async function evalCommand(opts, config) {
|
|
|
612357
612761
|
process.exit(failed > 0 ? 1 : 0);
|
|
612358
612762
|
}
|
|
612359
612763
|
function createTempEvalRepo() {
|
|
612360
|
-
const dir =
|
|
612361
|
-
|
|
612362
|
-
|
|
612363
|
-
|
|
612764
|
+
const dir = join127(tmpdir22(), `open-agents-eval-${Date.now()}`);
|
|
612765
|
+
mkdirSync67(dir, { recursive: true });
|
|
612766
|
+
writeFileSync59(
|
|
612767
|
+
join127(dir, "package.json"),
|
|
612364
612768
|
JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n",
|
|
612365
612769
|
"utf8"
|
|
612366
612770
|
);
|
|
@@ -612424,7 +612828,7 @@ init_typed_node_events();
|
|
|
612424
612828
|
import { parseArgs as nodeParseArgs2 } from "node:util";
|
|
612425
612829
|
import { createRequire as createRequire7 } from "node:module";
|
|
612426
612830
|
import { fileURLToPath as fileURLToPath19 } from "node:url";
|
|
612427
|
-
import { dirname as dirname38, join as
|
|
612831
|
+
import { dirname as dirname38, join as join128 } from "node:path";
|
|
612428
612832
|
|
|
612429
612833
|
// packages/cli/src/cli.ts
|
|
612430
612834
|
init_typed_node_events();
|
|
@@ -612564,7 +612968,7 @@ init_output();
|
|
|
612564
612968
|
function getVersion5() {
|
|
612565
612969
|
try {
|
|
612566
612970
|
const require4 = createRequire7(import.meta.url);
|
|
612567
|
-
const pkgPath =
|
|
612971
|
+
const pkgPath = join128(dirname38(fileURLToPath19(import.meta.url)), "..", "package.json");
|
|
612568
612972
|
const pkg = require4(pkgPath);
|
|
612569
612973
|
return pkg.version;
|
|
612570
612974
|
} catch {
|
|
@@ -612753,9 +613157,9 @@ async function main() {
|
|
|
612753
613157
|
const mode = process.argv[process.argv.indexOf("--self-test") + 1] || "crossmodal";
|
|
612754
613158
|
if (mode === "crossmodal") {
|
|
612755
613159
|
process.stdout.write("Running crossmodal smoke tests...\n");
|
|
612756
|
-
const { spawn:
|
|
613160
|
+
const { spawn: spawn28 } = await import("node:child_process");
|
|
612757
613161
|
const run = (file) => new Promise((resolve43, reject) => {
|
|
612758
|
-
const p2 =
|
|
613162
|
+
const p2 = spawn28(process.execPath, [file], { stdio: ["ignore", "pipe", "pipe"] });
|
|
612759
613163
|
p2.stdout.on("data", (d2) => process.stdout.write(d2));
|
|
612760
613164
|
p2.stderr.on("data", (d2) => process.stdout.write(d2));
|
|
612761
613165
|
onChildExit(p2, (code8) => code8 === 0 ? resolve43() : reject(new Error(`${file} exited ${code8}`)));
|
|
@@ -612878,12 +613282,12 @@ function crashLog(label, err) {
|
|
|
612878
613282
|
const logLine = `[${timestamp}] ${label}: ${msg}
|
|
612879
613283
|
`;
|
|
612880
613284
|
try {
|
|
612881
|
-
const { appendFileSync: appendFileSync9, mkdirSync:
|
|
612882
|
-
const { join:
|
|
613285
|
+
const { appendFileSync: appendFileSync9, mkdirSync: mkdirSync68 } = __require("node:fs");
|
|
613286
|
+
const { join: join129 } = __require("node:path");
|
|
612883
613287
|
const { homedir: homedir46 } = __require("node:os");
|
|
612884
|
-
const logDir =
|
|
612885
|
-
|
|
612886
|
-
appendFileSync9(
|
|
613288
|
+
const logDir = join129(homedir46(), ".open-agents");
|
|
613289
|
+
mkdirSync68(logDir, { recursive: true });
|
|
613290
|
+
appendFileSync9(join129(logDir, "crash.log"), logLine);
|
|
612887
613291
|
} catch {
|
|
612888
613292
|
}
|
|
612889
613293
|
try {
|