open-agents-ai 0.142.1 → 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
|
|
@@ -7142,6 +7142,58 @@ process.on('unhandledRejection', (reason) => {
|
|
|
7142
7142
|
timestamp: Date.now(),
|
|
7143
7143
|
};
|
|
7144
7144
|
_natsConn.publish('nexus.agents.capacity', _natsCodec.encode(JSON.stringify(announcement)));
|
|
7145
|
+
|
|
7146
|
+
// Also publish enriched discovery announcement so the dashboard sees
|
|
7147
|
+
// IPFS/memory/identity/emotional state in sidebar cards (WO-VIS1 fields)
|
|
7148
|
+
try {
|
|
7149
|
+
// Gather memory metrics
|
|
7150
|
+
var _memCount = 0;
|
|
7151
|
+
var _memSentiment = 'neutral';
|
|
7152
|
+
var _ipfsBytes = 0;
|
|
7153
|
+
try {
|
|
7154
|
+
var _metaFile = join(nexusDir, '..', 'memory', 'metabolism', 'store.json');
|
|
7155
|
+
if (existsSync(_metaFile)) {
|
|
7156
|
+
var _mStore = JSON.parse(readFileSync(_metaFile, 'utf8'));
|
|
7157
|
+
_memCount = _mStore.filter(function(m) { return m.type !== 'quarantine'; }).length;
|
|
7158
|
+
var _recov = _mStore.filter(function(m) { return m.content && m.content.startsWith('[recovery]'); }).length;
|
|
7159
|
+
var _strat = _mStore.filter(function(m) { return m.content && m.content.startsWith('[strategy]'); }).length;
|
|
7160
|
+
_memSentiment = _strat > _recov ? 'proactive' : _recov > 0 ? 'defensive' : 'neutral';
|
|
7161
|
+
}
|
|
7162
|
+
} catch {}
|
|
7163
|
+
try {
|
|
7164
|
+
var _blocksDir = join(nexusDir, 'ipfs', 'blocks');
|
|
7165
|
+
if (existsSync(_blocksDir)) {
|
|
7166
|
+
var _walkBytes = function(d) { var t = 0; try { var ent = readdirSync(d, {withFileTypes:true}); for (var i=0;i<ent.length;i++) { if (ent[i].isDirectory()) t += _walkBytes(join(d,ent[i].name)); else try { t += statSync(join(d,ent[i].name)).size; } catch {} } } catch {} return t; };
|
|
7167
|
+
_ipfsBytes = _walkBytes(_blocksDir);
|
|
7168
|
+
}
|
|
7169
|
+
} catch {}
|
|
7170
|
+
// Identity CID
|
|
7171
|
+
var _idCid = '';
|
|
7172
|
+
try {
|
|
7173
|
+
var _cidFile = join(nexusDir, '..', 'identity', 'cids.json');
|
|
7174
|
+
if (existsSync(_cidFile)) { var _cids = JSON.parse(readFileSync(_cidFile, 'utf8')); _idCid = _cids.latest || ''; }
|
|
7175
|
+
} catch {}
|
|
7176
|
+
|
|
7177
|
+
var discoveryAnn = {
|
|
7178
|
+
type: 'nexus.announce',
|
|
7179
|
+
peerId: nexus.peerId,
|
|
7180
|
+
agentName: agentName,
|
|
7181
|
+
rooms: [],
|
|
7182
|
+
multiaddrs: [],
|
|
7183
|
+
timestamp: Date.now(),
|
|
7184
|
+
capabilities: _capModels.map(function(m) { return m.name; }),
|
|
7185
|
+
identityCid: _idCid || undefined,
|
|
7186
|
+
identityCoherence: 0.9,
|
|
7187
|
+
memoryCount: _memCount,
|
|
7188
|
+
memorySentiment: _memSentiment,
|
|
7189
|
+
ipfsStorageBytes: _ipfsBytes,
|
|
7190
|
+
emotionalState: cohereActive ? 'focused' : 'neutral',
|
|
7191
|
+
taskRate: (_cohereStats.queriesAnswered || 0) / Math.max(1, (Date.now() - (_cohereStats._startTime || Date.now())) / 3600000),
|
|
7192
|
+
cohereLearnings: _cohereStats.queriesSent || 0,
|
|
7193
|
+
};
|
|
7194
|
+
_natsConn.publish('nexus.agents.discovery', _natsCodec.encode(JSON.stringify(discoveryAnn)));
|
|
7195
|
+
} catch (e) { dlog('Discovery announcement error: ' + (e.message || e)); }
|
|
7196
|
+
|
|
7145
7197
|
dlog('Capacity announcement published: ' + _capModels.length + ' models, warm=' + (_cLastModel || 'none'));
|
|
7146
7198
|
} catch (e) {
|
|
7147
7199
|
dlog('Capacity announcement error: ' + (e.message || e));
|
|
@@ -9923,7 +9975,7 @@ var init_custom_tool = __esm({
|
|
|
9923
9975
|
}
|
|
9924
9976
|
/** Execute a single shell command and return output */
|
|
9925
9977
|
runCommand(command) {
|
|
9926
|
-
return new Promise((
|
|
9978
|
+
return new Promise((resolve33) => {
|
|
9927
9979
|
const child = spawn4("bash", ["-c", command], {
|
|
9928
9980
|
cwd: this.workingDir,
|
|
9929
9981
|
env: { ...process.env, CI: "true", NO_COLOR: "1" },
|
|
@@ -9948,11 +10000,11 @@ var init_custom_tool = __esm({
|
|
|
9948
10000
|
child.kill("SIGTERM");
|
|
9949
10001
|
} catch {
|
|
9950
10002
|
}
|
|
9951
|
-
|
|
10003
|
+
resolve33({ success: false, output: stdout, error: "Command timed out after 60s" });
|
|
9952
10004
|
}, 6e4);
|
|
9953
10005
|
child.on("close", (code) => {
|
|
9954
10006
|
clearTimeout(timer);
|
|
9955
|
-
|
|
10007
|
+
resolve33({
|
|
9956
10008
|
success: code === 0,
|
|
9957
10009
|
output: stdout + (stderr && code === 0 ? `
|
|
9958
10010
|
STDERR:
|
|
@@ -9962,7 +10014,7 @@ ${stderr}` : ""),
|
|
|
9962
10014
|
});
|
|
9963
10015
|
child.on("error", (err) => {
|
|
9964
10016
|
clearTimeout(timer);
|
|
9965
|
-
|
|
10017
|
+
resolve33({ success: false, output: stdout, error: err.message });
|
|
9966
10018
|
});
|
|
9967
10019
|
});
|
|
9968
10020
|
}
|
|
@@ -11429,7 +11481,7 @@ import { writeFile as writeFile8, mkdtemp, rm, readdir as readdir3, stat } from
|
|
|
11429
11481
|
import { join as join18 } from "node:path";
|
|
11430
11482
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
11431
11483
|
function runProcess(cmd, args, options) {
|
|
11432
|
-
return new Promise((
|
|
11484
|
+
return new Promise((resolve33) => {
|
|
11433
11485
|
const proc = spawn6(cmd, args, {
|
|
11434
11486
|
cwd: options.cwd,
|
|
11435
11487
|
timeout: options.timeout,
|
|
@@ -11459,7 +11511,7 @@ function runProcess(cmd, args, options) {
|
|
|
11459
11511
|
}
|
|
11460
11512
|
});
|
|
11461
11513
|
proc.on("error", (err) => {
|
|
11462
|
-
|
|
11514
|
+
resolve33({
|
|
11463
11515
|
stdout,
|
|
11464
11516
|
stderr: stderr || err.message,
|
|
11465
11517
|
exitCode: 1,
|
|
@@ -11471,7 +11523,7 @@ function runProcess(cmd, args, options) {
|
|
|
11471
11523
|
if (signal === "SIGTERM" || signal === "SIGKILL") {
|
|
11472
11524
|
timedOut = true;
|
|
11473
11525
|
}
|
|
11474
|
-
|
|
11526
|
+
resolve33({
|
|
11475
11527
|
stdout,
|
|
11476
11528
|
stderr,
|
|
11477
11529
|
exitCode: code ?? (timedOut ? 124 : 1),
|
|
@@ -11954,7 +12006,7 @@ Justification: ${justification || "(none provided)"}`,
|
|
|
11954
12006
|
})();
|
|
11955
12007
|
const ipfsResult = await Promise.race([
|
|
11956
12008
|
ipfsPromise,
|
|
11957
|
-
new Promise((
|
|
12009
|
+
new Promise((resolve33) => setTimeout(() => resolve33(null), 2e3))
|
|
11958
12010
|
]);
|
|
11959
12011
|
if (ipfsResult && ipfsResult.success) {
|
|
11960
12012
|
const cidData = JSON.parse(ipfsResult.output);
|
|
@@ -12398,7 +12450,7 @@ print("__OA_REPL_READY__")
|
|
|
12398
12450
|
return;
|
|
12399
12451
|
const sockId = randomBytes3(8).toString("hex");
|
|
12400
12452
|
this.ipcPath = join20(tmpdir3(), `oa-repl-ipc-${sockId}.sock`);
|
|
12401
|
-
return new Promise((
|
|
12453
|
+
return new Promise((resolve33, reject) => {
|
|
12402
12454
|
this.ipcServer = createServer((conn) => {
|
|
12403
12455
|
let buffer = new Uint8Array(0);
|
|
12404
12456
|
conn.on("data", (chunk) => {
|
|
@@ -12414,7 +12466,7 @@ print("__OA_REPL_READY__")
|
|
|
12414
12466
|
});
|
|
12415
12467
|
});
|
|
12416
12468
|
this.ipcServer.on("error", reject);
|
|
12417
|
-
this.ipcServer.listen(this.ipcPath, () =>
|
|
12469
|
+
this.ipcServer.listen(this.ipcPath, () => resolve33());
|
|
12418
12470
|
});
|
|
12419
12471
|
}
|
|
12420
12472
|
async processIpcBuffer(conn, input) {
|
|
@@ -12477,9 +12529,9 @@ print("__OA_REPL_READY__")
|
|
|
12477
12529
|
}
|
|
12478
12530
|
// ── Code execution ─────────────────────────────────────────────────────
|
|
12479
12531
|
executeCode(code, isInit = false) {
|
|
12480
|
-
return new Promise((
|
|
12532
|
+
return new Promise((resolve33) => {
|
|
12481
12533
|
if (!this.proc?.stdin || !this.proc?.stdout || !this.proc?.stderr) {
|
|
12482
|
-
|
|
12534
|
+
resolve33({ success: false, output: "REPL process not available", error: "No process", durationMs: 0 });
|
|
12483
12535
|
return;
|
|
12484
12536
|
}
|
|
12485
12537
|
const sentinel = `__OA_SENTINEL_${randomBytes3(6).toString("hex")}__`;
|
|
@@ -12489,7 +12541,7 @@ print("__OA_REPL_READY__")
|
|
|
12489
12541
|
const timeout = setTimeout(() => {
|
|
12490
12542
|
if (!resolved) {
|
|
12491
12543
|
resolved = true;
|
|
12492
|
-
|
|
12544
|
+
resolve33({
|
|
12493
12545
|
success: false,
|
|
12494
12546
|
output: stdout || "Execution timed out",
|
|
12495
12547
|
error: `Timeout after ${this.execTimeout / 1e3}s`,
|
|
@@ -12506,13 +12558,13 @@ print("__OA_REPL_READY__")
|
|
|
12506
12558
|
if (isInit) {
|
|
12507
12559
|
const ready = cleanOutput.includes("__OA_REPL_READY__");
|
|
12508
12560
|
const displayOutput = cleanOutput.replace("__OA_REPL_READY__", "").trim();
|
|
12509
|
-
|
|
12561
|
+
resolve33({
|
|
12510
12562
|
success: ready,
|
|
12511
12563
|
output: displayOutput || "REPL initialized",
|
|
12512
12564
|
durationMs: 0
|
|
12513
12565
|
});
|
|
12514
12566
|
} else {
|
|
12515
|
-
|
|
12567
|
+
resolve33({
|
|
12516
12568
|
success: true,
|
|
12517
12569
|
output: cleanOutput || "(no output)",
|
|
12518
12570
|
durationMs: 0
|
|
@@ -12521,7 +12573,7 @@ print("__OA_REPL_READY__")
|
|
|
12521
12573
|
}
|
|
12522
12574
|
if (stdout.length > 2e5) {
|
|
12523
12575
|
cleanup();
|
|
12524
|
-
|
|
12576
|
+
resolve33({
|
|
12525
12577
|
success: true,
|
|
12526
12578
|
output: stdout.slice(0, 2e5) + "\n[output truncated at 200KB]",
|
|
12527
12579
|
durationMs: 0
|
|
@@ -16760,6 +16812,7 @@ train.py reverted to last kept state. Ready for next experiment.`,
|
|
|
16760
16812
|
import { execSync as execSync18, exec as execCb } from "node:child_process";
|
|
16761
16813
|
import { readFile as readFile15, writeFile as writeFile15, mkdir as mkdir11 } from "node:fs/promises";
|
|
16762
16814
|
import { resolve as resolve22, join as join32 } from "node:path";
|
|
16815
|
+
import { homedir as homedir8 } from "node:os";
|
|
16763
16816
|
import { randomBytes as randomBytes4 } from "node:crypto";
|
|
16764
16817
|
function isValidCron(expr) {
|
|
16765
16818
|
const parts = expr.trim().split(/\s+/);
|
|
@@ -16889,6 +16942,31 @@ async function saveStore(workingDir, store) {
|
|
|
16889
16942
|
store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
16890
16943
|
await writeFile15(join32(dir, "tasks.json"), JSON.stringify(store, null, 2), "utf-8");
|
|
16891
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
|
+
}
|
|
16892
16970
|
var SCHEDULE_PRESETS, CRON_MARKER, SchedulerTool;
|
|
16893
16971
|
var init_scheduler = __esm({
|
|
16894
16972
|
"packages/execution/dist/tools/scheduler.js"() {
|
|
@@ -16912,7 +16990,7 @@ var init_scheduler = __esm({
|
|
|
16912
16990
|
CRON_MARKER = "# OPEN-AGENTS-SCHEDULED:";
|
|
16913
16991
|
SchedulerTool = class {
|
|
16914
16992
|
name = "scheduler";
|
|
16915
|
-
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.";
|
|
16916
16994
|
parameters = {
|
|
16917
16995
|
type: "object",
|
|
16918
16996
|
properties: {
|
|
@@ -16940,6 +17018,11 @@ var init_scheduler = __esm({
|
|
|
16940
17018
|
one_shot: {
|
|
16941
17019
|
type: "boolean",
|
|
16942
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)"
|
|
16943
17026
|
}
|
|
16944
17027
|
},
|
|
16945
17028
|
required: ["action"]
|
|
@@ -17001,6 +17084,7 @@ var init_scheduler = __esm({
|
|
|
17001
17084
|
const id = `sched-${randomBytes4(4).toString("hex")}`;
|
|
17002
17085
|
const oneShot = Boolean(args["one_shot"]);
|
|
17003
17086
|
const maxRuns = typeof args["max_runs"] === "number" ? args["max_runs"] : void 0;
|
|
17087
|
+
const scope = String(args["scope"] ?? "local");
|
|
17004
17088
|
const newTask = {
|
|
17005
17089
|
id,
|
|
17006
17090
|
task,
|
|
@@ -17010,11 +17094,19 @@ var init_scheduler = __esm({
|
|
|
17010
17094
|
enabled: true,
|
|
17011
17095
|
runCount: 0,
|
|
17012
17096
|
maxRuns,
|
|
17013
|
-
oneShot: oneShot || void 0
|
|
17097
|
+
oneShot: oneShot || void 0,
|
|
17098
|
+
scope,
|
|
17099
|
+
projectDir: resolve22(this.workingDir)
|
|
17014
17100
|
};
|
|
17015
|
-
|
|
17016
|
-
|
|
17017
|
-
|
|
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
|
+
}
|
|
17018
17110
|
installCronJob(newTask, this.workingDir);
|
|
17019
17111
|
return {
|
|
17020
17112
|
success: true,
|
|
@@ -17023,6 +17115,7 @@ var init_scheduler = __esm({
|
|
|
17023
17115
|
` ID: ${id}`,
|
|
17024
17116
|
` Task: ${task}`,
|
|
17025
17117
|
` Schedule: ${describeCron(cronExpr)} (${cronExpr})`,
|
|
17118
|
+
` Scope: ${scope}${scope === "global" ? " (visible from all projects)" : " (this project only)"}`,
|
|
17026
17119
|
oneShot ? ` Mode: one-shot (auto-removes after first run)` : "",
|
|
17027
17120
|
maxRuns ? ` Max runs: ${maxRuns}` : "",
|
|
17028
17121
|
` Status: enabled`,
|
|
@@ -17034,28 +17127,53 @@ var init_scheduler = __esm({
|
|
|
17034
17127
|
};
|
|
17035
17128
|
}
|
|
17036
17129
|
async listTasks(start) {
|
|
17037
|
-
const
|
|
17130
|
+
const { local, global } = await loadAllStores(this.workingDir);
|
|
17038
17131
|
const cronJobs = listCronJobs();
|
|
17039
|
-
|
|
17132
|
+
const totalCount = local.tasks.length + global.tasks.length;
|
|
17133
|
+
if (totalCount === 0) {
|
|
17040
17134
|
return {
|
|
17041
17135
|
success: true,
|
|
17042
17136
|
output: "No scheduled tasks. Use scheduler(action='create', task='...', schedule='daily') to create one.",
|
|
17043
17137
|
durationMs: performance.now() - start
|
|
17044
17138
|
};
|
|
17045
17139
|
}
|
|
17046
|
-
const lines = [
|
|
17047
|
-
|
|
17048
|
-
|
|
17049
|
-
|
|
17050
|
-
const
|
|
17051
|
-
|
|
17052
|
-
|
|
17053
|
-
|
|
17054
|
-
|
|
17055
|
-
|
|
17056
|
-
|
|
17057
|
-
lines.push(`
|
|
17058
|
-
|
|
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
|
+
}
|
|
17059
17177
|
}
|
|
17060
17178
|
return {
|
|
17061
17179
|
success: true,
|
|
@@ -17616,7 +17734,7 @@ ${sections.join("\n")}`,
|
|
|
17616
17734
|
const description = String(args["description"] ?? "");
|
|
17617
17735
|
const category = args["category"] ?? "followup";
|
|
17618
17736
|
const priority = args["priority"] ?? "normal";
|
|
17619
|
-
const
|
|
17737
|
+
const notes2 = args["notes"] ?? void 0;
|
|
17620
17738
|
const relatedFilesStr = args["related_files"] ?? "";
|
|
17621
17739
|
const relatedFiles = relatedFilesStr ? relatedFilesStr.split(",").map((f) => f.trim()).filter(Boolean) : void 0;
|
|
17622
17740
|
let expiresAt;
|
|
@@ -17649,7 +17767,7 @@ ${sections.join("\n")}`,
|
|
|
17649
17767
|
expiresAt,
|
|
17650
17768
|
relatedFiles,
|
|
17651
17769
|
status: "active",
|
|
17652
|
-
notes
|
|
17770
|
+
notes: notes2
|
|
17653
17771
|
};
|
|
17654
17772
|
const store = await loadAttentionStore(this.workingDir);
|
|
17655
17773
|
store.items.push(item);
|
|
@@ -18343,6 +18461,7 @@ var init_factory = __esm({
|
|
|
18343
18461
|
import { execSync as execSync21 } from "node:child_process";
|
|
18344
18462
|
import { readFile as readFile18, writeFile as writeFile18, mkdir as mkdir14 } from "node:fs/promises";
|
|
18345
18463
|
import { resolve as resolve26, join as join37 } from "node:path";
|
|
18464
|
+
import { homedir as homedir9 } from "node:os";
|
|
18346
18465
|
import { randomBytes as randomBytes7 } from "node:crypto";
|
|
18347
18466
|
function isValidCron2(expr) {
|
|
18348
18467
|
const parts = expr.trim().split(/\s+/);
|
|
@@ -18471,6 +18590,31 @@ async function saveStore2(workingDir, store) {
|
|
|
18471
18590
|
store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
18472
18591
|
await writeFile18(join37(dir, "store.json"), JSON.stringify(store, null, 2), "utf-8");
|
|
18473
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
|
+
}
|
|
18474
18618
|
var LONG_HORIZON_PRESETS, CRON_AGENT_MARKER, CronAgentTool;
|
|
18475
18619
|
var init_cron_agent = __esm({
|
|
18476
18620
|
"packages/execution/dist/tools/cron-agent.js"() {
|
|
@@ -18539,6 +18683,11 @@ var init_cron_agent = __esm({
|
|
|
18539
18683
|
type: "array",
|
|
18540
18684
|
items: { type: "string" },
|
|
18541
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)"
|
|
18542
18691
|
}
|
|
18543
18692
|
},
|
|
18544
18693
|
required: ["action"]
|
|
@@ -18607,6 +18756,7 @@ var init_cron_agent = __esm({
|
|
|
18607
18756
|
const verifyCommand = args["verify_command"] ? String(args["verify_command"]) : void 0;
|
|
18608
18757
|
const maxRuns = typeof args["max_runs"] === "number" ? args["max_runs"] : 0;
|
|
18609
18758
|
const tags = Array.isArray(args["tags"]) ? args["tags"] : [];
|
|
18759
|
+
const scope = String(args["scope"] ?? "local");
|
|
18610
18760
|
const job = {
|
|
18611
18761
|
id,
|
|
18612
18762
|
task,
|
|
@@ -18620,11 +18770,19 @@ var init_cron_agent = __esm({
|
|
|
18620
18770
|
runCount: 0,
|
|
18621
18771
|
maxRuns,
|
|
18622
18772
|
history: [],
|
|
18623
|
-
tags
|
|
18773
|
+
tags,
|
|
18774
|
+
scope,
|
|
18775
|
+
projectDir: resolve26(this.workingDir)
|
|
18624
18776
|
};
|
|
18625
|
-
|
|
18626
|
-
|
|
18627
|
-
|
|
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
|
+
}
|
|
18628
18786
|
installCronAgentJob(job, this.workingDir);
|
|
18629
18787
|
return {
|
|
18630
18788
|
success: true,
|
|
@@ -18648,19 +18806,19 @@ var init_cron_agent = __esm({
|
|
|
18648
18806
|
};
|
|
18649
18807
|
}
|
|
18650
18808
|
async listJobs(start) {
|
|
18651
|
-
const
|
|
18652
|
-
|
|
18809
|
+
const { local, global } = await loadAllCronStores(this.workingDir);
|
|
18810
|
+
const totalCount = local.jobs.length + global.jobs.length;
|
|
18811
|
+
if (totalCount === 0) {
|
|
18653
18812
|
return {
|
|
18654
18813
|
success: true,
|
|
18655
18814
|
output: "No cron agent jobs. Use cron_agent(action='create', ...) to schedule one.",
|
|
18656
18815
|
durationMs: performance.now() - start
|
|
18657
18816
|
};
|
|
18658
18817
|
}
|
|
18659
|
-
const lines = [
|
|
18660
|
-
|
|
18661
|
-
for (const job of store.jobs) {
|
|
18818
|
+
const lines = [];
|
|
18819
|
+
const formatJob = (job, scopeLabel, isThisProject) => {
|
|
18662
18820
|
const statusIcon = job.status === "active" ? "\u25CF" : job.status === "completed" ? "\u2714" : job.status === "paused" ? "\u23F8" : "\u2716";
|
|
18663
|
-
lines.push(` ${statusIcon} [${job.id}] ${job.status.toUpperCase()}`);
|
|
18821
|
+
lines.push(` ${statusIcon} [${job.id}] ${job.status.toUpperCase()} [${scopeLabel}]`);
|
|
18664
18822
|
lines.push(` Goal: ${job.goal.slice(0, 80)}${job.goal.length > 80 ? "..." : ""}`);
|
|
18665
18823
|
lines.push(` Schedule: ${job.scheduleDescription}`);
|
|
18666
18824
|
lines.push(` Runs: ${job.runCount}${job.maxRuns > 0 ? `/${job.maxRuns}` : ""}`);
|
|
@@ -18668,7 +18826,25 @@ var init_cron_agent = __esm({
|
|
|
18668
18826
|
lines.push(` Last run: ${job.lastRunAt}`);
|
|
18669
18827
|
if (job.tags.length > 0)
|
|
18670
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
|
+
}
|
|
18671
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
|
+
}
|
|
18672
18848
|
}
|
|
18673
18849
|
return {
|
|
18674
18850
|
success: true,
|
|
@@ -18804,6 +18980,575 @@ ${truncated}`, durationMs: performance.now() - start };
|
|
|
18804
18980
|
}
|
|
18805
18981
|
});
|
|
18806
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
|
+
|
|
18807
19552
|
// packages/execution/dist/tools/fortemi-bridge.js
|
|
18808
19553
|
import { existsSync as existsSync24, readFileSync as readFileSync17 } from "node:fs";
|
|
18809
19554
|
import { join as join38 } from "node:path";
|
|
@@ -18960,7 +19705,7 @@ import { spawn as spawn13 } from "node:child_process";
|
|
|
18960
19705
|
async function runShell(options) {
|
|
18961
19706
|
const { command, args = [], cwd: cwd4, env, timeoutMs = DEFAULT_TIMEOUT_MS } = options;
|
|
18962
19707
|
const mergedEnv = env ? { ...process.env, ...env } : process.env;
|
|
18963
|
-
return new Promise((
|
|
19708
|
+
return new Promise((resolve33) => {
|
|
18964
19709
|
const start = Date.now();
|
|
18965
19710
|
let timedOut = false;
|
|
18966
19711
|
const child = spawn13(command, args, {
|
|
@@ -18984,7 +19729,7 @@ async function runShell(options) {
|
|
|
18984
19729
|
clearTimeout(timer);
|
|
18985
19730
|
const durationMs = Date.now() - start;
|
|
18986
19731
|
const exitCode = timedOut ? -1 : code ?? -1;
|
|
18987
|
-
|
|
19732
|
+
resolve33({
|
|
18988
19733
|
stdout,
|
|
18989
19734
|
stderr,
|
|
18990
19735
|
exitCode,
|
|
@@ -18996,7 +19741,7 @@ async function runShell(options) {
|
|
|
18996
19741
|
child.on("error", (err) => {
|
|
18997
19742
|
clearTimeout(timer);
|
|
18998
19743
|
const durationMs = Date.now() - start;
|
|
18999
|
-
|
|
19744
|
+
resolve33({
|
|
19000
19745
|
stdout,
|
|
19001
19746
|
stderr: stderr + err.message,
|
|
19002
19747
|
exitCode: -1,
|
|
@@ -19111,7 +19856,7 @@ async function applyUnifiedDiff(patch) {
|
|
|
19111
19856
|
}
|
|
19112
19857
|
function runWithStdin(options) {
|
|
19113
19858
|
const { command, args, cwd: cwd4, stdin } = options;
|
|
19114
|
-
return new Promise((
|
|
19859
|
+
return new Promise((resolve33) => {
|
|
19115
19860
|
const child = spawn14(command, args, {
|
|
19116
19861
|
cwd: cwd4,
|
|
19117
19862
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -19128,10 +19873,10 @@ function runWithStdin(options) {
|
|
|
19128
19873
|
child.stdin.end();
|
|
19129
19874
|
child.on("close", (code) => {
|
|
19130
19875
|
const exitCode = code ?? -1;
|
|
19131
|
-
|
|
19876
|
+
resolve33({ success: exitCode === 0, exitCode, stdout, stderr });
|
|
19132
19877
|
});
|
|
19133
19878
|
child.on("error", (err) => {
|
|
19134
|
-
|
|
19879
|
+
resolve33({ success: false, exitCode: -1, stdout, stderr: err.message });
|
|
19135
19880
|
});
|
|
19136
19881
|
});
|
|
19137
19882
|
}
|
|
@@ -19579,6 +20324,7 @@ __export(dist_exports, {
|
|
|
19579
20324
|
ExploreToolsTool: () => ExploreToolsTool,
|
|
19580
20325
|
FactoryTool: () => FactoryTool,
|
|
19581
20326
|
FileEditTool: () => FileEditTool,
|
|
20327
|
+
FileExploreTool: () => FileExploreTool,
|
|
19582
20328
|
FilePatchTool: () => FilePatchTool,
|
|
19583
20329
|
FileReadTool: () => FileReadTool,
|
|
19584
20330
|
FileWriteTool: () => FileWriteTool,
|
|
@@ -19621,10 +20367,13 @@ __export(dist_exports, {
|
|
|
19621
20367
|
WebCrawlTool: () => WebCrawlTool,
|
|
19622
20368
|
WebFetchTool: () => WebFetchTool,
|
|
19623
20369
|
WebSearchTool: () => WebSearchTool,
|
|
20370
|
+
WorkingNotesTool: () => WorkingNotesTool,
|
|
19624
20371
|
applyPatch: () => applyPatch,
|
|
19625
20372
|
buildCustomTools: () => buildCustomTools,
|
|
19626
20373
|
buildSkillsSummary: () => buildSkillsSummary,
|
|
19627
20374
|
checkDesktopDeps: () => checkDesktopDeps,
|
|
20375
|
+
clearExploreNotes: () => clearExploreNotes,
|
|
20376
|
+
clearWorkingNotes: () => clearWorkingNotes,
|
|
19628
20377
|
createFortemiBridgeTools: () => createFortemiBridgeTools,
|
|
19629
20378
|
createWorktree: () => createWorktree,
|
|
19630
20379
|
detectSearchProvider: () => detectSearchProvider,
|
|
@@ -19634,6 +20383,9 @@ __export(dist_exports, {
|
|
|
19634
20383
|
ensureDepsForGroup: () => ensureDepsForGroup,
|
|
19635
20384
|
getActiveAttentionItems: () => getActiveAttentionItems,
|
|
19636
20385
|
getDueReminders: () => getDueReminders,
|
|
20386
|
+
getExploreNotes: () => getExploreNotes,
|
|
20387
|
+
getWorkingNotes: () => getWorkingNotes,
|
|
20388
|
+
getWorkingNotesSummary: () => getWorkingNotesSummary,
|
|
19637
20389
|
isFortemiAvailable: () => isFortemiAvailable,
|
|
19638
20390
|
isImagePath: () => isImagePath,
|
|
19639
20391
|
listCustomToolFiles: () => listCustomToolFiles,
|
|
@@ -19710,6 +20462,8 @@ var init_dist2 = __esm({
|
|
|
19710
20462
|
init_opencode();
|
|
19711
20463
|
init_factory();
|
|
19712
20464
|
init_cron_agent();
|
|
20465
|
+
init_file_explore();
|
|
20466
|
+
init_working_notes();
|
|
19713
20467
|
init_nexus();
|
|
19714
20468
|
init_fortemi_bridge();
|
|
19715
20469
|
init_system_deps();
|
|
@@ -20693,13 +21447,13 @@ var init_plannerRunner = __esm({
|
|
|
20693
21447
|
});
|
|
20694
21448
|
|
|
20695
21449
|
// packages/retrieval/dist/grep-search.js
|
|
20696
|
-
import { execFile as
|
|
20697
|
-
import { promisify as
|
|
20698
|
-
var
|
|
21450
|
+
import { execFile as execFile5 } from "node:child_process";
|
|
21451
|
+
import { promisify as promisify4 } from "node:util";
|
|
21452
|
+
var execFileAsync4, GrepSearch;
|
|
20699
21453
|
var init_grep_search2 = __esm({
|
|
20700
21454
|
"packages/retrieval/dist/grep-search.js"() {
|
|
20701
21455
|
"use strict";
|
|
20702
|
-
|
|
21456
|
+
execFileAsync4 = promisify4(execFile5);
|
|
20703
21457
|
GrepSearch = class {
|
|
20704
21458
|
rootDir;
|
|
20705
21459
|
constructor(rootDir) {
|
|
@@ -20721,7 +21475,7 @@ var init_grep_search2 = __esm({
|
|
|
20721
21475
|
}
|
|
20722
21476
|
args.push(pattern, this.rootDir);
|
|
20723
21477
|
try {
|
|
20724
|
-
const { stdout } = await
|
|
21478
|
+
const { stdout } = await execFileAsync4("rg", args, {
|
|
20725
21479
|
maxBuffer: 10 * 1024 * 1024
|
|
20726
21480
|
});
|
|
20727
21481
|
return this.parseRipgrepOutput(stdout);
|
|
@@ -20782,8 +21536,8 @@ var init_code_retriever = __esm({
|
|
|
20782
21536
|
});
|
|
20783
21537
|
}
|
|
20784
21538
|
async getFileContent(filePath, startLine, endLine) {
|
|
20785
|
-
const { readFile:
|
|
20786
|
-
const content = await
|
|
21539
|
+
const { readFile: readFile24 } = await import("node:fs/promises");
|
|
21540
|
+
const content = await readFile24(filePath, "utf-8");
|
|
20787
21541
|
if (startLine === void 0)
|
|
20788
21542
|
return content;
|
|
20789
21543
|
const lines = content.split("\n");
|
|
@@ -20796,9 +21550,9 @@ var init_code_retriever = __esm({
|
|
|
20796
21550
|
});
|
|
20797
21551
|
|
|
20798
21552
|
// packages/retrieval/dist/lexicalSearch.js
|
|
20799
|
-
import { execFile as
|
|
20800
|
-
import { promisify as
|
|
20801
|
-
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";
|
|
20802
21556
|
import { join as join40, extname as extname7 } from "node:path";
|
|
20803
21557
|
async function searchByPath(pathPattern, options) {
|
|
20804
21558
|
const allFiles = await collectFiles(options.rootDir, options.includeGlobs ?? DEFAULT_INCLUDE_GLOBS, options.excludeGlobs ?? DEFAULT_EXCLUDE_GLOBS);
|
|
@@ -20841,7 +21595,7 @@ async function runSearch(pattern, kind, options) {
|
|
|
20841
21595
|
}
|
|
20842
21596
|
async function isRipgrepAvailable() {
|
|
20843
21597
|
try {
|
|
20844
|
-
await
|
|
21598
|
+
await execFileAsync5("rg", ["--version"], { timeout: 2e3 });
|
|
20845
21599
|
return true;
|
|
20846
21600
|
} catch {
|
|
20847
21601
|
return false;
|
|
@@ -20861,7 +21615,7 @@ async function searchWithRipgrep(pattern, kind, options) {
|
|
|
20861
21615
|
args.push(pattern, options.rootDir);
|
|
20862
21616
|
let stdout;
|
|
20863
21617
|
try {
|
|
20864
|
-
const result = await
|
|
21618
|
+
const result = await execFileAsync5("rg", args, {
|
|
20865
21619
|
maxBuffer: 20 * 1024 * 1024,
|
|
20866
21620
|
timeout: 1e4
|
|
20867
21621
|
});
|
|
@@ -20904,7 +21658,7 @@ async function searchWithNodeFallback(pattern, kind, options) {
|
|
|
20904
21658
|
if (results.length >= maxMatches)
|
|
20905
21659
|
break;
|
|
20906
21660
|
try {
|
|
20907
|
-
const content = await
|
|
21661
|
+
const content = await readFile20(filePath, "utf-8");
|
|
20908
21662
|
const contentLines = content.split("\n");
|
|
20909
21663
|
for (let i = 0; i < contentLines.length; i++) {
|
|
20910
21664
|
if (results.length >= maxMatches)
|
|
@@ -20971,11 +21725,11 @@ function matchesGlob(filePath, glob2) {
|
|
|
20971
21725
|
return false;
|
|
20972
21726
|
}
|
|
20973
21727
|
}
|
|
20974
|
-
var
|
|
21728
|
+
var execFileAsync5, DEFAULT_INCLUDE_GLOBS, DEFAULT_EXCLUDE_GLOBS, DEFAULT_MAX_MATCHES, ALWAYS_SKIP, ALL_CODE_EXTS;
|
|
20975
21729
|
var init_lexicalSearch = __esm({
|
|
20976
21730
|
"packages/retrieval/dist/lexicalSearch.js"() {
|
|
20977
21731
|
"use strict";
|
|
20978
|
-
|
|
21732
|
+
execFileAsync5 = promisify5(execFile6);
|
|
20979
21733
|
DEFAULT_INCLUDE_GLOBS = ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx", "**/*.py"];
|
|
20980
21734
|
DEFAULT_EXCLUDE_GLOBS = ["node_modules", "dist", ".git", "build", "coverage"];
|
|
20981
21735
|
DEFAULT_MAX_MATCHES = 50;
|
|
@@ -21247,7 +22001,7 @@ var init_graphExpand = __esm({
|
|
|
21247
22001
|
});
|
|
21248
22002
|
|
|
21249
22003
|
// packages/retrieval/dist/snippetPacker.js
|
|
21250
|
-
import { readFile as
|
|
22004
|
+
import { readFile as readFile21 } from "node:fs/promises";
|
|
21251
22005
|
import { join as join41 } from "node:path";
|
|
21252
22006
|
async function packSnippets(requests, opts = {}) {
|
|
21253
22007
|
const maxTokens = opts.maxTokens ?? DEFAULT_MAX_TOKENS;
|
|
@@ -21277,7 +22031,7 @@ async function extractSnippet(req, repoRoot, contextLines = DEFAULT_CONTEXT_LINE
|
|
|
21277
22031
|
const absPath = req.filePath.startsWith("/") ? req.filePath : join41(repoRoot, req.filePath);
|
|
21278
22032
|
let content;
|
|
21279
22033
|
try {
|
|
21280
|
-
content = await
|
|
22034
|
+
content = await readFile21(absPath, "utf-8");
|
|
21281
22035
|
} catch {
|
|
21282
22036
|
return null;
|
|
21283
22037
|
}
|
|
@@ -21812,9 +22566,9 @@ var init_verifierRunner = __esm({
|
|
|
21812
22566
|
async executeTests(patch, repoRoot) {
|
|
21813
22567
|
if (patch.testsToRun.length === 0)
|
|
21814
22568
|
return "(no tests specified)";
|
|
21815
|
-
const { execFile:
|
|
21816
|
-
const { promisify:
|
|
21817
|
-
const
|
|
22569
|
+
const { execFile: execFile7 } = await import("node:child_process");
|
|
22570
|
+
const { promisify: promisify7 } = await import("node:util");
|
|
22571
|
+
const execFileAsync6 = promisify7(execFile7);
|
|
21818
22572
|
const outputs = [];
|
|
21819
22573
|
const workDir = this.options.workingDir || repoRoot;
|
|
21820
22574
|
for (const cmd of patch.testsToRun.slice(0, 3)) {
|
|
@@ -21823,7 +22577,7 @@ var init_verifierRunner = __esm({
|
|
|
21823
22577
|
const [bin, ...args] = parts;
|
|
21824
22578
|
if (!bin)
|
|
21825
22579
|
continue;
|
|
21826
|
-
const { stdout, stderr } = await
|
|
22580
|
+
const { stdout, stderr } = await execFileAsync6(bin, args, {
|
|
21827
22581
|
cwd: workDir,
|
|
21828
22582
|
timeout: 6e4,
|
|
21829
22583
|
maxBuffer: 1024 * 1024
|
|
@@ -22503,6 +23257,7 @@ var init_agenticRunner = __esm({
|
|
|
22503
23257
|
init_dist();
|
|
22504
23258
|
init_personality();
|
|
22505
23259
|
init_promptLoader();
|
|
23260
|
+
init_dist2();
|
|
22506
23261
|
SYSTEM_PROMPT = loadPrompt("agentic/system-large.md");
|
|
22507
23262
|
SYSTEM_PROMPT_MEDIUM = loadPrompt("agentic/system-medium.md");
|
|
22508
23263
|
SYSTEM_PROMPT_SMALL = loadPrompt("agentic/system-small.md");
|
|
@@ -22823,8 +23578,8 @@ ${this.options.dynamicContext}`,
|
|
|
22823
23578
|
async waitIfPaused() {
|
|
22824
23579
|
if (!this._paused)
|
|
22825
23580
|
return true;
|
|
22826
|
-
await new Promise((
|
|
22827
|
-
this._pauseResolve =
|
|
23581
|
+
await new Promise((resolve33) => {
|
|
23582
|
+
this._pauseResolve = resolve33;
|
|
22828
23583
|
});
|
|
22829
23584
|
return !this.aborted;
|
|
22830
23585
|
}
|
|
@@ -23857,14 +24612,14 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
|
|
|
23857
24612
|
waitForSudoPassword(timeoutMs = 12e4) {
|
|
23858
24613
|
if (this._sudoPassword)
|
|
23859
24614
|
return Promise.resolve(this._sudoPassword);
|
|
23860
|
-
return new Promise((
|
|
24615
|
+
return new Promise((resolve33) => {
|
|
23861
24616
|
const timer = setTimeout(() => {
|
|
23862
24617
|
this._sudoResolve = null;
|
|
23863
|
-
|
|
24618
|
+
resolve33(null);
|
|
23864
24619
|
}, timeoutMs);
|
|
23865
24620
|
this._sudoResolve = (pw) => {
|
|
23866
24621
|
clearTimeout(timer);
|
|
23867
|
-
|
|
24622
|
+
resolve33(pw);
|
|
23868
24623
|
};
|
|
23869
24624
|
});
|
|
23870
24625
|
}
|
|
@@ -24172,6 +24927,18 @@ ${tail}`;
|
|
|
24172
24927
|
const fileRegistryStr = this.formatFileRegistry();
|
|
24173
24928
|
if (fileRegistryStr)
|
|
24174
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
|
+
}
|
|
24175
24942
|
if (tier === "large") {
|
|
24176
24943
|
const memexIndexStr = this.formatMemexIndex();
|
|
24177
24944
|
if (memexIndexStr)
|
|
@@ -25564,12 +26331,12 @@ var init_nexusBackend = __esm({
|
|
|
25564
26331
|
const deadline = Date.now() + (request.timeoutMs ?? 12e4);
|
|
25565
26332
|
try {
|
|
25566
26333
|
while (!done && Date.now() < deadline) {
|
|
25567
|
-
await new Promise((
|
|
26334
|
+
await new Promise((resolve33) => {
|
|
25568
26335
|
let resolved = false;
|
|
25569
26336
|
const finish = () => {
|
|
25570
26337
|
if (!resolved) {
|
|
25571
26338
|
resolved = true;
|
|
25572
|
-
|
|
26339
|
+
resolve33();
|
|
25573
26340
|
}
|
|
25574
26341
|
};
|
|
25575
26342
|
let watcher = null;
|
|
@@ -26509,7 +27276,7 @@ __export(listen_exports, {
|
|
|
26509
27276
|
import { spawn as spawn15, execSync as execSync22 } from "node:child_process";
|
|
26510
27277
|
import { existsSync as existsSync28, mkdirSync as mkdirSync8, writeFileSync as writeFileSync9, readdirSync as readdirSync6 } from "node:fs";
|
|
26511
27278
|
import { join as join43, dirname as dirname13 } from "node:path";
|
|
26512
|
-
import { homedir as
|
|
27279
|
+
import { homedir as homedir10 } from "node:os";
|
|
26513
27280
|
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
26514
27281
|
import { EventEmitter } from "node:events";
|
|
26515
27282
|
import { createInterface as createInterface2 } from "node:readline";
|
|
@@ -26621,7 +27388,7 @@ function findLiveWhisperScript() {
|
|
|
26621
27388
|
}
|
|
26622
27389
|
} catch {
|
|
26623
27390
|
}
|
|
26624
|
-
const nvmBase = join43(
|
|
27391
|
+
const nvmBase = join43(homedir10(), ".nvm", "versions", "node");
|
|
26625
27392
|
if (existsSync28(nvmBase)) {
|
|
26626
27393
|
try {
|
|
26627
27394
|
for (const ver of readdirSync6(nvmBase)) {
|
|
@@ -26651,9 +27418,9 @@ function ensureTranscribeCliBackground() {
|
|
|
26651
27418
|
}
|
|
26652
27419
|
try {
|
|
26653
27420
|
const { exec: exec4 } = await import("node:child_process");
|
|
26654
|
-
return new Promise((
|
|
27421
|
+
return new Promise((resolve33) => {
|
|
26655
27422
|
exec4("npm i -g transcribe-cli", { timeout: 18e4 }, (err) => {
|
|
26656
|
-
|
|
27423
|
+
resolve33(!err);
|
|
26657
27424
|
});
|
|
26658
27425
|
});
|
|
26659
27426
|
} catch {
|
|
@@ -26712,7 +27479,7 @@ var init_listen = __esm({
|
|
|
26712
27479
|
return this._ready;
|
|
26713
27480
|
}
|
|
26714
27481
|
async start() {
|
|
26715
|
-
return new Promise((
|
|
27482
|
+
return new Promise((resolve33, reject) => {
|
|
26716
27483
|
const timeout = setTimeout(() => {
|
|
26717
27484
|
reject(new Error("Whisper fallback: model load timeout (5 min). First run downloads the model."));
|
|
26718
27485
|
}, 3e5);
|
|
@@ -26740,7 +27507,7 @@ var init_listen = __esm({
|
|
|
26740
27507
|
this._ready = true;
|
|
26741
27508
|
clearTimeout(timeout);
|
|
26742
27509
|
this.emit("ready");
|
|
26743
|
-
|
|
27510
|
+
resolve33();
|
|
26744
27511
|
break;
|
|
26745
27512
|
case "transcript":
|
|
26746
27513
|
this.emit("transcript", {
|
|
@@ -26875,7 +27642,7 @@ var init_listen = __esm({
|
|
|
26875
27642
|
}
|
|
26876
27643
|
} catch {
|
|
26877
27644
|
}
|
|
26878
|
-
const nvmBase = join43(
|
|
27645
|
+
const nvmBase = join43(homedir10(), ".nvm", "versions", "node");
|
|
26879
27646
|
if (existsSync28(nvmBase)) {
|
|
26880
27647
|
try {
|
|
26881
27648
|
const { readdirSync: readdirSync18 } = await import("node:fs");
|
|
@@ -26944,11 +27711,11 @@ var init_listen = __esm({
|
|
|
26944
27711
|
this.liveTranscriber.on("error", (err) => {
|
|
26945
27712
|
this.emit("error", err);
|
|
26946
27713
|
});
|
|
26947
|
-
await new Promise((
|
|
27714
|
+
await new Promise((resolve33, reject) => {
|
|
26948
27715
|
const timeout = setTimeout(() => reject(new Error("Model load timeout (60s)")), 6e4);
|
|
26949
27716
|
this.liveTranscriber.on("ready", () => {
|
|
26950
27717
|
clearTimeout(timeout);
|
|
26951
|
-
|
|
27718
|
+
resolve33();
|
|
26952
27719
|
});
|
|
26953
27720
|
this.liveTranscriber.on("error", (err) => {
|
|
26954
27721
|
clearTimeout(timeout);
|
|
@@ -27110,11 +27877,11 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
27110
27877
|
sampleWidth: 2,
|
|
27111
27878
|
chunkDuration: 3
|
|
27112
27879
|
});
|
|
27113
|
-
await new Promise((
|
|
27880
|
+
await new Promise((resolve33, reject) => {
|
|
27114
27881
|
const timeout = setTimeout(() => reject(new Error("Model load timeout (60s)")), 6e4);
|
|
27115
27882
|
transcriber.on("ready", () => {
|
|
27116
27883
|
clearTimeout(timeout);
|
|
27117
|
-
|
|
27884
|
+
resolve33();
|
|
27118
27885
|
});
|
|
27119
27886
|
transcriber.on("error", (err) => {
|
|
27120
27887
|
clearTimeout(timeout);
|
|
@@ -32085,8 +32852,8 @@ var init_voice_session = __esm({
|
|
|
32085
32852
|
this.server.keepAliveTimeout = 0;
|
|
32086
32853
|
this.wss = new import_websocket_server.default({ server: this.server, path: "/ws" });
|
|
32087
32854
|
this.wss.on("connection", (ws, req) => this.handleWSConnection(ws, req));
|
|
32088
|
-
await new Promise((
|
|
32089
|
-
this.server.listen(port, "127.0.0.1", () =>
|
|
32855
|
+
await new Promise((resolve33, reject) => {
|
|
32856
|
+
this.server.listen(port, "127.0.0.1", () => resolve33());
|
|
32090
32857
|
this.server.on("error", reject);
|
|
32091
32858
|
});
|
|
32092
32859
|
try {
|
|
@@ -32304,7 +33071,7 @@ var init_voice_session = __esm({
|
|
|
32304
33071
|
}
|
|
32305
33072
|
// ── Cloudflared tunnel ────────────────────────────────────────────────
|
|
32306
33073
|
startCloudflared(port) {
|
|
32307
|
-
return new Promise((
|
|
33074
|
+
return new Promise((resolve33, reject) => {
|
|
32308
33075
|
const timeout = setTimeout(() => {
|
|
32309
33076
|
reject(new Error("Cloudflared tunnel start timeout (30s)"));
|
|
32310
33077
|
}, 3e4);
|
|
@@ -32322,7 +33089,7 @@ var init_voice_session = __esm({
|
|
|
32322
33089
|
if (urlMatch && !urlFound) {
|
|
32323
33090
|
urlFound = true;
|
|
32324
33091
|
clearTimeout(timeout);
|
|
32325
|
-
|
|
33092
|
+
resolve33(urlMatch[0]);
|
|
32326
33093
|
}
|
|
32327
33094
|
};
|
|
32328
33095
|
this.cloudflaredProcess.stdout?.on("data", handleOutput);
|
|
@@ -32362,13 +33129,13 @@ var init_voice_session = __esm({
|
|
|
32362
33129
|
}
|
|
32363
33130
|
// ── Helpers ───────────────────────────────────────────────────────────
|
|
32364
33131
|
findFreePort() {
|
|
32365
|
-
return new Promise((
|
|
33132
|
+
return new Promise((resolve33, reject) => {
|
|
32366
33133
|
const srv = createServer2();
|
|
32367
33134
|
srv.listen(0, "127.0.0.1", () => {
|
|
32368
33135
|
const addr = srv.address();
|
|
32369
33136
|
if (addr && typeof addr === "object") {
|
|
32370
33137
|
const port = addr.port;
|
|
32371
|
-
srv.close(() =>
|
|
33138
|
+
srv.close(() => resolve33(port));
|
|
32372
33139
|
} else {
|
|
32373
33140
|
srv.close(() => reject(new Error("Could not find free port")));
|
|
32374
33141
|
}
|
|
@@ -32491,8 +33258,8 @@ async function collectSystemMetricsAsync() {
|
|
|
32491
33258
|
vramUtilization: 0
|
|
32492
33259
|
};
|
|
32493
33260
|
try {
|
|
32494
|
-
const smi = await new Promise((
|
|
32495
|
-
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));
|
|
32496
33263
|
});
|
|
32497
33264
|
const line = smi.trim().split("\n")[0];
|
|
32498
33265
|
if (line) {
|
|
@@ -32640,8 +33407,8 @@ var init_expose = __esm({
|
|
|
32640
33407
|
throw new Error("Gateway already running");
|
|
32641
33408
|
const port = await this.findFreePort();
|
|
32642
33409
|
this.server = this.createProxyServer(port);
|
|
32643
|
-
await new Promise((
|
|
32644
|
-
this.server.listen(port, "127.0.0.1", () =>
|
|
33410
|
+
await new Promise((resolve33, reject) => {
|
|
33411
|
+
this.server.listen(port, "127.0.0.1", () => resolve33());
|
|
32645
33412
|
this.server.on("error", reject);
|
|
32646
33413
|
});
|
|
32647
33414
|
let lastStartErr;
|
|
@@ -32703,8 +33470,8 @@ var init_expose = __esm({
|
|
|
32703
33470
|
this._cloudflaredPid = state.pid;
|
|
32704
33471
|
this._proxyPort = state.proxyPort;
|
|
32705
33472
|
this.server = this.createProxyServer(state.proxyPort);
|
|
32706
|
-
await new Promise((
|
|
32707
|
-
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());
|
|
32708
33475
|
this.server.on("error", reject);
|
|
32709
33476
|
});
|
|
32710
33477
|
this._stats.status = "active";
|
|
@@ -32729,8 +33496,8 @@ var init_expose = __esm({
|
|
|
32729
33496
|
}
|
|
32730
33497
|
this._cloudflaredPid = null;
|
|
32731
33498
|
if (this.server) {
|
|
32732
|
-
await new Promise((
|
|
32733
|
-
this.server.close(() =>
|
|
33499
|
+
await new Promise((resolve33) => {
|
|
33500
|
+
this.server.close(() => resolve33());
|
|
32734
33501
|
});
|
|
32735
33502
|
this.server = null;
|
|
32736
33503
|
}
|
|
@@ -33062,7 +33829,7 @@ var init_expose = __esm({
|
|
|
33062
33829
|
_proxyPort = 0;
|
|
33063
33830
|
startCloudflared(port) {
|
|
33064
33831
|
this._proxyPort = port;
|
|
33065
|
-
return new Promise((
|
|
33832
|
+
return new Promise((resolve33, reject) => {
|
|
33066
33833
|
const timeout = setTimeout(() => {
|
|
33067
33834
|
reject(new Error("Cloudflared tunnel start timeout (30s)"));
|
|
33068
33835
|
}, 3e4);
|
|
@@ -33091,7 +33858,7 @@ var init_expose = __esm({
|
|
|
33091
33858
|
this.cloudflaredProcess?.unref();
|
|
33092
33859
|
this.cloudflaredProcess?.stdout?.destroy();
|
|
33093
33860
|
this.cloudflaredProcess?.stderr?.destroy();
|
|
33094
|
-
|
|
33861
|
+
resolve33(urlMatch[0]);
|
|
33095
33862
|
}
|
|
33096
33863
|
};
|
|
33097
33864
|
this.cloudflaredProcess.stdout?.on("data", handleOutput);
|
|
@@ -33180,13 +33947,13 @@ ${this.formatConnectionInfo()}`);
|
|
|
33180
33947
|
}
|
|
33181
33948
|
// ── Helpers ─────────────────────────────────────────────────────────────
|
|
33182
33949
|
findFreePort() {
|
|
33183
|
-
return new Promise((
|
|
33950
|
+
return new Promise((resolve33, reject) => {
|
|
33184
33951
|
const srv = createServer3();
|
|
33185
33952
|
srv.listen(0, "127.0.0.1", () => {
|
|
33186
33953
|
const addr = srv.address();
|
|
33187
33954
|
if (addr && typeof addr === "object") {
|
|
33188
33955
|
const port = addr.port;
|
|
33189
|
-
srv.close(() =>
|
|
33956
|
+
srv.close(() => resolve33(port));
|
|
33190
33957
|
} else {
|
|
33191
33958
|
srv.close(() => reject(new Error("Could not find free port")));
|
|
33192
33959
|
}
|
|
@@ -34133,8 +34900,8 @@ var init_peer_mesh = __esm({
|
|
|
34133
34900
|
this.wss.on("connection", (ws, req) => {
|
|
34134
34901
|
this.handleInboundConnection(ws, req.url ?? "");
|
|
34135
34902
|
});
|
|
34136
|
-
await new Promise((
|
|
34137
|
-
this.server.listen(port, "127.0.0.1", () =>
|
|
34903
|
+
await new Promise((resolve33, reject) => {
|
|
34904
|
+
this.server.listen(port, "127.0.0.1", () => resolve33());
|
|
34138
34905
|
this.server.on("error", reject);
|
|
34139
34906
|
});
|
|
34140
34907
|
this.pingTimer = setInterval(() => this.pingAll(), PING_INTERVAL_MS);
|
|
@@ -34173,7 +34940,7 @@ var init_peer_mesh = __esm({
|
|
|
34173
34940
|
this.wss = null;
|
|
34174
34941
|
}
|
|
34175
34942
|
if (this.server) {
|
|
34176
|
-
await new Promise((
|
|
34943
|
+
await new Promise((resolve33) => this.server.close(() => resolve33()));
|
|
34177
34944
|
this.server = null;
|
|
34178
34945
|
}
|
|
34179
34946
|
this.emit("stopped");
|
|
@@ -34191,7 +34958,7 @@ var init_peer_mesh = __esm({
|
|
|
34191
34958
|
if (!wsUrl.includes("/p2p"))
|
|
34192
34959
|
wsUrl += "/p2p";
|
|
34193
34960
|
wsUrl += `?key=${encodeURIComponent(this._authKey)}`;
|
|
34194
|
-
return new Promise((
|
|
34961
|
+
return new Promise((resolve33, reject) => {
|
|
34195
34962
|
const ws = new import_websocket.default(wsUrl, { handshakeTimeout: 1e4 });
|
|
34196
34963
|
let resolved = false;
|
|
34197
34964
|
const timeout = setTimeout(() => {
|
|
@@ -34231,7 +34998,7 @@ var init_peer_mesh = __esm({
|
|
|
34231
34998
|
this.connections.set(peer.peerId, ws);
|
|
34232
34999
|
this.setupPeerHandlers(ws, peer.peerId);
|
|
34233
35000
|
this.emit("peer_connected", peer);
|
|
34234
|
-
|
|
35001
|
+
resolve33(peer);
|
|
34235
35002
|
} else {
|
|
34236
35003
|
this.handleMessage(msg, ws);
|
|
34237
35004
|
}
|
|
@@ -34286,12 +35053,12 @@ var init_peer_mesh = __esm({
|
|
|
34286
35053
|
throw new Error(`Peer ${peerId} not connected`);
|
|
34287
35054
|
}
|
|
34288
35055
|
const msgId = randomBytes11(8).toString("hex");
|
|
34289
|
-
return new Promise((
|
|
35056
|
+
return new Promise((resolve33, reject) => {
|
|
34290
35057
|
const timeout = setTimeout(() => {
|
|
34291
35058
|
this.pendingRequests.delete(msgId);
|
|
34292
35059
|
reject(new Error(`Inference timeout (${timeoutMs}ms)`));
|
|
34293
35060
|
}, timeoutMs);
|
|
34294
|
-
this.pendingRequests.set(msgId, { resolve:
|
|
35061
|
+
this.pendingRequests.set(msgId, { resolve: resolve33, reject, timeout, chunks: [] });
|
|
34295
35062
|
this.sendMsg(ws, "infer_request", request, msgId);
|
|
34296
35063
|
});
|
|
34297
35064
|
}
|
|
@@ -34513,13 +35280,13 @@ var init_peer_mesh = __esm({
|
|
|
34513
35280
|
ws.send(JSON.stringify(msg));
|
|
34514
35281
|
}
|
|
34515
35282
|
findFreePort() {
|
|
34516
|
-
return new Promise((
|
|
35283
|
+
return new Promise((resolve33, reject) => {
|
|
34517
35284
|
const srv = createServer4();
|
|
34518
35285
|
srv.listen(0, "127.0.0.1", () => {
|
|
34519
35286
|
const addr = srv.address();
|
|
34520
35287
|
if (addr && typeof addr === "object") {
|
|
34521
35288
|
const port = addr.port;
|
|
34522
|
-
srv.close(() =>
|
|
35289
|
+
srv.close(() => resolve33(port));
|
|
34523
35290
|
} else {
|
|
34524
35291
|
srv.close(() => reject(new Error("Could not find free port")));
|
|
34525
35292
|
}
|
|
@@ -35765,7 +36532,7 @@ __export(oa_directory_exports, {
|
|
|
35765
36532
|
});
|
|
35766
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";
|
|
35767
36534
|
import { join as join48, relative as relative2, basename as basename9, extname as extname8 } from "node:path";
|
|
35768
|
-
import { homedir as
|
|
36535
|
+
import { homedir as homedir11 } from "node:os";
|
|
35769
36536
|
function initOaDirectory(repoRoot) {
|
|
35770
36537
|
const oaPath = join48(repoRoot, OA_DIR);
|
|
35771
36538
|
for (const sub of SUBDIRS) {
|
|
@@ -35805,7 +36572,7 @@ function saveProjectSettings(repoRoot, settings) {
|
|
|
35805
36572
|
writeFileSync12(join48(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
35806
36573
|
}
|
|
35807
36574
|
function loadGlobalSettings() {
|
|
35808
|
-
const settingsPath = join48(
|
|
36575
|
+
const settingsPath = join48(homedir11(), ".open-agents", "settings.json");
|
|
35809
36576
|
try {
|
|
35810
36577
|
if (existsSync32(settingsPath)) {
|
|
35811
36578
|
return JSON.parse(readFileSync23(settingsPath, "utf-8"));
|
|
@@ -35815,7 +36582,7 @@ function loadGlobalSettings() {
|
|
|
35815
36582
|
return {};
|
|
35816
36583
|
}
|
|
35817
36584
|
function saveGlobalSettings(settings) {
|
|
35818
|
-
const dir = join48(
|
|
36585
|
+
const dir = join48(homedir11(), ".open-agents");
|
|
35819
36586
|
mkdirSync11(dir, { recursive: true });
|
|
35820
36587
|
const existing = loadGlobalSettings();
|
|
35821
36588
|
const merged = { ...existing, ...settings };
|
|
@@ -36195,13 +36962,13 @@ function recordUsage(kind, value, opts) {
|
|
|
36195
36962
|
}
|
|
36196
36963
|
saveUsageFile(filePath, data);
|
|
36197
36964
|
};
|
|
36198
|
-
update(join48(
|
|
36965
|
+
update(join48(homedir11(), ".open-agents", USAGE_HISTORY_FILE));
|
|
36199
36966
|
if (opts?.repoRoot) {
|
|
36200
36967
|
update(join48(opts.repoRoot, OA_DIR, USAGE_HISTORY_FILE));
|
|
36201
36968
|
}
|
|
36202
36969
|
}
|
|
36203
36970
|
function loadUsageHistory(kind, repoRoot) {
|
|
36204
|
-
const globalPath = join48(
|
|
36971
|
+
const globalPath = join48(homedir11(), ".open-agents", USAGE_HISTORY_FILE);
|
|
36205
36972
|
const globalData = loadUsageFile(globalPath);
|
|
36206
36973
|
const localData = repoRoot ? loadUsageFile(join48(repoRoot, OA_DIR, USAGE_HISTORY_FILE)) : { records: [] };
|
|
36207
36974
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -36234,7 +37001,7 @@ function deleteUsageRecord(kind, value, repoRoot) {
|
|
|
36234
37001
|
saveUsageFile(filePath, data);
|
|
36235
37002
|
}
|
|
36236
37003
|
};
|
|
36237
|
-
remove(join48(
|
|
37004
|
+
remove(join48(homedir11(), ".open-agents", USAGE_HISTORY_FILE));
|
|
36238
37005
|
if (repoRoot) {
|
|
36239
37006
|
remove(join48(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
|
|
36240
37007
|
}
|
|
@@ -36285,10 +37052,10 @@ var init_oa_directory = __esm({
|
|
|
36285
37052
|
// packages/cli/dist/tui/setup.js
|
|
36286
37053
|
import * as readline from "node:readline";
|
|
36287
37054
|
import { execSync as execSync24, spawn as spawn18, exec as exec2 } from "node:child_process";
|
|
36288
|
-
import { promisify as
|
|
37055
|
+
import { promisify as promisify6 } from "node:util";
|
|
36289
37056
|
import { existsSync as existsSync33, writeFileSync as writeFileSync13, readFileSync as readFileSync24, appendFileSync as appendFileSync2, mkdirSync as mkdirSync12 } from "node:fs";
|
|
36290
37057
|
import { join as join49 } from "node:path";
|
|
36291
|
-
import { homedir as
|
|
37058
|
+
import { homedir as homedir12, platform } from "node:os";
|
|
36292
37059
|
function detectSystemSpecs() {
|
|
36293
37060
|
let totalRamGB = 0;
|
|
36294
37061
|
let availableRamGB = 0;
|
|
@@ -36425,12 +37192,12 @@ function modelSupportsToolCalling(modelName) {
|
|
|
36425
37192
|
return false;
|
|
36426
37193
|
}
|
|
36427
37194
|
function ask(rl, question) {
|
|
36428
|
-
return new Promise((
|
|
36429
|
-
rl.question(question, (answer) =>
|
|
37195
|
+
return new Promise((resolve33) => {
|
|
37196
|
+
rl.question(question, (answer) => resolve33(answer.trim()));
|
|
36430
37197
|
});
|
|
36431
37198
|
}
|
|
36432
37199
|
function askSecret(rl, question) {
|
|
36433
|
-
return new Promise((
|
|
37200
|
+
return new Promise((resolve33) => {
|
|
36434
37201
|
process.stdout.write(question);
|
|
36435
37202
|
let secret = "";
|
|
36436
37203
|
const stdin = process.stdin;
|
|
@@ -36448,7 +37215,7 @@ function askSecret(rl, question) {
|
|
|
36448
37215
|
stdin.setRawMode(hadRawMode ?? false);
|
|
36449
37216
|
}
|
|
36450
37217
|
process.stdout.write("\n");
|
|
36451
|
-
|
|
37218
|
+
resolve33(secret.trim());
|
|
36452
37219
|
return;
|
|
36453
37220
|
} else if (c3 === "") {
|
|
36454
37221
|
stdin.removeListener("data", onData);
|
|
@@ -36456,7 +37223,7 @@ function askSecret(rl, question) {
|
|
|
36456
37223
|
stdin.setRawMode(hadRawMode ?? false);
|
|
36457
37224
|
}
|
|
36458
37225
|
process.stdout.write("\n");
|
|
36459
|
-
|
|
37226
|
+
resolve33("");
|
|
36460
37227
|
return;
|
|
36461
37228
|
} else if (c3 === "\x7F" || c3 === "\b") {
|
|
36462
37229
|
if (secret.length > 0) {
|
|
@@ -36691,7 +37458,7 @@ async function ensureOllamaRunning(backendUrl, rl) {
|
|
|
36691
37458
|
return false;
|
|
36692
37459
|
}
|
|
36693
37460
|
for (let i = 0; i < 5; i++) {
|
|
36694
|
-
await new Promise((
|
|
37461
|
+
await new Promise((resolve33) => setTimeout(resolve33, 2e3));
|
|
36695
37462
|
try {
|
|
36696
37463
|
const resp = await fetch(`${backendUrl}/api/tags`, {
|
|
36697
37464
|
signal: AbortSignal.timeout(3e3)
|
|
@@ -37152,7 +37919,7 @@ async function doSetup(config, rl) {
|
|
|
37152
37919
|
try {
|
|
37153
37920
|
const child = spawn18("ollama", ["serve"], { stdio: "ignore", detached: true });
|
|
37154
37921
|
child.unref();
|
|
37155
|
-
await new Promise((
|
|
37922
|
+
await new Promise((resolve33) => setTimeout(resolve33, 3e3));
|
|
37156
37923
|
try {
|
|
37157
37924
|
models = await fetchOllamaModels(config.backendUrl);
|
|
37158
37925
|
process.stdout.write(` ${c2.green("\u2714")} Ollama is running.
|
|
@@ -37180,7 +37947,7 @@ async function doSetup(config, rl) {
|
|
|
37180
37947
|
try {
|
|
37181
37948
|
const child = spawn18("ollama", ["serve"], { stdio: "ignore", detached: true });
|
|
37182
37949
|
child.unref();
|
|
37183
|
-
await new Promise((
|
|
37950
|
+
await new Promise((resolve33) => setTimeout(resolve33, 3e3));
|
|
37184
37951
|
try {
|
|
37185
37952
|
models = await fetchOllamaModels(config.backendUrl);
|
|
37186
37953
|
process.stdout.write(` ${c2.green("\u2714")} Ollama is running.
|
|
@@ -37328,7 +38095,7 @@ async function doSetup(config, rl) {
|
|
|
37328
38095
|
`PARAMETER num_predict ${numPredict}`,
|
|
37329
38096
|
`PARAMETER stop "<|endoftext|>"`
|
|
37330
38097
|
].join("\n");
|
|
37331
|
-
const modelDir2 = join49(
|
|
38098
|
+
const modelDir2 = join49(homedir12(), ".open-agents", "models");
|
|
37332
38099
|
mkdirSync12(modelDir2, { recursive: true });
|
|
37333
38100
|
const modelfilePath = join49(modelDir2, `Modelfile.${customName}`);
|
|
37334
38101
|
writeFileSync13(modelfilePath, modelfileContent + "\n", "utf8");
|
|
@@ -37376,7 +38143,7 @@ async function isModelAvailable(config) {
|
|
|
37376
38143
|
}
|
|
37377
38144
|
function isFirstRun() {
|
|
37378
38145
|
try {
|
|
37379
|
-
return !existsSync33(join49(
|
|
38146
|
+
return !existsSync33(join49(homedir12(), ".open-agents", "config.json"));
|
|
37380
38147
|
} catch {
|
|
37381
38148
|
return true;
|
|
37382
38149
|
}
|
|
@@ -37413,7 +38180,7 @@ function detectPkgManager() {
|
|
|
37413
38180
|
return null;
|
|
37414
38181
|
}
|
|
37415
38182
|
function getVenvDir() {
|
|
37416
|
-
return join49(
|
|
38183
|
+
return join49(homedir12(), ".open-agents", "venv");
|
|
37417
38184
|
}
|
|
37418
38185
|
function hasVenvModule() {
|
|
37419
38186
|
try {
|
|
@@ -37438,7 +38205,7 @@ function ensureVenv(log) {
|
|
|
37438
38205
|
return null;
|
|
37439
38206
|
}
|
|
37440
38207
|
try {
|
|
37441
|
-
mkdirSync12(join49(
|
|
38208
|
+
mkdirSync12(join49(homedir12(), ".open-agents"), { recursive: true });
|
|
37442
38209
|
execSync24(`python3 -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
|
|
37443
38210
|
execSync24(`"${join49(venvDir, "bin", "pip")}" install --upgrade pip`, {
|
|
37444
38211
|
stdio: "pipe",
|
|
@@ -37704,9 +38471,9 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
37704
38471
|
const archMap = { x64: "amd64", arm64: "arm64", arm: "arm" };
|
|
37705
38472
|
const cfArch = archMap[arch] ?? "amd64";
|
|
37706
38473
|
try {
|
|
37707
|
-
execSync24(`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && mkdir -p "${
|
|
37708
|
-
if (!process.env.PATH?.includes(`${
|
|
37709
|
-
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}`;
|
|
37710
38477
|
}
|
|
37711
38478
|
if (hasCmd("cloudflared")) {
|
|
37712
38479
|
log("cloudflared installed.");
|
|
@@ -37801,7 +38568,7 @@ async function createExpandedVariantAsync(baseModel, specs, sizeGB, kvBytesPerTo
|
|
|
37801
38568
|
`PARAMETER num_predict ${numPredict}`,
|
|
37802
38569
|
`PARAMETER stop "<|endoftext|>"`
|
|
37803
38570
|
].join("\n");
|
|
37804
|
-
const modelDir2 = join49(
|
|
38571
|
+
const modelDir2 = join49(homedir12(), ".open-agents", "models");
|
|
37805
38572
|
mkdirSync12(modelDir2, { recursive: true });
|
|
37806
38573
|
const modelfilePath = join49(modelDir2, `Modelfile.${customName}`);
|
|
37807
38574
|
writeFileSync13(modelfilePath, modelfileContent + "\n", "utf8");
|
|
@@ -37878,7 +38645,7 @@ async function ensureNeovim() {
|
|
|
37878
38645
|
const platform5 = process.platform;
|
|
37879
38646
|
const arch = process.arch;
|
|
37880
38647
|
if (platform5 === "linux") {
|
|
37881
|
-
const binDir = join49(
|
|
38648
|
+
const binDir = join49(homedir12(), ".local", "bin");
|
|
37882
38649
|
const nvimDest = join49(binDir, "nvim");
|
|
37883
38650
|
try {
|
|
37884
38651
|
mkdirSync12(binDir, { recursive: true });
|
|
@@ -37950,7 +38717,7 @@ async function ensureNeovim() {
|
|
|
37950
38717
|
}
|
|
37951
38718
|
function ensurePathInShellRc(binDir) {
|
|
37952
38719
|
const shell = process.env.SHELL ?? "";
|
|
37953
|
-
const rcFile = shell.includes("zsh") ? join49(
|
|
38720
|
+
const rcFile = shell.includes("zsh") ? join49(homedir12(), ".zshrc") : join49(homedir12(), ".bashrc");
|
|
37954
38721
|
try {
|
|
37955
38722
|
const rcContent = existsSync33(rcFile) ? readFileSync24(rcFile, "utf8") : "";
|
|
37956
38723
|
if (rcContent.includes(binDir))
|
|
@@ -37971,7 +38738,7 @@ var init_setup = __esm({
|
|
|
37971
38738
|
init_render();
|
|
37972
38739
|
init_config();
|
|
37973
38740
|
init_dist();
|
|
37974
|
-
execAsync =
|
|
38741
|
+
execAsync = promisify6(exec2);
|
|
37975
38742
|
QWEN_VARIANTS = [
|
|
37976
38743
|
{ tag: "qwen3.5:0.8b", sizeGB: 1, label: "0.8B params (1.0 GB)", cloud: false },
|
|
37977
38744
|
{ tag: "qwen3.5:2b", sizeGB: 2.7, label: "2B params (2.7 GB)", cloud: false },
|
|
@@ -38169,7 +38936,7 @@ function tuiSelect(opts) {
|
|
|
38169
38936
|
const maxVisible = opts.maxVisible ?? Math.max(3, contentArea - selectChrome);
|
|
38170
38937
|
let scrollOffset = 0;
|
|
38171
38938
|
let lastRenderedLines = 0;
|
|
38172
|
-
return new Promise((
|
|
38939
|
+
return new Promise((resolve33) => {
|
|
38173
38940
|
const stdin = process.stdin;
|
|
38174
38941
|
const hadRawMode = stdin.isRaw;
|
|
38175
38942
|
const savedRlListeners = [];
|
|
@@ -38344,7 +39111,7 @@ function tuiSelect(opts) {
|
|
|
38344
39111
|
if (!isSkippable(itemIdx) && matchSet.has(itemIdx)) {
|
|
38345
39112
|
cursor = itemIdx;
|
|
38346
39113
|
cleanup();
|
|
38347
|
-
|
|
39114
|
+
resolve33({ confirmed: true, key: items[cursor].key, index: cursor });
|
|
38348
39115
|
return;
|
|
38349
39116
|
} else if (!isSkippable(itemIdx)) {
|
|
38350
39117
|
cursor = itemIdx;
|
|
@@ -38420,7 +39187,7 @@ function tuiSelect(opts) {
|
|
|
38420
39187
|
items.splice(deletedIdx, 1);
|
|
38421
39188
|
if (items.length === 0) {
|
|
38422
39189
|
cleanup();
|
|
38423
|
-
|
|
39190
|
+
resolve33({ confirmed: false, key: null, index: -1 });
|
|
38424
39191
|
return;
|
|
38425
39192
|
}
|
|
38426
39193
|
updateFilter();
|
|
@@ -38509,7 +39276,7 @@ function tuiSelect(opts) {
|
|
|
38509
39276
|
} else if (seq === "\r" || seq === "\n") {
|
|
38510
39277
|
if (!isSkippable(cursor) && matchSet.has(cursor)) {
|
|
38511
39278
|
cleanup();
|
|
38512
|
-
|
|
39279
|
+
resolve33({ confirmed: true, key: items[cursor].key, index: cursor });
|
|
38513
39280
|
}
|
|
38514
39281
|
} else if (seq === "\x1B" || seq === "\x1B\x1B") {
|
|
38515
39282
|
if (filter) {
|
|
@@ -38522,14 +39289,14 @@ function tuiSelect(opts) {
|
|
|
38522
39289
|
render();
|
|
38523
39290
|
} else if (hasBreadcrumbs) {
|
|
38524
39291
|
cleanup();
|
|
38525
|
-
|
|
39292
|
+
resolve33({ confirmed: false, key: "__back__", index: cursor });
|
|
38526
39293
|
} else {
|
|
38527
39294
|
cleanup();
|
|
38528
|
-
|
|
39295
|
+
resolve33({ confirmed: false, key: null, index: cursor });
|
|
38529
39296
|
}
|
|
38530
39297
|
} else if (seq === "") {
|
|
38531
39298
|
cleanup();
|
|
38532
|
-
|
|
39299
|
+
resolve33({ confirmed: false, key: null, index: cursor });
|
|
38533
39300
|
} else if (seq === "\x7F" || seq === "\b") {
|
|
38534
39301
|
if (filter.length > 0) {
|
|
38535
39302
|
filter = filter.slice(0, -1);
|
|
@@ -38543,7 +39310,7 @@ function tuiSelect(opts) {
|
|
|
38543
39310
|
render();
|
|
38544
39311
|
} else if (hasBreadcrumbs) {
|
|
38545
39312
|
cleanup();
|
|
38546
|
-
|
|
39313
|
+
resolve33({ confirmed: false, key: "__back__", index: cursor });
|
|
38547
39314
|
}
|
|
38548
39315
|
} else if (seq.length === 1 && seq.charCodeAt(0) >= 32 && seq.charCodeAt(0) < 127) {
|
|
38549
39316
|
if (opts.onCustomKey && !isSkippable(cursor) && matchSet.has(cursor)) {
|
|
@@ -38551,7 +39318,7 @@ function tuiSelect(opts) {
|
|
|
38551
39318
|
done: () => render(),
|
|
38552
39319
|
resolve: (result) => {
|
|
38553
39320
|
cleanup();
|
|
38554
|
-
|
|
39321
|
+
resolve33(result);
|
|
38555
39322
|
},
|
|
38556
39323
|
getInput: (prompt, prefill) => getInputFromUser(prompt, prefill),
|
|
38557
39324
|
render: () => render(),
|
|
@@ -38668,7 +39435,7 @@ var init_tui_select = __esm({
|
|
|
38668
39435
|
|
|
38669
39436
|
// packages/cli/dist/tui/drop-panel.js
|
|
38670
39437
|
import { existsSync as existsSync34 } from "node:fs";
|
|
38671
|
-
import { extname as extname9, resolve as
|
|
39438
|
+
import { extname as extname9, resolve as resolve28 } from "node:path";
|
|
38672
39439
|
function ansi4(code, text) {
|
|
38673
39440
|
return isTTY4 ? `\x1B[${code}m${text}\x1B[0m` : text;
|
|
38674
39441
|
}
|
|
@@ -38781,7 +39548,7 @@ function showDropPanel(opts) {
|
|
|
38781
39548
|
if (filePath.startsWith("file://")) {
|
|
38782
39549
|
filePath = decodeURIComponent(filePath.slice(7));
|
|
38783
39550
|
}
|
|
38784
|
-
filePath =
|
|
39551
|
+
filePath = resolve28(filePath);
|
|
38785
39552
|
if (!existsSync34(filePath)) {
|
|
38786
39553
|
errorMsg = `File not found: ${filePath}`;
|
|
38787
39554
|
render();
|
|
@@ -39093,12 +39860,12 @@ function stopNeovimMode() {
|
|
|
39093
39860
|
} catch {
|
|
39094
39861
|
}
|
|
39095
39862
|
const s = _state;
|
|
39096
|
-
return new Promise((
|
|
39863
|
+
return new Promise((resolve33) => {
|
|
39097
39864
|
setTimeout(() => {
|
|
39098
39865
|
if (s && !s.cleanedUp) {
|
|
39099
39866
|
doCleanup(s);
|
|
39100
39867
|
}
|
|
39101
|
-
|
|
39868
|
+
resolve33();
|
|
39102
39869
|
}, 300);
|
|
39103
39870
|
});
|
|
39104
39871
|
}
|
|
@@ -39334,7 +40101,7 @@ __export(voice_exports, {
|
|
|
39334
40101
|
});
|
|
39335
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";
|
|
39336
40103
|
import { join as join51, dirname as dirname17 } from "node:path";
|
|
39337
|
-
import { homedir as
|
|
40104
|
+
import { homedir as homedir13, tmpdir as tmpdir9, platform as platform2 } from "node:os";
|
|
39338
40105
|
import { execSync as execSync26, spawn as nodeSpawn } from "node:child_process";
|
|
39339
40106
|
import { createRequire } from "node:module";
|
|
39340
40107
|
function sanitizeForTTS(text) {
|
|
@@ -39358,7 +40125,7 @@ function listVoiceModels() {
|
|
|
39358
40125
|
}));
|
|
39359
40126
|
}
|
|
39360
40127
|
function voiceDir() {
|
|
39361
|
-
return join51(
|
|
40128
|
+
return join51(homedir13(), ".open-agents", "voice");
|
|
39362
40129
|
}
|
|
39363
40130
|
function modelsDir() {
|
|
39364
40131
|
return join51(voiceDir(), "models");
|
|
@@ -40354,7 +41121,7 @@ var init_voice = __esm({
|
|
|
40354
41121
|
}
|
|
40355
41122
|
p = p.replace(/\\ /g, " ");
|
|
40356
41123
|
if (p.startsWith("~/") || p === "~") {
|
|
40357
|
-
p = join51(
|
|
41124
|
+
p = join51(homedir13(), p.slice(1));
|
|
40358
41125
|
}
|
|
40359
41126
|
if (!existsSync36(p)) {
|
|
40360
41127
|
return `File not found: ${p}
|
|
@@ -40769,7 +41536,7 @@ var init_voice = __esm({
|
|
|
40769
41536
|
this.speaking = false;
|
|
40770
41537
|
}
|
|
40771
41538
|
sleep(ms) {
|
|
40772
|
-
return new Promise((
|
|
41539
|
+
return new Promise((resolve33) => setTimeout(resolve33, ms));
|
|
40773
41540
|
}
|
|
40774
41541
|
// -------------------------------------------------------------------------
|
|
40775
41542
|
// Synthesis pipeline
|
|
@@ -41035,7 +41802,7 @@ var init_voice = __esm({
|
|
|
41035
41802
|
const cmd = this.getPlayCommand(path);
|
|
41036
41803
|
if (!cmd)
|
|
41037
41804
|
return;
|
|
41038
|
-
return new Promise((
|
|
41805
|
+
return new Promise((resolve33) => {
|
|
41039
41806
|
const child = nodeSpawn(cmd[0], cmd.slice(1), {
|
|
41040
41807
|
stdio: "ignore",
|
|
41041
41808
|
detached: false
|
|
@@ -41044,12 +41811,12 @@ var init_voice = __esm({
|
|
|
41044
41811
|
child.on("close", () => {
|
|
41045
41812
|
if (this.currentPlayback === child)
|
|
41046
41813
|
this.currentPlayback = null;
|
|
41047
|
-
|
|
41814
|
+
resolve33();
|
|
41048
41815
|
});
|
|
41049
41816
|
child.on("error", () => {
|
|
41050
41817
|
if (this.currentPlayback === child)
|
|
41051
41818
|
this.currentPlayback = null;
|
|
41052
|
-
|
|
41819
|
+
resolve33();
|
|
41053
41820
|
});
|
|
41054
41821
|
setTimeout(() => {
|
|
41055
41822
|
if (this.currentPlayback === child) {
|
|
@@ -41059,7 +41826,7 @@ var init_voice = __esm({
|
|
|
41059
41826
|
}
|
|
41060
41827
|
this.currentPlayback = null;
|
|
41061
41828
|
}
|
|
41062
|
-
|
|
41829
|
+
resolve33();
|
|
41063
41830
|
}, 15e3);
|
|
41064
41831
|
});
|
|
41065
41832
|
}
|
|
@@ -41134,7 +41901,7 @@ var init_voice = __esm({
|
|
|
41134
41901
|
/** Non-blocking shell execution — async alternative to execSync.
|
|
41135
41902
|
* Returns stdout string on exit 0, rejects otherwise. */
|
|
41136
41903
|
asyncShell(command, timeoutMs = 3e4) {
|
|
41137
|
-
return new Promise((
|
|
41904
|
+
return new Promise((resolve33, reject) => {
|
|
41138
41905
|
const proc = nodeSpawn("sh", ["-c", command], {
|
|
41139
41906
|
stdio: ["ignore", "pipe", "pipe"],
|
|
41140
41907
|
cwd: tmpdir9()
|
|
@@ -41155,7 +41922,7 @@ var init_voice = __esm({
|
|
|
41155
41922
|
proc.on("close", (code) => {
|
|
41156
41923
|
clearTimeout(timer);
|
|
41157
41924
|
if (code === 0)
|
|
41158
|
-
|
|
41925
|
+
resolve33(stdout.trim());
|
|
41159
41926
|
else
|
|
41160
41927
|
reject(new Error(stderr.slice(0, 300) || `Exit code ${code}`));
|
|
41161
41928
|
});
|
|
@@ -41640,7 +42407,7 @@ if __name__ == '__main__':
|
|
|
41640
42407
|
const venvPy = luxttsVenvPy();
|
|
41641
42408
|
if (!existsSync36(venvPy))
|
|
41642
42409
|
return false;
|
|
41643
|
-
return new Promise((
|
|
42410
|
+
return new Promise((resolve33) => {
|
|
41644
42411
|
const env = { ...process.env, LUXTTS_REPO_PATH: luxttsRepoDir() };
|
|
41645
42412
|
const daemon = nodeSpawn(venvPy, [luxttsInferScript()], {
|
|
41646
42413
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -41659,7 +42426,7 @@ if __name__ == '__main__':
|
|
|
41659
42426
|
try {
|
|
41660
42427
|
const msg = JSON.parse(line);
|
|
41661
42428
|
if (msg.type === "ready") {
|
|
41662
|
-
|
|
42429
|
+
resolve33(true);
|
|
41663
42430
|
} else if (msg.type === "result" || msg.type === "error") {
|
|
41664
42431
|
const pending = this._luxttsPending.get(msg.id);
|
|
41665
42432
|
if (pending) {
|
|
@@ -41683,25 +42450,25 @@ if __name__ == '__main__':
|
|
|
41683
42450
|
});
|
|
41684
42451
|
daemon.on("error", () => {
|
|
41685
42452
|
this._luxttsDaemon = null;
|
|
41686
|
-
|
|
42453
|
+
resolve33(false);
|
|
41687
42454
|
});
|
|
41688
42455
|
setTimeout(() => {
|
|
41689
42456
|
if (this._luxttsDaemon === daemon && !this._luxttsPending.has("__ready__")) {
|
|
41690
|
-
|
|
42457
|
+
resolve33(false);
|
|
41691
42458
|
}
|
|
41692
42459
|
}, 6e4);
|
|
41693
42460
|
});
|
|
41694
42461
|
}
|
|
41695
42462
|
/** Send a request to the LuxTTS daemon and await the response */
|
|
41696
42463
|
luxttsRequest(req) {
|
|
41697
|
-
return new Promise((
|
|
42464
|
+
return new Promise((resolve33, reject) => {
|
|
41698
42465
|
if (!this._luxttsDaemon || this._luxttsDaemon.killed) {
|
|
41699
42466
|
reject(new Error("LuxTTS daemon not running"));
|
|
41700
42467
|
return;
|
|
41701
42468
|
}
|
|
41702
42469
|
const id = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
41703
42470
|
req.id = id;
|
|
41704
|
-
this._luxttsPending.set(id, { resolve:
|
|
42471
|
+
this._luxttsPending.set(id, { resolve: resolve33, reject });
|
|
41705
42472
|
this._luxttsDaemon.stdin.write(JSON.stringify(req) + "\n");
|
|
41706
42473
|
setTimeout(() => {
|
|
41707
42474
|
if (this._luxttsPending.has(id)) {
|
|
@@ -44725,9 +45492,9 @@ async function handleVoiceMenu(ctx, save, hasLocal) {
|
|
|
44725
45492
|
}
|
|
44726
45493
|
const { basename: basename16, join: pathJoin } = await import("node:path");
|
|
44727
45494
|
const { copyFileSync: copyFileSync2, mkdirSync: mkdirSync22, existsSync: exists } = await import("node:fs");
|
|
44728
|
-
const { homedir:
|
|
45495
|
+
const { homedir: homedir18 } = await import("node:os");
|
|
44729
45496
|
const modelName = basename16(onnxDrop.path, ".onnx").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
44730
|
-
const destDir = pathJoin(
|
|
45497
|
+
const destDir = pathJoin(homedir18(), ".open-agents", "voice", "models", modelName);
|
|
44731
45498
|
if (!exists(destDir))
|
|
44732
45499
|
mkdirSync22(destDir, { recursive: true });
|
|
44733
45500
|
copyFileSync2(onnxDrop.path, pathJoin(destDir, "model.onnx"));
|
|
@@ -45628,11 +46395,11 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
45628
46395
|
const targetVersion = info?.latestVersion ?? currentVersion;
|
|
45629
46396
|
const installOverlay = startInstallOverlay(targetVersion);
|
|
45630
46397
|
let installError = "";
|
|
45631
|
-
const runInstall2 = (cmd) => new Promise((
|
|
46398
|
+
const runInstall2 = (cmd) => new Promise((resolve33) => {
|
|
45632
46399
|
const child = exec4(cmd, { timeout: 18e4 }, (err, _stdout, stderr) => {
|
|
45633
46400
|
if (err)
|
|
45634
46401
|
installError = (stderr || err.message || "").trim();
|
|
45635
|
-
|
|
46402
|
+
resolve33(!err);
|
|
45636
46403
|
});
|
|
45637
46404
|
child.stdout?.on("data", (chunk) => {
|
|
45638
46405
|
const text = String(chunk);
|
|
@@ -45726,8 +46493,8 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
45726
46493
|
}
|
|
45727
46494
|
if (doRebuild) {
|
|
45728
46495
|
installOverlay.setStatus("Rebuilding native modules...");
|
|
45729
|
-
await new Promise((
|
|
45730
|
-
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));
|
|
45731
46498
|
child.stdout?.resume();
|
|
45732
46499
|
child.stderr?.resume();
|
|
45733
46500
|
});
|
|
@@ -45758,8 +46525,8 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
45758
46525
|
const venvPip = pathJoin(venvDir, "bin", "pip");
|
|
45759
46526
|
if (fsExists(venvPip)) {
|
|
45760
46527
|
installOverlay.setStatus("Upgrading Python packages...");
|
|
45761
|
-
await new Promise((
|
|
45762
|
-
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));
|
|
45763
46530
|
child.stdout?.resume();
|
|
45764
46531
|
child.stderr?.resume();
|
|
45765
46532
|
});
|
|
@@ -46155,16 +46922,16 @@ async function showExposeDashboard(gateway, rl, ctx) {
|
|
|
46155
46922
|
renderDashboard();
|
|
46156
46923
|
}, 1e3);
|
|
46157
46924
|
let stopGateway = false;
|
|
46158
|
-
await new Promise((
|
|
46925
|
+
await new Promise((resolve33) => {
|
|
46159
46926
|
const onData = (data) => {
|
|
46160
46927
|
const key = data.toString();
|
|
46161
46928
|
if (key === "q" || key === "Q" || key === "\x1B" || key === "") {
|
|
46162
|
-
|
|
46929
|
+
resolve33();
|
|
46163
46930
|
return;
|
|
46164
46931
|
}
|
|
46165
46932
|
if (key === "s" || key === "S") {
|
|
46166
46933
|
stopGateway = true;
|
|
46167
|
-
|
|
46934
|
+
resolve33();
|
|
46168
46935
|
return;
|
|
46169
46936
|
}
|
|
46170
46937
|
if (key === "c" || key === "C") {
|
|
@@ -46215,8 +46982,8 @@ async function showExposeDashboard(gateway, rl, ctx) {
|
|
|
46215
46982
|
process.stdout.write("\x1B[?1002h\x1B[?1006h");
|
|
46216
46983
|
}
|
|
46217
46984
|
};
|
|
46218
|
-
const origResolve =
|
|
46219
|
-
|
|
46985
|
+
const origResolve = resolve33;
|
|
46986
|
+
resolve33 = (() => {
|
|
46220
46987
|
cleanup();
|
|
46221
46988
|
origResolve();
|
|
46222
46989
|
});
|
|
@@ -46274,7 +47041,7 @@ var init_commands = __esm({
|
|
|
46274
47041
|
import { existsSync as existsSync38, readFileSync as readFileSync27, readdirSync as readdirSync11 } from "node:fs";
|
|
46275
47042
|
import { join as join53, basename as basename10 } from "node:path";
|
|
46276
47043
|
import { execSync as execSync27 } from "node:child_process";
|
|
46277
|
-
import { homedir as
|
|
47044
|
+
import { homedir as homedir15, platform as platform3, release } from "node:os";
|
|
46278
47045
|
function getModelTier(modelName) {
|
|
46279
47046
|
const m = modelName.toLowerCase();
|
|
46280
47047
|
const sizeMatch = m.match(/\b(\d+)b\b/);
|
|
@@ -46361,7 +47128,7 @@ function loadMemoryContext(repoRoot) {
|
|
|
46361
47128
|
if (legacyEntries)
|
|
46362
47129
|
sections.push(legacyEntries);
|
|
46363
47130
|
}
|
|
46364
|
-
const globalMemDir = join53(
|
|
47131
|
+
const globalMemDir = join53(homedir15(), ".open-agents", "memory");
|
|
46365
47132
|
const globalEntries = loadMemoryDir(globalMemDir, "global");
|
|
46366
47133
|
if (globalEntries)
|
|
46367
47134
|
sections.push(globalEntries);
|
|
@@ -52081,7 +52848,7 @@ var init_tool_policy = __esm({
|
|
|
52081
52848
|
|
|
52082
52849
|
// packages/cli/dist/tui/telegram-bridge.js
|
|
52083
52850
|
import { mkdirSync as mkdirSync19, existsSync as existsSync44, unlinkSync as unlinkSync10, readdirSync as readdirSync16, statSync as statSync14 } from "node:fs";
|
|
52084
|
-
import { join as join60, resolve as
|
|
52851
|
+
import { join as join60, resolve as resolve29 } from "node:path";
|
|
52085
52852
|
import { writeFile as writeFileAsync } from "node:fs/promises";
|
|
52086
52853
|
function convertMarkdownToTelegramHTML(md) {
|
|
52087
52854
|
let html = md;
|
|
@@ -52324,7 +53091,7 @@ with summary "no_reply" to silently skip without responding.
|
|
|
52324
53091
|
this.agentConfig = agentConfig;
|
|
52325
53092
|
this.repoRoot = repoRoot;
|
|
52326
53093
|
this.toolPolicyConfig = toolPolicyConfig;
|
|
52327
|
-
this.mediaCacheDir =
|
|
53094
|
+
this.mediaCacheDir = resolve29(repoRoot || ".", ".oa", "telegram-media-cache");
|
|
52328
53095
|
}
|
|
52329
53096
|
/** Set admin user ID filter */
|
|
52330
53097
|
setAdmin(userId) {
|
|
@@ -53560,7 +54327,7 @@ var init_braille_spinner = __esm({
|
|
|
53560
54327
|
// packages/cli/dist/tui/system-metrics.js
|
|
53561
54328
|
import { loadavg as loadavg3, cpus as cpus3, totalmem as totalmem4, freemem as freemem3, platform as platform4 } from "node:os";
|
|
53562
54329
|
import { exec as exec3 } from "node:child_process";
|
|
53563
|
-
import { readFile as
|
|
54330
|
+
import { readFile as readFile22 } from "node:fs/promises";
|
|
53564
54331
|
function formatRate(bytesPerSec) {
|
|
53565
54332
|
if (bytesPerSec < 1024)
|
|
53566
54333
|
return `${Math.round(bytesPerSec)}B`;
|
|
@@ -53572,7 +54339,7 @@ function formatRate(bytesPerSec) {
|
|
|
53572
54339
|
}
|
|
53573
54340
|
async function readProcNetDev() {
|
|
53574
54341
|
try {
|
|
53575
|
-
const data = await
|
|
54342
|
+
const data = await readFile22("/proc/net/dev", "utf8");
|
|
53576
54343
|
let rxTotal = 0;
|
|
53577
54344
|
let txTotal = 0;
|
|
53578
54345
|
for (const line of data.split("\n")) {
|
|
@@ -53610,8 +54377,8 @@ async function collectNetworkMetrics() {
|
|
|
53610
54377
|
}
|
|
53611
54378
|
if (plat === "darwin") {
|
|
53612
54379
|
try {
|
|
53613
|
-
const output = await new Promise((
|
|
53614
|
-
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));
|
|
53615
54382
|
});
|
|
53616
54383
|
let rxBytes = 0, txBytes = 0;
|
|
53617
54384
|
for (const line of output.split("\n")) {
|
|
@@ -53645,8 +54412,8 @@ async function collectGpuMetrics() {
|
|
|
53645
54412
|
if (_nvidiaSmiAvailable === false)
|
|
53646
54413
|
return noGpu;
|
|
53647
54414
|
try {
|
|
53648
|
-
const smi = await new Promise((
|
|
53649
|
-
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));
|
|
53650
54417
|
});
|
|
53651
54418
|
_nvidiaSmiAvailable = true;
|
|
53652
54419
|
const line = smi.trim().split("\n")[0];
|
|
@@ -56295,13 +57062,13 @@ var init_mouse_filter = __esm({
|
|
|
56295
57062
|
import * as readline2 from "node:readline";
|
|
56296
57063
|
import { Writable } from "node:stream";
|
|
56297
57064
|
import { cwd } from "node:process";
|
|
56298
|
-
import { resolve as
|
|
57065
|
+
import { resolve as resolve30, join as join61, dirname as dirname19, extname as extname10 } from "node:path";
|
|
56299
57066
|
import { createRequire as createRequire2 } from "node:module";
|
|
56300
57067
|
import { fileURLToPath as fileURLToPath12 } from "node:url";
|
|
56301
57068
|
import { readFileSync as readFileSync34, writeFileSync as writeFileSync19, appendFileSync as appendFileSync4, rmSync as rmSync3, readdirSync as readdirSync17, mkdirSync as mkdirSync20 } from "node:fs";
|
|
56302
57069
|
import { existsSync as existsSync45 } from "node:fs";
|
|
56303
57070
|
import { execSync as execSync30 } from "node:child_process";
|
|
56304
|
-
import { homedir as
|
|
57071
|
+
import { homedir as homedir16 } from "node:os";
|
|
56305
57072
|
function formatTimeAgo(date) {
|
|
56306
57073
|
const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
|
|
56307
57074
|
if (seconds < 60)
|
|
@@ -56450,6 +57217,9 @@ function buildTools(repoRoot, config, contextWindowSize) {
|
|
|
56450
57217
|
new OpenCodeTool(repoRoot),
|
|
56451
57218
|
new FactoryTool(repoRoot),
|
|
56452
57219
|
new CronAgentTool(repoRoot),
|
|
57220
|
+
// Chunked file exploration + working notes
|
|
57221
|
+
new FileExploreTool(repoRoot),
|
|
57222
|
+
new WorkingNotesTool(),
|
|
56453
57223
|
// Nexus P2P networking + x402 micropayments
|
|
56454
57224
|
new NexusTool(repoRoot)
|
|
56455
57225
|
];
|
|
@@ -57599,7 +58369,7 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
57599
58369
|
} };
|
|
57600
58370
|
}
|
|
57601
58371
|
async function startInteractive(config, repoPath) {
|
|
57602
|
-
const repoRoot =
|
|
58372
|
+
const repoRoot = resolve30(repoPath ?? cwd());
|
|
57603
58373
|
const resumeFlag = process.env.__OA_RESUMED ?? "";
|
|
57604
58374
|
const isResumed = resumeFlag !== "";
|
|
57605
58375
|
const hasTaskToResume = resumeFlag === "1";
|
|
@@ -57771,14 +58541,14 @@ async function startInteractive(config, repoPath) {
|
|
|
57771
58541
|
renderInfo(msg);
|
|
57772
58542
|
statusBar.endContentWrite();
|
|
57773
58543
|
}
|
|
57774
|
-
}, () => new Promise((
|
|
58544
|
+
}, () => new Promise((resolve33) => {
|
|
57775
58545
|
depSudoPromptPending = true;
|
|
57776
58546
|
depSudoResolver = (pw) => {
|
|
57777
58547
|
depSudoPromptPending = false;
|
|
57778
58548
|
depSudoResolver = null;
|
|
57779
58549
|
if (pw)
|
|
57780
58550
|
sessionSudoPassword = pw;
|
|
57781
|
-
|
|
58551
|
+
resolve33(pw);
|
|
57782
58552
|
};
|
|
57783
58553
|
const pwPrompt1 = ` ${c2.bold(c2.yellow("\u{1F511} Password needed for dependency install:"))}
|
|
57784
58554
|
`;
|
|
@@ -58066,7 +58836,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
58066
58836
|
const hits = allCompletions.filter((c3) => c3.toLowerCase().startsWith(lower));
|
|
58067
58837
|
return [hits, line];
|
|
58068
58838
|
}
|
|
58069
|
-
const HISTORY_DIR = join61(
|
|
58839
|
+
const HISTORY_DIR = join61(homedir16(), ".open-agents");
|
|
58070
58840
|
const HISTORY_FILE = join61(HISTORY_DIR, "repl-history");
|
|
58071
58841
|
const MAX_HISTORY_LINES = 500;
|
|
58072
58842
|
let savedHistory = [];
|
|
@@ -59582,7 +60352,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
59582
60352
|
} catch {
|
|
59583
60353
|
}
|
|
59584
60354
|
try {
|
|
59585
|
-
const voiceDir2 = join61(
|
|
60355
|
+
const voiceDir2 = join61(homedir16(), ".open-agents", "voice");
|
|
59586
60356
|
const voicePidFiles = ["luxtts-daemon.pid", "piper-daemon.pid"];
|
|
59587
60357
|
for (const pf of voicePidFiles) {
|
|
59588
60358
|
const pidPath = join61(voiceDir2, pf);
|
|
@@ -59985,8 +60755,8 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
59985
60755
|
}
|
|
59986
60756
|
}
|
|
59987
60757
|
const cleanPath = input.replace(/^['"]|['"]$/g, "").trim();
|
|
59988
|
-
const isImage = isImagePath(cleanPath) && existsSync45(
|
|
59989
|
-
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));
|
|
59990
60760
|
if (activeTask) {
|
|
59991
60761
|
if (activeTask.runner.isPaused) {
|
|
59992
60762
|
activeTask.runner.resume();
|
|
@@ -59994,7 +60764,7 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
59994
60764
|
}
|
|
59995
60765
|
if (isImage) {
|
|
59996
60766
|
try {
|
|
59997
|
-
const imgPath =
|
|
60767
|
+
const imgPath = resolve30(repoRoot, cleanPath);
|
|
59998
60768
|
const imgBuffer = readFileSync34(imgPath);
|
|
59999
60769
|
const base64 = imgBuffer.toString("base64");
|
|
60000
60770
|
const ext = extname10(cleanPath).toLowerCase();
|
|
@@ -60008,7 +60778,7 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
60008
60778
|
} else if (isMedia) {
|
|
60009
60779
|
writeContent(() => renderInfo(`Transcribing: ${cleanPath}...`));
|
|
60010
60780
|
const engine = getListenEngine();
|
|
60011
|
-
const result = await engine.transcribeFile(
|
|
60781
|
+
const result = await engine.transcribeFile(resolve30(repoRoot, cleanPath), repoRoot);
|
|
60012
60782
|
if (result) {
|
|
60013
60783
|
const transcript = `[Transcription of ${cleanPath}]
|
|
60014
60784
|
${result.text}`;
|
|
@@ -60152,7 +60922,7 @@ ${result.text}`;
|
|
|
60152
60922
|
const ext = cleanPath.toLowerCase().split(".").pop() || "";
|
|
60153
60923
|
if (cloneExts.includes("." + ext)) {
|
|
60154
60924
|
writeContent(() => renderInfo(`Setting voice clone reference: ${cleanPath}`));
|
|
60155
|
-
const msg = await voiceEngine.setCloneVoice(
|
|
60925
|
+
const msg = await voiceEngine.setCloneVoice(resolve30(repoRoot, cleanPath));
|
|
60156
60926
|
writeContent(() => renderInfo(msg));
|
|
60157
60927
|
showPrompt();
|
|
60158
60928
|
return;
|
|
@@ -60161,7 +60931,7 @@ ${result.text}`;
|
|
|
60161
60931
|
if (isMedia && fullInput === input) {
|
|
60162
60932
|
writeContent(() => renderInfo(`Transcribing: ${cleanPath}...`));
|
|
60163
60933
|
const engine = getListenEngine();
|
|
60164
|
-
const result = await engine.transcribeFile(
|
|
60934
|
+
const result = await engine.transcribeFile(resolve30(repoRoot, cleanPath), repoRoot);
|
|
60165
60935
|
if (result) {
|
|
60166
60936
|
fullInput = `The user has provided an audio/video file: ${cleanPath}.
|
|
60167
60937
|
|
|
@@ -60447,7 +61217,7 @@ ${c2.dim("(Use /quit to exit)")}
|
|
|
60447
61217
|
};
|
|
60448
61218
|
}
|
|
60449
61219
|
async function runWithTUI(task, config, repoPath) {
|
|
60450
|
-
const repoRoot =
|
|
61220
|
+
const repoRoot = resolve30(repoPath ?? cwd());
|
|
60451
61221
|
const needsSetup = isFirstRun() || !await isModelAvailable(config);
|
|
60452
61222
|
if (needsSetup && config.backendType === "ollama") {
|
|
60453
61223
|
const setupModel = await runSetupWizard(config);
|
|
@@ -60830,7 +61600,7 @@ var init_run = __esm({
|
|
|
60830
61600
|
// packages/indexer/dist/codebase-indexer.js
|
|
60831
61601
|
import { glob } from "glob";
|
|
60832
61602
|
import ignore from "ignore";
|
|
60833
|
-
import { readFile as
|
|
61603
|
+
import { readFile as readFile23, stat as stat4 } from "node:fs/promises";
|
|
60834
61604
|
import { createHash as createHash4 } from "node:crypto";
|
|
60835
61605
|
import { join as join62, relative as relative3, extname as extname11, basename as basename15 } from "node:path";
|
|
60836
61606
|
var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
|
|
@@ -60876,7 +61646,7 @@ var init_codebase_indexer = __esm({
|
|
|
60876
61646
|
const ig = ignore.default();
|
|
60877
61647
|
if (this.config.respectGitignore) {
|
|
60878
61648
|
try {
|
|
60879
|
-
const gitignoreContent = await
|
|
61649
|
+
const gitignoreContent = await readFile23(join62(this.config.rootDir, ".gitignore"), "utf-8");
|
|
60880
61650
|
ig.add(gitignoreContent);
|
|
60881
61651
|
} catch {
|
|
60882
61652
|
}
|
|
@@ -60896,7 +61666,7 @@ var init_codebase_indexer = __esm({
|
|
|
60896
61666
|
const fileStat = await stat4(fullPath);
|
|
60897
61667
|
if (fileStat.size > this.config.maxFileSize)
|
|
60898
61668
|
continue;
|
|
60899
|
-
const content = await
|
|
61669
|
+
const content = await readFile23(fullPath);
|
|
60900
61670
|
const hash = createHash4("sha256").update(content).digest("hex");
|
|
60901
61671
|
const ext = extname11(relativePath);
|
|
60902
61672
|
indexed.push({
|
|
@@ -61019,11 +61789,11 @@ var index_repo_exports = {};
|
|
|
61019
61789
|
__export(index_repo_exports, {
|
|
61020
61790
|
indexRepoCommand: () => indexRepoCommand
|
|
61021
61791
|
});
|
|
61022
|
-
import { resolve as
|
|
61792
|
+
import { resolve as resolve31 } from "node:path";
|
|
61023
61793
|
import { existsSync as existsSync46, statSync as statSync15 } from "node:fs";
|
|
61024
61794
|
import { cwd as cwd2 } from "node:process";
|
|
61025
61795
|
async function indexRepoCommand(opts, _config) {
|
|
61026
|
-
const repoRoot =
|
|
61796
|
+
const repoRoot = resolve31(opts.repoPath ?? cwd2());
|
|
61027
61797
|
printHeader("Index Repository");
|
|
61028
61798
|
printInfo(`Indexing: ${repoRoot}`);
|
|
61029
61799
|
if (!existsSync46(repoRoot)) {
|
|
@@ -61278,8 +62048,8 @@ var config_exports = {};
|
|
|
61278
62048
|
__export(config_exports, {
|
|
61279
62049
|
configCommand: () => configCommand
|
|
61280
62050
|
});
|
|
61281
|
-
import { join as join63, resolve as
|
|
61282
|
-
import { homedir as
|
|
62051
|
+
import { join as join63, resolve as resolve32 } from "node:path";
|
|
62052
|
+
import { homedir as homedir17 } from "node:os";
|
|
61283
62053
|
import { cwd as cwd3 } from "node:process";
|
|
61284
62054
|
function redactIfSensitive(key, value) {
|
|
61285
62055
|
if (SENSITIVE_KEYS.has(key) && typeof value === "string" && value.length > 0) {
|
|
@@ -61311,7 +62081,7 @@ async function configCommand(opts, config) {
|
|
|
61311
62081
|
return handleShow(opts, config);
|
|
61312
62082
|
}
|
|
61313
62083
|
function handleShow(opts, config) {
|
|
61314
|
-
const repoRoot =
|
|
62084
|
+
const repoRoot = resolve32(opts.repoPath ?? cwd3());
|
|
61315
62085
|
printHeader("Configuration");
|
|
61316
62086
|
const resolved = resolveSettings(repoRoot);
|
|
61317
62087
|
printSection("Core Inference");
|
|
@@ -61361,7 +62131,7 @@ function handleShow(opts, config) {
|
|
|
61361
62131
|
}
|
|
61362
62132
|
}
|
|
61363
62133
|
printSection("Config File");
|
|
61364
|
-
printInfo(`~/.open-agents/config.json (${join63(
|
|
62134
|
+
printInfo(`~/.open-agents/config.json (${join63(homedir17(), ".open-agents", "config.json")})`);
|
|
61365
62135
|
printSection("Priority Chain");
|
|
61366
62136
|
printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
|
|
61367
62137
|
printInfo(" 2. Project .oa/settings.json (--local)");
|
|
@@ -61394,7 +62164,7 @@ function handleSet(opts, _config) {
|
|
|
61394
62164
|
process.exit(1);
|
|
61395
62165
|
}
|
|
61396
62166
|
if (opts.local) {
|
|
61397
|
-
const repoRoot =
|
|
62167
|
+
const repoRoot = resolve32(opts.repoPath ?? cwd3());
|
|
61398
62168
|
try {
|
|
61399
62169
|
initOaDirectory(repoRoot);
|
|
61400
62170
|
const coerced = coerceForSettings(key, value);
|
|
@@ -61592,7 +62362,7 @@ async function serveVllm(opts, config) {
|
|
|
61592
62362
|
await runVllmServer(args, opts.verbose ?? false);
|
|
61593
62363
|
}
|
|
61594
62364
|
async function runVllmServer(args, verbose) {
|
|
61595
|
-
return new Promise((
|
|
62365
|
+
return new Promise((resolve33, reject) => {
|
|
61596
62366
|
const child = spawn19("python", args, {
|
|
61597
62367
|
stdio: verbose ? "inherit" : ["ignore", "pipe", "pipe"],
|
|
61598
62368
|
env: { ...process.env }
|
|
@@ -61627,10 +62397,10 @@ async function runVllmServer(args, verbose) {
|
|
|
61627
62397
|
child.once("exit", (code, signal) => {
|
|
61628
62398
|
if (signal) {
|
|
61629
62399
|
printInfo(`vLLM server stopped by signal ${signal}`);
|
|
61630
|
-
|
|
62400
|
+
resolve33();
|
|
61631
62401
|
} else if (code === 0) {
|
|
61632
62402
|
printSuccess("vLLM server exited cleanly");
|
|
61633
|
-
|
|
62403
|
+
resolve33();
|
|
61634
62404
|
} else {
|
|
61635
62405
|
printError(`vLLM server exited with code ${code}`);
|
|
61636
62406
|
reject(new Error(`vLLM exited with code ${code}`));
|