open-agents-ai 0.142.2 → 0.143.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js
CHANGED
|
@@ -1370,7 +1370,7 @@ ${stdinInput ?? ""}`);
|
|
|
1370
1370
|
}
|
|
1371
1371
|
runCommand(command, timeout, stdinInput) {
|
|
1372
1372
|
const start = performance.now();
|
|
1373
|
-
return new Promise((
|
|
1373
|
+
return new Promise((resolve33) => {
|
|
1374
1374
|
const child = spawn("bash", ["-c", command], {
|
|
1375
1375
|
cwd: this.workingDir,
|
|
1376
1376
|
env: {
|
|
@@ -1395,7 +1395,7 @@ ${stdinInput ?? ""}`);
|
|
|
1395
1395
|
clearTimeout(timer);
|
|
1396
1396
|
if (exitFlushTimer)
|
|
1397
1397
|
clearTimeout(exitFlushTimer);
|
|
1398
|
-
|
|
1398
|
+
resolve33(result);
|
|
1399
1399
|
};
|
|
1400
1400
|
const timer = setTimeout(() => {
|
|
1401
1401
|
killed = true;
|
|
@@ -2556,7 +2556,7 @@ ${JSON.stringify(extracted, null, 2)}`);
|
|
|
2556
2556
|
return null;
|
|
2557
2557
|
}
|
|
2558
2558
|
runProcess(cmd, args, timeoutMs) {
|
|
2559
|
-
return new Promise((
|
|
2559
|
+
return new Promise((resolve33, reject) => {
|
|
2560
2560
|
const proc = execFile3(cmd, args, {
|
|
2561
2561
|
timeout: timeoutMs,
|
|
2562
2562
|
maxBuffer: 10 * 1024 * 1024,
|
|
@@ -2566,7 +2566,7 @@ ${JSON.stringify(extracted, null, 2)}`);
|
|
|
2566
2566
|
reject(new Error(`Process timeout after ${timeoutMs}ms`));
|
|
2567
2567
|
return;
|
|
2568
2568
|
}
|
|
2569
|
-
|
|
2569
|
+
resolve33({
|
|
2570
2570
|
stdout: String(stdout),
|
|
2571
2571
|
stderr: String(stderr),
|
|
2572
2572
|
exitCode: error ? error.code ?? 1 : 0
|
|
@@ -9975,7 +9975,7 @@ var init_custom_tool = __esm({
|
|
|
9975
9975
|
}
|
|
9976
9976
|
/** Execute a single shell command and return output */
|
|
9977
9977
|
runCommand(command) {
|
|
9978
|
-
return new Promise((
|
|
9978
|
+
return new Promise((resolve33) => {
|
|
9979
9979
|
const child = spawn4("bash", ["-c", command], {
|
|
9980
9980
|
cwd: this.workingDir,
|
|
9981
9981
|
env: { ...process.env, CI: "true", NO_COLOR: "1" },
|
|
@@ -10000,11 +10000,11 @@ var init_custom_tool = __esm({
|
|
|
10000
10000
|
child.kill("SIGTERM");
|
|
10001
10001
|
} catch {
|
|
10002
10002
|
}
|
|
10003
|
-
|
|
10003
|
+
resolve33({ success: false, output: stdout, error: "Command timed out after 60s" });
|
|
10004
10004
|
}, 6e4);
|
|
10005
10005
|
child.on("close", (code) => {
|
|
10006
10006
|
clearTimeout(timer);
|
|
10007
|
-
|
|
10007
|
+
resolve33({
|
|
10008
10008
|
success: code === 0,
|
|
10009
10009
|
output: stdout + (stderr && code === 0 ? `
|
|
10010
10010
|
STDERR:
|
|
@@ -10014,7 +10014,7 @@ ${stderr}` : ""),
|
|
|
10014
10014
|
});
|
|
10015
10015
|
child.on("error", (err) => {
|
|
10016
10016
|
clearTimeout(timer);
|
|
10017
|
-
|
|
10017
|
+
resolve33({ success: false, output: stdout, error: err.message });
|
|
10018
10018
|
});
|
|
10019
10019
|
});
|
|
10020
10020
|
}
|
|
@@ -11481,7 +11481,7 @@ import { writeFile as writeFile8, mkdtemp, rm, readdir as readdir3, stat } from
|
|
|
11481
11481
|
import { join as join18 } from "node:path";
|
|
11482
11482
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
11483
11483
|
function runProcess(cmd, args, options) {
|
|
11484
|
-
return new Promise((
|
|
11484
|
+
return new Promise((resolve33) => {
|
|
11485
11485
|
const proc = spawn6(cmd, args, {
|
|
11486
11486
|
cwd: options.cwd,
|
|
11487
11487
|
timeout: options.timeout,
|
|
@@ -11511,7 +11511,7 @@ function runProcess(cmd, args, options) {
|
|
|
11511
11511
|
}
|
|
11512
11512
|
});
|
|
11513
11513
|
proc.on("error", (err) => {
|
|
11514
|
-
|
|
11514
|
+
resolve33({
|
|
11515
11515
|
stdout,
|
|
11516
11516
|
stderr: stderr || err.message,
|
|
11517
11517
|
exitCode: 1,
|
|
@@ -11523,7 +11523,7 @@ function runProcess(cmd, args, options) {
|
|
|
11523
11523
|
if (signal === "SIGTERM" || signal === "SIGKILL") {
|
|
11524
11524
|
timedOut = true;
|
|
11525
11525
|
}
|
|
11526
|
-
|
|
11526
|
+
resolve33({
|
|
11527
11527
|
stdout,
|
|
11528
11528
|
stderr,
|
|
11529
11529
|
exitCode: code ?? (timedOut ? 124 : 1),
|
|
@@ -12006,7 +12006,7 @@ Justification: ${justification || "(none provided)"}`,
|
|
|
12006
12006
|
})();
|
|
12007
12007
|
const ipfsResult = await Promise.race([
|
|
12008
12008
|
ipfsPromise,
|
|
12009
|
-
new Promise((
|
|
12009
|
+
new Promise((resolve33) => setTimeout(() => resolve33(null), 2e3))
|
|
12010
12010
|
]);
|
|
12011
12011
|
if (ipfsResult && ipfsResult.success) {
|
|
12012
12012
|
const cidData = JSON.parse(ipfsResult.output);
|
|
@@ -12450,7 +12450,7 @@ print("__OA_REPL_READY__")
|
|
|
12450
12450
|
return;
|
|
12451
12451
|
const sockId = randomBytes3(8).toString("hex");
|
|
12452
12452
|
this.ipcPath = join20(tmpdir3(), `oa-repl-ipc-${sockId}.sock`);
|
|
12453
|
-
return new Promise((
|
|
12453
|
+
return new Promise((resolve33, reject) => {
|
|
12454
12454
|
this.ipcServer = createServer((conn) => {
|
|
12455
12455
|
let buffer = new Uint8Array(0);
|
|
12456
12456
|
conn.on("data", (chunk) => {
|
|
@@ -12466,7 +12466,7 @@ print("__OA_REPL_READY__")
|
|
|
12466
12466
|
});
|
|
12467
12467
|
});
|
|
12468
12468
|
this.ipcServer.on("error", reject);
|
|
12469
|
-
this.ipcServer.listen(this.ipcPath, () =>
|
|
12469
|
+
this.ipcServer.listen(this.ipcPath, () => resolve33());
|
|
12470
12470
|
});
|
|
12471
12471
|
}
|
|
12472
12472
|
async processIpcBuffer(conn, input) {
|
|
@@ -12529,9 +12529,9 @@ print("__OA_REPL_READY__")
|
|
|
12529
12529
|
}
|
|
12530
12530
|
// ── Code execution ─────────────────────────────────────────────────────
|
|
12531
12531
|
executeCode(code, isInit = false) {
|
|
12532
|
-
return new Promise((
|
|
12532
|
+
return new Promise((resolve33) => {
|
|
12533
12533
|
if (!this.proc?.stdin || !this.proc?.stdout || !this.proc?.stderr) {
|
|
12534
|
-
|
|
12534
|
+
resolve33({ success: false, output: "REPL process not available", error: "No process", durationMs: 0 });
|
|
12535
12535
|
return;
|
|
12536
12536
|
}
|
|
12537
12537
|
const sentinel = `__OA_SENTINEL_${randomBytes3(6).toString("hex")}__`;
|
|
@@ -12541,7 +12541,7 @@ print("__OA_REPL_READY__")
|
|
|
12541
12541
|
const timeout = setTimeout(() => {
|
|
12542
12542
|
if (!resolved) {
|
|
12543
12543
|
resolved = true;
|
|
12544
|
-
|
|
12544
|
+
resolve33({
|
|
12545
12545
|
success: false,
|
|
12546
12546
|
output: stdout || "Execution timed out",
|
|
12547
12547
|
error: `Timeout after ${this.execTimeout / 1e3}s`,
|
|
@@ -12558,13 +12558,13 @@ print("__OA_REPL_READY__")
|
|
|
12558
12558
|
if (isInit) {
|
|
12559
12559
|
const ready = cleanOutput.includes("__OA_REPL_READY__");
|
|
12560
12560
|
const displayOutput = cleanOutput.replace("__OA_REPL_READY__", "").trim();
|
|
12561
|
-
|
|
12561
|
+
resolve33({
|
|
12562
12562
|
success: ready,
|
|
12563
12563
|
output: displayOutput || "REPL initialized",
|
|
12564
12564
|
durationMs: 0
|
|
12565
12565
|
});
|
|
12566
12566
|
} else {
|
|
12567
|
-
|
|
12567
|
+
resolve33({
|
|
12568
12568
|
success: true,
|
|
12569
12569
|
output: cleanOutput || "(no output)",
|
|
12570
12570
|
durationMs: 0
|
|
@@ -12573,7 +12573,7 @@ print("__OA_REPL_READY__")
|
|
|
12573
12573
|
}
|
|
12574
12574
|
if (stdout.length > 2e5) {
|
|
12575
12575
|
cleanup();
|
|
12576
|
-
|
|
12576
|
+
resolve33({
|
|
12577
12577
|
success: true,
|
|
12578
12578
|
output: stdout.slice(0, 2e5) + "\n[output truncated at 200KB]",
|
|
12579
12579
|
durationMs: 0
|
|
@@ -16812,6 +16812,7 @@ train.py reverted to last kept state. Ready for next experiment.`,
|
|
|
16812
16812
|
import { execSync as execSync18, exec as execCb } from "node:child_process";
|
|
16813
16813
|
import { readFile as readFile15, writeFile as writeFile15, mkdir as mkdir11 } from "node:fs/promises";
|
|
16814
16814
|
import { resolve as resolve22, join as join32 } from "node:path";
|
|
16815
|
+
import { homedir as homedir8 } from "node:os";
|
|
16815
16816
|
import { randomBytes as randomBytes4 } from "node:crypto";
|
|
16816
16817
|
function isValidCron(expr) {
|
|
16817
16818
|
const parts = expr.trim().split(/\s+/);
|
|
@@ -16941,6 +16942,31 @@ async function saveStore(workingDir, store) {
|
|
|
16941
16942
|
store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
16942
16943
|
await writeFile15(join32(dir, "tasks.json"), JSON.stringify(store, null, 2), "utf-8");
|
|
16943
16944
|
}
|
|
16945
|
+
function globalStoreDir() {
|
|
16946
|
+
return join32(homedir8(), ".open-agents", "scheduled");
|
|
16947
|
+
}
|
|
16948
|
+
async function loadGlobalStore() {
|
|
16949
|
+
try {
|
|
16950
|
+
const raw = await readFile15(join32(globalStoreDir(), "tasks.json"), "utf-8");
|
|
16951
|
+
return JSON.parse(raw);
|
|
16952
|
+
} catch {
|
|
16953
|
+
return { tasks: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
16954
|
+
}
|
|
16955
|
+
}
|
|
16956
|
+
async function saveGlobalStore(store) {
|
|
16957
|
+
const dir = globalStoreDir();
|
|
16958
|
+
await mkdir11(dir, { recursive: true });
|
|
16959
|
+
await mkdir11(join32(dir, "logs"), { recursive: true });
|
|
16960
|
+
store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
16961
|
+
await writeFile15(join32(dir, "tasks.json"), JSON.stringify(store, null, 2), "utf-8");
|
|
16962
|
+
}
|
|
16963
|
+
async function loadAllStores(workingDir) {
|
|
16964
|
+
const [local, global] = await Promise.all([
|
|
16965
|
+
loadStore(workingDir),
|
|
16966
|
+
loadGlobalStore()
|
|
16967
|
+
]);
|
|
16968
|
+
return { local, global };
|
|
16969
|
+
}
|
|
16944
16970
|
var SCHEDULE_PRESETS, CRON_MARKER, SchedulerTool;
|
|
16945
16971
|
var init_scheduler = __esm({
|
|
16946
16972
|
"packages/execution/dist/tools/scheduler.js"() {
|
|
@@ -16964,7 +16990,7 @@ var init_scheduler = __esm({
|
|
|
16964
16990
|
CRON_MARKER = "# OPEN-AGENTS-SCHEDULED:";
|
|
16965
16991
|
SchedulerTool = class {
|
|
16966
16992
|
name = "scheduler";
|
|
16967
|
-
description = "Schedule tasks for automatic future execution using OS-level cron. Actions: 'create' a new scheduled task, 'list' all scheduled tasks, 'cancel' a task by ID, 'pause'/'resume' a task. Schedules: use presets ('daily', 'every 5 minutes', 'hourly', 'weekly'), natural language ('in 30m', 'at 14:30'), or raw cron expressions ('0 */2 * * *'). Tasks launch the agent automatically at the scheduled time.";
|
|
16993
|
+
description = "Schedule tasks for automatic future execution using OS-level cron. Actions: 'create' a new scheduled task, 'list' all scheduled tasks, 'cancel' a task by ID, 'pause'/'resume' a task. Schedules: use presets ('daily', 'every 5 minutes', 'hourly', 'weekly'), natural language ('in 30m', 'at 14:30'), or raw cron expressions ('0 */2 * * *'). Scope: 'local' (default, stored in .oa/) or 'global' (stored in ~/.open-agents/, visible from all projects). Tasks launch the agent automatically at the scheduled time.";
|
|
16968
16994
|
parameters = {
|
|
16969
16995
|
type: "object",
|
|
16970
16996
|
properties: {
|
|
@@ -16992,6 +17018,11 @@ var init_scheduler = __esm({
|
|
|
16992
17018
|
one_shot: {
|
|
16993
17019
|
type: "boolean",
|
|
16994
17020
|
description: "If true, task auto-removes after first execution"
|
|
17021
|
+
},
|
|
17022
|
+
scope: {
|
|
17023
|
+
type: "string",
|
|
17024
|
+
enum: ["local", "global"],
|
|
17025
|
+
description: "Scope: 'local' (project .oa/, default) or 'global' (~/.open-agents/, visible from all projects)"
|
|
16995
17026
|
}
|
|
16996
17027
|
},
|
|
16997
17028
|
required: ["action"]
|
|
@@ -17053,6 +17084,7 @@ var init_scheduler = __esm({
|
|
|
17053
17084
|
const id = `sched-${randomBytes4(4).toString("hex")}`;
|
|
17054
17085
|
const oneShot = Boolean(args["one_shot"]);
|
|
17055
17086
|
const maxRuns = typeof args["max_runs"] === "number" ? args["max_runs"] : void 0;
|
|
17087
|
+
const scope = String(args["scope"] ?? "local");
|
|
17056
17088
|
const newTask = {
|
|
17057
17089
|
id,
|
|
17058
17090
|
task,
|
|
@@ -17062,11 +17094,19 @@ var init_scheduler = __esm({
|
|
|
17062
17094
|
enabled: true,
|
|
17063
17095
|
runCount: 0,
|
|
17064
17096
|
maxRuns,
|
|
17065
|
-
oneShot: oneShot || void 0
|
|
17097
|
+
oneShot: oneShot || void 0,
|
|
17098
|
+
scope,
|
|
17099
|
+
projectDir: resolve22(this.workingDir)
|
|
17066
17100
|
};
|
|
17067
|
-
|
|
17068
|
-
|
|
17069
|
-
|
|
17101
|
+
if (scope === "global") {
|
|
17102
|
+
const store = await loadGlobalStore();
|
|
17103
|
+
store.tasks.push(newTask);
|
|
17104
|
+
await saveGlobalStore(store);
|
|
17105
|
+
} else {
|
|
17106
|
+
const store = await loadStore(this.workingDir);
|
|
17107
|
+
store.tasks.push(newTask);
|
|
17108
|
+
await saveStore(this.workingDir, store);
|
|
17109
|
+
}
|
|
17070
17110
|
installCronJob(newTask, this.workingDir);
|
|
17071
17111
|
return {
|
|
17072
17112
|
success: true,
|
|
@@ -17075,6 +17115,7 @@ var init_scheduler = __esm({
|
|
|
17075
17115
|
` ID: ${id}`,
|
|
17076
17116
|
` Task: ${task}`,
|
|
17077
17117
|
` Schedule: ${describeCron(cronExpr)} (${cronExpr})`,
|
|
17118
|
+
` Scope: ${scope}${scope === "global" ? " (visible from all projects)" : " (this project only)"}`,
|
|
17078
17119
|
oneShot ? ` Mode: one-shot (auto-removes after first run)` : "",
|
|
17079
17120
|
maxRuns ? ` Max runs: ${maxRuns}` : "",
|
|
17080
17121
|
` Status: enabled`,
|
|
@@ -17086,28 +17127,53 @@ var init_scheduler = __esm({
|
|
|
17086
17127
|
};
|
|
17087
17128
|
}
|
|
17088
17129
|
async listTasks(start) {
|
|
17089
|
-
const
|
|
17130
|
+
const { local, global } = await loadAllStores(this.workingDir);
|
|
17090
17131
|
const cronJobs = listCronJobs();
|
|
17091
|
-
|
|
17132
|
+
const totalCount = local.tasks.length + global.tasks.length;
|
|
17133
|
+
if (totalCount === 0) {
|
|
17092
17134
|
return {
|
|
17093
17135
|
success: true,
|
|
17094
17136
|
output: "No scheduled tasks. Use scheduler(action='create', task='...', schedule='daily') to create one.",
|
|
17095
17137
|
durationMs: performance.now() - start
|
|
17096
17138
|
};
|
|
17097
17139
|
}
|
|
17098
|
-
const lines = [
|
|
17099
|
-
|
|
17100
|
-
|
|
17101
|
-
|
|
17102
|
-
const
|
|
17103
|
-
|
|
17104
|
-
|
|
17105
|
-
|
|
17106
|
-
|
|
17107
|
-
|
|
17108
|
-
|
|
17109
|
-
lines.push(`
|
|
17110
|
-
|
|
17140
|
+
const lines = [];
|
|
17141
|
+
if (local.tasks.length > 0) {
|
|
17142
|
+
lines.push(`Local Tasks \u2014 this project (${local.tasks.length}):
|
|
17143
|
+
`);
|
|
17144
|
+
for (const t of local.tasks) {
|
|
17145
|
+
const status = t.enabled ? "enabled" : "PAUSED";
|
|
17146
|
+
const cronInstalled = cronJobs.some((j) => j.id === t.id);
|
|
17147
|
+
const cronStatus = cronInstalled ? "" : " [cron not installed]";
|
|
17148
|
+
lines.push(` [${t.id}] ${status}${cronStatus} [local]`);
|
|
17149
|
+
lines.push(` Task: ${t.task.slice(0, 100)}${t.task.length > 100 ? "..." : ""}`);
|
|
17150
|
+
lines.push(` Schedule: ${t.nextRunDescription} (${t.schedule})`);
|
|
17151
|
+
lines.push(` Runs: ${t.runCount}${t.maxRuns ? `/${t.maxRuns}` : ""}${t.oneShot ? " (one-shot)" : ""}`);
|
|
17152
|
+
if (t.lastRun)
|
|
17153
|
+
lines.push(` Last run: ${t.lastRun}`);
|
|
17154
|
+
lines.push("");
|
|
17155
|
+
}
|
|
17156
|
+
}
|
|
17157
|
+
if (global.tasks.length > 0) {
|
|
17158
|
+
lines.push(`Global Tasks \u2014 shared across projects (${global.tasks.length}):
|
|
17159
|
+
`);
|
|
17160
|
+
for (const t of global.tasks) {
|
|
17161
|
+
const status = t.enabled ? "enabled" : "PAUSED";
|
|
17162
|
+
const cronInstalled = cronJobs.some((j) => j.id === t.id);
|
|
17163
|
+
const cronStatus = cronInstalled ? "" : " [cron not installed]";
|
|
17164
|
+
const isThisProject = t.projectDir === resolve22(this.workingDir);
|
|
17165
|
+
const origin = isThisProject ? " [this project]" : t.projectDir ? ` [from: ${t.projectDir}]` : "";
|
|
17166
|
+
lines.push(` [${t.id}] ${status}${cronStatus} [global]${origin}`);
|
|
17167
|
+
lines.push(` Task: ${t.task.slice(0, 100)}${t.task.length > 100 ? "..." : ""}`);
|
|
17168
|
+
lines.push(` Schedule: ${t.nextRunDescription} (${t.schedule})`);
|
|
17169
|
+
lines.push(` Runs: ${t.runCount}${t.maxRuns ? `/${t.maxRuns}` : ""}${t.oneShot ? " (one-shot)" : ""}`);
|
|
17170
|
+
if (t.lastRun)
|
|
17171
|
+
lines.push(` Last run: ${t.lastRun}`);
|
|
17172
|
+
if (!isThisProject && t.projectDir) {
|
|
17173
|
+
lines.push(` \u26A0 NOT scoped to this project \u2014 override with caution`);
|
|
17174
|
+
}
|
|
17175
|
+
lines.push("");
|
|
17176
|
+
}
|
|
17111
17177
|
}
|
|
17112
17178
|
return {
|
|
17113
17179
|
success: true,
|
|
@@ -17668,7 +17734,7 @@ ${sections.join("\n")}`,
|
|
|
17668
17734
|
const description = String(args["description"] ?? "");
|
|
17669
17735
|
const category = args["category"] ?? "followup";
|
|
17670
17736
|
const priority = args["priority"] ?? "normal";
|
|
17671
|
-
const
|
|
17737
|
+
const notes2 = args["notes"] ?? void 0;
|
|
17672
17738
|
const relatedFilesStr = args["related_files"] ?? "";
|
|
17673
17739
|
const relatedFiles = relatedFilesStr ? relatedFilesStr.split(",").map((f) => f.trim()).filter(Boolean) : void 0;
|
|
17674
17740
|
let expiresAt;
|
|
@@ -17701,7 +17767,7 @@ ${sections.join("\n")}`,
|
|
|
17701
17767
|
expiresAt,
|
|
17702
17768
|
relatedFiles,
|
|
17703
17769
|
status: "active",
|
|
17704
|
-
notes
|
|
17770
|
+
notes: notes2
|
|
17705
17771
|
};
|
|
17706
17772
|
const store = await loadAttentionStore(this.workingDir);
|
|
17707
17773
|
store.items.push(item);
|
|
@@ -18395,6 +18461,7 @@ var init_factory = __esm({
|
|
|
18395
18461
|
import { execSync as execSync21 } from "node:child_process";
|
|
18396
18462
|
import { readFile as readFile18, writeFile as writeFile18, mkdir as mkdir14 } from "node:fs/promises";
|
|
18397
18463
|
import { resolve as resolve26, join as join37 } from "node:path";
|
|
18464
|
+
import { homedir as homedir9 } from "node:os";
|
|
18398
18465
|
import { randomBytes as randomBytes7 } from "node:crypto";
|
|
18399
18466
|
function isValidCron2(expr) {
|
|
18400
18467
|
const parts = expr.trim().split(/\s+/);
|
|
@@ -18523,6 +18590,31 @@ async function saveStore2(workingDir, store) {
|
|
|
18523
18590
|
store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
18524
18591
|
await writeFile18(join37(dir, "store.json"), JSON.stringify(store, null, 2), "utf-8");
|
|
18525
18592
|
}
|
|
18593
|
+
function globalCronDir() {
|
|
18594
|
+
return join37(homedir9(), ".open-agents", "cron-agents");
|
|
18595
|
+
}
|
|
18596
|
+
async function loadGlobalCronStore() {
|
|
18597
|
+
try {
|
|
18598
|
+
const raw = await readFile18(join37(globalCronDir(), "store.json"), "utf-8");
|
|
18599
|
+
return JSON.parse(raw);
|
|
18600
|
+
} catch {
|
|
18601
|
+
return { jobs: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
18602
|
+
}
|
|
18603
|
+
}
|
|
18604
|
+
async function saveGlobalCronStore(store) {
|
|
18605
|
+
const dir = globalCronDir();
|
|
18606
|
+
await mkdir14(dir, { recursive: true });
|
|
18607
|
+
await mkdir14(join37(dir, "logs"), { recursive: true });
|
|
18608
|
+
store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
18609
|
+
await writeFile18(join37(dir, "store.json"), JSON.stringify(store, null, 2), "utf-8");
|
|
18610
|
+
}
|
|
18611
|
+
async function loadAllCronStores(workingDir) {
|
|
18612
|
+
const [local, global] = await Promise.all([
|
|
18613
|
+
loadStore2(workingDir),
|
|
18614
|
+
loadGlobalCronStore()
|
|
18615
|
+
]);
|
|
18616
|
+
return { local, global };
|
|
18617
|
+
}
|
|
18526
18618
|
var LONG_HORIZON_PRESETS, CRON_AGENT_MARKER, CronAgentTool;
|
|
18527
18619
|
var init_cron_agent = __esm({
|
|
18528
18620
|
"packages/execution/dist/tools/cron-agent.js"() {
|
|
@@ -18591,6 +18683,11 @@ var init_cron_agent = __esm({
|
|
|
18591
18683
|
type: "array",
|
|
18592
18684
|
items: { type: "string" },
|
|
18593
18685
|
description: "Tags for organizing jobs (for 'create')"
|
|
18686
|
+
},
|
|
18687
|
+
scope: {
|
|
18688
|
+
type: "string",
|
|
18689
|
+
enum: ["local", "global"],
|
|
18690
|
+
description: "Scope: 'local' (project .oa/, default) or 'global' (~/.open-agents/, visible from all projects)"
|
|
18594
18691
|
}
|
|
18595
18692
|
},
|
|
18596
18693
|
required: ["action"]
|
|
@@ -18659,6 +18756,7 @@ var init_cron_agent = __esm({
|
|
|
18659
18756
|
const verifyCommand = args["verify_command"] ? String(args["verify_command"]) : void 0;
|
|
18660
18757
|
const maxRuns = typeof args["max_runs"] === "number" ? args["max_runs"] : 0;
|
|
18661
18758
|
const tags = Array.isArray(args["tags"]) ? args["tags"] : [];
|
|
18759
|
+
const scope = String(args["scope"] ?? "local");
|
|
18662
18760
|
const job = {
|
|
18663
18761
|
id,
|
|
18664
18762
|
task,
|
|
@@ -18672,11 +18770,19 @@ var init_cron_agent = __esm({
|
|
|
18672
18770
|
runCount: 0,
|
|
18673
18771
|
maxRuns,
|
|
18674
18772
|
history: [],
|
|
18675
|
-
tags
|
|
18773
|
+
tags,
|
|
18774
|
+
scope,
|
|
18775
|
+
projectDir: resolve26(this.workingDir)
|
|
18676
18776
|
};
|
|
18677
|
-
|
|
18678
|
-
|
|
18679
|
-
|
|
18777
|
+
if (scope === "global") {
|
|
18778
|
+
const store = await loadGlobalCronStore();
|
|
18779
|
+
store.jobs.push(job);
|
|
18780
|
+
await saveGlobalCronStore(store);
|
|
18781
|
+
} else {
|
|
18782
|
+
const store = await loadStore2(this.workingDir);
|
|
18783
|
+
store.jobs.push(job);
|
|
18784
|
+
await saveStore2(this.workingDir, store);
|
|
18785
|
+
}
|
|
18680
18786
|
installCronAgentJob(job, this.workingDir);
|
|
18681
18787
|
return {
|
|
18682
18788
|
success: true,
|
|
@@ -18700,19 +18806,19 @@ var init_cron_agent = __esm({
|
|
|
18700
18806
|
};
|
|
18701
18807
|
}
|
|
18702
18808
|
async listJobs(start) {
|
|
18703
|
-
const
|
|
18704
|
-
|
|
18809
|
+
const { local, global } = await loadAllCronStores(this.workingDir);
|
|
18810
|
+
const totalCount = local.jobs.length + global.jobs.length;
|
|
18811
|
+
if (totalCount === 0) {
|
|
18705
18812
|
return {
|
|
18706
18813
|
success: true,
|
|
18707
18814
|
output: "No cron agent jobs. Use cron_agent(action='create', ...) to schedule one.",
|
|
18708
18815
|
durationMs: performance.now() - start
|
|
18709
18816
|
};
|
|
18710
18817
|
}
|
|
18711
|
-
const lines = [
|
|
18712
|
-
|
|
18713
|
-
for (const job of store.jobs) {
|
|
18818
|
+
const lines = [];
|
|
18819
|
+
const formatJob = (job, scopeLabel, isThisProject) => {
|
|
18714
18820
|
const statusIcon = job.status === "active" ? "\u25CF" : job.status === "completed" ? "\u2714" : job.status === "paused" ? "\u23F8" : "\u2716";
|
|
18715
|
-
lines.push(` ${statusIcon} [${job.id}] ${job.status.toUpperCase()}`);
|
|
18821
|
+
lines.push(` ${statusIcon} [${job.id}] ${job.status.toUpperCase()} [${scopeLabel}]`);
|
|
18716
18822
|
lines.push(` Goal: ${job.goal.slice(0, 80)}${job.goal.length > 80 ? "..." : ""}`);
|
|
18717
18823
|
lines.push(` Schedule: ${job.scheduleDescription}`);
|
|
18718
18824
|
lines.push(` Runs: ${job.runCount}${job.maxRuns > 0 ? `/${job.maxRuns}` : ""}`);
|
|
@@ -18720,7 +18826,25 @@ var init_cron_agent = __esm({
|
|
|
18720
18826
|
lines.push(` Last run: ${job.lastRunAt}`);
|
|
18721
18827
|
if (job.tags.length > 0)
|
|
18722
18828
|
lines.push(` Tags: ${job.tags.join(", ")}`);
|
|
18829
|
+
if (!isThisProject && job.projectDir) {
|
|
18830
|
+
lines.push(` Origin: ${job.projectDir}`);
|
|
18831
|
+
lines.push(` \u26A0 NOT scoped to this project \u2014 override with caution`);
|
|
18832
|
+
}
|
|
18723
18833
|
lines.push("");
|
|
18834
|
+
};
|
|
18835
|
+
if (local.jobs.length > 0) {
|
|
18836
|
+
lines.push(`Local Cron Jobs \u2014 this project (${local.jobs.length}):
|
|
18837
|
+
`);
|
|
18838
|
+
for (const job of local.jobs)
|
|
18839
|
+
formatJob(job, "local", true);
|
|
18840
|
+
}
|
|
18841
|
+
if (global.jobs.length > 0) {
|
|
18842
|
+
lines.push(`Global Cron Jobs \u2014 shared (${global.jobs.length}):
|
|
18843
|
+
`);
|
|
18844
|
+
for (const job of global.jobs) {
|
|
18845
|
+
const isThisProject = job.projectDir === resolve26(this.workingDir);
|
|
18846
|
+
formatJob(job, isThisProject ? "global, this project" : "global", isThisProject);
|
|
18847
|
+
}
|
|
18724
18848
|
}
|
|
18725
18849
|
return {
|
|
18726
18850
|
success: true,
|
|
@@ -18856,6 +18980,575 @@ ${truncated}`, durationMs: performance.now() - start };
|
|
|
18856
18980
|
}
|
|
18857
18981
|
});
|
|
18858
18982
|
|
|
18983
|
+
// packages/execution/dist/tools/file-explore.js
|
|
18984
|
+
import { readFile as readFile19 } from "node:fs/promises";
|
|
18985
|
+
import { resolve as resolve27 } from "node:path";
|
|
18986
|
+
import { execFile as execFile4 } from "node:child_process";
|
|
18987
|
+
import { promisify as promisify3 } from "node:util";
|
|
18988
|
+
function getPatterns(filePath) {
|
|
18989
|
+
if (/\.(ts|tsx|js|jsx|mjs|cjs)$/.test(filePath))
|
|
18990
|
+
return SIG_PATTERNS.ts;
|
|
18991
|
+
if (/\.py$/.test(filePath))
|
|
18992
|
+
return SIG_PATTERNS.py;
|
|
18993
|
+
if (/\.rs$/.test(filePath))
|
|
18994
|
+
return SIG_PATTERNS.rs;
|
|
18995
|
+
if (/\.go$/.test(filePath))
|
|
18996
|
+
return SIG_PATTERNS.go;
|
|
18997
|
+
return SIG_PATTERNS.default;
|
|
18998
|
+
}
|
|
18999
|
+
function clearExploreNotes() {
|
|
19000
|
+
sessionNotes.length = 0;
|
|
19001
|
+
}
|
|
19002
|
+
function getExploreNotes() {
|
|
19003
|
+
return sessionNotes;
|
|
19004
|
+
}
|
|
19005
|
+
var execFileAsync3, sessionNotes, SIG_PATTERNS, FileExploreTool;
|
|
19006
|
+
var init_file_explore = __esm({
|
|
19007
|
+
"packages/execution/dist/tools/file-explore.js"() {
|
|
19008
|
+
"use strict";
|
|
19009
|
+
execFileAsync3 = promisify3(execFile4);
|
|
19010
|
+
sessionNotes = [];
|
|
19011
|
+
SIG_PATTERNS = {
|
|
19012
|
+
ts: [
|
|
19013
|
+
/^\s*(export\s+)?(async\s+)?function\s+\w+/,
|
|
19014
|
+
/^\s*(export\s+)?(abstract\s+)?class\s+\w+/,
|
|
19015
|
+
/^\s*(export\s+)?(const|let|var)\s+\w+\s*[:=]/,
|
|
19016
|
+
/^\s*(export\s+)?interface\s+\w+/,
|
|
19017
|
+
/^\s*(export\s+)?type\s+\w+\s*=/,
|
|
19018
|
+
/^\s*(export\s+)?enum\s+\w+/,
|
|
19019
|
+
/^\s*(?:public|private|protected|static|async|get|set)\s+\w+\s*[(<]/
|
|
19020
|
+
],
|
|
19021
|
+
py: [
|
|
19022
|
+
/^\s*def\s+\w+/,
|
|
19023
|
+
/^\s*class\s+\w+/,
|
|
19024
|
+
/^\s*async\s+def\s+\w+/,
|
|
19025
|
+
/^[A-Z_][A-Z_0-9]*\s*=/
|
|
19026
|
+
],
|
|
19027
|
+
rs: [
|
|
19028
|
+
/^\s*(pub\s+)?(async\s+)?fn\s+\w+/,
|
|
19029
|
+
/^\s*(pub\s+)?struct\s+\w+/,
|
|
19030
|
+
/^\s*(pub\s+)?enum\s+\w+/,
|
|
19031
|
+
/^\s*(pub\s+)?trait\s+\w+/,
|
|
19032
|
+
/^\s*impl\s+/
|
|
19033
|
+
],
|
|
19034
|
+
go: [
|
|
19035
|
+
/^\s*func\s+/,
|
|
19036
|
+
/^\s*type\s+\w+\s+struct/,
|
|
19037
|
+
/^\s*type\s+\w+\s+interface/
|
|
19038
|
+
],
|
|
19039
|
+
default: [
|
|
19040
|
+
/^\s*(export\s+)?(function|class|const|let|var|def|fn|pub|type|interface|enum|struct|trait|impl)\s+/
|
|
19041
|
+
]
|
|
19042
|
+
};
|
|
19043
|
+
FileExploreTool = class {
|
|
19044
|
+
name = "file_explore";
|
|
19045
|
+
description = "Explore large files without reading them entirely into context. Strategies: 'overview' (structural skeleton \u2014 imports, exports, signatures), 'search' (grep pattern with \xB1N context lines), 'chunk' (read specific line range, auto-saved to working notes), 'outline' (function/class/method signatures only), 'notes' (show accumulated findings from this session). Use this INSTEAD of file_read for files > 200 lines. Pattern: overview \u2192 search for target \u2192 chunk to read details \u2192 note findings.";
|
|
19046
|
+
parameters = {
|
|
19047
|
+
type: "object",
|
|
19048
|
+
properties: {
|
|
19049
|
+
path: {
|
|
19050
|
+
type: "string",
|
|
19051
|
+
description: "File path to explore"
|
|
19052
|
+
},
|
|
19053
|
+
strategy: {
|
|
19054
|
+
type: "string",
|
|
19055
|
+
enum: ["overview", "search", "chunk", "outline", "notes"],
|
|
19056
|
+
description: "Exploration strategy"
|
|
19057
|
+
},
|
|
19058
|
+
query: {
|
|
19059
|
+
type: "string",
|
|
19060
|
+
description: "Search pattern (for 'search' strategy) or note text (for 'chunk' with note)"
|
|
19061
|
+
},
|
|
19062
|
+
offset: {
|
|
19063
|
+
type: "number",
|
|
19064
|
+
description: "Starting line number, 1-based (for 'chunk' strategy)"
|
|
19065
|
+
},
|
|
19066
|
+
limit: {
|
|
19067
|
+
type: "number",
|
|
19068
|
+
description: "Number of lines to read (for 'chunk', default 50)"
|
|
19069
|
+
},
|
|
19070
|
+
context_lines: {
|
|
19071
|
+
type: "number",
|
|
19072
|
+
description: "Lines of context around each match (for 'search', default 5)"
|
|
19073
|
+
},
|
|
19074
|
+
note: {
|
|
19075
|
+
type: "string",
|
|
19076
|
+
description: "Working note to save about this chunk (for 'chunk' strategy)"
|
|
19077
|
+
}
|
|
19078
|
+
},
|
|
19079
|
+
required: ["strategy"]
|
|
19080
|
+
};
|
|
19081
|
+
workingDir;
|
|
19082
|
+
constructor(workingDir) {
|
|
19083
|
+
this.workingDir = workingDir;
|
|
19084
|
+
}
|
|
19085
|
+
async execute(args) {
|
|
19086
|
+
const strategy = String(args["strategy"] ?? "overview");
|
|
19087
|
+
const filePath = String(args["path"] ?? "");
|
|
19088
|
+
const start = performance.now();
|
|
19089
|
+
switch (strategy) {
|
|
19090
|
+
case "overview":
|
|
19091
|
+
return this.overview(filePath, start);
|
|
19092
|
+
case "search":
|
|
19093
|
+
return this.search(filePath, String(args["query"] ?? ""), args, start);
|
|
19094
|
+
case "chunk":
|
|
19095
|
+
return this.chunk(filePath, args, start);
|
|
19096
|
+
case "outline":
|
|
19097
|
+
return this.outline(filePath, start);
|
|
19098
|
+
case "notes":
|
|
19099
|
+
return this.showNotes(filePath, start);
|
|
19100
|
+
default:
|
|
19101
|
+
return {
|
|
19102
|
+
success: false,
|
|
19103
|
+
output: "",
|
|
19104
|
+
error: `Unknown strategy '${strategy}'. Use: overview, search, chunk, outline, notes`,
|
|
19105
|
+
durationMs: performance.now() - start
|
|
19106
|
+
};
|
|
19107
|
+
}
|
|
19108
|
+
}
|
|
19109
|
+
/**
|
|
19110
|
+
* overview: Read structural skeleton — first 30 lines (imports/config),
|
|
19111
|
+
* all signature lines, last 20 lines (exports/module boundary).
|
|
19112
|
+
*/
|
|
19113
|
+
async overview(filePath, start) {
|
|
19114
|
+
if (!filePath)
|
|
19115
|
+
return { success: false, output: "", error: "path required for overview", durationMs: performance.now() - start };
|
|
19116
|
+
try {
|
|
19117
|
+
const fullPath = resolve27(this.workingDir, filePath);
|
|
19118
|
+
const content = await readFile19(fullPath, "utf-8");
|
|
19119
|
+
const lines = content.split("\n");
|
|
19120
|
+
const total = lines.length;
|
|
19121
|
+
const HEAD = Math.min(30, total);
|
|
19122
|
+
const TAIL = Math.min(20, Math.max(0, total - HEAD));
|
|
19123
|
+
const parts = [];
|
|
19124
|
+
parts.push(`# ${filePath} (${total} lines)
|
|
19125
|
+
`);
|
|
19126
|
+
parts.push("## Head (lines 1-" + HEAD + ")");
|
|
19127
|
+
for (let i = 0; i < HEAD; i++) {
|
|
19128
|
+
parts.push(`${String(i + 1).padStart(6)} | ${lines[i]}`);
|
|
19129
|
+
}
|
|
19130
|
+
if (total > HEAD + TAIL) {
|
|
19131
|
+
const patterns = getPatterns(filePath);
|
|
19132
|
+
const sigs = [];
|
|
19133
|
+
for (let i = HEAD; i < total - TAIL; i++) {
|
|
19134
|
+
const line = lines[i];
|
|
19135
|
+
if (patterns.some((p) => p.test(line))) {
|
|
19136
|
+
sigs.push(`${String(i + 1).padStart(6)} | ${line}`);
|
|
19137
|
+
}
|
|
19138
|
+
}
|
|
19139
|
+
if (sigs.length > 0) {
|
|
19140
|
+
parts.push(`
|
|
19141
|
+
## Signatures (lines ${HEAD + 1}-${total - TAIL}) \u2014 ${sigs.length} found`);
|
|
19142
|
+
parts.push(...sigs);
|
|
19143
|
+
} else {
|
|
19144
|
+
parts.push(`
|
|
19145
|
+
## Middle (lines ${HEAD + 1}-${total - TAIL}) \u2014 ${total - HEAD - TAIL} lines, no signatures detected`);
|
|
19146
|
+
}
|
|
19147
|
+
}
|
|
19148
|
+
if (TAIL > 0) {
|
|
19149
|
+
const tailStart = total - TAIL;
|
|
19150
|
+
parts.push(`
|
|
19151
|
+
## Tail (lines ${tailStart + 1}-${total})`);
|
|
19152
|
+
for (let i = tailStart; i < total; i++) {
|
|
19153
|
+
parts.push(`${String(i + 1).padStart(6)} | ${lines[i]}`);
|
|
19154
|
+
}
|
|
19155
|
+
}
|
|
19156
|
+
parts.push(`
|
|
19157
|
+
[Use file_explore(strategy='search', query='...') to find specific sections]`);
|
|
19158
|
+
parts.push(`[Use file_explore(strategy='chunk', offset=N, limit=50) to read a section]`);
|
|
19159
|
+
return {
|
|
19160
|
+
success: true,
|
|
19161
|
+
output: parts.join("\n"),
|
|
19162
|
+
durationMs: performance.now() - start
|
|
19163
|
+
};
|
|
19164
|
+
} catch (error) {
|
|
19165
|
+
return {
|
|
19166
|
+
success: false,
|
|
19167
|
+
output: "",
|
|
19168
|
+
error: error instanceof Error ? error.message : String(error),
|
|
19169
|
+
durationMs: performance.now() - start
|
|
19170
|
+
};
|
|
19171
|
+
}
|
|
19172
|
+
}
|
|
19173
|
+
/**
|
|
19174
|
+
* search: Grep for pattern with context lines around each match.
|
|
19175
|
+
*/
|
|
19176
|
+
async search(filePath, query, args, start) {
|
|
19177
|
+
if (!query)
|
|
19178
|
+
return { success: false, output: "", error: "query required for search strategy", durationMs: performance.now() - start };
|
|
19179
|
+
const contextLines = Number(args["context_lines"] ?? 5);
|
|
19180
|
+
const searchPath = filePath ? resolve27(this.workingDir, filePath) : this.workingDir;
|
|
19181
|
+
try {
|
|
19182
|
+
const rgArgs = [
|
|
19183
|
+
"--line-number",
|
|
19184
|
+
"--no-heading",
|
|
19185
|
+
"--color=never",
|
|
19186
|
+
"-C",
|
|
19187
|
+
String(contextLines)
|
|
19188
|
+
];
|
|
19189
|
+
if (filePath) {
|
|
19190
|
+
rgArgs.push(query, searchPath);
|
|
19191
|
+
} else {
|
|
19192
|
+
rgArgs.push(query, this.workingDir);
|
|
19193
|
+
}
|
|
19194
|
+
const { stdout } = await execFileAsync3("rg", rgArgs, {
|
|
19195
|
+
cwd: this.workingDir,
|
|
19196
|
+
maxBuffer: 1024 * 1024
|
|
19197
|
+
});
|
|
19198
|
+
const lines = stdout.split("\n").filter((l) => l.length > 0);
|
|
19199
|
+
const matchCount = lines.filter((l) => /^\d+:/.test(l) || /:\d+:/.test(l)).length;
|
|
19200
|
+
const MAX = 80;
|
|
19201
|
+
const truncated = lines.length > MAX;
|
|
19202
|
+
const output = lines.slice(0, MAX).join("\n");
|
|
19203
|
+
const result = [
|
|
19204
|
+
`Found ${matchCount} matches for "${query}"${filePath ? ` in ${filePath}` : ""}:`,
|
|
19205
|
+
"",
|
|
19206
|
+
truncated ? output + `
|
|
19207
|
+
|
|
19208
|
+
[Truncated \u2014 ${lines.length - MAX} more lines]` : output,
|
|
19209
|
+
"",
|
|
19210
|
+
`[Use file_explore(strategy='chunk', path='...', offset=N) to read around a specific match]`
|
|
19211
|
+
].join("\n");
|
|
19212
|
+
return {
|
|
19213
|
+
success: true,
|
|
19214
|
+
output: result,
|
|
19215
|
+
durationMs: performance.now() - start
|
|
19216
|
+
};
|
|
19217
|
+
} catch (error) {
|
|
19218
|
+
const err = error;
|
|
19219
|
+
if (err.code === 1) {
|
|
19220
|
+
return {
|
|
19221
|
+
success: true,
|
|
19222
|
+
output: `No matches for "${query}"${filePath ? ` in ${filePath}` : ""}.`,
|
|
19223
|
+
durationMs: performance.now() - start
|
|
19224
|
+
};
|
|
19225
|
+
}
|
|
19226
|
+
try {
|
|
19227
|
+
const grepArgs = ["-rn", "--color=never", `-C${contextLines}`];
|
|
19228
|
+
if (filePath) {
|
|
19229
|
+
grepArgs.push(query, searchPath);
|
|
19230
|
+
} else {
|
|
19231
|
+
grepArgs.push(query, this.workingDir);
|
|
19232
|
+
}
|
|
19233
|
+
const { stdout } = await execFileAsync3("grep", grepArgs, {
|
|
19234
|
+
cwd: this.workingDir,
|
|
19235
|
+
maxBuffer: 1024 * 1024
|
|
19236
|
+
});
|
|
19237
|
+
return {
|
|
19238
|
+
success: true,
|
|
19239
|
+
output: stdout.split("\n").slice(0, 80).join("\n"),
|
|
19240
|
+
durationMs: performance.now() - start
|
|
19241
|
+
};
|
|
19242
|
+
} catch {
|
|
19243
|
+
return {
|
|
19244
|
+
success: true,
|
|
19245
|
+
output: `No matches for "${query}".`,
|
|
19246
|
+
durationMs: performance.now() - start
|
|
19247
|
+
};
|
|
19248
|
+
}
|
|
19249
|
+
}
|
|
19250
|
+
}
|
|
19251
|
+
/**
|
|
19252
|
+
* chunk: Read a specific line range and optionally save a working note.
|
|
19253
|
+
*/
|
|
19254
|
+
async chunk(filePath, args, start) {
|
|
19255
|
+
if (!filePath)
|
|
19256
|
+
return { success: false, output: "", error: "path required for chunk strategy", durationMs: performance.now() - start };
|
|
19257
|
+
const offset = Number(args["offset"] ?? 1);
|
|
19258
|
+
const limit = Number(args["limit"] ?? 50);
|
|
19259
|
+
const note = args["note"];
|
|
19260
|
+
try {
|
|
19261
|
+
const fullPath = resolve27(this.workingDir, filePath);
|
|
19262
|
+
const content = await readFile19(fullPath, "utf-8");
|
|
19263
|
+
const allLines = content.split("\n");
|
|
19264
|
+
const total = allLines.length;
|
|
19265
|
+
const startIdx = Math.max(0, offset - 1);
|
|
19266
|
+
const endIdx = Math.min(total, startIdx + limit);
|
|
19267
|
+
const chunk = allLines.slice(startIdx, endIdx);
|
|
19268
|
+
const numbered = chunk.map((line, i) => `${String(startIdx + i + 1).padStart(6)} | ${line}`).join("\n");
|
|
19269
|
+
if (note) {
|
|
19270
|
+
sessionNotes.push({
|
|
19271
|
+
file: filePath,
|
|
19272
|
+
lineRange: [startIdx + 1, endIdx],
|
|
19273
|
+
finding: note,
|
|
19274
|
+
timestamp: Date.now()
|
|
19275
|
+
});
|
|
19276
|
+
}
|
|
19277
|
+
const nav = [];
|
|
19278
|
+
if (startIdx > 0) {
|
|
19279
|
+
nav.push(`[Previous: file_explore(strategy='chunk', path='${filePath}', offset=${Math.max(1, startIdx + 1 - limit)}, limit=${limit})]`);
|
|
19280
|
+
}
|
|
19281
|
+
if (endIdx < total) {
|
|
19282
|
+
nav.push(`[Next: file_explore(strategy='chunk', path='${filePath}', offset=${endIdx + 1}, limit=${limit})]`);
|
|
19283
|
+
}
|
|
19284
|
+
nav.push(`[${total} total lines \u2014 showing ${startIdx + 1}-${endIdx}]`);
|
|
19285
|
+
if (sessionNotes.length > 0) {
|
|
19286
|
+
nav.push(`[${sessionNotes.length} working notes \u2014 file_explore(strategy='notes') to review]`);
|
|
19287
|
+
}
|
|
19288
|
+
return {
|
|
19289
|
+
success: true,
|
|
19290
|
+
output: numbered + "\n\n" + nav.join("\n"),
|
|
19291
|
+
durationMs: performance.now() - start
|
|
19292
|
+
};
|
|
19293
|
+
} catch (error) {
|
|
19294
|
+
return {
|
|
19295
|
+
success: false,
|
|
19296
|
+
output: "",
|
|
19297
|
+
error: error instanceof Error ? error.message : String(error),
|
|
19298
|
+
durationMs: performance.now() - start
|
|
19299
|
+
};
|
|
19300
|
+
}
|
|
19301
|
+
}
|
|
19302
|
+
/**
|
|
19303
|
+
* outline: Extract only function/class/method/export signatures.
|
|
19304
|
+
*/
|
|
19305
|
+
async outline(filePath, start) {
|
|
19306
|
+
if (!filePath)
|
|
19307
|
+
return { success: false, output: "", error: "path required for outline", durationMs: performance.now() - start };
|
|
19308
|
+
try {
|
|
19309
|
+
const fullPath = resolve27(this.workingDir, filePath);
|
|
19310
|
+
const content = await readFile19(fullPath, "utf-8");
|
|
19311
|
+
const lines = content.split("\n");
|
|
19312
|
+
const patterns = getPatterns(filePath);
|
|
19313
|
+
const sigs = [];
|
|
19314
|
+
for (let i = 0; i < lines.length; i++) {
|
|
19315
|
+
const line = lines[i];
|
|
19316
|
+
if (patterns.some((p) => p.test(line))) {
|
|
19317
|
+
sigs.push(`${String(i + 1).padStart(6)} | ${line.trimEnd()}`);
|
|
19318
|
+
}
|
|
19319
|
+
}
|
|
19320
|
+
if (sigs.length === 0) {
|
|
19321
|
+
return {
|
|
19322
|
+
success: true,
|
|
19323
|
+
output: `${filePath}: ${lines.length} lines, no recognizable signatures found.
|
|
19324
|
+
[Use file_explore(strategy='overview') for a broader view]`,
|
|
19325
|
+
durationMs: performance.now() - start
|
|
19326
|
+
};
|
|
19327
|
+
}
|
|
19328
|
+
return {
|
|
19329
|
+
success: true,
|
|
19330
|
+
output: `# ${filePath} \u2014 ${sigs.length} signatures (${lines.length} total lines)
|
|
19331
|
+
|
|
19332
|
+
` + sigs.join("\n") + `
|
|
19333
|
+
|
|
19334
|
+
[Use file_explore(strategy='chunk', offset=N) to read around a specific signature]`,
|
|
19335
|
+
durationMs: performance.now() - start
|
|
19336
|
+
};
|
|
19337
|
+
} catch (error) {
|
|
19338
|
+
return {
|
|
19339
|
+
success: false,
|
|
19340
|
+
output: "",
|
|
19341
|
+
error: error instanceof Error ? error.message : String(error),
|
|
19342
|
+
durationMs: performance.now() - start
|
|
19343
|
+
};
|
|
19344
|
+
}
|
|
19345
|
+
}
|
|
19346
|
+
/**
|
|
19347
|
+
* notes: Show accumulated working notes from this exploration session.
|
|
19348
|
+
*/
|
|
19349
|
+
showNotes(filePath, start) {
|
|
19350
|
+
const notes2 = filePath ? sessionNotes.filter((n) => n.file === filePath) : sessionNotes;
|
|
19351
|
+
if (notes2.length === 0) {
|
|
19352
|
+
return {
|
|
19353
|
+
success: true,
|
|
19354
|
+
output: "No working notes yet. Use file_explore(strategy='chunk', note='your finding') to save notes as you explore.",
|
|
19355
|
+
durationMs: performance.now() - start
|
|
19356
|
+
};
|
|
19357
|
+
}
|
|
19358
|
+
const parts = [`# Working Notes (${notes2.length})
|
|
19359
|
+
`];
|
|
19360
|
+
for (const n of notes2) {
|
|
19361
|
+
parts.push(`- **${n.file}** lines ${n.lineRange[0]}-${n.lineRange[1]}: ${n.finding}`);
|
|
19362
|
+
}
|
|
19363
|
+
return {
|
|
19364
|
+
success: true,
|
|
19365
|
+
output: parts.join("\n"),
|
|
19366
|
+
durationMs: performance.now() - start
|
|
19367
|
+
};
|
|
19368
|
+
}
|
|
19369
|
+
};
|
|
19370
|
+
}
|
|
19371
|
+
});
|
|
19372
|
+
|
|
19373
|
+
// packages/execution/dist/tools/working-notes.js
|
|
19374
|
+
function getWorkingNotes() {
|
|
19375
|
+
return notes;
|
|
19376
|
+
}
|
|
19377
|
+
function getWorkingNotesSummary() {
|
|
19378
|
+
if (notes.length === 0)
|
|
19379
|
+
return "";
|
|
19380
|
+
const parts = [`Working notes (${notes.length}):`];
|
|
19381
|
+
for (const n of notes) {
|
|
19382
|
+
const loc = n.file ? ` [${n.file}${n.line ? `:${n.line}` : ""}]` : "";
|
|
19383
|
+
parts.push(`- [${n.category}] ${n.content.slice(0, 150)}${loc}`);
|
|
19384
|
+
}
|
|
19385
|
+
return parts.join("\n");
|
|
19386
|
+
}
|
|
19387
|
+
function clearWorkingNotes() {
|
|
19388
|
+
notes.length = 0;
|
|
19389
|
+
noteCounter = 0;
|
|
19390
|
+
}
|
|
19391
|
+
var noteCounter, notes, WorkingNotesTool;
|
|
19392
|
+
var init_working_notes = __esm({
|
|
19393
|
+
"packages/execution/dist/tools/working-notes.js"() {
|
|
19394
|
+
"use strict";
|
|
19395
|
+
noteCounter = 0;
|
|
19396
|
+
notes = [];
|
|
19397
|
+
WorkingNotesTool = class {
|
|
19398
|
+
name = "working_notes";
|
|
19399
|
+
description = "In-task scratchpad for tracking discoveries, decisions, and TODOs. Notes persist across tool calls and survive context compaction. Actions: 'add' a note, 'list' all notes, 'search' notes by keyword, 'clear' all notes, 'summary' get a compact summary. Use this to maintain signal when exploring large codebases \u2014 note findings as you go so you don't lose them to context limits.";
|
|
19400
|
+
parameters = {
|
|
19401
|
+
type: "object",
|
|
19402
|
+
properties: {
|
|
19403
|
+
action: {
|
|
19404
|
+
type: "string",
|
|
19405
|
+
enum: ["add", "list", "search", "clear", "summary"],
|
|
19406
|
+
description: "Action to perform (default: 'list')"
|
|
19407
|
+
},
|
|
19408
|
+
content: {
|
|
19409
|
+
type: "string",
|
|
19410
|
+
description: "Note content (for 'add') or search query (for 'search')"
|
|
19411
|
+
},
|
|
19412
|
+
category: {
|
|
19413
|
+
type: "string",
|
|
19414
|
+
enum: ["finding", "todo", "question", "decision", "blocker"],
|
|
19415
|
+
description: "Note category (for 'add', default: 'finding')"
|
|
19416
|
+
},
|
|
19417
|
+
file: {
|
|
19418
|
+
type: "string",
|
|
19419
|
+
description: "Related file path (for 'add')"
|
|
19420
|
+
},
|
|
19421
|
+
line: {
|
|
19422
|
+
type: "number",
|
|
19423
|
+
description: "Related line number (for 'add')"
|
|
19424
|
+
}
|
|
19425
|
+
},
|
|
19426
|
+
required: []
|
|
19427
|
+
};
|
|
19428
|
+
async execute(args) {
|
|
19429
|
+
const action = String(args["action"] ?? "list");
|
|
19430
|
+
const start = performance.now();
|
|
19431
|
+
switch (action) {
|
|
19432
|
+
case "add": {
|
|
19433
|
+
const content = String(args["content"] ?? "");
|
|
19434
|
+
if (!content)
|
|
19435
|
+
return { success: false, output: "", error: "content required", durationMs: performance.now() - start };
|
|
19436
|
+
const note = {
|
|
19437
|
+
id: ++noteCounter,
|
|
19438
|
+
category: String(args["category"] ?? "finding"),
|
|
19439
|
+
content,
|
|
19440
|
+
file: args["file"],
|
|
19441
|
+
line: args["line"],
|
|
19442
|
+
timestamp: Date.now()
|
|
19443
|
+
};
|
|
19444
|
+
notes.push(note);
|
|
19445
|
+
return {
|
|
19446
|
+
success: true,
|
|
19447
|
+
output: `Note #${note.id} added [${note.category}]${note.file ? ` (${note.file}${note.line ? `:${note.line}` : ""})` : ""}: ${content.slice(0, 100)}`,
|
|
19448
|
+
durationMs: performance.now() - start
|
|
19449
|
+
};
|
|
19450
|
+
}
|
|
19451
|
+
case "list": {
|
|
19452
|
+
if (notes.length === 0) {
|
|
19453
|
+
return {
|
|
19454
|
+
success: true,
|
|
19455
|
+
output: "No working notes. Use working_notes(action='add', content='...') to start tracking findings.",
|
|
19456
|
+
durationMs: performance.now() - start
|
|
19457
|
+
};
|
|
19458
|
+
}
|
|
19459
|
+
const lines = [`Working Notes (${notes.length}):
|
|
19460
|
+
`];
|
|
19461
|
+
for (const n of notes) {
|
|
19462
|
+
const loc = n.file ? ` @ ${n.file}${n.line ? `:${n.line}` : ""}` : "";
|
|
19463
|
+
lines.push(` #${n.id} [${n.category}]${loc}: ${n.content}`);
|
|
19464
|
+
}
|
|
19465
|
+
return {
|
|
19466
|
+
success: true,
|
|
19467
|
+
output: lines.join("\n"),
|
|
19468
|
+
durationMs: performance.now() - start
|
|
19469
|
+
};
|
|
19470
|
+
}
|
|
19471
|
+
case "search": {
|
|
19472
|
+
const query = String(args["content"] ?? "").toLowerCase();
|
|
19473
|
+
if (!query)
|
|
19474
|
+
return { success: false, output: "", error: "content (search query) required", durationMs: performance.now() - start };
|
|
19475
|
+
const matches = notes.filter((n) => n.content.toLowerCase().includes(query) || n.file && n.file.toLowerCase().includes(query) || n.category.toLowerCase().includes(query));
|
|
19476
|
+
if (matches.length === 0) {
|
|
19477
|
+
return {
|
|
19478
|
+
success: true,
|
|
19479
|
+
output: `No notes matching "${query}".`,
|
|
19480
|
+
durationMs: performance.now() - start
|
|
19481
|
+
};
|
|
19482
|
+
}
|
|
19483
|
+
const lines = [`Notes matching "${query}" (${matches.length}):
|
|
19484
|
+
`];
|
|
19485
|
+
for (const n of matches) {
|
|
19486
|
+
const loc = n.file ? ` @ ${n.file}${n.line ? `:${n.line}` : ""}` : "";
|
|
19487
|
+
lines.push(` #${n.id} [${n.category}]${loc}: ${n.content}`);
|
|
19488
|
+
}
|
|
19489
|
+
return {
|
|
19490
|
+
success: true,
|
|
19491
|
+
output: lines.join("\n"),
|
|
19492
|
+
durationMs: performance.now() - start
|
|
19493
|
+
};
|
|
19494
|
+
}
|
|
19495
|
+
case "clear": {
|
|
19496
|
+
const count = notes.length;
|
|
19497
|
+
notes.length = 0;
|
|
19498
|
+
noteCounter = 0;
|
|
19499
|
+
return {
|
|
19500
|
+
success: true,
|
|
19501
|
+
output: `Cleared ${count} working notes.`,
|
|
19502
|
+
durationMs: performance.now() - start
|
|
19503
|
+
};
|
|
19504
|
+
}
|
|
19505
|
+
case "summary": {
|
|
19506
|
+
if (notes.length === 0) {
|
|
19507
|
+
return {
|
|
19508
|
+
success: true,
|
|
19509
|
+
output: "No working notes to summarize.",
|
|
19510
|
+
durationMs: performance.now() - start
|
|
19511
|
+
};
|
|
19512
|
+
}
|
|
19513
|
+
const groups = /* @__PURE__ */ new Map();
|
|
19514
|
+
for (const n of notes) {
|
|
19515
|
+
const list = groups.get(n.category) ?? [];
|
|
19516
|
+
list.push(n);
|
|
19517
|
+
groups.set(n.category, list);
|
|
19518
|
+
}
|
|
19519
|
+
const parts = [`Working Notes Summary (${notes.length} total):
|
|
19520
|
+
`];
|
|
19521
|
+
for (const [cat, items] of groups) {
|
|
19522
|
+
parts.push(` ${cat.toUpperCase()} (${items.length}):`);
|
|
19523
|
+
for (const n of items) {
|
|
19524
|
+
const loc = n.file ? ` [${n.file}${n.line ? `:${n.line}` : ""}]` : "";
|
|
19525
|
+
parts.push(` - ${n.content.slice(0, 120)}${loc}`);
|
|
19526
|
+
}
|
|
19527
|
+
}
|
|
19528
|
+
const files = new Set(notes.filter((n) => n.file).map((n) => n.file));
|
|
19529
|
+
if (files.size > 0) {
|
|
19530
|
+
parts.push(`
|
|
19531
|
+
Files referenced: ${[...files].join(", ")}`);
|
|
19532
|
+
}
|
|
19533
|
+
return {
|
|
19534
|
+
success: true,
|
|
19535
|
+
output: parts.join("\n"),
|
|
19536
|
+
durationMs: performance.now() - start
|
|
19537
|
+
};
|
|
19538
|
+
}
|
|
19539
|
+
default:
|
|
19540
|
+
return {
|
|
19541
|
+
success: false,
|
|
19542
|
+
output: "",
|
|
19543
|
+
error: `Unknown action '${action}'. Use: add, list, search, clear, summary`,
|
|
19544
|
+
durationMs: performance.now() - start
|
|
19545
|
+
};
|
|
19546
|
+
}
|
|
19547
|
+
}
|
|
19548
|
+
};
|
|
19549
|
+
}
|
|
19550
|
+
});
|
|
19551
|
+
|
|
18859
19552
|
// packages/execution/dist/tools/fortemi-bridge.js
|
|
18860
19553
|
import { existsSync as existsSync24, readFileSync as readFileSync17 } from "node:fs";
|
|
18861
19554
|
import { join as join38 } from "node:path";
|
|
@@ -19012,7 +19705,7 @@ import { spawn as spawn13 } from "node:child_process";
|
|
|
19012
19705
|
async function runShell(options) {
|
|
19013
19706
|
const { command, args = [], cwd: cwd4, env, timeoutMs = DEFAULT_TIMEOUT_MS } = options;
|
|
19014
19707
|
const mergedEnv = env ? { ...process.env, ...env } : process.env;
|
|
19015
|
-
return new Promise((
|
|
19708
|
+
return new Promise((resolve33) => {
|
|
19016
19709
|
const start = Date.now();
|
|
19017
19710
|
let timedOut = false;
|
|
19018
19711
|
const child = spawn13(command, args, {
|
|
@@ -19036,7 +19729,7 @@ async function runShell(options) {
|
|
|
19036
19729
|
clearTimeout(timer);
|
|
19037
19730
|
const durationMs = Date.now() - start;
|
|
19038
19731
|
const exitCode = timedOut ? -1 : code ?? -1;
|
|
19039
|
-
|
|
19732
|
+
resolve33({
|
|
19040
19733
|
stdout,
|
|
19041
19734
|
stderr,
|
|
19042
19735
|
exitCode,
|
|
@@ -19048,7 +19741,7 @@ async function runShell(options) {
|
|
|
19048
19741
|
child.on("error", (err) => {
|
|
19049
19742
|
clearTimeout(timer);
|
|
19050
19743
|
const durationMs = Date.now() - start;
|
|
19051
|
-
|
|
19744
|
+
resolve33({
|
|
19052
19745
|
stdout,
|
|
19053
19746
|
stderr: stderr + err.message,
|
|
19054
19747
|
exitCode: -1,
|
|
@@ -19163,7 +19856,7 @@ async function applyUnifiedDiff(patch) {
|
|
|
19163
19856
|
}
|
|
19164
19857
|
function runWithStdin(options) {
|
|
19165
19858
|
const { command, args, cwd: cwd4, stdin } = options;
|
|
19166
|
-
return new Promise((
|
|
19859
|
+
return new Promise((resolve33) => {
|
|
19167
19860
|
const child = spawn14(command, args, {
|
|
19168
19861
|
cwd: cwd4,
|
|
19169
19862
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -19180,10 +19873,10 @@ function runWithStdin(options) {
|
|
|
19180
19873
|
child.stdin.end();
|
|
19181
19874
|
child.on("close", (code) => {
|
|
19182
19875
|
const exitCode = code ?? -1;
|
|
19183
|
-
|
|
19876
|
+
resolve33({ success: exitCode === 0, exitCode, stdout, stderr });
|
|
19184
19877
|
});
|
|
19185
19878
|
child.on("error", (err) => {
|
|
19186
|
-
|
|
19879
|
+
resolve33({ success: false, exitCode: -1, stdout, stderr: err.message });
|
|
19187
19880
|
});
|
|
19188
19881
|
});
|
|
19189
19882
|
}
|
|
@@ -19631,6 +20324,7 @@ __export(dist_exports, {
|
|
|
19631
20324
|
ExploreToolsTool: () => ExploreToolsTool,
|
|
19632
20325
|
FactoryTool: () => FactoryTool,
|
|
19633
20326
|
FileEditTool: () => FileEditTool,
|
|
20327
|
+
FileExploreTool: () => FileExploreTool,
|
|
19634
20328
|
FilePatchTool: () => FilePatchTool,
|
|
19635
20329
|
FileReadTool: () => FileReadTool,
|
|
19636
20330
|
FileWriteTool: () => FileWriteTool,
|
|
@@ -19673,10 +20367,13 @@ __export(dist_exports, {
|
|
|
19673
20367
|
WebCrawlTool: () => WebCrawlTool,
|
|
19674
20368
|
WebFetchTool: () => WebFetchTool,
|
|
19675
20369
|
WebSearchTool: () => WebSearchTool,
|
|
20370
|
+
WorkingNotesTool: () => WorkingNotesTool,
|
|
19676
20371
|
applyPatch: () => applyPatch,
|
|
19677
20372
|
buildCustomTools: () => buildCustomTools,
|
|
19678
20373
|
buildSkillsSummary: () => buildSkillsSummary,
|
|
19679
20374
|
checkDesktopDeps: () => checkDesktopDeps,
|
|
20375
|
+
clearExploreNotes: () => clearExploreNotes,
|
|
20376
|
+
clearWorkingNotes: () => clearWorkingNotes,
|
|
19680
20377
|
createFortemiBridgeTools: () => createFortemiBridgeTools,
|
|
19681
20378
|
createWorktree: () => createWorktree,
|
|
19682
20379
|
detectSearchProvider: () => detectSearchProvider,
|
|
@@ -19686,6 +20383,9 @@ __export(dist_exports, {
|
|
|
19686
20383
|
ensureDepsForGroup: () => ensureDepsForGroup,
|
|
19687
20384
|
getActiveAttentionItems: () => getActiveAttentionItems,
|
|
19688
20385
|
getDueReminders: () => getDueReminders,
|
|
20386
|
+
getExploreNotes: () => getExploreNotes,
|
|
20387
|
+
getWorkingNotes: () => getWorkingNotes,
|
|
20388
|
+
getWorkingNotesSummary: () => getWorkingNotesSummary,
|
|
19689
20389
|
isFortemiAvailable: () => isFortemiAvailable,
|
|
19690
20390
|
isImagePath: () => isImagePath,
|
|
19691
20391
|
listCustomToolFiles: () => listCustomToolFiles,
|
|
@@ -19762,6 +20462,8 @@ var init_dist2 = __esm({
|
|
|
19762
20462
|
init_opencode();
|
|
19763
20463
|
init_factory();
|
|
19764
20464
|
init_cron_agent();
|
|
20465
|
+
init_file_explore();
|
|
20466
|
+
init_working_notes();
|
|
19765
20467
|
init_nexus();
|
|
19766
20468
|
init_fortemi_bridge();
|
|
19767
20469
|
init_system_deps();
|
|
@@ -20745,13 +21447,13 @@ var init_plannerRunner = __esm({
|
|
|
20745
21447
|
});
|
|
20746
21448
|
|
|
20747
21449
|
// packages/retrieval/dist/grep-search.js
|
|
20748
|
-
import { execFile as
|
|
20749
|
-
import { promisify as
|
|
20750
|
-
var
|
|
21450
|
+
import { execFile as execFile5 } from "node:child_process";
|
|
21451
|
+
import { promisify as promisify4 } from "node:util";
|
|
21452
|
+
var execFileAsync4, GrepSearch;
|
|
20751
21453
|
var init_grep_search2 = __esm({
|
|
20752
21454
|
"packages/retrieval/dist/grep-search.js"() {
|
|
20753
21455
|
"use strict";
|
|
20754
|
-
|
|
21456
|
+
execFileAsync4 = promisify4(execFile5);
|
|
20755
21457
|
GrepSearch = class {
|
|
20756
21458
|
rootDir;
|
|
20757
21459
|
constructor(rootDir) {
|
|
@@ -20773,7 +21475,7 @@ var init_grep_search2 = __esm({
|
|
|
20773
21475
|
}
|
|
20774
21476
|
args.push(pattern, this.rootDir);
|
|
20775
21477
|
try {
|
|
20776
|
-
const { stdout } = await
|
|
21478
|
+
const { stdout } = await execFileAsync4("rg", args, {
|
|
20777
21479
|
maxBuffer: 10 * 1024 * 1024
|
|
20778
21480
|
});
|
|
20779
21481
|
return this.parseRipgrepOutput(stdout);
|
|
@@ -20834,8 +21536,8 @@ var init_code_retriever = __esm({
|
|
|
20834
21536
|
});
|
|
20835
21537
|
}
|
|
20836
21538
|
async getFileContent(filePath, startLine, endLine) {
|
|
20837
|
-
const { readFile:
|
|
20838
|
-
const content = await
|
|
21539
|
+
const { readFile: readFile24 } = await import("node:fs/promises");
|
|
21540
|
+
const content = await readFile24(filePath, "utf-8");
|
|
20839
21541
|
if (startLine === void 0)
|
|
20840
21542
|
return content;
|
|
20841
21543
|
const lines = content.split("\n");
|
|
@@ -20848,9 +21550,9 @@ var init_code_retriever = __esm({
|
|
|
20848
21550
|
});
|
|
20849
21551
|
|
|
20850
21552
|
// packages/retrieval/dist/lexicalSearch.js
|
|
20851
|
-
import { execFile as
|
|
20852
|
-
import { promisify as
|
|
20853
|
-
import { readFile as
|
|
21553
|
+
import { execFile as execFile6 } from "node:child_process";
|
|
21554
|
+
import { promisify as promisify5 } from "node:util";
|
|
21555
|
+
import { readFile as readFile20, readdir as readdir5, stat as stat3 } from "node:fs/promises";
|
|
20854
21556
|
import { join as join40, extname as extname7 } from "node:path";
|
|
20855
21557
|
async function searchByPath(pathPattern, options) {
|
|
20856
21558
|
const allFiles = await collectFiles(options.rootDir, options.includeGlobs ?? DEFAULT_INCLUDE_GLOBS, options.excludeGlobs ?? DEFAULT_EXCLUDE_GLOBS);
|
|
@@ -20893,7 +21595,7 @@ async function runSearch(pattern, kind, options) {
|
|
|
20893
21595
|
}
|
|
20894
21596
|
async function isRipgrepAvailable() {
|
|
20895
21597
|
try {
|
|
20896
|
-
await
|
|
21598
|
+
await execFileAsync5("rg", ["--version"], { timeout: 2e3 });
|
|
20897
21599
|
return true;
|
|
20898
21600
|
} catch {
|
|
20899
21601
|
return false;
|
|
@@ -20913,7 +21615,7 @@ async function searchWithRipgrep(pattern, kind, options) {
|
|
|
20913
21615
|
args.push(pattern, options.rootDir);
|
|
20914
21616
|
let stdout;
|
|
20915
21617
|
try {
|
|
20916
|
-
const result = await
|
|
21618
|
+
const result = await execFileAsync5("rg", args, {
|
|
20917
21619
|
maxBuffer: 20 * 1024 * 1024,
|
|
20918
21620
|
timeout: 1e4
|
|
20919
21621
|
});
|
|
@@ -20956,7 +21658,7 @@ async function searchWithNodeFallback(pattern, kind, options) {
|
|
|
20956
21658
|
if (results.length >= maxMatches)
|
|
20957
21659
|
break;
|
|
20958
21660
|
try {
|
|
20959
|
-
const content = await
|
|
21661
|
+
const content = await readFile20(filePath, "utf-8");
|
|
20960
21662
|
const contentLines = content.split("\n");
|
|
20961
21663
|
for (let i = 0; i < contentLines.length; i++) {
|
|
20962
21664
|
if (results.length >= maxMatches)
|
|
@@ -21023,11 +21725,11 @@ function matchesGlob(filePath, glob2) {
|
|
|
21023
21725
|
return false;
|
|
21024
21726
|
}
|
|
21025
21727
|
}
|
|
21026
|
-
var
|
|
21728
|
+
var execFileAsync5, DEFAULT_INCLUDE_GLOBS, DEFAULT_EXCLUDE_GLOBS, DEFAULT_MAX_MATCHES, ALWAYS_SKIP, ALL_CODE_EXTS;
|
|
21027
21729
|
var init_lexicalSearch = __esm({
|
|
21028
21730
|
"packages/retrieval/dist/lexicalSearch.js"() {
|
|
21029
21731
|
"use strict";
|
|
21030
|
-
|
|
21732
|
+
execFileAsync5 = promisify5(execFile6);
|
|
21031
21733
|
DEFAULT_INCLUDE_GLOBS = ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx", "**/*.py"];
|
|
21032
21734
|
DEFAULT_EXCLUDE_GLOBS = ["node_modules", "dist", ".git", "build", "coverage"];
|
|
21033
21735
|
DEFAULT_MAX_MATCHES = 50;
|
|
@@ -21299,7 +22001,7 @@ var init_graphExpand = __esm({
|
|
|
21299
22001
|
});
|
|
21300
22002
|
|
|
21301
22003
|
// packages/retrieval/dist/snippetPacker.js
|
|
21302
|
-
import { readFile as
|
|
22004
|
+
import { readFile as readFile21 } from "node:fs/promises";
|
|
21303
22005
|
import { join as join41 } from "node:path";
|
|
21304
22006
|
async function packSnippets(requests, opts = {}) {
|
|
21305
22007
|
const maxTokens = opts.maxTokens ?? DEFAULT_MAX_TOKENS;
|
|
@@ -21329,7 +22031,7 @@ async function extractSnippet(req, repoRoot, contextLines = DEFAULT_CONTEXT_LINE
|
|
|
21329
22031
|
const absPath = req.filePath.startsWith("/") ? req.filePath : join41(repoRoot, req.filePath);
|
|
21330
22032
|
let content;
|
|
21331
22033
|
try {
|
|
21332
|
-
content = await
|
|
22034
|
+
content = await readFile21(absPath, "utf-8");
|
|
21333
22035
|
} catch {
|
|
21334
22036
|
return null;
|
|
21335
22037
|
}
|
|
@@ -21864,9 +22566,9 @@ var init_verifierRunner = __esm({
|
|
|
21864
22566
|
async executeTests(patch, repoRoot) {
|
|
21865
22567
|
if (patch.testsToRun.length === 0)
|
|
21866
22568
|
return "(no tests specified)";
|
|
21867
|
-
const { execFile:
|
|
21868
|
-
const { promisify:
|
|
21869
|
-
const
|
|
22569
|
+
const { execFile: execFile7 } = await import("node:child_process");
|
|
22570
|
+
const { promisify: promisify7 } = await import("node:util");
|
|
22571
|
+
const execFileAsync6 = promisify7(execFile7);
|
|
21870
22572
|
const outputs = [];
|
|
21871
22573
|
const workDir = this.options.workingDir || repoRoot;
|
|
21872
22574
|
for (const cmd of patch.testsToRun.slice(0, 3)) {
|
|
@@ -21875,7 +22577,7 @@ var init_verifierRunner = __esm({
|
|
|
21875
22577
|
const [bin, ...args] = parts;
|
|
21876
22578
|
if (!bin)
|
|
21877
22579
|
continue;
|
|
21878
|
-
const { stdout, stderr } = await
|
|
22580
|
+
const { stdout, stderr } = await execFileAsync6(bin, args, {
|
|
21879
22581
|
cwd: workDir,
|
|
21880
22582
|
timeout: 6e4,
|
|
21881
22583
|
maxBuffer: 1024 * 1024
|
|
@@ -22555,6 +23257,7 @@ var init_agenticRunner = __esm({
|
|
|
22555
23257
|
init_dist();
|
|
22556
23258
|
init_personality();
|
|
22557
23259
|
init_promptLoader();
|
|
23260
|
+
init_dist2();
|
|
22558
23261
|
SYSTEM_PROMPT = loadPrompt("agentic/system-large.md");
|
|
22559
23262
|
SYSTEM_PROMPT_MEDIUM = loadPrompt("agentic/system-medium.md");
|
|
22560
23263
|
SYSTEM_PROMPT_SMALL = loadPrompt("agentic/system-small.md");
|
|
@@ -22875,8 +23578,8 @@ ${this.options.dynamicContext}`,
|
|
|
22875
23578
|
async waitIfPaused() {
|
|
22876
23579
|
if (!this._paused)
|
|
22877
23580
|
return true;
|
|
22878
|
-
await new Promise((
|
|
22879
|
-
this._pauseResolve =
|
|
23581
|
+
await new Promise((resolve33) => {
|
|
23582
|
+
this._pauseResolve = resolve33;
|
|
22880
23583
|
});
|
|
22881
23584
|
return !this.aborted;
|
|
22882
23585
|
}
|
|
@@ -23909,14 +24612,14 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
|
|
|
23909
24612
|
waitForSudoPassword(timeoutMs = 12e4) {
|
|
23910
24613
|
if (this._sudoPassword)
|
|
23911
24614
|
return Promise.resolve(this._sudoPassword);
|
|
23912
|
-
return new Promise((
|
|
24615
|
+
return new Promise((resolve33) => {
|
|
23913
24616
|
const timer = setTimeout(() => {
|
|
23914
24617
|
this._sudoResolve = null;
|
|
23915
|
-
|
|
24618
|
+
resolve33(null);
|
|
23916
24619
|
}, timeoutMs);
|
|
23917
24620
|
this._sudoResolve = (pw) => {
|
|
23918
24621
|
clearTimeout(timer);
|
|
23919
|
-
|
|
24622
|
+
resolve33(pw);
|
|
23920
24623
|
};
|
|
23921
24624
|
});
|
|
23922
24625
|
}
|
|
@@ -24224,6 +24927,18 @@ ${tail}`;
|
|
|
24224
24927
|
const fileRegistryStr = this.formatFileRegistry();
|
|
24225
24928
|
if (fileRegistryStr)
|
|
24226
24929
|
enrichments.push(fileRegistryStr);
|
|
24930
|
+
try {
|
|
24931
|
+
const notesSummary = getWorkingNotesSummary();
|
|
24932
|
+
if (notesSummary)
|
|
24933
|
+
enrichments.push(notesSummary);
|
|
24934
|
+
const exploreNotes = getExploreNotes();
|
|
24935
|
+
if (exploreNotes.length > 0) {
|
|
24936
|
+
const exploreStr = `File exploration notes (${exploreNotes.length}):
|
|
24937
|
+
` + exploreNotes.map((n) => `- ${n.file} lines ${n.lineRange[0]}-${n.lineRange[1]}: ${n.finding}`).join("\n");
|
|
24938
|
+
enrichments.push(exploreStr);
|
|
24939
|
+
}
|
|
24940
|
+
} catch {
|
|
24941
|
+
}
|
|
24227
24942
|
if (tier === "large") {
|
|
24228
24943
|
const memexIndexStr = this.formatMemexIndex();
|
|
24229
24944
|
if (memexIndexStr)
|
|
@@ -25616,12 +26331,12 @@ var init_nexusBackend = __esm({
|
|
|
25616
26331
|
const deadline = Date.now() + (request.timeoutMs ?? 12e4);
|
|
25617
26332
|
try {
|
|
25618
26333
|
while (!done && Date.now() < deadline) {
|
|
25619
|
-
await new Promise((
|
|
26334
|
+
await new Promise((resolve33) => {
|
|
25620
26335
|
let resolved = false;
|
|
25621
26336
|
const finish = () => {
|
|
25622
26337
|
if (!resolved) {
|
|
25623
26338
|
resolved = true;
|
|
25624
|
-
|
|
26339
|
+
resolve33();
|
|
25625
26340
|
}
|
|
25626
26341
|
};
|
|
25627
26342
|
let watcher = null;
|
|
@@ -26561,7 +27276,7 @@ __export(listen_exports, {
|
|
|
26561
27276
|
import { spawn as spawn15, execSync as execSync22 } from "node:child_process";
|
|
26562
27277
|
import { existsSync as existsSync28, mkdirSync as mkdirSync8, writeFileSync as writeFileSync9, readdirSync as readdirSync6 } from "node:fs";
|
|
26563
27278
|
import { join as join43, dirname as dirname13 } from "node:path";
|
|
26564
|
-
import { homedir as
|
|
27279
|
+
import { homedir as homedir10 } from "node:os";
|
|
26565
27280
|
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
26566
27281
|
import { EventEmitter } from "node:events";
|
|
26567
27282
|
import { createInterface as createInterface2 } from "node:readline";
|
|
@@ -26673,7 +27388,7 @@ function findLiveWhisperScript() {
|
|
|
26673
27388
|
}
|
|
26674
27389
|
} catch {
|
|
26675
27390
|
}
|
|
26676
|
-
const nvmBase = join43(
|
|
27391
|
+
const nvmBase = join43(homedir10(), ".nvm", "versions", "node");
|
|
26677
27392
|
if (existsSync28(nvmBase)) {
|
|
26678
27393
|
try {
|
|
26679
27394
|
for (const ver of readdirSync6(nvmBase)) {
|
|
@@ -26703,9 +27418,9 @@ function ensureTranscribeCliBackground() {
|
|
|
26703
27418
|
}
|
|
26704
27419
|
try {
|
|
26705
27420
|
const { exec: exec4 } = await import("node:child_process");
|
|
26706
|
-
return new Promise((
|
|
27421
|
+
return new Promise((resolve33) => {
|
|
26707
27422
|
exec4("npm i -g transcribe-cli", { timeout: 18e4 }, (err) => {
|
|
26708
|
-
|
|
27423
|
+
resolve33(!err);
|
|
26709
27424
|
});
|
|
26710
27425
|
});
|
|
26711
27426
|
} catch {
|
|
@@ -26764,7 +27479,7 @@ var init_listen = __esm({
|
|
|
26764
27479
|
return this._ready;
|
|
26765
27480
|
}
|
|
26766
27481
|
async start() {
|
|
26767
|
-
return new Promise((
|
|
27482
|
+
return new Promise((resolve33, reject) => {
|
|
26768
27483
|
const timeout = setTimeout(() => {
|
|
26769
27484
|
reject(new Error("Whisper fallback: model load timeout (5 min). First run downloads the model."));
|
|
26770
27485
|
}, 3e5);
|
|
@@ -26792,7 +27507,7 @@ var init_listen = __esm({
|
|
|
26792
27507
|
this._ready = true;
|
|
26793
27508
|
clearTimeout(timeout);
|
|
26794
27509
|
this.emit("ready");
|
|
26795
|
-
|
|
27510
|
+
resolve33();
|
|
26796
27511
|
break;
|
|
26797
27512
|
case "transcript":
|
|
26798
27513
|
this.emit("transcript", {
|
|
@@ -26927,7 +27642,7 @@ var init_listen = __esm({
|
|
|
26927
27642
|
}
|
|
26928
27643
|
} catch {
|
|
26929
27644
|
}
|
|
26930
|
-
const nvmBase = join43(
|
|
27645
|
+
const nvmBase = join43(homedir10(), ".nvm", "versions", "node");
|
|
26931
27646
|
if (existsSync28(nvmBase)) {
|
|
26932
27647
|
try {
|
|
26933
27648
|
const { readdirSync: readdirSync18 } = await import("node:fs");
|
|
@@ -26996,11 +27711,11 @@ var init_listen = __esm({
|
|
|
26996
27711
|
this.liveTranscriber.on("error", (err) => {
|
|
26997
27712
|
this.emit("error", err);
|
|
26998
27713
|
});
|
|
26999
|
-
await new Promise((
|
|
27714
|
+
await new Promise((resolve33, reject) => {
|
|
27000
27715
|
const timeout = setTimeout(() => reject(new Error("Model load timeout (60s)")), 6e4);
|
|
27001
27716
|
this.liveTranscriber.on("ready", () => {
|
|
27002
27717
|
clearTimeout(timeout);
|
|
27003
|
-
|
|
27718
|
+
resolve33();
|
|
27004
27719
|
});
|
|
27005
27720
|
this.liveTranscriber.on("error", (err) => {
|
|
27006
27721
|
clearTimeout(timeout);
|
|
@@ -27162,11 +27877,11 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
27162
27877
|
sampleWidth: 2,
|
|
27163
27878
|
chunkDuration: 3
|
|
27164
27879
|
});
|
|
27165
|
-
await new Promise((
|
|
27880
|
+
await new Promise((resolve33, reject) => {
|
|
27166
27881
|
const timeout = setTimeout(() => reject(new Error("Model load timeout (60s)")), 6e4);
|
|
27167
27882
|
transcriber.on("ready", () => {
|
|
27168
27883
|
clearTimeout(timeout);
|
|
27169
|
-
|
|
27884
|
+
resolve33();
|
|
27170
27885
|
});
|
|
27171
27886
|
transcriber.on("error", (err) => {
|
|
27172
27887
|
clearTimeout(timeout);
|
|
@@ -32137,8 +32852,8 @@ var init_voice_session = __esm({
|
|
|
32137
32852
|
this.server.keepAliveTimeout = 0;
|
|
32138
32853
|
this.wss = new import_websocket_server.default({ server: this.server, path: "/ws" });
|
|
32139
32854
|
this.wss.on("connection", (ws, req) => this.handleWSConnection(ws, req));
|
|
32140
|
-
await new Promise((
|
|
32141
|
-
this.server.listen(port, "127.0.0.1", () =>
|
|
32855
|
+
await new Promise((resolve33, reject) => {
|
|
32856
|
+
this.server.listen(port, "127.0.0.1", () => resolve33());
|
|
32142
32857
|
this.server.on("error", reject);
|
|
32143
32858
|
});
|
|
32144
32859
|
try {
|
|
@@ -32356,7 +33071,7 @@ var init_voice_session = __esm({
|
|
|
32356
33071
|
}
|
|
32357
33072
|
// ── Cloudflared tunnel ────────────────────────────────────────────────
|
|
32358
33073
|
startCloudflared(port) {
|
|
32359
|
-
return new Promise((
|
|
33074
|
+
return new Promise((resolve33, reject) => {
|
|
32360
33075
|
const timeout = setTimeout(() => {
|
|
32361
33076
|
reject(new Error("Cloudflared tunnel start timeout (30s)"));
|
|
32362
33077
|
}, 3e4);
|
|
@@ -32374,7 +33089,7 @@ var init_voice_session = __esm({
|
|
|
32374
33089
|
if (urlMatch && !urlFound) {
|
|
32375
33090
|
urlFound = true;
|
|
32376
33091
|
clearTimeout(timeout);
|
|
32377
|
-
|
|
33092
|
+
resolve33(urlMatch[0]);
|
|
32378
33093
|
}
|
|
32379
33094
|
};
|
|
32380
33095
|
this.cloudflaredProcess.stdout?.on("data", handleOutput);
|
|
@@ -32414,13 +33129,13 @@ var init_voice_session = __esm({
|
|
|
32414
33129
|
}
|
|
32415
33130
|
// ── Helpers ───────────────────────────────────────────────────────────
|
|
32416
33131
|
findFreePort() {
|
|
32417
|
-
return new Promise((
|
|
33132
|
+
return new Promise((resolve33, reject) => {
|
|
32418
33133
|
const srv = createServer2();
|
|
32419
33134
|
srv.listen(0, "127.0.0.1", () => {
|
|
32420
33135
|
const addr = srv.address();
|
|
32421
33136
|
if (addr && typeof addr === "object") {
|
|
32422
33137
|
const port = addr.port;
|
|
32423
|
-
srv.close(() =>
|
|
33138
|
+
srv.close(() => resolve33(port));
|
|
32424
33139
|
} else {
|
|
32425
33140
|
srv.close(() => reject(new Error("Could not find free port")));
|
|
32426
33141
|
}
|
|
@@ -32543,8 +33258,8 @@ async function collectSystemMetricsAsync() {
|
|
|
32543
33258
|
vramUtilization: 0
|
|
32544
33259
|
};
|
|
32545
33260
|
try {
|
|
32546
|
-
const smi = await new Promise((
|
|
32547
|
-
exec("nvidia-smi --query-gpu=utilization.gpu,memory.used,memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 3e3 }, (err, stdout) => err ? reject(err) :
|
|
33261
|
+
const smi = await new Promise((resolve33, reject) => {
|
|
33262
|
+
exec("nvidia-smi --query-gpu=utilization.gpu,memory.used,memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 3e3 }, (err, stdout) => err ? reject(err) : resolve33(stdout));
|
|
32548
33263
|
});
|
|
32549
33264
|
const line = smi.trim().split("\n")[0];
|
|
32550
33265
|
if (line) {
|
|
@@ -32692,8 +33407,8 @@ var init_expose = __esm({
|
|
|
32692
33407
|
throw new Error("Gateway already running");
|
|
32693
33408
|
const port = await this.findFreePort();
|
|
32694
33409
|
this.server = this.createProxyServer(port);
|
|
32695
|
-
await new Promise((
|
|
32696
|
-
this.server.listen(port, "127.0.0.1", () =>
|
|
33410
|
+
await new Promise((resolve33, reject) => {
|
|
33411
|
+
this.server.listen(port, "127.0.0.1", () => resolve33());
|
|
32697
33412
|
this.server.on("error", reject);
|
|
32698
33413
|
});
|
|
32699
33414
|
let lastStartErr;
|
|
@@ -32755,8 +33470,8 @@ var init_expose = __esm({
|
|
|
32755
33470
|
this._cloudflaredPid = state.pid;
|
|
32756
33471
|
this._proxyPort = state.proxyPort;
|
|
32757
33472
|
this.server = this.createProxyServer(state.proxyPort);
|
|
32758
|
-
await new Promise((
|
|
32759
|
-
this.server.listen(state.proxyPort, "127.0.0.1", () =>
|
|
33473
|
+
await new Promise((resolve33, reject) => {
|
|
33474
|
+
this.server.listen(state.proxyPort, "127.0.0.1", () => resolve33());
|
|
32760
33475
|
this.server.on("error", reject);
|
|
32761
33476
|
});
|
|
32762
33477
|
this._stats.status = "active";
|
|
@@ -32781,8 +33496,8 @@ var init_expose = __esm({
|
|
|
32781
33496
|
}
|
|
32782
33497
|
this._cloudflaredPid = null;
|
|
32783
33498
|
if (this.server) {
|
|
32784
|
-
await new Promise((
|
|
32785
|
-
this.server.close(() =>
|
|
33499
|
+
await new Promise((resolve33) => {
|
|
33500
|
+
this.server.close(() => resolve33());
|
|
32786
33501
|
});
|
|
32787
33502
|
this.server = null;
|
|
32788
33503
|
}
|
|
@@ -33114,7 +33829,7 @@ var init_expose = __esm({
|
|
|
33114
33829
|
_proxyPort = 0;
|
|
33115
33830
|
startCloudflared(port) {
|
|
33116
33831
|
this._proxyPort = port;
|
|
33117
|
-
return new Promise((
|
|
33832
|
+
return new Promise((resolve33, reject) => {
|
|
33118
33833
|
const timeout = setTimeout(() => {
|
|
33119
33834
|
reject(new Error("Cloudflared tunnel start timeout (30s)"));
|
|
33120
33835
|
}, 3e4);
|
|
@@ -33143,7 +33858,7 @@ var init_expose = __esm({
|
|
|
33143
33858
|
this.cloudflaredProcess?.unref();
|
|
33144
33859
|
this.cloudflaredProcess?.stdout?.destroy();
|
|
33145
33860
|
this.cloudflaredProcess?.stderr?.destroy();
|
|
33146
|
-
|
|
33861
|
+
resolve33(urlMatch[0]);
|
|
33147
33862
|
}
|
|
33148
33863
|
};
|
|
33149
33864
|
this.cloudflaredProcess.stdout?.on("data", handleOutput);
|
|
@@ -33232,13 +33947,13 @@ ${this.formatConnectionInfo()}`);
|
|
|
33232
33947
|
}
|
|
33233
33948
|
// ── Helpers ─────────────────────────────────────────────────────────────
|
|
33234
33949
|
findFreePort() {
|
|
33235
|
-
return new Promise((
|
|
33950
|
+
return new Promise((resolve33, reject) => {
|
|
33236
33951
|
const srv = createServer3();
|
|
33237
33952
|
srv.listen(0, "127.0.0.1", () => {
|
|
33238
33953
|
const addr = srv.address();
|
|
33239
33954
|
if (addr && typeof addr === "object") {
|
|
33240
33955
|
const port = addr.port;
|
|
33241
|
-
srv.close(() =>
|
|
33956
|
+
srv.close(() => resolve33(port));
|
|
33242
33957
|
} else {
|
|
33243
33958
|
srv.close(() => reject(new Error("Could not find free port")));
|
|
33244
33959
|
}
|
|
@@ -34185,8 +34900,8 @@ var init_peer_mesh = __esm({
|
|
|
34185
34900
|
this.wss.on("connection", (ws, req) => {
|
|
34186
34901
|
this.handleInboundConnection(ws, req.url ?? "");
|
|
34187
34902
|
});
|
|
34188
|
-
await new Promise((
|
|
34189
|
-
this.server.listen(port, "127.0.0.1", () =>
|
|
34903
|
+
await new Promise((resolve33, reject) => {
|
|
34904
|
+
this.server.listen(port, "127.0.0.1", () => resolve33());
|
|
34190
34905
|
this.server.on("error", reject);
|
|
34191
34906
|
});
|
|
34192
34907
|
this.pingTimer = setInterval(() => this.pingAll(), PING_INTERVAL_MS);
|
|
@@ -34225,7 +34940,7 @@ var init_peer_mesh = __esm({
|
|
|
34225
34940
|
this.wss = null;
|
|
34226
34941
|
}
|
|
34227
34942
|
if (this.server) {
|
|
34228
|
-
await new Promise((
|
|
34943
|
+
await new Promise((resolve33) => this.server.close(() => resolve33()));
|
|
34229
34944
|
this.server = null;
|
|
34230
34945
|
}
|
|
34231
34946
|
this.emit("stopped");
|
|
@@ -34243,7 +34958,7 @@ var init_peer_mesh = __esm({
|
|
|
34243
34958
|
if (!wsUrl.includes("/p2p"))
|
|
34244
34959
|
wsUrl += "/p2p";
|
|
34245
34960
|
wsUrl += `?key=${encodeURIComponent(this._authKey)}`;
|
|
34246
|
-
return new Promise((
|
|
34961
|
+
return new Promise((resolve33, reject) => {
|
|
34247
34962
|
const ws = new import_websocket.default(wsUrl, { handshakeTimeout: 1e4 });
|
|
34248
34963
|
let resolved = false;
|
|
34249
34964
|
const timeout = setTimeout(() => {
|
|
@@ -34283,7 +34998,7 @@ var init_peer_mesh = __esm({
|
|
|
34283
34998
|
this.connections.set(peer.peerId, ws);
|
|
34284
34999
|
this.setupPeerHandlers(ws, peer.peerId);
|
|
34285
35000
|
this.emit("peer_connected", peer);
|
|
34286
|
-
|
|
35001
|
+
resolve33(peer);
|
|
34287
35002
|
} else {
|
|
34288
35003
|
this.handleMessage(msg, ws);
|
|
34289
35004
|
}
|
|
@@ -34338,12 +35053,12 @@ var init_peer_mesh = __esm({
|
|
|
34338
35053
|
throw new Error(`Peer ${peerId} not connected`);
|
|
34339
35054
|
}
|
|
34340
35055
|
const msgId = randomBytes11(8).toString("hex");
|
|
34341
|
-
return new Promise((
|
|
35056
|
+
return new Promise((resolve33, reject) => {
|
|
34342
35057
|
const timeout = setTimeout(() => {
|
|
34343
35058
|
this.pendingRequests.delete(msgId);
|
|
34344
35059
|
reject(new Error(`Inference timeout (${timeoutMs}ms)`));
|
|
34345
35060
|
}, timeoutMs);
|
|
34346
|
-
this.pendingRequests.set(msgId, { resolve:
|
|
35061
|
+
this.pendingRequests.set(msgId, { resolve: resolve33, reject, timeout, chunks: [] });
|
|
34347
35062
|
this.sendMsg(ws, "infer_request", request, msgId);
|
|
34348
35063
|
});
|
|
34349
35064
|
}
|
|
@@ -34565,13 +35280,13 @@ var init_peer_mesh = __esm({
|
|
|
34565
35280
|
ws.send(JSON.stringify(msg));
|
|
34566
35281
|
}
|
|
34567
35282
|
findFreePort() {
|
|
34568
|
-
return new Promise((
|
|
35283
|
+
return new Promise((resolve33, reject) => {
|
|
34569
35284
|
const srv = createServer4();
|
|
34570
35285
|
srv.listen(0, "127.0.0.1", () => {
|
|
34571
35286
|
const addr = srv.address();
|
|
34572
35287
|
if (addr && typeof addr === "object") {
|
|
34573
35288
|
const port = addr.port;
|
|
34574
|
-
srv.close(() =>
|
|
35289
|
+
srv.close(() => resolve33(port));
|
|
34575
35290
|
} else {
|
|
34576
35291
|
srv.close(() => reject(new Error("Could not find free port")));
|
|
34577
35292
|
}
|
|
@@ -35817,7 +36532,7 @@ __export(oa_directory_exports, {
|
|
|
35817
36532
|
});
|
|
35818
36533
|
import { existsSync as existsSync32, mkdirSync as mkdirSync11, readFileSync as readFileSync23, writeFileSync as writeFileSync12, readdirSync as readdirSync8, statSync as statSync11, unlinkSync as unlinkSync6 } from "node:fs";
|
|
35819
36534
|
import { join as join48, relative as relative2, basename as basename9, extname as extname8 } from "node:path";
|
|
35820
|
-
import { homedir as
|
|
36535
|
+
import { homedir as homedir11 } from "node:os";
|
|
35821
36536
|
function initOaDirectory(repoRoot) {
|
|
35822
36537
|
const oaPath = join48(repoRoot, OA_DIR);
|
|
35823
36538
|
for (const sub of SUBDIRS) {
|
|
@@ -35857,7 +36572,7 @@ function saveProjectSettings(repoRoot, settings) {
|
|
|
35857
36572
|
writeFileSync12(join48(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
35858
36573
|
}
|
|
35859
36574
|
function loadGlobalSettings() {
|
|
35860
|
-
const settingsPath = join48(
|
|
36575
|
+
const settingsPath = join48(homedir11(), ".open-agents", "settings.json");
|
|
35861
36576
|
try {
|
|
35862
36577
|
if (existsSync32(settingsPath)) {
|
|
35863
36578
|
return JSON.parse(readFileSync23(settingsPath, "utf-8"));
|
|
@@ -35867,7 +36582,7 @@ function loadGlobalSettings() {
|
|
|
35867
36582
|
return {};
|
|
35868
36583
|
}
|
|
35869
36584
|
function saveGlobalSettings(settings) {
|
|
35870
|
-
const dir = join48(
|
|
36585
|
+
const dir = join48(homedir11(), ".open-agents");
|
|
35871
36586
|
mkdirSync11(dir, { recursive: true });
|
|
35872
36587
|
const existing = loadGlobalSettings();
|
|
35873
36588
|
const merged = { ...existing, ...settings };
|
|
@@ -36247,13 +36962,13 @@ function recordUsage(kind, value, opts) {
|
|
|
36247
36962
|
}
|
|
36248
36963
|
saveUsageFile(filePath, data);
|
|
36249
36964
|
};
|
|
36250
|
-
update(join48(
|
|
36965
|
+
update(join48(homedir11(), ".open-agents", USAGE_HISTORY_FILE));
|
|
36251
36966
|
if (opts?.repoRoot) {
|
|
36252
36967
|
update(join48(opts.repoRoot, OA_DIR, USAGE_HISTORY_FILE));
|
|
36253
36968
|
}
|
|
36254
36969
|
}
|
|
36255
36970
|
function loadUsageHistory(kind, repoRoot) {
|
|
36256
|
-
const globalPath = join48(
|
|
36971
|
+
const globalPath = join48(homedir11(), ".open-agents", USAGE_HISTORY_FILE);
|
|
36257
36972
|
const globalData = loadUsageFile(globalPath);
|
|
36258
36973
|
const localData = repoRoot ? loadUsageFile(join48(repoRoot, OA_DIR, USAGE_HISTORY_FILE)) : { records: [] };
|
|
36259
36974
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -36286,7 +37001,7 @@ function deleteUsageRecord(kind, value, repoRoot) {
|
|
|
36286
37001
|
saveUsageFile(filePath, data);
|
|
36287
37002
|
}
|
|
36288
37003
|
};
|
|
36289
|
-
remove(join48(
|
|
37004
|
+
remove(join48(homedir11(), ".open-agents", USAGE_HISTORY_FILE));
|
|
36290
37005
|
if (repoRoot) {
|
|
36291
37006
|
remove(join48(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
|
|
36292
37007
|
}
|
|
@@ -36337,10 +37052,10 @@ var init_oa_directory = __esm({
|
|
|
36337
37052
|
// packages/cli/dist/tui/setup.js
|
|
36338
37053
|
import * as readline from "node:readline";
|
|
36339
37054
|
import { execSync as execSync24, spawn as spawn18, exec as exec2 } from "node:child_process";
|
|
36340
|
-
import { promisify as
|
|
37055
|
+
import { promisify as promisify6 } from "node:util";
|
|
36341
37056
|
import { existsSync as existsSync33, writeFileSync as writeFileSync13, readFileSync as readFileSync24, appendFileSync as appendFileSync2, mkdirSync as mkdirSync12 } from "node:fs";
|
|
36342
37057
|
import { join as join49 } from "node:path";
|
|
36343
|
-
import { homedir as
|
|
37058
|
+
import { homedir as homedir12, platform } from "node:os";
|
|
36344
37059
|
function detectSystemSpecs() {
|
|
36345
37060
|
let totalRamGB = 0;
|
|
36346
37061
|
let availableRamGB = 0;
|
|
@@ -36477,12 +37192,12 @@ function modelSupportsToolCalling(modelName) {
|
|
|
36477
37192
|
return false;
|
|
36478
37193
|
}
|
|
36479
37194
|
function ask(rl, question) {
|
|
36480
|
-
return new Promise((
|
|
36481
|
-
rl.question(question, (answer) =>
|
|
37195
|
+
return new Promise((resolve33) => {
|
|
37196
|
+
rl.question(question, (answer) => resolve33(answer.trim()));
|
|
36482
37197
|
});
|
|
36483
37198
|
}
|
|
36484
37199
|
function askSecret(rl, question) {
|
|
36485
|
-
return new Promise((
|
|
37200
|
+
return new Promise((resolve33) => {
|
|
36486
37201
|
process.stdout.write(question);
|
|
36487
37202
|
let secret = "";
|
|
36488
37203
|
const stdin = process.stdin;
|
|
@@ -36500,7 +37215,7 @@ function askSecret(rl, question) {
|
|
|
36500
37215
|
stdin.setRawMode(hadRawMode ?? false);
|
|
36501
37216
|
}
|
|
36502
37217
|
process.stdout.write("\n");
|
|
36503
|
-
|
|
37218
|
+
resolve33(secret.trim());
|
|
36504
37219
|
return;
|
|
36505
37220
|
} else if (c3 === "") {
|
|
36506
37221
|
stdin.removeListener("data", onData);
|
|
@@ -36508,7 +37223,7 @@ function askSecret(rl, question) {
|
|
|
36508
37223
|
stdin.setRawMode(hadRawMode ?? false);
|
|
36509
37224
|
}
|
|
36510
37225
|
process.stdout.write("\n");
|
|
36511
|
-
|
|
37226
|
+
resolve33("");
|
|
36512
37227
|
return;
|
|
36513
37228
|
} else if (c3 === "\x7F" || c3 === "\b") {
|
|
36514
37229
|
if (secret.length > 0) {
|
|
@@ -36743,7 +37458,7 @@ async function ensureOllamaRunning(backendUrl, rl) {
|
|
|
36743
37458
|
return false;
|
|
36744
37459
|
}
|
|
36745
37460
|
for (let i = 0; i < 5; i++) {
|
|
36746
|
-
await new Promise((
|
|
37461
|
+
await new Promise((resolve33) => setTimeout(resolve33, 2e3));
|
|
36747
37462
|
try {
|
|
36748
37463
|
const resp = await fetch(`${backendUrl}/api/tags`, {
|
|
36749
37464
|
signal: AbortSignal.timeout(3e3)
|
|
@@ -37204,7 +37919,7 @@ async function doSetup(config, rl) {
|
|
|
37204
37919
|
try {
|
|
37205
37920
|
const child = spawn18("ollama", ["serve"], { stdio: "ignore", detached: true });
|
|
37206
37921
|
child.unref();
|
|
37207
|
-
await new Promise((
|
|
37922
|
+
await new Promise((resolve33) => setTimeout(resolve33, 3e3));
|
|
37208
37923
|
try {
|
|
37209
37924
|
models = await fetchOllamaModels(config.backendUrl);
|
|
37210
37925
|
process.stdout.write(` ${c2.green("\u2714")} Ollama is running.
|
|
@@ -37232,7 +37947,7 @@ async function doSetup(config, rl) {
|
|
|
37232
37947
|
try {
|
|
37233
37948
|
const child = spawn18("ollama", ["serve"], { stdio: "ignore", detached: true });
|
|
37234
37949
|
child.unref();
|
|
37235
|
-
await new Promise((
|
|
37950
|
+
await new Promise((resolve33) => setTimeout(resolve33, 3e3));
|
|
37236
37951
|
try {
|
|
37237
37952
|
models = await fetchOllamaModels(config.backendUrl);
|
|
37238
37953
|
process.stdout.write(` ${c2.green("\u2714")} Ollama is running.
|
|
@@ -37380,7 +38095,7 @@ async function doSetup(config, rl) {
|
|
|
37380
38095
|
`PARAMETER num_predict ${numPredict}`,
|
|
37381
38096
|
`PARAMETER stop "<|endoftext|>"`
|
|
37382
38097
|
].join("\n");
|
|
37383
|
-
const modelDir2 = join49(
|
|
38098
|
+
const modelDir2 = join49(homedir12(), ".open-agents", "models");
|
|
37384
38099
|
mkdirSync12(modelDir2, { recursive: true });
|
|
37385
38100
|
const modelfilePath = join49(modelDir2, `Modelfile.${customName}`);
|
|
37386
38101
|
writeFileSync13(modelfilePath, modelfileContent + "\n", "utf8");
|
|
@@ -37428,7 +38143,7 @@ async function isModelAvailable(config) {
|
|
|
37428
38143
|
}
|
|
37429
38144
|
function isFirstRun() {
|
|
37430
38145
|
try {
|
|
37431
|
-
return !existsSync33(join49(
|
|
38146
|
+
return !existsSync33(join49(homedir12(), ".open-agents", "config.json"));
|
|
37432
38147
|
} catch {
|
|
37433
38148
|
return true;
|
|
37434
38149
|
}
|
|
@@ -37465,7 +38180,7 @@ function detectPkgManager() {
|
|
|
37465
38180
|
return null;
|
|
37466
38181
|
}
|
|
37467
38182
|
function getVenvDir() {
|
|
37468
|
-
return join49(
|
|
38183
|
+
return join49(homedir12(), ".open-agents", "venv");
|
|
37469
38184
|
}
|
|
37470
38185
|
function hasVenvModule() {
|
|
37471
38186
|
try {
|
|
@@ -37490,7 +38205,7 @@ function ensureVenv(log) {
|
|
|
37490
38205
|
return null;
|
|
37491
38206
|
}
|
|
37492
38207
|
try {
|
|
37493
|
-
mkdirSync12(join49(
|
|
38208
|
+
mkdirSync12(join49(homedir12(), ".open-agents"), { recursive: true });
|
|
37494
38209
|
execSync24(`python3 -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
|
|
37495
38210
|
execSync24(`"${join49(venvDir, "bin", "pip")}" install --upgrade pip`, {
|
|
37496
38211
|
stdio: "pipe",
|
|
@@ -37756,9 +38471,9 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
37756
38471
|
const archMap = { x64: "amd64", arm64: "arm64", arm: "arm" };
|
|
37757
38472
|
const cfArch = archMap[arch] ?? "amd64";
|
|
37758
38473
|
try {
|
|
37759
|
-
execSync24(`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && mkdir -p "${
|
|
37760
|
-
if (!process.env.PATH?.includes(`${
|
|
37761
|
-
process.env.PATH = `${
|
|
38474
|
+
execSync24(`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && mkdir -p "${homedir12()}/.local/bin" && mv /tmp/cloudflared "${homedir12()}/.local/bin/cloudflared"`, { stdio: "pipe", timeout: 6e4 });
|
|
38475
|
+
if (!process.env.PATH?.includes(`${homedir12()}/.local/bin`)) {
|
|
38476
|
+
process.env.PATH = `${homedir12()}/.local/bin:${process.env.PATH}`;
|
|
37762
38477
|
}
|
|
37763
38478
|
if (hasCmd("cloudflared")) {
|
|
37764
38479
|
log("cloudflared installed.");
|
|
@@ -37853,7 +38568,7 @@ async function createExpandedVariantAsync(baseModel, specs, sizeGB, kvBytesPerTo
|
|
|
37853
38568
|
`PARAMETER num_predict ${numPredict}`,
|
|
37854
38569
|
`PARAMETER stop "<|endoftext|>"`
|
|
37855
38570
|
].join("\n");
|
|
37856
|
-
const modelDir2 = join49(
|
|
38571
|
+
const modelDir2 = join49(homedir12(), ".open-agents", "models");
|
|
37857
38572
|
mkdirSync12(modelDir2, { recursive: true });
|
|
37858
38573
|
const modelfilePath = join49(modelDir2, `Modelfile.${customName}`);
|
|
37859
38574
|
writeFileSync13(modelfilePath, modelfileContent + "\n", "utf8");
|
|
@@ -37930,7 +38645,7 @@ async function ensureNeovim() {
|
|
|
37930
38645
|
const platform5 = process.platform;
|
|
37931
38646
|
const arch = process.arch;
|
|
37932
38647
|
if (platform5 === "linux") {
|
|
37933
|
-
const binDir = join49(
|
|
38648
|
+
const binDir = join49(homedir12(), ".local", "bin");
|
|
37934
38649
|
const nvimDest = join49(binDir, "nvim");
|
|
37935
38650
|
try {
|
|
37936
38651
|
mkdirSync12(binDir, { recursive: true });
|
|
@@ -38002,7 +38717,7 @@ async function ensureNeovim() {
|
|
|
38002
38717
|
}
|
|
38003
38718
|
function ensurePathInShellRc(binDir) {
|
|
38004
38719
|
const shell = process.env.SHELL ?? "";
|
|
38005
|
-
const rcFile = shell.includes("zsh") ? join49(
|
|
38720
|
+
const rcFile = shell.includes("zsh") ? join49(homedir12(), ".zshrc") : join49(homedir12(), ".bashrc");
|
|
38006
38721
|
try {
|
|
38007
38722
|
const rcContent = existsSync33(rcFile) ? readFileSync24(rcFile, "utf8") : "";
|
|
38008
38723
|
if (rcContent.includes(binDir))
|
|
@@ -38023,7 +38738,7 @@ var init_setup = __esm({
|
|
|
38023
38738
|
init_render();
|
|
38024
38739
|
init_config();
|
|
38025
38740
|
init_dist();
|
|
38026
|
-
execAsync =
|
|
38741
|
+
execAsync = promisify6(exec2);
|
|
38027
38742
|
QWEN_VARIANTS = [
|
|
38028
38743
|
{ tag: "qwen3.5:0.8b", sizeGB: 1, label: "0.8B params (1.0 GB)", cloud: false },
|
|
38029
38744
|
{ tag: "qwen3.5:2b", sizeGB: 2.7, label: "2B params (2.7 GB)", cloud: false },
|
|
@@ -38221,7 +38936,7 @@ function tuiSelect(opts) {
|
|
|
38221
38936
|
const maxVisible = opts.maxVisible ?? Math.max(3, contentArea - selectChrome);
|
|
38222
38937
|
let scrollOffset = 0;
|
|
38223
38938
|
let lastRenderedLines = 0;
|
|
38224
|
-
return new Promise((
|
|
38939
|
+
return new Promise((resolve33) => {
|
|
38225
38940
|
const stdin = process.stdin;
|
|
38226
38941
|
const hadRawMode = stdin.isRaw;
|
|
38227
38942
|
const savedRlListeners = [];
|
|
@@ -38396,7 +39111,7 @@ function tuiSelect(opts) {
|
|
|
38396
39111
|
if (!isSkippable(itemIdx) && matchSet.has(itemIdx)) {
|
|
38397
39112
|
cursor = itemIdx;
|
|
38398
39113
|
cleanup();
|
|
38399
|
-
|
|
39114
|
+
resolve33({ confirmed: true, key: items[cursor].key, index: cursor });
|
|
38400
39115
|
return;
|
|
38401
39116
|
} else if (!isSkippable(itemIdx)) {
|
|
38402
39117
|
cursor = itemIdx;
|
|
@@ -38472,7 +39187,7 @@ function tuiSelect(opts) {
|
|
|
38472
39187
|
items.splice(deletedIdx, 1);
|
|
38473
39188
|
if (items.length === 0) {
|
|
38474
39189
|
cleanup();
|
|
38475
|
-
|
|
39190
|
+
resolve33({ confirmed: false, key: null, index: -1 });
|
|
38476
39191
|
return;
|
|
38477
39192
|
}
|
|
38478
39193
|
updateFilter();
|
|
@@ -38561,7 +39276,7 @@ function tuiSelect(opts) {
|
|
|
38561
39276
|
} else if (seq === "\r" || seq === "\n") {
|
|
38562
39277
|
if (!isSkippable(cursor) && matchSet.has(cursor)) {
|
|
38563
39278
|
cleanup();
|
|
38564
|
-
|
|
39279
|
+
resolve33({ confirmed: true, key: items[cursor].key, index: cursor });
|
|
38565
39280
|
}
|
|
38566
39281
|
} else if (seq === "\x1B" || seq === "\x1B\x1B") {
|
|
38567
39282
|
if (filter) {
|
|
@@ -38574,14 +39289,14 @@ function tuiSelect(opts) {
|
|
|
38574
39289
|
render();
|
|
38575
39290
|
} else if (hasBreadcrumbs) {
|
|
38576
39291
|
cleanup();
|
|
38577
|
-
|
|
39292
|
+
resolve33({ confirmed: false, key: "__back__", index: cursor });
|
|
38578
39293
|
} else {
|
|
38579
39294
|
cleanup();
|
|
38580
|
-
|
|
39295
|
+
resolve33({ confirmed: false, key: null, index: cursor });
|
|
38581
39296
|
}
|
|
38582
39297
|
} else if (seq === "") {
|
|
38583
39298
|
cleanup();
|
|
38584
|
-
|
|
39299
|
+
resolve33({ confirmed: false, key: null, index: cursor });
|
|
38585
39300
|
} else if (seq === "\x7F" || seq === "\b") {
|
|
38586
39301
|
if (filter.length > 0) {
|
|
38587
39302
|
filter = filter.slice(0, -1);
|
|
@@ -38595,7 +39310,7 @@ function tuiSelect(opts) {
|
|
|
38595
39310
|
render();
|
|
38596
39311
|
} else if (hasBreadcrumbs) {
|
|
38597
39312
|
cleanup();
|
|
38598
|
-
|
|
39313
|
+
resolve33({ confirmed: false, key: "__back__", index: cursor });
|
|
38599
39314
|
}
|
|
38600
39315
|
} else if (seq.length === 1 && seq.charCodeAt(0) >= 32 && seq.charCodeAt(0) < 127) {
|
|
38601
39316
|
if (opts.onCustomKey && !isSkippable(cursor) && matchSet.has(cursor)) {
|
|
@@ -38603,7 +39318,7 @@ function tuiSelect(opts) {
|
|
|
38603
39318
|
done: () => render(),
|
|
38604
39319
|
resolve: (result) => {
|
|
38605
39320
|
cleanup();
|
|
38606
|
-
|
|
39321
|
+
resolve33(result);
|
|
38607
39322
|
},
|
|
38608
39323
|
getInput: (prompt, prefill) => getInputFromUser(prompt, prefill),
|
|
38609
39324
|
render: () => render(),
|
|
@@ -38720,7 +39435,7 @@ var init_tui_select = __esm({
|
|
|
38720
39435
|
|
|
38721
39436
|
// packages/cli/dist/tui/drop-panel.js
|
|
38722
39437
|
import { existsSync as existsSync34 } from "node:fs";
|
|
38723
|
-
import { extname as extname9, resolve as
|
|
39438
|
+
import { extname as extname9, resolve as resolve28 } from "node:path";
|
|
38724
39439
|
function ansi4(code, text) {
|
|
38725
39440
|
return isTTY4 ? `\x1B[${code}m${text}\x1B[0m` : text;
|
|
38726
39441
|
}
|
|
@@ -38833,7 +39548,7 @@ function showDropPanel(opts) {
|
|
|
38833
39548
|
if (filePath.startsWith("file://")) {
|
|
38834
39549
|
filePath = decodeURIComponent(filePath.slice(7));
|
|
38835
39550
|
}
|
|
38836
|
-
filePath =
|
|
39551
|
+
filePath = resolve28(filePath);
|
|
38837
39552
|
if (!existsSync34(filePath)) {
|
|
38838
39553
|
errorMsg = `File not found: ${filePath}`;
|
|
38839
39554
|
render();
|
|
@@ -39145,12 +39860,12 @@ function stopNeovimMode() {
|
|
|
39145
39860
|
} catch {
|
|
39146
39861
|
}
|
|
39147
39862
|
const s = _state;
|
|
39148
|
-
return new Promise((
|
|
39863
|
+
return new Promise((resolve33) => {
|
|
39149
39864
|
setTimeout(() => {
|
|
39150
39865
|
if (s && !s.cleanedUp) {
|
|
39151
39866
|
doCleanup(s);
|
|
39152
39867
|
}
|
|
39153
|
-
|
|
39868
|
+
resolve33();
|
|
39154
39869
|
}, 300);
|
|
39155
39870
|
});
|
|
39156
39871
|
}
|
|
@@ -39386,7 +40101,7 @@ __export(voice_exports, {
|
|
|
39386
40101
|
});
|
|
39387
40102
|
import { existsSync as existsSync36, mkdirSync as mkdirSync13, writeFileSync as writeFileSync14, readFileSync as readFileSync25, unlinkSync as unlinkSync8, readdirSync as readdirSync9, renameSync, statSync as statSync12 } from "node:fs";
|
|
39388
40103
|
import { join as join51, dirname as dirname17 } from "node:path";
|
|
39389
|
-
import { homedir as
|
|
40104
|
+
import { homedir as homedir13, tmpdir as tmpdir9, platform as platform2 } from "node:os";
|
|
39390
40105
|
import { execSync as execSync26, spawn as nodeSpawn } from "node:child_process";
|
|
39391
40106
|
import { createRequire } from "node:module";
|
|
39392
40107
|
function sanitizeForTTS(text) {
|
|
@@ -39410,7 +40125,7 @@ function listVoiceModels() {
|
|
|
39410
40125
|
}));
|
|
39411
40126
|
}
|
|
39412
40127
|
function voiceDir() {
|
|
39413
|
-
return join51(
|
|
40128
|
+
return join51(homedir13(), ".open-agents", "voice");
|
|
39414
40129
|
}
|
|
39415
40130
|
function modelsDir() {
|
|
39416
40131
|
return join51(voiceDir(), "models");
|
|
@@ -40406,7 +41121,7 @@ var init_voice = __esm({
|
|
|
40406
41121
|
}
|
|
40407
41122
|
p = p.replace(/\\ /g, " ");
|
|
40408
41123
|
if (p.startsWith("~/") || p === "~") {
|
|
40409
|
-
p = join51(
|
|
41124
|
+
p = join51(homedir13(), p.slice(1));
|
|
40410
41125
|
}
|
|
40411
41126
|
if (!existsSync36(p)) {
|
|
40412
41127
|
return `File not found: ${p}
|
|
@@ -40821,7 +41536,7 @@ var init_voice = __esm({
|
|
|
40821
41536
|
this.speaking = false;
|
|
40822
41537
|
}
|
|
40823
41538
|
sleep(ms) {
|
|
40824
|
-
return new Promise((
|
|
41539
|
+
return new Promise((resolve33) => setTimeout(resolve33, ms));
|
|
40825
41540
|
}
|
|
40826
41541
|
// -------------------------------------------------------------------------
|
|
40827
41542
|
// Synthesis pipeline
|
|
@@ -41087,7 +41802,7 @@ var init_voice = __esm({
|
|
|
41087
41802
|
const cmd = this.getPlayCommand(path);
|
|
41088
41803
|
if (!cmd)
|
|
41089
41804
|
return;
|
|
41090
|
-
return new Promise((
|
|
41805
|
+
return new Promise((resolve33) => {
|
|
41091
41806
|
const child = nodeSpawn(cmd[0], cmd.slice(1), {
|
|
41092
41807
|
stdio: "ignore",
|
|
41093
41808
|
detached: false
|
|
@@ -41096,12 +41811,12 @@ var init_voice = __esm({
|
|
|
41096
41811
|
child.on("close", () => {
|
|
41097
41812
|
if (this.currentPlayback === child)
|
|
41098
41813
|
this.currentPlayback = null;
|
|
41099
|
-
|
|
41814
|
+
resolve33();
|
|
41100
41815
|
});
|
|
41101
41816
|
child.on("error", () => {
|
|
41102
41817
|
if (this.currentPlayback === child)
|
|
41103
41818
|
this.currentPlayback = null;
|
|
41104
|
-
|
|
41819
|
+
resolve33();
|
|
41105
41820
|
});
|
|
41106
41821
|
setTimeout(() => {
|
|
41107
41822
|
if (this.currentPlayback === child) {
|
|
@@ -41111,7 +41826,7 @@ var init_voice = __esm({
|
|
|
41111
41826
|
}
|
|
41112
41827
|
this.currentPlayback = null;
|
|
41113
41828
|
}
|
|
41114
|
-
|
|
41829
|
+
resolve33();
|
|
41115
41830
|
}, 15e3);
|
|
41116
41831
|
});
|
|
41117
41832
|
}
|
|
@@ -41186,7 +41901,7 @@ var init_voice = __esm({
|
|
|
41186
41901
|
/** Non-blocking shell execution — async alternative to execSync.
|
|
41187
41902
|
* Returns stdout string on exit 0, rejects otherwise. */
|
|
41188
41903
|
asyncShell(command, timeoutMs = 3e4) {
|
|
41189
|
-
return new Promise((
|
|
41904
|
+
return new Promise((resolve33, reject) => {
|
|
41190
41905
|
const proc = nodeSpawn("sh", ["-c", command], {
|
|
41191
41906
|
stdio: ["ignore", "pipe", "pipe"],
|
|
41192
41907
|
cwd: tmpdir9()
|
|
@@ -41207,7 +41922,7 @@ var init_voice = __esm({
|
|
|
41207
41922
|
proc.on("close", (code) => {
|
|
41208
41923
|
clearTimeout(timer);
|
|
41209
41924
|
if (code === 0)
|
|
41210
|
-
|
|
41925
|
+
resolve33(stdout.trim());
|
|
41211
41926
|
else
|
|
41212
41927
|
reject(new Error(stderr.slice(0, 300) || `Exit code ${code}`));
|
|
41213
41928
|
});
|
|
@@ -41692,7 +42407,7 @@ if __name__ == '__main__':
|
|
|
41692
42407
|
const venvPy = luxttsVenvPy();
|
|
41693
42408
|
if (!existsSync36(venvPy))
|
|
41694
42409
|
return false;
|
|
41695
|
-
return new Promise((
|
|
42410
|
+
return new Promise((resolve33) => {
|
|
41696
42411
|
const env = { ...process.env, LUXTTS_REPO_PATH: luxttsRepoDir() };
|
|
41697
42412
|
const daemon = nodeSpawn(venvPy, [luxttsInferScript()], {
|
|
41698
42413
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -41711,7 +42426,7 @@ if __name__ == '__main__':
|
|
|
41711
42426
|
try {
|
|
41712
42427
|
const msg = JSON.parse(line);
|
|
41713
42428
|
if (msg.type === "ready") {
|
|
41714
|
-
|
|
42429
|
+
resolve33(true);
|
|
41715
42430
|
} else if (msg.type === "result" || msg.type === "error") {
|
|
41716
42431
|
const pending = this._luxttsPending.get(msg.id);
|
|
41717
42432
|
if (pending) {
|
|
@@ -41735,25 +42450,25 @@ if __name__ == '__main__':
|
|
|
41735
42450
|
});
|
|
41736
42451
|
daemon.on("error", () => {
|
|
41737
42452
|
this._luxttsDaemon = null;
|
|
41738
|
-
|
|
42453
|
+
resolve33(false);
|
|
41739
42454
|
});
|
|
41740
42455
|
setTimeout(() => {
|
|
41741
42456
|
if (this._luxttsDaemon === daemon && !this._luxttsPending.has("__ready__")) {
|
|
41742
|
-
|
|
42457
|
+
resolve33(false);
|
|
41743
42458
|
}
|
|
41744
42459
|
}, 6e4);
|
|
41745
42460
|
});
|
|
41746
42461
|
}
|
|
41747
42462
|
/** Send a request to the LuxTTS daemon and await the response */
|
|
41748
42463
|
luxttsRequest(req) {
|
|
41749
|
-
return new Promise((
|
|
42464
|
+
return new Promise((resolve33, reject) => {
|
|
41750
42465
|
if (!this._luxttsDaemon || this._luxttsDaemon.killed) {
|
|
41751
42466
|
reject(new Error("LuxTTS daemon not running"));
|
|
41752
42467
|
return;
|
|
41753
42468
|
}
|
|
41754
42469
|
const id = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
41755
42470
|
req.id = id;
|
|
41756
|
-
this._luxttsPending.set(id, { resolve:
|
|
42471
|
+
this._luxttsPending.set(id, { resolve: resolve33, reject });
|
|
41757
42472
|
this._luxttsDaemon.stdin.write(JSON.stringify(req) + "\n");
|
|
41758
42473
|
setTimeout(() => {
|
|
41759
42474
|
if (this._luxttsPending.has(id)) {
|
|
@@ -44777,9 +45492,9 @@ async function handleVoiceMenu(ctx, save, hasLocal) {
|
|
|
44777
45492
|
}
|
|
44778
45493
|
const { basename: basename16, join: pathJoin } = await import("node:path");
|
|
44779
45494
|
const { copyFileSync: copyFileSync2, mkdirSync: mkdirSync22, existsSync: exists } = await import("node:fs");
|
|
44780
|
-
const { homedir:
|
|
45495
|
+
const { homedir: homedir18 } = await import("node:os");
|
|
44781
45496
|
const modelName = basename16(onnxDrop.path, ".onnx").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
44782
|
-
const destDir = pathJoin(
|
|
45497
|
+
const destDir = pathJoin(homedir18(), ".open-agents", "voice", "models", modelName);
|
|
44783
45498
|
if (!exists(destDir))
|
|
44784
45499
|
mkdirSync22(destDir, { recursive: true });
|
|
44785
45500
|
copyFileSync2(onnxDrop.path, pathJoin(destDir, "model.onnx"));
|
|
@@ -45680,11 +46395,11 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
45680
46395
|
const targetVersion = info?.latestVersion ?? currentVersion;
|
|
45681
46396
|
const installOverlay = startInstallOverlay(targetVersion);
|
|
45682
46397
|
let installError = "";
|
|
45683
|
-
const runInstall2 = (cmd) => new Promise((
|
|
46398
|
+
const runInstall2 = (cmd) => new Promise((resolve33) => {
|
|
45684
46399
|
const child = exec4(cmd, { timeout: 18e4 }, (err, _stdout, stderr) => {
|
|
45685
46400
|
if (err)
|
|
45686
46401
|
installError = (stderr || err.message || "").trim();
|
|
45687
|
-
|
|
46402
|
+
resolve33(!err);
|
|
45688
46403
|
});
|
|
45689
46404
|
child.stdout?.on("data", (chunk) => {
|
|
45690
46405
|
const text = String(chunk);
|
|
@@ -45778,8 +46493,8 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
45778
46493
|
}
|
|
45779
46494
|
if (doRebuild) {
|
|
45780
46495
|
installOverlay.setStatus("Rebuilding native modules...");
|
|
45781
|
-
await new Promise((
|
|
45782
|
-
const child = exec4(`${sudoPrefix}npm rebuild -g open-agents-ai 2>/dev/null || true`, { timeout: 12e4 }, () =>
|
|
46496
|
+
await new Promise((resolve33) => {
|
|
46497
|
+
const child = exec4(`${sudoPrefix}npm rebuild -g open-agents-ai 2>/dev/null || true`, { timeout: 12e4 }, () => resolve33(true));
|
|
45783
46498
|
child.stdout?.resume();
|
|
45784
46499
|
child.stderr?.resume();
|
|
45785
46500
|
});
|
|
@@ -45810,8 +46525,8 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
45810
46525
|
const venvPip = pathJoin(venvDir, "bin", "pip");
|
|
45811
46526
|
if (fsExists(venvPip)) {
|
|
45812
46527
|
installOverlay.setStatus("Upgrading Python packages...");
|
|
45813
|
-
await new Promise((
|
|
45814
|
-
const child = exec4(`"${venvPip}" install --upgrade moondream-station pytesseract Pillow opencv-python-headless numpy 2>/dev/null || true`, { timeout: 3e5 }, (err) =>
|
|
46528
|
+
await new Promise((resolve33) => {
|
|
46529
|
+
const child = exec4(`"${venvPip}" install --upgrade moondream-station pytesseract Pillow opencv-python-headless numpy 2>/dev/null || true`, { timeout: 3e5 }, (err) => resolve33(!err));
|
|
45815
46530
|
child.stdout?.resume();
|
|
45816
46531
|
child.stderr?.resume();
|
|
45817
46532
|
});
|
|
@@ -46207,16 +46922,16 @@ async function showExposeDashboard(gateway, rl, ctx) {
|
|
|
46207
46922
|
renderDashboard();
|
|
46208
46923
|
}, 1e3);
|
|
46209
46924
|
let stopGateway = false;
|
|
46210
|
-
await new Promise((
|
|
46925
|
+
await new Promise((resolve33) => {
|
|
46211
46926
|
const onData = (data) => {
|
|
46212
46927
|
const key = data.toString();
|
|
46213
46928
|
if (key === "q" || key === "Q" || key === "\x1B" || key === "") {
|
|
46214
|
-
|
|
46929
|
+
resolve33();
|
|
46215
46930
|
return;
|
|
46216
46931
|
}
|
|
46217
46932
|
if (key === "s" || key === "S") {
|
|
46218
46933
|
stopGateway = true;
|
|
46219
|
-
|
|
46934
|
+
resolve33();
|
|
46220
46935
|
return;
|
|
46221
46936
|
}
|
|
46222
46937
|
if (key === "c" || key === "C") {
|
|
@@ -46267,8 +46982,8 @@ async function showExposeDashboard(gateway, rl, ctx) {
|
|
|
46267
46982
|
process.stdout.write("\x1B[?1002h\x1B[?1006h");
|
|
46268
46983
|
}
|
|
46269
46984
|
};
|
|
46270
|
-
const origResolve =
|
|
46271
|
-
|
|
46985
|
+
const origResolve = resolve33;
|
|
46986
|
+
resolve33 = (() => {
|
|
46272
46987
|
cleanup();
|
|
46273
46988
|
origResolve();
|
|
46274
46989
|
});
|
|
@@ -46326,7 +47041,7 @@ var init_commands = __esm({
|
|
|
46326
47041
|
import { existsSync as existsSync38, readFileSync as readFileSync27, readdirSync as readdirSync11 } from "node:fs";
|
|
46327
47042
|
import { join as join53, basename as basename10 } from "node:path";
|
|
46328
47043
|
import { execSync as execSync27 } from "node:child_process";
|
|
46329
|
-
import { homedir as
|
|
47044
|
+
import { homedir as homedir15, platform as platform3, release } from "node:os";
|
|
46330
47045
|
function getModelTier(modelName) {
|
|
46331
47046
|
const m = modelName.toLowerCase();
|
|
46332
47047
|
const sizeMatch = m.match(/\b(\d+)b\b/);
|
|
@@ -46413,7 +47128,7 @@ function loadMemoryContext(repoRoot) {
|
|
|
46413
47128
|
if (legacyEntries)
|
|
46414
47129
|
sections.push(legacyEntries);
|
|
46415
47130
|
}
|
|
46416
|
-
const globalMemDir = join53(
|
|
47131
|
+
const globalMemDir = join53(homedir15(), ".open-agents", "memory");
|
|
46417
47132
|
const globalEntries = loadMemoryDir(globalMemDir, "global");
|
|
46418
47133
|
if (globalEntries)
|
|
46419
47134
|
sections.push(globalEntries);
|
|
@@ -52133,7 +52848,7 @@ var init_tool_policy = __esm({
|
|
|
52133
52848
|
|
|
52134
52849
|
// packages/cli/dist/tui/telegram-bridge.js
|
|
52135
52850
|
import { mkdirSync as mkdirSync19, existsSync as existsSync44, unlinkSync as unlinkSync10, readdirSync as readdirSync16, statSync as statSync14 } from "node:fs";
|
|
52136
|
-
import { join as join60, resolve as
|
|
52851
|
+
import { join as join60, resolve as resolve29 } from "node:path";
|
|
52137
52852
|
import { writeFile as writeFileAsync } from "node:fs/promises";
|
|
52138
52853
|
function convertMarkdownToTelegramHTML(md) {
|
|
52139
52854
|
let html = md;
|
|
@@ -52376,7 +53091,7 @@ with summary "no_reply" to silently skip without responding.
|
|
|
52376
53091
|
this.agentConfig = agentConfig;
|
|
52377
53092
|
this.repoRoot = repoRoot;
|
|
52378
53093
|
this.toolPolicyConfig = toolPolicyConfig;
|
|
52379
|
-
this.mediaCacheDir =
|
|
53094
|
+
this.mediaCacheDir = resolve29(repoRoot || ".", ".oa", "telegram-media-cache");
|
|
52380
53095
|
}
|
|
52381
53096
|
/** Set admin user ID filter */
|
|
52382
53097
|
setAdmin(userId) {
|
|
@@ -53612,7 +54327,7 @@ var init_braille_spinner = __esm({
|
|
|
53612
54327
|
// packages/cli/dist/tui/system-metrics.js
|
|
53613
54328
|
import { loadavg as loadavg3, cpus as cpus3, totalmem as totalmem4, freemem as freemem3, platform as platform4 } from "node:os";
|
|
53614
54329
|
import { exec as exec3 } from "node:child_process";
|
|
53615
|
-
import { readFile as
|
|
54330
|
+
import { readFile as readFile22 } from "node:fs/promises";
|
|
53616
54331
|
function formatRate(bytesPerSec) {
|
|
53617
54332
|
if (bytesPerSec < 1024)
|
|
53618
54333
|
return `${Math.round(bytesPerSec)}B`;
|
|
@@ -53624,7 +54339,7 @@ function formatRate(bytesPerSec) {
|
|
|
53624
54339
|
}
|
|
53625
54340
|
async function readProcNetDev() {
|
|
53626
54341
|
try {
|
|
53627
|
-
const data = await
|
|
54342
|
+
const data = await readFile22("/proc/net/dev", "utf8");
|
|
53628
54343
|
let rxTotal = 0;
|
|
53629
54344
|
let txTotal = 0;
|
|
53630
54345
|
for (const line of data.split("\n")) {
|
|
@@ -53662,8 +54377,8 @@ async function collectNetworkMetrics() {
|
|
|
53662
54377
|
}
|
|
53663
54378
|
if (plat === "darwin") {
|
|
53664
54379
|
try {
|
|
53665
|
-
const output = await new Promise((
|
|
53666
|
-
exec3("netstat -ib 2>/dev/null | head -30", { encoding: "utf8", timeout: 3e3 }, (err, stdout) => err ? reject(err) :
|
|
54380
|
+
const output = await new Promise((resolve33, reject) => {
|
|
54381
|
+
exec3("netstat -ib 2>/dev/null | head -30", { encoding: "utf8", timeout: 3e3 }, (err, stdout) => err ? reject(err) : resolve33(stdout));
|
|
53667
54382
|
});
|
|
53668
54383
|
let rxBytes = 0, txBytes = 0;
|
|
53669
54384
|
for (const line of output.split("\n")) {
|
|
@@ -53697,8 +54412,8 @@ async function collectGpuMetrics() {
|
|
|
53697
54412
|
if (_nvidiaSmiAvailable === false)
|
|
53698
54413
|
return noGpu;
|
|
53699
54414
|
try {
|
|
53700
|
-
const smi = await new Promise((
|
|
53701
|
-
exec3("nvidia-smi --query-gpu=utilization.gpu,memory.used,memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 3e3 }, (err, stdout) => err ? reject(err) :
|
|
54415
|
+
const smi = await new Promise((resolve33, reject) => {
|
|
54416
|
+
exec3("nvidia-smi --query-gpu=utilization.gpu,memory.used,memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 3e3 }, (err, stdout) => err ? reject(err) : resolve33(stdout));
|
|
53702
54417
|
});
|
|
53703
54418
|
_nvidiaSmiAvailable = true;
|
|
53704
54419
|
const line = smi.trim().split("\n")[0];
|
|
@@ -56347,13 +57062,13 @@ var init_mouse_filter = __esm({
|
|
|
56347
57062
|
import * as readline2 from "node:readline";
|
|
56348
57063
|
import { Writable } from "node:stream";
|
|
56349
57064
|
import { cwd } from "node:process";
|
|
56350
|
-
import { resolve as
|
|
57065
|
+
import { resolve as resolve30, join as join61, dirname as dirname19, extname as extname10 } from "node:path";
|
|
56351
57066
|
import { createRequire as createRequire2 } from "node:module";
|
|
56352
57067
|
import { fileURLToPath as fileURLToPath12 } from "node:url";
|
|
56353
57068
|
import { readFileSync as readFileSync34, writeFileSync as writeFileSync19, appendFileSync as appendFileSync4, rmSync as rmSync3, readdirSync as readdirSync17, mkdirSync as mkdirSync20 } from "node:fs";
|
|
56354
57069
|
import { existsSync as existsSync45 } from "node:fs";
|
|
56355
57070
|
import { execSync as execSync30 } from "node:child_process";
|
|
56356
|
-
import { homedir as
|
|
57071
|
+
import { homedir as homedir16 } from "node:os";
|
|
56357
57072
|
function formatTimeAgo(date) {
|
|
56358
57073
|
const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
|
|
56359
57074
|
if (seconds < 60)
|
|
@@ -56502,6 +57217,9 @@ function buildTools(repoRoot, config, contextWindowSize) {
|
|
|
56502
57217
|
new OpenCodeTool(repoRoot),
|
|
56503
57218
|
new FactoryTool(repoRoot),
|
|
56504
57219
|
new CronAgentTool(repoRoot),
|
|
57220
|
+
// Chunked file exploration + working notes
|
|
57221
|
+
new FileExploreTool(repoRoot),
|
|
57222
|
+
new WorkingNotesTool(),
|
|
56505
57223
|
// Nexus P2P networking + x402 micropayments
|
|
56506
57224
|
new NexusTool(repoRoot)
|
|
56507
57225
|
];
|
|
@@ -57651,7 +58369,7 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
57651
58369
|
} };
|
|
57652
58370
|
}
|
|
57653
58371
|
async function startInteractive(config, repoPath) {
|
|
57654
|
-
const repoRoot =
|
|
58372
|
+
const repoRoot = resolve30(repoPath ?? cwd());
|
|
57655
58373
|
const resumeFlag = process.env.__OA_RESUMED ?? "";
|
|
57656
58374
|
const isResumed = resumeFlag !== "";
|
|
57657
58375
|
const hasTaskToResume = resumeFlag === "1";
|
|
@@ -57823,14 +58541,14 @@ async function startInteractive(config, repoPath) {
|
|
|
57823
58541
|
renderInfo(msg);
|
|
57824
58542
|
statusBar.endContentWrite();
|
|
57825
58543
|
}
|
|
57826
|
-
}, () => new Promise((
|
|
58544
|
+
}, () => new Promise((resolve33) => {
|
|
57827
58545
|
depSudoPromptPending = true;
|
|
57828
58546
|
depSudoResolver = (pw) => {
|
|
57829
58547
|
depSudoPromptPending = false;
|
|
57830
58548
|
depSudoResolver = null;
|
|
57831
58549
|
if (pw)
|
|
57832
58550
|
sessionSudoPassword = pw;
|
|
57833
|
-
|
|
58551
|
+
resolve33(pw);
|
|
57834
58552
|
};
|
|
57835
58553
|
const pwPrompt1 = ` ${c2.bold(c2.yellow("\u{1F511} Password needed for dependency install:"))}
|
|
57836
58554
|
`;
|
|
@@ -58118,7 +58836,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
58118
58836
|
const hits = allCompletions.filter((c3) => c3.toLowerCase().startsWith(lower));
|
|
58119
58837
|
return [hits, line];
|
|
58120
58838
|
}
|
|
58121
|
-
const HISTORY_DIR = join61(
|
|
58839
|
+
const HISTORY_DIR = join61(homedir16(), ".open-agents");
|
|
58122
58840
|
const HISTORY_FILE = join61(HISTORY_DIR, "repl-history");
|
|
58123
58841
|
const MAX_HISTORY_LINES = 500;
|
|
58124
58842
|
let savedHistory = [];
|
|
@@ -59634,7 +60352,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
59634
60352
|
} catch {
|
|
59635
60353
|
}
|
|
59636
60354
|
try {
|
|
59637
|
-
const voiceDir2 = join61(
|
|
60355
|
+
const voiceDir2 = join61(homedir16(), ".open-agents", "voice");
|
|
59638
60356
|
const voicePidFiles = ["luxtts-daemon.pid", "piper-daemon.pid"];
|
|
59639
60357
|
for (const pf of voicePidFiles) {
|
|
59640
60358
|
const pidPath = join61(voiceDir2, pf);
|
|
@@ -60037,8 +60755,8 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
60037
60755
|
}
|
|
60038
60756
|
}
|
|
60039
60757
|
const cleanPath = input.replace(/^['"]|['"]$/g, "").trim();
|
|
60040
|
-
const isImage = isImagePath(cleanPath) && existsSync45(
|
|
60041
|
-
const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync45(
|
|
60758
|
+
const isImage = isImagePath(cleanPath) && existsSync45(resolve30(repoRoot, cleanPath));
|
|
60759
|
+
const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync45(resolve30(repoRoot, cleanPath));
|
|
60042
60760
|
if (activeTask) {
|
|
60043
60761
|
if (activeTask.runner.isPaused) {
|
|
60044
60762
|
activeTask.runner.resume();
|
|
@@ -60046,7 +60764,7 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
60046
60764
|
}
|
|
60047
60765
|
if (isImage) {
|
|
60048
60766
|
try {
|
|
60049
|
-
const imgPath =
|
|
60767
|
+
const imgPath = resolve30(repoRoot, cleanPath);
|
|
60050
60768
|
const imgBuffer = readFileSync34(imgPath);
|
|
60051
60769
|
const base64 = imgBuffer.toString("base64");
|
|
60052
60770
|
const ext = extname10(cleanPath).toLowerCase();
|
|
@@ -60060,7 +60778,7 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
60060
60778
|
} else if (isMedia) {
|
|
60061
60779
|
writeContent(() => renderInfo(`Transcribing: ${cleanPath}...`));
|
|
60062
60780
|
const engine = getListenEngine();
|
|
60063
|
-
const result = await engine.transcribeFile(
|
|
60781
|
+
const result = await engine.transcribeFile(resolve30(repoRoot, cleanPath), repoRoot);
|
|
60064
60782
|
if (result) {
|
|
60065
60783
|
const transcript = `[Transcription of ${cleanPath}]
|
|
60066
60784
|
${result.text}`;
|
|
@@ -60204,7 +60922,7 @@ ${result.text}`;
|
|
|
60204
60922
|
const ext = cleanPath.toLowerCase().split(".").pop() || "";
|
|
60205
60923
|
if (cloneExts.includes("." + ext)) {
|
|
60206
60924
|
writeContent(() => renderInfo(`Setting voice clone reference: ${cleanPath}`));
|
|
60207
|
-
const msg = await voiceEngine.setCloneVoice(
|
|
60925
|
+
const msg = await voiceEngine.setCloneVoice(resolve30(repoRoot, cleanPath));
|
|
60208
60926
|
writeContent(() => renderInfo(msg));
|
|
60209
60927
|
showPrompt();
|
|
60210
60928
|
return;
|
|
@@ -60213,7 +60931,7 @@ ${result.text}`;
|
|
|
60213
60931
|
if (isMedia && fullInput === input) {
|
|
60214
60932
|
writeContent(() => renderInfo(`Transcribing: ${cleanPath}...`));
|
|
60215
60933
|
const engine = getListenEngine();
|
|
60216
|
-
const result = await engine.transcribeFile(
|
|
60934
|
+
const result = await engine.transcribeFile(resolve30(repoRoot, cleanPath), repoRoot);
|
|
60217
60935
|
if (result) {
|
|
60218
60936
|
fullInput = `The user has provided an audio/video file: ${cleanPath}.
|
|
60219
60937
|
|
|
@@ -60499,7 +61217,7 @@ ${c2.dim("(Use /quit to exit)")}
|
|
|
60499
61217
|
};
|
|
60500
61218
|
}
|
|
60501
61219
|
async function runWithTUI(task, config, repoPath) {
|
|
60502
|
-
const repoRoot =
|
|
61220
|
+
const repoRoot = resolve30(repoPath ?? cwd());
|
|
60503
61221
|
const needsSetup = isFirstRun() || !await isModelAvailable(config);
|
|
60504
61222
|
if (needsSetup && config.backendType === "ollama") {
|
|
60505
61223
|
const setupModel = await runSetupWizard(config);
|
|
@@ -60882,7 +61600,7 @@ var init_run = __esm({
|
|
|
60882
61600
|
// packages/indexer/dist/codebase-indexer.js
|
|
60883
61601
|
import { glob } from "glob";
|
|
60884
61602
|
import ignore from "ignore";
|
|
60885
|
-
import { readFile as
|
|
61603
|
+
import { readFile as readFile23, stat as stat4 } from "node:fs/promises";
|
|
60886
61604
|
import { createHash as createHash4 } from "node:crypto";
|
|
60887
61605
|
import { join as join62, relative as relative3, extname as extname11, basename as basename15 } from "node:path";
|
|
60888
61606
|
var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
|
|
@@ -60928,7 +61646,7 @@ var init_codebase_indexer = __esm({
|
|
|
60928
61646
|
const ig = ignore.default();
|
|
60929
61647
|
if (this.config.respectGitignore) {
|
|
60930
61648
|
try {
|
|
60931
|
-
const gitignoreContent = await
|
|
61649
|
+
const gitignoreContent = await readFile23(join62(this.config.rootDir, ".gitignore"), "utf-8");
|
|
60932
61650
|
ig.add(gitignoreContent);
|
|
60933
61651
|
} catch {
|
|
60934
61652
|
}
|
|
@@ -60948,7 +61666,7 @@ var init_codebase_indexer = __esm({
|
|
|
60948
61666
|
const fileStat = await stat4(fullPath);
|
|
60949
61667
|
if (fileStat.size > this.config.maxFileSize)
|
|
60950
61668
|
continue;
|
|
60951
|
-
const content = await
|
|
61669
|
+
const content = await readFile23(fullPath);
|
|
60952
61670
|
const hash = createHash4("sha256").update(content).digest("hex");
|
|
60953
61671
|
const ext = extname11(relativePath);
|
|
60954
61672
|
indexed.push({
|
|
@@ -61071,11 +61789,11 @@ var index_repo_exports = {};
|
|
|
61071
61789
|
__export(index_repo_exports, {
|
|
61072
61790
|
indexRepoCommand: () => indexRepoCommand
|
|
61073
61791
|
});
|
|
61074
|
-
import { resolve as
|
|
61792
|
+
import { resolve as resolve31 } from "node:path";
|
|
61075
61793
|
import { existsSync as existsSync46, statSync as statSync15 } from "node:fs";
|
|
61076
61794
|
import { cwd as cwd2 } from "node:process";
|
|
61077
61795
|
async function indexRepoCommand(opts, _config) {
|
|
61078
|
-
const repoRoot =
|
|
61796
|
+
const repoRoot = resolve31(opts.repoPath ?? cwd2());
|
|
61079
61797
|
printHeader("Index Repository");
|
|
61080
61798
|
printInfo(`Indexing: ${repoRoot}`);
|
|
61081
61799
|
if (!existsSync46(repoRoot)) {
|
|
@@ -61330,8 +62048,8 @@ var config_exports = {};
|
|
|
61330
62048
|
__export(config_exports, {
|
|
61331
62049
|
configCommand: () => configCommand
|
|
61332
62050
|
});
|
|
61333
|
-
import { join as join63, resolve as
|
|
61334
|
-
import { homedir as
|
|
62051
|
+
import { join as join63, resolve as resolve32 } from "node:path";
|
|
62052
|
+
import { homedir as homedir17 } from "node:os";
|
|
61335
62053
|
import { cwd as cwd3 } from "node:process";
|
|
61336
62054
|
function redactIfSensitive(key, value) {
|
|
61337
62055
|
if (SENSITIVE_KEYS.has(key) && typeof value === "string" && value.length > 0) {
|
|
@@ -61363,7 +62081,7 @@ async function configCommand(opts, config) {
|
|
|
61363
62081
|
return handleShow(opts, config);
|
|
61364
62082
|
}
|
|
61365
62083
|
function handleShow(opts, config) {
|
|
61366
|
-
const repoRoot =
|
|
62084
|
+
const repoRoot = resolve32(opts.repoPath ?? cwd3());
|
|
61367
62085
|
printHeader("Configuration");
|
|
61368
62086
|
const resolved = resolveSettings(repoRoot);
|
|
61369
62087
|
printSection("Core Inference");
|
|
@@ -61413,7 +62131,7 @@ function handleShow(opts, config) {
|
|
|
61413
62131
|
}
|
|
61414
62132
|
}
|
|
61415
62133
|
printSection("Config File");
|
|
61416
|
-
printInfo(`~/.open-agents/config.json (${join63(
|
|
62134
|
+
printInfo(`~/.open-agents/config.json (${join63(homedir17(), ".open-agents", "config.json")})`);
|
|
61417
62135
|
printSection("Priority Chain");
|
|
61418
62136
|
printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
|
|
61419
62137
|
printInfo(" 2. Project .oa/settings.json (--local)");
|
|
@@ -61446,7 +62164,7 @@ function handleSet(opts, _config) {
|
|
|
61446
62164
|
process.exit(1);
|
|
61447
62165
|
}
|
|
61448
62166
|
if (opts.local) {
|
|
61449
|
-
const repoRoot =
|
|
62167
|
+
const repoRoot = resolve32(opts.repoPath ?? cwd3());
|
|
61450
62168
|
try {
|
|
61451
62169
|
initOaDirectory(repoRoot);
|
|
61452
62170
|
const coerced = coerceForSettings(key, value);
|
|
@@ -61644,7 +62362,7 @@ async function serveVllm(opts, config) {
|
|
|
61644
62362
|
await runVllmServer(args, opts.verbose ?? false);
|
|
61645
62363
|
}
|
|
61646
62364
|
async function runVllmServer(args, verbose) {
|
|
61647
|
-
return new Promise((
|
|
62365
|
+
return new Promise((resolve33, reject) => {
|
|
61648
62366
|
const child = spawn19("python", args, {
|
|
61649
62367
|
stdio: verbose ? "inherit" : ["ignore", "pipe", "pipe"],
|
|
61650
62368
|
env: { ...process.env }
|
|
@@ -61679,10 +62397,10 @@ async function runVllmServer(args, verbose) {
|
|
|
61679
62397
|
child.once("exit", (code, signal) => {
|
|
61680
62398
|
if (signal) {
|
|
61681
62399
|
printInfo(`vLLM server stopped by signal ${signal}`);
|
|
61682
|
-
|
|
62400
|
+
resolve33();
|
|
61683
62401
|
} else if (code === 0) {
|
|
61684
62402
|
printSuccess("vLLM server exited cleanly");
|
|
61685
|
-
|
|
62403
|
+
resolve33();
|
|
61686
62404
|
} else {
|
|
61687
62405
|
printError(`vLLM server exited with code ${code}`);
|
|
61688
62406
|
reject(new Error(`vLLM exited with code ${code}`));
|