open-agents-ai 0.115.0 → 0.116.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.
Files changed (2) hide show
  1. package/dist/index.js +684 -397
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -7994,12 +7994,12 @@ var init_memory_metabolism = __esm({
7994
7994
  properties: {
7995
7995
  op: {
7996
7996
  type: "string",
7997
- enum: ["admit", "consolidate", "list", "promote", "forget"],
7998
- description: "Operation: admit (store new), consolidate (extract lessons from recent work), list (show memories), promote (upgrade type), forget (remove)"
7997
+ enum: ["admit", "consolidate", "list", "promote", "forget", "repair"],
7998
+ description: "Operation: admit (store new), consolidate (extract lessons), list (show), promote (upgrade type), forget (remove), repair (validate and fix contradictions in stored memories \u2014 MemMA backward-path, arxiv:2603.18718)"
7999
7999
  },
8000
8000
  memory_type: {
8001
8001
  type: "string",
8002
- enum: ["episodic", "semantic", "procedural", "normative", "quarantine"],
8002
+ enum: ["working", "episodic", "semantic", "procedural", "normative", "quarantine"],
8003
8003
  description: "Memory classification type"
8004
8004
  },
8005
8005
  content: {
@@ -8047,6 +8047,8 @@ var init_memory_metabolism = __esm({
8047
8047
  return await this.promoteMemory(args, start);
8048
8048
  case "forget":
8049
8049
  return await this.forgetMemory(args, start);
8050
+ case "repair":
8051
+ return await this.repairMemories(start);
8050
8052
  default:
8051
8053
  return { success: false, output: `Unknown op: ${op}`, error: "Invalid operation", durationMs: performance.now() - start };
8052
8054
  }
@@ -8229,6 +8231,102 @@ ${lines.join("\n")}`,
8229
8231
  durationMs: performance.now() - start
8230
8232
  };
8231
8233
  }
8234
+ // ── Repair (MemMA backward-path, arxiv:2603.18718) ─────────────────────
8235
+ /**
8236
+ * Validate stored memories and repair contradictions before they become
8237
+ * canonical. Inspired by MemMA's backward-path repair (arxiv:2603.18718):
8238
+ * "The system should be allowed to repair memory before committing it."
8239
+ */
8240
+ async repairMemories(start) {
8241
+ const metaDir = join19(this.cwd, ".oa", "memory", "metabolism");
8242
+ const store = await this.loadStore(metaDir);
8243
+ if (store.length === 0) {
8244
+ return { success: true, output: "No memories to repair.", durationMs: performance.now() - start };
8245
+ }
8246
+ let repaired = 0;
8247
+ let quarantined = 0;
8248
+ let expired = 0;
8249
+ const issues = [];
8250
+ for (const item of store) {
8251
+ if (item.type === "working") {
8252
+ const ageMs = Date.now() - new Date(item.createdAt).getTime();
8253
+ if (ageMs > 24 * 60 * 60 * 1e3) {
8254
+ item.decision = { action: "forget", reason: "Working memory expired (>24h)" };
8255
+ expired++;
8256
+ issues.push(`[${item.id}] Working memory expired \u2014 marked for cleanup`);
8257
+ }
8258
+ }
8259
+ const duplicates = store.filter((m) => m.id !== item.id && m.content === item.content);
8260
+ if (duplicates.length > 0) {
8261
+ for (const dup of duplicates) {
8262
+ const dupScore = (dup.scores.novelty + dup.scores.utility + dup.scores.confidence + dup.scores.identityRelevance) / 4;
8263
+ const itemScore = (item.scores.novelty + item.scores.utility + item.scores.confidence + item.scores.identityRelevance) / 4;
8264
+ if (dupScore < itemScore && dup.decision.action !== "quarantine") {
8265
+ dup.type = "quarantine";
8266
+ dup.decision = { action: "quarantine", reason: `Duplicate of ${item.id} (lower score)` };
8267
+ quarantined++;
8268
+ issues.push(`[${dup.id}] Duplicate content quarantined`);
8269
+ }
8270
+ }
8271
+ }
8272
+ if (item.type === "procedural" || item.type === "semantic") {
8273
+ const conflicts = store.filter((m) => m.id !== item.id && m.type === item.type && m.decision.action !== "quarantine" && this.detectContradiction(item.content, m.content));
8274
+ if (conflicts.length > 0) {
8275
+ for (const conflict of conflicts) {
8276
+ if (new Date(conflict.createdAt) < new Date(item.createdAt)) {
8277
+ conflict.type = "quarantine";
8278
+ conflict.decision = { action: "quarantine", reason: `Contradicts newer memory ${item.id}` };
8279
+ quarantined++;
8280
+ issues.push(`[${conflict.id}] Contradicts [${item.id}] \u2014 older version quarantined`);
8281
+ }
8282
+ }
8283
+ repaired++;
8284
+ }
8285
+ }
8286
+ if (item.scores.confidence < 0.3 && item.decision.action === "admit") {
8287
+ item.type = "quarantine";
8288
+ item.decision = { action: "quarantine", reason: "Low confidence on re-evaluation" };
8289
+ quarantined++;
8290
+ issues.push(`[${item.id}] Low confidence (${item.scores.confidence.toFixed(2)}) \u2014 quarantined`);
8291
+ }
8292
+ }
8293
+ const cleanedStore = store.filter((m) => !(m.type === "working" && m.decision.action === "forget"));
8294
+ await this.saveStore(metaDir, cleanedStore);
8295
+ return {
8296
+ success: true,
8297
+ output: `Memory repair complete:
8298
+ Scanned: ${store.length} memories
8299
+ Repaired contradictions: ${repaired}
8300
+ Quarantined (duplicates/low-confidence): ${quarantined}
8301
+ Expired working memories removed: ${expired}
8302
+ ` + (issues.length > 0 ? `
8303
+ Issues found:
8304
+ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
8305
+ durationMs: performance.now() - start
8306
+ };
8307
+ }
8308
+ /** Simple contradiction detection between two memory contents */
8309
+ detectContradiction(a, b) {
8310
+ const aLower = a.toLowerCase();
8311
+ const bLower = b.toLowerCase();
8312
+ const negationPairs = [
8313
+ [/\bshould\b/, /\bshould not\b/],
8314
+ [/\balways\b/, /\bnever\b/],
8315
+ [/\bdo\b/, /\bdon't\b/],
8316
+ [/\btrue\b/, /\bfalse\b/],
8317
+ [/\benable\b/, /\bdisable\b/],
8318
+ [/\buse\b/, /\bavoid\b/]
8319
+ ];
8320
+ for (const [pos, neg] of negationPairs) {
8321
+ if (pos.test(aLower) && neg.test(bLower) || neg.test(aLower) && pos.test(bLower)) {
8322
+ const aWords = new Set(aLower.split(/\s+/).filter((w) => w.length > 4));
8323
+ const bWords = bLower.split(/\s+/).filter((w) => w.length > 4);
8324
+ if (bWords.some((w) => aWords.has(w)))
8325
+ return true;
8326
+ }
8327
+ }
8328
+ return false;
8329
+ }
8232
8330
  // ── Scoring ──────────────────────────────────────────────────────────────
8233
8331
  scoreMemory(content, type, source) {
8234
8332
  const words = content.split(/\s+/).length;
@@ -8975,8 +9073,193 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
8975
9073
  }
8976
9074
  });
8977
9075
 
9076
+ // packages/execution/dist/tools/embedding-store.js
9077
+ import { readFile as readFile12, writeFile as writeFile12, mkdir as mkdir8, readdir as readdir3 } from "node:fs/promises";
9078
+ import { join as join23 } from "node:path";
9079
+ var EmbeddingStoreTool;
9080
+ var init_embedding_store = __esm({
9081
+ "packages/execution/dist/tools/embedding-store.js"() {
9082
+ "use strict";
9083
+ EmbeddingStoreTool = class {
9084
+ name = "embedding_store";
9085
+ description = "Local semantic memory \u2014 store and retrieve memories by meaning, not just keywords. Operations: store (embed and save text), search (find semantically similar memories), list (show stored entries). Uses Ollama embeddings API locally \u2014 data never leaves your machine. (COHERE Private Brain, p.34)";
9086
+ parameters = {
9087
+ type: "object",
9088
+ properties: {
9089
+ op: {
9090
+ type: "string",
9091
+ enum: ["store", "search", "list"],
9092
+ description: "store (embed + save), search (find similar), list (show all)"
9093
+ },
9094
+ content: {
9095
+ type: "string",
9096
+ description: "For store: text to embed. For search: query text."
9097
+ },
9098
+ source: {
9099
+ type: "string",
9100
+ description: "For store: origin of this memory (tool name, etc.)"
9101
+ },
9102
+ type: {
9103
+ type: "string",
9104
+ description: "For store: memory type (fact, procedure, lesson, etc.)"
9105
+ },
9106
+ top_k: {
9107
+ type: "number",
9108
+ description: "For search: number of results (default: 5)"
9109
+ }
9110
+ },
9111
+ required: ["op"]
9112
+ };
9113
+ cwd;
9114
+ ollamaUrl;
9115
+ model;
9116
+ cache = null;
9117
+ constructor(cwd4, ollamaUrl = "http://localhost:11434", model = "nomic-embed-text") {
9118
+ this.cwd = cwd4;
9119
+ this.ollamaUrl = ollamaUrl;
9120
+ this.model = model;
9121
+ }
9122
+ async execute(args) {
9123
+ const op = String(args.op ?? "");
9124
+ const start = performance.now();
9125
+ try {
9126
+ switch (op) {
9127
+ case "store":
9128
+ return await this.storeEmbedding(args, start);
9129
+ case "search":
9130
+ return await this.searchEmbeddings(args, start);
9131
+ case "list":
9132
+ return await this.listEmbeddings(start);
9133
+ default:
9134
+ return { success: false, output: `Unknown op: ${op}`, error: "Invalid", durationMs: performance.now() - start };
9135
+ }
9136
+ } catch (err) {
9137
+ return { success: false, output: `Error: ${err instanceof Error ? err.message : String(err)}`, durationMs: performance.now() - start };
9138
+ }
9139
+ }
9140
+ async storeEmbedding(args, start) {
9141
+ const content = String(args.content ?? "");
9142
+ const source = String(args.source ?? "user");
9143
+ const type = String(args.type ?? "fact");
9144
+ if (!content.trim()) {
9145
+ return { success: false, output: "No content", durationMs: performance.now() - start };
9146
+ }
9147
+ const vector = await this.embed(content);
9148
+ if (!vector) {
9149
+ return { success: false, output: "Embedding generation failed \u2014 is Ollama running with an embedding model?", durationMs: performance.now() - start };
9150
+ }
9151
+ const entry = {
9152
+ id: `emb-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`,
9153
+ content,
9154
+ vector,
9155
+ metadata: { source, type, createdAt: (/* @__PURE__ */ new Date()).toISOString() }
9156
+ };
9157
+ const dir = join23(this.cwd, ".oa", "embeddings");
9158
+ await mkdir8(dir, { recursive: true });
9159
+ await writeFile12(join23(dir, `${entry.id}.json`), JSON.stringify(entry), "utf8");
9160
+ this.cache = null;
9161
+ return {
9162
+ success: true,
9163
+ output: `Stored: [${entry.id}] ${content.slice(0, 60)}... (${vector.length}d vector)`,
9164
+ durationMs: performance.now() - start
9165
+ };
9166
+ }
9167
+ async searchEmbeddings(args, start) {
9168
+ const query = String(args.content ?? "");
9169
+ const topK = Math.min(20, Math.max(1, Number(args.top_k ?? 5)));
9170
+ if (!query.trim()) {
9171
+ return { success: false, output: "No query", durationMs: performance.now() - start };
9172
+ }
9173
+ const queryVec = await this.embed(query);
9174
+ if (!queryVec) {
9175
+ return { success: false, output: "Query embedding failed", durationMs: performance.now() - start };
9176
+ }
9177
+ const entries = await this.loadAll();
9178
+ if (entries.length === 0) {
9179
+ return { success: true, output: "No embeddings stored yet.", durationMs: performance.now() - start };
9180
+ }
9181
+ const scored = entries.map((e) => ({
9182
+ entry: e,
9183
+ similarity: this.cosineSimilarity(queryVec, e.vector)
9184
+ })).sort((a, b) => b.similarity - a.similarity).slice(0, topK);
9185
+ const results = scored.map((s, i) => `${i + 1}. [${s.entry.id}] sim=${s.similarity.toFixed(3)} type=${s.entry.metadata.type}
9186
+ ${s.entry.content.slice(0, 120)}`);
9187
+ return {
9188
+ success: true,
9189
+ output: `Semantic search: "${query.slice(0, 40)}..." \u2014 ${scored.length} results:
9190
+
9191
+ ${results.join("\n\n")}`,
9192
+ durationMs: performance.now() - start
9193
+ };
9194
+ }
9195
+ async listEmbeddings(start) {
9196
+ const entries = await this.loadAll();
9197
+ if (entries.length === 0) {
9198
+ return { success: true, output: "No embeddings stored.", durationMs: performance.now() - start };
9199
+ }
9200
+ const lines = entries.map((e) => `[${e.id}] type=${e.metadata.type} src=${e.metadata.source} ${e.content.slice(0, 80)}`);
9201
+ return {
9202
+ success: true,
9203
+ output: `Embedding store (${entries.length} entries):
9204
+ ${lines.join("\n")}`,
9205
+ durationMs: performance.now() - start
9206
+ };
9207
+ }
9208
+ // ── Helpers ──
9209
+ async embed(text) {
9210
+ try {
9211
+ const resp = await fetch(`${this.ollamaUrl}/api/embed`, {
9212
+ method: "POST",
9213
+ headers: { "Content-Type": "application/json" },
9214
+ body: JSON.stringify({ model: this.model, input: text }),
9215
+ signal: AbortSignal.timeout(3e4)
9216
+ });
9217
+ if (!resp.ok)
9218
+ return null;
9219
+ const data = await resp.json();
9220
+ return data.embeddings?.[0] ?? null;
9221
+ } catch {
9222
+ return null;
9223
+ }
9224
+ }
9225
+ cosineSimilarity(a, b) {
9226
+ if (a.length !== b.length)
9227
+ return 0;
9228
+ let dot = 0, normA = 0, normB = 0;
9229
+ for (let i = 0; i < a.length; i++) {
9230
+ dot += a[i] * b[i];
9231
+ normA += a[i] * a[i];
9232
+ normB += b[i] * b[i];
9233
+ }
9234
+ const denom = Math.sqrt(normA) * Math.sqrt(normB);
9235
+ return denom === 0 ? 0 : dot / denom;
9236
+ }
9237
+ async loadAll() {
9238
+ if (this.cache)
9239
+ return this.cache;
9240
+ const dir = join23(this.cwd, ".oa", "embeddings");
9241
+ try {
9242
+ const files = await readdir3(dir);
9243
+ const entries = [];
9244
+ for (const f of files.filter((f2) => f2.endsWith(".json"))) {
9245
+ try {
9246
+ const raw = await readFile12(join23(dir, f), "utf8");
9247
+ entries.push(JSON.parse(raw));
9248
+ } catch {
9249
+ }
9250
+ }
9251
+ this.cache = entries;
9252
+ return entries;
9253
+ } catch {
9254
+ return [];
9255
+ }
9256
+ }
9257
+ };
9258
+ }
9259
+ });
9260
+
8978
9261
  // packages/execution/dist/tools/structured-read.js
8979
- import { readFile as readFile12, stat as stat2 } from "node:fs/promises";
9262
+ import { readFile as readFile13, stat as stat2 } from "node:fs/promises";
8980
9263
  import { resolve as resolve15, extname as extname5 } from "node:path";
8981
9264
  function parseCSV(text, separator = ",") {
8982
9265
  const lines = text.split("\n").filter((l) => l.trim() !== "");
@@ -9171,7 +9454,7 @@ var init_structured_read = __esm({
9171
9454
  }
9172
9455
  }
9173
9456
  if (format === "xlsx" || format === "pdf" || format === "docx" || format === "auto") {
9174
- const buffer = await readFile12(fullPath);
9457
+ const buffer = await readFile13(fullPath);
9175
9458
  const detected = detectBinaryFormat(buffer);
9176
9459
  if (detected === "xlsx") {
9177
9460
  return {
@@ -9216,7 +9499,7 @@ Or install mammoth for programmatic access.`,
9216
9499
  }
9217
9500
  }
9218
9501
  }
9219
- const text = await readFile12(fullPath, "utf-8");
9502
+ const text = await readFile13(fullPath, "utf-8");
9220
9503
  switch (format) {
9221
9504
  case "csv": {
9222
9505
  const rows = parseCSV(text, ",");
@@ -9313,7 +9596,7 @@ ${parts.join("\n\n")}`,
9313
9596
  // packages/execution/dist/tools/vision.js
9314
9597
  import { readFileSync as readFileSync11, existsSync as existsSync14, statSync as statSync5 } from "node:fs";
9315
9598
  import { execSync as execSync11, spawn as spawn7 } from "node:child_process";
9316
- import { resolve as resolve16, extname as extname6, basename as basename5, dirname as dirname6, join as join23 } from "node:path";
9599
+ import { resolve as resolve16, extname as extname6, basename as basename5, dirname as dirname6, join as join24 } from "node:path";
9317
9600
  import { fileURLToPath as fileURLToPath2 } from "node:url";
9318
9601
  async function probeStation(endpoint) {
9319
9602
  try {
@@ -9328,7 +9611,7 @@ async function probeStation(endpoint) {
9328
9611
  }
9329
9612
  }
9330
9613
  function findStationBinary() {
9331
- const oaVenvPython = join23(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "python");
9614
+ const oaVenvPython = join24(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "python");
9332
9615
  if (existsSync14(oaVenvPython)) {
9333
9616
  try {
9334
9617
  execSync11(`${JSON.stringify(oaVenvPython)} -c "import moondream_station"`, { stdio: "pipe", timeout: 5e3 });
@@ -9336,7 +9619,7 @@ function findStationBinary() {
9336
9619
  } catch {
9337
9620
  }
9338
9621
  }
9339
- const oaVenvBin = join23(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "moondream-station");
9622
+ const oaVenvBin = join24(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "moondream-station");
9340
9623
  if (existsSync14(oaVenvBin))
9341
9624
  return oaVenvBin;
9342
9625
  const thisDir = dirname6(fileURLToPath2(import.meta.url));
@@ -9688,7 +9971,7 @@ ${response}`, durationMs: performance.now() - start };
9688
9971
  import { readFileSync as readFileSync12, existsSync as existsSync15 } from "node:fs";
9689
9972
  import { execSync as execSync12 } from "node:child_process";
9690
9973
  import { tmpdir as tmpdir4 } from "node:os";
9691
- import { join as join24, dirname as dirname7 } from "node:path";
9974
+ import { join as join25, dirname as dirname7 } from "node:path";
9692
9975
  import { fileURLToPath as fileURLToPath3 } from "node:url";
9693
9976
  function hasCommand2(cmd) {
9694
9977
  try {
@@ -9812,7 +10095,7 @@ for i in range(${clicks}):
9812
10095
  } catch {
9813
10096
  }
9814
10097
  try {
9815
- const venvPy = join24(__dirname2, "../../../../.moondream-venv/bin/python");
10098
+ const venvPy = join25(__dirname2, "../../../../.moondream-venv/bin/python");
9816
10099
  execSync12(`DISPLAY=:0 ${JSON.stringify(venvPy)} -c "${pyScript}"`, { stdio: "pipe", timeout: 5e3 });
9817
10100
  return;
9818
10101
  } catch {
@@ -9904,7 +10187,7 @@ var init_desktop_click = __esm({
9904
10187
  if (delayMs > 0) {
9905
10188
  await new Promise((r) => setTimeout(r, delayMs));
9906
10189
  }
9907
- const screenshotPath = join24(tmpdir4(), `oa-desktop-click-${Date.now()}.png`);
10190
+ const screenshotPath = join25(tmpdir4(), `oa-desktop-click-${Date.now()}.png`);
9908
10191
  captureScreenshot(screenshotPath);
9909
10192
  const dims = getImageDimensions2(screenshotPath);
9910
10193
  if (!dims) {
@@ -10079,7 +10362,7 @@ Screenshot: ${screenshotPath}`,
10079
10362
  if (delayMs > 0) {
10080
10363
  await new Promise((r) => setTimeout(r, delayMs));
10081
10364
  }
10082
- const screenshotPath = join24(tmpdir4(), `oa-desktop-describe-${Date.now()}.png`);
10365
+ const screenshotPath = join25(tmpdir4(), `oa-desktop-describe-${Date.now()}.png`);
10083
10366
  captureScreenshot(screenshotPath);
10084
10367
  const dims = getImageDimensions2(screenshotPath);
10085
10368
  const imageBuffer = readFileSync12(screenshotPath);
@@ -10318,7 +10601,7 @@ Language: ${language}
10318
10601
 
10319
10602
  // packages/execution/dist/tools/pdf-to-text.js
10320
10603
  import { existsSync as existsSync17, statSync as statSync7, readFileSync as readFileSync13, unlinkSync as unlinkSync3 } from "node:fs";
10321
- import { resolve as resolve18, basename as basename7, join as join25 } from "node:path";
10604
+ import { resolve as resolve18, basename as basename7, join as join26 } from "node:path";
10322
10605
  import { execSync as execSync14 } from "node:child_process";
10323
10606
  import { tmpdir as tmpdir5 } from "node:os";
10324
10607
  var PdfToTextTool;
@@ -10472,7 +10755,7 @@ ${text}`,
10472
10755
  if (!ocrCheck.available || !tesCheck.available || !gsCheck.available) {
10473
10756
  return null;
10474
10757
  }
10475
- const tmpPdf = join25(tmpdir5(), `oa-ocr-${Date.now()}.pdf`);
10758
+ const tmpPdf = join26(tmpdir5(), `oa-ocr-${Date.now()}.pdf`);
10476
10759
  try {
10477
10760
  const ocrCmd = `ocrmypdf -l ${language} --skip-text ${JSON.stringify(inputPath)} ${JSON.stringify(tmpPdf)}`;
10478
10761
  execSync14(ocrCmd, { stdio: "pipe", timeout: 6e5 });
@@ -10503,7 +10786,7 @@ ${text}`,
10503
10786
 
10504
10787
  // packages/execution/dist/tools/ocr-image-advanced.js
10505
10788
  import { existsSync as existsSync18, statSync as statSync8 } from "node:fs";
10506
- import { resolve as resolve19, basename as basename8, dirname as dirname8, join as join26 } from "node:path";
10789
+ import { resolve as resolve19, basename as basename8, dirname as dirname8, join as join27 } from "node:path";
10507
10790
  import { execSync as execSync15 } from "node:child_process";
10508
10791
  import { fileURLToPath as fileURLToPath4 } from "node:url";
10509
10792
  import { homedir as homedir7, tmpdir as tmpdir6 } from "node:os";
@@ -10521,7 +10804,7 @@ function findOcrScript() {
10521
10804
  return null;
10522
10805
  }
10523
10806
  function findPython() {
10524
- const venvPython = join26(homedir7(), ".open-agents", "venv", "bin", "python");
10807
+ const venvPython = join27(homedir7(), ".open-agents", "venv", "bin", "python");
10525
10808
  if (existsSync18(venvPython)) {
10526
10809
  try {
10527
10810
  execSync15(`${JSON.stringify(venvPython)} -c "import cv2, pytesseract, numpy, PIL"`, {
@@ -10667,7 +10950,7 @@ var init_ocr_image_advanced = __esm({
10667
10950
  cmdParts.push("--output-dir", JSON.stringify(resolve19(this.workingDir, outputDir)));
10668
10951
  let debugDir;
10669
10952
  if (debug) {
10670
- debugDir = join26(tmpdir6(), `oa-ocr-debug-${Date.now()}`);
10953
+ debugDir = join27(tmpdir6(), `oa-ocr-debug-${Date.now()}`);
10671
10954
  cmdParts.push("--debug-dir", debugDir);
10672
10955
  }
10673
10956
  try {
@@ -10766,7 +11049,7 @@ var init_ocr_image_advanced = __esm({
10766
11049
  if (region) {
10767
11050
  try {
10768
11051
  const [x, y, w, h] = region.split(",").map(Number);
10769
- const croppedPath = join26(tmpdir6(), `oa-ocr-crop-${Date.now()}.png`);
11052
+ const croppedPath = join27(tmpdir6(), `oa-ocr-crop-${Date.now()}.png`);
10770
11053
  execSync15(`convert ${JSON.stringify(imagePath)} -crop ${w}x${h}+${x}+${y} +repage ${JSON.stringify(croppedPath)}`, { stdio: "pipe", timeout: 1e4 });
10771
11054
  inputPath = croppedPath;
10772
11055
  } catch {
@@ -10807,18 +11090,18 @@ Note: Advanced Python pipeline not available \u2014 install pytesseract, opencv-
10807
11090
  // packages/execution/dist/tools/browser-action.js
10808
11091
  import { execSync as execSync16, spawn as spawn8 } from "node:child_process";
10809
11092
  import { existsSync as existsSync19, readFileSync as readFileSync14 } from "node:fs";
10810
- import { join as join27, dirname as dirname9 } from "node:path";
11093
+ import { join as join28, dirname as dirname9 } from "node:path";
10811
11094
  import { fileURLToPath as fileURLToPath5 } from "node:url";
10812
11095
  function findScrapeScript() {
10813
11096
  const candidates = [
10814
11097
  // Published npm package: dist/scripts/web_scrape.py
10815
- join27(__dirname3, "scripts", "web_scrape.py"),
11098
+ join28(__dirname3, "scripts", "web_scrape.py"),
10816
11099
  // Published npm package (from node_modules): node_modules/open-agents-ai/dist/scripts/
10817
- join27(__dirname3, "..", "node_modules", "open-agents-ai", "dist", "scripts", "web_scrape.py"),
11100
+ join28(__dirname3, "..", "node_modules", "open-agents-ai", "dist", "scripts", "web_scrape.py"),
10818
11101
  // Dev monorepo: packages/execution/src/tools/../../scripts/
10819
- join27(__dirname3, "..", "..", "scripts", "web_scrape.py"),
11102
+ join28(__dirname3, "..", "..", "scripts", "web_scrape.py"),
10820
11103
  // Dev monorepo alt: packages/execution/scripts/
10821
- join27(__dirname3, "..", "scripts", "web_scrape.py")
11104
+ join28(__dirname3, "..", "scripts", "web_scrape.py")
10822
11105
  ];
10823
11106
  return candidates.find((p) => existsSync19(p)) || candidates[0];
10824
11107
  }
@@ -11073,7 +11356,7 @@ var init_browser_action = __esm({
11073
11356
  // packages/execution/dist/tools/autoresearch.js
11074
11357
  import { execSync as execSync17, spawn as spawn9 } from "node:child_process";
11075
11358
  import { existsSync as existsSync20, readFileSync as readFileSync15, writeFileSync as writeFileSync6, mkdirSync as mkdirSync6, appendFileSync, copyFileSync } from "node:fs";
11076
- import { join as join28, resolve as resolve20, dirname as dirname10 } from "node:path";
11359
+ import { join as join29, resolve as resolve20, dirname as dirname10 } from "node:path";
11077
11360
  import { fileURLToPath as fileURLToPath6 } from "node:url";
11078
11361
  function findAutoresearchScript(scriptName) {
11079
11362
  const thisDir = dirname10(fileURLToPath6(import.meta.url));
@@ -11175,7 +11458,7 @@ Requires: NVIDIA GPU, Python 3.10+, uv (astral.sh package manager).`;
11175
11458
  async execute(args) {
11176
11459
  const start = Date.now();
11177
11460
  const action = String(args["action"] ?? "status");
11178
- const workspacePath = String(args["workspace"] ?? join28(this.repoRoot, ".oa", "autoresearch"));
11461
+ const workspacePath = String(args["workspace"] ?? join29(this.repoRoot, ".oa", "autoresearch"));
11179
11462
  try {
11180
11463
  switch (action) {
11181
11464
  case "setup":
@@ -11216,13 +11499,13 @@ Requires: NVIDIA GPU, Python 3.10+, uv (astral.sh package manager).`;
11216
11499
  const prepareScript = findAutoresearchScript("autoresearch-prepare.py");
11217
11500
  const trainScript = findAutoresearchScript("autoresearch-train.py");
11218
11501
  if (prepareScript) {
11219
- copyFileSync(prepareScript, join28(workspace, "prepare.py"));
11502
+ copyFileSync(prepareScript, join29(workspace, "prepare.py"));
11220
11503
  output.push("Copied prepare.py template");
11221
11504
  } else {
11222
11505
  return { success: false, output: output.join("\n"), error: "autoresearch-prepare.py template not found in distribution", durationMs: Date.now() - start };
11223
11506
  }
11224
11507
  if (trainScript) {
11225
- copyFileSync(trainScript, join28(workspace, "train.py"));
11508
+ copyFileSync(trainScript, join29(workspace, "train.py"));
11226
11509
  output.push("Copied train.py template");
11227
11510
  } else {
11228
11511
  return { success: false, output: output.join("\n"), error: "autoresearch-train.py template not found in distribution", durationMs: Date.now() - start };
@@ -11254,7 +11537,7 @@ name = "pytorch-cu128"
11254
11537
  url = "https://download.pytorch.org/whl/cu128"
11255
11538
  explicit = true
11256
11539
  `;
11257
- writeFileSync6(join28(workspace, "pyproject.toml"), pyprojectContent, "utf-8");
11540
+ writeFileSync6(join29(workspace, "pyproject.toml"), pyprojectContent, "utf-8");
11258
11541
  output.push("Created pyproject.toml");
11259
11542
  try {
11260
11543
  execSync17("git rev-parse --git-dir", { cwd: workspace, encoding: "utf-8", timeout: 5e3 });
@@ -11296,7 +11579,7 @@ explicit = true
11296
11579
  const e = err;
11297
11580
  output.push(`Data prep warning: ${(e.stderr ?? e.stdout ?? "failed").slice(0, 500)}`);
11298
11581
  }
11299
- const tsvPath = join28(workspace, "results.tsv");
11582
+ const tsvPath = join29(workspace, "results.tsv");
11300
11583
  if (!existsSync20(tsvPath)) {
11301
11584
  writeFileSync6(tsvPath, "commit val_bpb memory_gb status description\n", "utf-8");
11302
11585
  output.push("Created results.tsv");
@@ -11318,10 +11601,10 @@ Next steps:
11318
11601
  }
11319
11602
  // ── Run experiment ─────────────────────────────────────────────────────
11320
11603
  async run(workspace, args, start) {
11321
- if (!existsSync20(join28(workspace, "train.py"))) {
11604
+ if (!existsSync20(join29(workspace, "train.py"))) {
11322
11605
  return { success: false, output: "", error: `No train.py found in ${workspace}. Run autoresearch(action="setup") first.`, durationMs: Date.now() - start };
11323
11606
  }
11324
- if (!existsSync20(join28(workspace, ".venv")) && existsSync20(join28(workspace, "pyproject.toml"))) {
11607
+ if (!existsSync20(join29(workspace, ".venv")) && existsSync20(join29(workspace, "pyproject.toml"))) {
11325
11608
  try {
11326
11609
  execSync17("uv sync 2>&1", { cwd: workspace, encoding: "utf-8", timeout: 3e5 });
11327
11610
  } catch {
@@ -11329,7 +11612,7 @@ Next steps:
11329
11612
  }
11330
11613
  const timeoutMin = Number(args["timeout_minutes"] ?? 10);
11331
11614
  const timeoutMs = timeoutMin * 60 * 1e3;
11332
- const logPath = join28(workspace, "run.log");
11615
+ const logPath = join29(workspace, "run.log");
11333
11616
  return new Promise((resolveResult) => {
11334
11617
  const proc = spawn9("uv", ["run", "train.py"], {
11335
11618
  cwd: workspace,
@@ -11400,7 +11683,7 @@ ${fullLog.slice(-2e3)}`,
11400
11683
  return;
11401
11684
  }
11402
11685
  try {
11403
- writeFileSync6(join28(workspace, ".last-result.json"), JSON.stringify(result, null, 2), "utf-8");
11686
+ writeFileSync6(join29(workspace, ".last-result.json"), JSON.stringify(result, null, 2), "utf-8");
11404
11687
  } catch {
11405
11688
  }
11406
11689
  const memGB = (result.peak_vram_mb / 1024).toFixed(1);
@@ -11436,7 +11719,7 @@ ${fullLog.slice(-2e3)}`,
11436
11719
  }
11437
11720
  // ── Results ────────────────────────────────────────────────────────────
11438
11721
  getResults(workspace, start) {
11439
- const tsvPath = join28(workspace, "results.tsv");
11722
+ const tsvPath = join29(workspace, "results.tsv");
11440
11723
  if (!existsSync20(tsvPath)) {
11441
11724
  return { success: false, output: "", error: `No results.tsv found. Run autoresearch(action="setup") first.`, durationMs: Date.now() - start };
11442
11725
  }
@@ -11463,7 +11746,7 @@ ${fullLog.slice(-2e3)}`,
11463
11746
  // ── Status ─────────────────────────────────────────────────────────────
11464
11747
  getStatus(workspace, start) {
11465
11748
  const output = [];
11466
- if (!existsSync20(join28(workspace, "train.py"))) {
11749
+ if (!existsSync20(join29(workspace, "train.py"))) {
11467
11750
  return {
11468
11751
  success: true,
11469
11752
  output: `Autoresearch workspace not initialized at ${workspace}.
@@ -11486,7 +11769,7 @@ Run autoresearch(action="setup") to begin.`,
11486
11769
  } catch {
11487
11770
  output.push("GPU: not detected");
11488
11771
  }
11489
- const lastResultPath = join28(workspace, ".last-result.json");
11772
+ const lastResultPath = join29(workspace, ".last-result.json");
11490
11773
  if (existsSync20(lastResultPath)) {
11491
11774
  try {
11492
11775
  const last = JSON.parse(readFileSync15(lastResultPath, "utf-8"));
@@ -11494,20 +11777,20 @@ Run autoresearch(action="setup") to begin.`,
11494
11777
  } catch {
11495
11778
  }
11496
11779
  }
11497
- const tsvPath = join28(workspace, "results.tsv");
11780
+ const tsvPath = join29(workspace, "results.tsv");
11498
11781
  if (existsSync20(tsvPath)) {
11499
11782
  const lines = readFileSync15(tsvPath, "utf-8").trim().split("\n");
11500
11783
  output.push(`Experiments recorded: ${lines.length - 1}`);
11501
11784
  }
11502
- const cacheDir = join28(process.env["HOME"] ?? "~", ".cache", "autoresearch");
11785
+ const cacheDir = join29(process.env["HOME"] ?? "~", ".cache", "autoresearch");
11503
11786
  output.push(`Data cache: ${existsSync20(cacheDir) ? "present" : "not found"} (${cacheDir})`);
11504
11787
  return { success: true, output: output.join("\n"), durationMs: Date.now() - start };
11505
11788
  }
11506
11789
  // ── Keep / Discard ─────────────────────────────────────────────────────
11507
11790
  keepExperiment(workspace, args, start) {
11508
11791
  const desc = String(args["description"] ?? "experiment");
11509
- const tsvPath = join28(workspace, "results.tsv");
11510
- const lastResultPath = join28(workspace, ".last-result.json");
11792
+ const tsvPath = join29(workspace, "results.tsv");
11793
+ const lastResultPath = join29(workspace, ".last-result.json");
11511
11794
  let valBpb = args["val_bpb"];
11512
11795
  let memGb = args["memory_gb"];
11513
11796
  if ((valBpb === void 0 || memGb === void 0) && existsSync20(lastResultPath)) {
@@ -11545,8 +11828,8 @@ Branch advanced. Ready for next experiment.`,
11545
11828
  }
11546
11829
  discardExperiment(workspace, args, start) {
11547
11830
  const desc = String(args["description"] ?? "experiment");
11548
- const tsvPath = join28(workspace, "results.tsv");
11549
- const lastResultPath = join28(workspace, ".last-result.json");
11831
+ const tsvPath = join29(workspace, "results.tsv");
11832
+ const lastResultPath = join29(workspace, ".last-result.json");
11550
11833
  let valBpb = args["val_bpb"];
11551
11834
  let memGb = args["memory_gb"];
11552
11835
  if ((valBpb === void 0 || memGb === void 0) && existsSync20(lastResultPath)) {
@@ -11592,8 +11875,8 @@ train.py reverted to last kept state. Ready for next experiment.`,
11592
11875
 
11593
11876
  // packages/execution/dist/tools/scheduler.js
11594
11877
  import { execSync as execSync18, exec as execCb } from "node:child_process";
11595
- import { readFile as readFile13, writeFile as writeFile12, mkdir as mkdir8 } from "node:fs/promises";
11596
- import { resolve as resolve21, join as join29 } from "node:path";
11878
+ import { readFile as readFile14, writeFile as writeFile13, mkdir as mkdir9 } from "node:fs/promises";
11879
+ import { resolve as resolve21, join as join30 } from "node:path";
11597
11880
  import { randomBytes as randomBytes3 } from "node:crypto";
11598
11881
  function isValidCron(expr) {
11599
11882
  const parts = expr.trim().split(/\s+/);
@@ -11677,7 +11960,7 @@ function installCronJob(task, workingDir) {
11677
11960
  const lines = getCurrentCrontab();
11678
11961
  const oaBin = findOaBinary();
11679
11962
  const logDir = resolve21(workingDir, ".oa", "scheduled", "logs");
11680
- const logFile = join29(logDir, `${task.id}.log`);
11963
+ const logFile = join30(logDir, `${task.id}.log`);
11681
11964
  const storeFile = resolve21(workingDir, ".oa", "scheduled", "tasks.json");
11682
11965
  const taskEscaped = task.task.replace(/'/g, "'\\''");
11683
11966
  const taskId = task.id;
@@ -11710,7 +11993,7 @@ function listCronJobs() {
11710
11993
  async function loadStore(workingDir) {
11711
11994
  const storePath = resolve21(workingDir, ".oa", "scheduled", "tasks.json");
11712
11995
  try {
11713
- const raw = await readFile13(storePath, "utf-8");
11996
+ const raw = await readFile14(storePath, "utf-8");
11714
11997
  return JSON.parse(raw);
11715
11998
  } catch {
11716
11999
  return { tasks: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
@@ -11718,10 +12001,10 @@ async function loadStore(workingDir) {
11718
12001
  }
11719
12002
  async function saveStore(workingDir, store) {
11720
12003
  const dir = resolve21(workingDir, ".oa", "scheduled");
11721
- await mkdir8(dir, { recursive: true });
11722
- await mkdir8(join29(dir, "logs"), { recursive: true });
12004
+ await mkdir9(dir, { recursive: true });
12005
+ await mkdir9(join30(dir, "logs"), { recursive: true });
11723
12006
  store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
11724
- await writeFile12(join29(dir, "tasks.json"), JSON.stringify(store, null, 2), "utf-8");
12007
+ await writeFile13(join30(dir, "tasks.json"), JSON.stringify(store, null, 2), "utf-8");
11725
12008
  }
11726
12009
  var SCHEDULE_PRESETS, CRON_MARKER, SchedulerTool;
11727
12010
  var init_scheduler = __esm({
@@ -11941,7 +12224,7 @@ var init_scheduler = __esm({
11941
12224
  return { success: false, output: "", error: "id is required for logs action", durationMs: performance.now() - start };
11942
12225
  const logFile = resolve21(this.workingDir, ".oa", "scheduled", "logs", `${id}.log`);
11943
12226
  try {
11944
- const raw = await readFile13(logFile, "utf-8");
12227
+ const raw = await readFile14(logFile, "utf-8");
11945
12228
  const truncated = raw.length > 1e4 ? "...(truncated)\n" + raw.slice(-1e4) : raw;
11946
12229
  return { success: true, output: `Logs for ${id}:
11947
12230
  ${truncated}`, durationMs: performance.now() - start };
@@ -11954,8 +12237,8 @@ ${truncated}`, durationMs: performance.now() - start };
11954
12237
  });
11955
12238
 
11956
12239
  // packages/execution/dist/tools/reminder.js
11957
- import { readFile as readFile14, writeFile as writeFile13, mkdir as mkdir9 } from "node:fs/promises";
11958
- import { resolve as resolve22, join as join30 } from "node:path";
12240
+ import { readFile as readFile15, writeFile as writeFile14, mkdir as mkdir10 } from "node:fs/promises";
12241
+ import { resolve as resolve22, join as join31 } from "node:path";
11959
12242
  import { randomBytes as randomBytes4 } from "node:crypto";
11960
12243
  function parseDueTime(due) {
11961
12244
  const lower = due.toLowerCase().trim();
@@ -12006,13 +12289,13 @@ function parseDueTime(due) {
12006
12289
  }
12007
12290
  async function getStorePath(workingDir) {
12008
12291
  const dir = resolve22(workingDir, ".oa", "scheduled");
12009
- await mkdir9(dir, { recursive: true });
12010
- return join30(dir, STORE_FILE);
12292
+ await mkdir10(dir, { recursive: true });
12293
+ return join31(dir, STORE_FILE);
12011
12294
  }
12012
12295
  async function loadReminderStore(workingDir) {
12013
12296
  const storePath = await getStorePath(workingDir);
12014
12297
  try {
12015
- const raw = await readFile14(storePath, "utf-8");
12298
+ const raw = await readFile15(storePath, "utf-8");
12016
12299
  return JSON.parse(raw);
12017
12300
  } catch {
12018
12301
  return { reminders: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
@@ -12021,7 +12304,7 @@ async function loadReminderStore(workingDir) {
12021
12304
  async function saveReminderStore(workingDir, store) {
12022
12305
  const storePath = await getStorePath(workingDir);
12023
12306
  store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
12024
- await writeFile13(storePath, JSON.stringify(store, null, 2), "utf-8");
12307
+ await writeFile14(storePath, JSON.stringify(store, null, 2), "utf-8");
12025
12308
  }
12026
12309
  async function getDueReminders(workingDir) {
12027
12310
  const store = await loadReminderStore(workingDir);
@@ -12267,13 +12550,13 @@ var init_reminder = __esm({
12267
12550
  });
12268
12551
 
12269
12552
  // packages/execution/dist/tools/agenda.js
12270
- import { readFile as readFile15, writeFile as writeFile14, mkdir as mkdir10 } from "node:fs/promises";
12271
- import { resolve as resolve23, join as join31 } from "node:path";
12553
+ import { readFile as readFile16, writeFile as writeFile15, mkdir as mkdir11 } from "node:fs/promises";
12554
+ import { resolve as resolve23, join as join32 } from "node:path";
12272
12555
  import { randomBytes as randomBytes5 } from "node:crypto";
12273
12556
  async function loadAttentionStore(workingDir) {
12274
12557
  const storePath = resolve23(workingDir, ".oa", "scheduled", "attention.json");
12275
12558
  try {
12276
- const raw = await readFile15(storePath, "utf-8");
12559
+ const raw = await readFile16(storePath, "utf-8");
12277
12560
  return JSON.parse(raw);
12278
12561
  } catch {
12279
12562
  return { items: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
@@ -12281,9 +12564,9 @@ async function loadAttentionStore(workingDir) {
12281
12564
  }
12282
12565
  async function saveAttentionStore(workingDir, store) {
12283
12566
  const dir = resolve23(workingDir, ".oa", "scheduled");
12284
- await mkdir10(dir, { recursive: true });
12567
+ await mkdir11(dir, { recursive: true });
12285
12568
  store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
12286
- await writeFile14(join31(dir, "attention.json"), JSON.stringify(store, null, 2), "utf-8");
12569
+ await writeFile15(join32(dir, "attention.json"), JSON.stringify(store, null, 2), "utf-8");
12287
12570
  }
12288
12571
  async function getActiveAttentionItems(workingDir) {
12289
12572
  const store = await loadAttentionStore(workingDir);
@@ -12579,7 +12862,7 @@ ${sections.join("\n")}`,
12579
12862
  async loadScheduleStore() {
12580
12863
  try {
12581
12864
  const storePath = resolve23(this.workingDir, ".oa", "scheduled", "tasks.json");
12582
- const raw = await readFile15(storePath, "utf-8");
12865
+ const raw = await readFile16(storePath, "utf-8");
12583
12866
  const store = JSON.parse(raw);
12584
12867
  return store.tasks ?? [];
12585
12868
  } catch {
@@ -12593,7 +12876,7 @@ ${sections.join("\n")}`,
12593
12876
  // packages/execution/dist/tools/opencode.js
12594
12877
  import { execSync as execSync19, spawn as spawn10 } from "node:child_process";
12595
12878
  import { existsSync as existsSync21 } from "node:fs";
12596
- import { join as join32, resolve as resolve24 } from "node:path";
12879
+ import { join as join33, resolve as resolve24 } from "node:path";
12597
12880
  function findOpencode() {
12598
12881
  for (const cmd of ["opencode"]) {
12599
12882
  try {
@@ -12605,8 +12888,8 @@ function findOpencode() {
12605
12888
  }
12606
12889
  const homeDir = process.env.HOME || process.env.USERPROFILE || "";
12607
12890
  const candidates = [
12608
- join32(homeDir, ".opencode", "bin", "opencode"),
12609
- join32(homeDir, "bin", "opencode"),
12891
+ join33(homeDir, ".opencode", "bin", "opencode"),
12892
+ join33(homeDir, "bin", "opencode"),
12610
12893
  "/usr/local/bin/opencode"
12611
12894
  ];
12612
12895
  for (const p of candidates) {
@@ -12867,7 +13150,7 @@ var init_opencode = __esm({
12867
13150
  // packages/execution/dist/tools/factory.js
12868
13151
  import { execSync as execSync20, spawn as spawn11 } from "node:child_process";
12869
13152
  import { existsSync as existsSync22 } from "node:fs";
12870
- import { join as join33 } from "node:path";
13153
+ import { join as join34 } from "node:path";
12871
13154
  function findDroid() {
12872
13155
  for (const cmd of ["droid"]) {
12873
13156
  try {
@@ -12879,8 +13162,8 @@ function findDroid() {
12879
13162
  }
12880
13163
  const homeDir = process.env.HOME || process.env.USERPROFILE || "";
12881
13164
  const candidates = [
12882
- join33(homeDir, ".factory", "bin", "droid"),
12883
- join33(homeDir, "bin", "droid"),
13165
+ join34(homeDir, ".factory", "bin", "droid"),
13166
+ join34(homeDir, "bin", "droid"),
12884
13167
  "/usr/local/bin/droid"
12885
13168
  ];
12886
13169
  for (const p of candidates) {
@@ -13175,8 +13458,8 @@ var init_factory = __esm({
13175
13458
 
13176
13459
  // packages/execution/dist/tools/cron-agent.js
13177
13460
  import { execSync as execSync21 } from "node:child_process";
13178
- import { readFile as readFile16, writeFile as writeFile15, mkdir as mkdir11 } from "node:fs/promises";
13179
- import { resolve as resolve25, join as join34 } from "node:path";
13461
+ import { readFile as readFile17, writeFile as writeFile16, mkdir as mkdir12 } from "node:fs/promises";
13462
+ import { resolve as resolve25, join as join35 } from "node:path";
13180
13463
  import { randomBytes as randomBytes6 } from "node:crypto";
13181
13464
  function isValidCron2(expr) {
13182
13465
  const parts = expr.trim().split(/\s+/);
@@ -13262,7 +13545,7 @@ function installCronAgentJob(job, workingDir) {
13262
13545
  const lines = getCurrentCrontab2();
13263
13546
  const oaBin = findOaBinary2();
13264
13547
  const logDir = resolve25(workingDir, ".oa", "cron-agents", "logs");
13265
- const logFile = join34(logDir, `${job.id}.log`);
13548
+ const logFile = join35(logDir, `${job.id}.log`);
13266
13549
  const storeFile = resolve25(workingDir, ".oa", "cron-agents", "store.json");
13267
13550
  const taskEscaped = job.task.replace(/'/g, "'\\''");
13268
13551
  const jobId = job.id;
@@ -13292,7 +13575,7 @@ function removeCronAgentJob(jobId) {
13292
13575
  async function loadStore2(workingDir) {
13293
13576
  const storePath = resolve25(workingDir, ".oa", "cron-agents", "store.json");
13294
13577
  try {
13295
- const raw = await readFile16(storePath, "utf-8");
13578
+ const raw = await readFile17(storePath, "utf-8");
13296
13579
  return JSON.parse(raw);
13297
13580
  } catch {
13298
13581
  return { jobs: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
@@ -13300,10 +13583,10 @@ async function loadStore2(workingDir) {
13300
13583
  }
13301
13584
  async function saveStore2(workingDir, store) {
13302
13585
  const dir = resolve25(workingDir, ".oa", "cron-agents");
13303
- await mkdir11(dir, { recursive: true });
13304
- await mkdir11(join34(dir, "logs"), { recursive: true });
13586
+ await mkdir12(dir, { recursive: true });
13587
+ await mkdir12(join35(dir, "logs"), { recursive: true });
13305
13588
  store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
13306
- await writeFile15(join34(dir, "store.json"), JSON.stringify(store, null, 2), "utf-8");
13589
+ await writeFile16(join35(dir, "store.json"), JSON.stringify(store, null, 2), "utf-8");
13307
13590
  }
13308
13591
  var LONG_HORIZON_PRESETS, CRON_AGENT_MARKER, CronAgentTool;
13309
13592
  var init_cron_agent = __esm({
@@ -13568,7 +13851,7 @@ var init_cron_agent = __esm({
13568
13851
  return { success: false, output: "", error: "id is required", durationMs: performance.now() - start };
13569
13852
  const logFile = resolve25(this.workingDir, ".oa", "cron-agents", "logs", `${id}.log`);
13570
13853
  try {
13571
- const raw = await readFile16(logFile, "utf-8");
13854
+ const raw = await readFile17(logFile, "utf-8");
13572
13855
  const truncated = raw.length > 2e4 ? "...(truncated)\n" + raw.slice(-2e4) : raw;
13573
13856
  return { success: true, output: `Logs for ${id}:
13574
13857
  ${truncated}`, durationMs: performance.now() - start };
@@ -13639,9 +13922,9 @@ ${truncated}`, durationMs: performance.now() - start };
13639
13922
  });
13640
13923
 
13641
13924
  // packages/execution/dist/tools/nexus.js
13642
- import { readFile as readFile17, writeFile as writeFile16, mkdir as mkdir12, chmod, unlink, readdir as readdir3, open as fsOpen } from "node:fs/promises";
13925
+ import { readFile as readFile18, writeFile as writeFile17, mkdir as mkdir13, chmod, unlink, readdir as readdir4, open as fsOpen } from "node:fs/promises";
13643
13926
  import { existsSync as existsSync23, readFileSync as readFileSync16, watch as fsWatchLocal } from "node:fs";
13644
- import { resolve as resolve26, join as join35 } from "node:path";
13927
+ import { resolve as resolve26, join as join36 } from "node:path";
13645
13928
  import { randomBytes as randomBytes7, createCipheriv, createDecipheriv, scryptSync, createHash } from "node:crypto";
13646
13929
  import { execSync as execSync22, spawn as spawn12 } from "node:child_process";
13647
13930
  import { hostname, userInfo } from "node:os";
@@ -15615,7 +15898,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15615
15898
  }
15616
15899
  async ensureDir() {
15617
15900
  if (!existsSync23(this.nexusDir)) {
15618
- await mkdir12(this.nexusDir, { recursive: true });
15901
+ await mkdir13(this.nexusDir, { recursive: true });
15619
15902
  }
15620
15903
  }
15621
15904
  async execute(args) {
@@ -15738,7 +16021,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15738
16021
  // Daemon management
15739
16022
  // =========================================================================
15740
16023
  getDaemonPid() {
15741
- const pidFile = join35(this.nexusDir, "daemon.pid");
16024
+ const pidFile = join36(this.nexusDir, "daemon.pid");
15742
16025
  if (!existsSync23(pidFile))
15743
16026
  return null;
15744
16027
  try {
@@ -15764,12 +16047,12 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15764
16047
  throw new Error("Nexus daemon not running. Use action 'connect' first.");
15765
16048
  }
15766
16049
  const cmdId = randomBytes7(8).toString("hex");
15767
- const cmdFile = join35(this.nexusDir, "cmd.json");
15768
- const respFile = join35(this.nexusDir, "resp.json");
16050
+ const cmdFile = join36(this.nexusDir, "cmd.json");
16051
+ const respFile = join36(this.nexusDir, "resp.json");
15769
16052
  if (existsSync23(respFile))
15770
16053
  await unlink(respFile).catch(() => {
15771
16054
  });
15772
- await writeFile16(cmdFile, JSON.stringify({ id: cmdId, action, args }, null, 2));
16055
+ await writeFile17(cmdFile, JSON.stringify({ id: cmdId, action, args }, null, 2));
15773
16056
  const pollMs = 50;
15774
16057
  const polls = Math.ceil(timeoutMs / pollMs);
15775
16058
  let resolved = false;
@@ -15801,7 +16084,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15801
16084
  if (!existsSync23(respFile))
15802
16085
  continue;
15803
16086
  try {
15804
- const resp = JSON.parse(await readFile17(respFile, "utf8"));
16087
+ const resp = JSON.parse(await readFile18(respFile, "utf8"));
15805
16088
  if (resp.id === cmdId) {
15806
16089
  resolved = true;
15807
16090
  return resp.output || (resp.ok ? "OK" : "Failed");
@@ -15824,7 +16107,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15824
16107
  }
15825
16108
  if (existsSync23(respFile)) {
15826
16109
  try {
15827
- const resp = JSON.parse(await readFile17(respFile, "utf8"));
16110
+ const resp = JSON.parse(await readFile18(respFile, "utf8"));
15828
16111
  if (resp.id === cmdId) {
15829
16112
  return resp.output || (resp.ok ? "OK" : "Failed");
15830
16113
  }
@@ -15849,7 +16132,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15849
16132
  const currentScriptHash = createHash("sha256").update(DAEMON_SCRIPT).digest("hex").slice(0, 16);
15850
16133
  const existingPid = this.getDaemonPid();
15851
16134
  if (existingPid) {
15852
- const daemonPath2 = join35(this.nexusDir, "nexus-daemon.mjs");
16135
+ const daemonPath2 = join36(this.nexusDir, "nexus-daemon.mjs");
15853
16136
  let needsRestart = true;
15854
16137
  if (existsSync23(daemonPath2)) {
15855
16138
  try {
@@ -15873,16 +16156,16 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15873
16156
  } catch {
15874
16157
  }
15875
16158
  for (const f of ["daemon.pid", "status.json", "cmd.json", "resp.json"]) {
15876
- const p = join35(this.nexusDir, f);
16159
+ const p = join36(this.nexusDir, f);
15877
16160
  if (existsSync23(p))
15878
16161
  await unlink(p).catch(() => {
15879
16162
  });
15880
16163
  }
15881
16164
  } else {
15882
- const statusFile2 = join35(this.nexusDir, "status.json");
16165
+ const statusFile2 = join36(this.nexusDir, "status.json");
15883
16166
  if (existsSync23(statusFile2)) {
15884
16167
  try {
15885
- const status = JSON.parse(await readFile17(statusFile2, "utf8"));
16168
+ const status = JSON.parse(await readFile18(statusFile2, "utf8"));
15886
16169
  if (status.connected && status.peerId) {
15887
16170
  await this.ensureWallet();
15888
16171
  return `Already connected (pid: ${existingPid}, peerId: ${status.peerId})`;
@@ -15898,7 +16181,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15898
16181
  }
15899
16182
  }
15900
16183
  for (const f of ["daemon.pid", "status.json", "cmd.json", "resp.json"]) {
15901
- const p = join35(this.nexusDir, f);
16184
+ const p = join36(this.nexusDir, f);
15902
16185
  if (existsSync23(p))
15903
16186
  await unlink(p).catch(() => {
15904
16187
  });
@@ -15916,7 +16199,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15916
16199
  });
15917
16200
  });
15918
16201
  try {
15919
- const nexusPkg = join35(nodeModulesDir, "open-agents-nexus", "package.json");
16202
+ const nexusPkg = join36(nodeModulesDir, "open-agents-nexus", "package.json");
15920
16203
  if (existsSync23(nexusPkg)) {
15921
16204
  nexusResolved = true;
15922
16205
  try {
@@ -15927,7 +16210,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15927
16210
  } else {
15928
16211
  try {
15929
16212
  const globalDir = await execAsync2("npm root -g", { timeout: 5e3 });
15930
- const globalPkg = join35(globalDir, "open-agents-nexus", "package.json");
16213
+ const globalPkg = join36(globalDir, "open-agents-nexus", "package.json");
15931
16214
  if (existsSync23(globalPkg)) {
15932
16215
  nexusResolved = true;
15933
16216
  try {
@@ -15972,8 +16255,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15972
16255
  }
15973
16256
  }
15974
16257
  await this.ensureWallet();
15975
- const daemonPath = join35(this.nexusDir, "nexus-daemon.mjs");
15976
- await writeFile16(daemonPath, DAEMON_SCRIPT);
16258
+ const daemonPath = join36(this.nexusDir, "nexus-daemon.mjs");
16259
+ await writeFile17(daemonPath, DAEMON_SCRIPT);
15977
16260
  const agentName = args.agent_name || "open-agents-node";
15978
16261
  const agentType = args.agent_type || "general";
15979
16262
  const nodePaths = [nodeModulesDir];
@@ -15983,8 +16266,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15983
16266
  } catch {
15984
16267
  }
15985
16268
  const { openSync: openSync2, closeSync: closeSync2 } = await import("node:fs");
15986
- const daemonLogPath = join35(this.nexusDir, "daemon.log");
15987
- const daemonErrPath = join35(this.nexusDir, "daemon.err");
16269
+ const daemonLogPath = join36(this.nexusDir, "daemon.log");
16270
+ const daemonErrPath = join36(this.nexusDir, "daemon.err");
15988
16271
  const outFd = openSync2(daemonLogPath, "w");
15989
16272
  const errFd = openSync2(daemonErrPath, "w");
15990
16273
  const child = spawn12("node", [daemonPath, this.nexusDir, agentName, agentType], {
@@ -16002,16 +16285,16 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16002
16285
  closeSync2(errFd);
16003
16286
  } catch {
16004
16287
  }
16005
- const statusFile = join35(this.nexusDir, "status.json");
16288
+ const statusFile = join36(this.nexusDir, "status.json");
16006
16289
  for (let i = 0; i < 40; i++) {
16007
16290
  await new Promise((r) => setTimeout(r, 500));
16008
16291
  if (existsSync23(statusFile)) {
16009
16292
  try {
16010
- const status = JSON.parse(await readFile17(statusFile, "utf8"));
16293
+ const status = JSON.parse(await readFile18(statusFile, "utf8"));
16011
16294
  if (status.error) {
16012
16295
  let errTail = "";
16013
16296
  try {
16014
- errTail = (await readFile17(daemonErrPath, "utf8")).slice(-300);
16297
+ errTail = (await readFile18(daemonErrPath, "utf8")).slice(-300);
16015
16298
  } catch {
16016
16299
  }
16017
16300
  return `Nexus daemon failed to connect: ${status.error}${errTail ? "\n" + errTail : ""}`;
@@ -16033,12 +16316,12 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16033
16316
  const pid = this.getDaemonPid();
16034
16317
  let earlyError = "";
16035
16318
  try {
16036
- earlyError = (await readFile17(daemonErrPath, "utf8")).slice(-500);
16319
+ earlyError = (await readFile18(daemonErrPath, "utf8")).slice(-500);
16037
16320
  } catch {
16038
16321
  }
16039
16322
  let earlyOutput = "";
16040
16323
  try {
16041
- earlyOutput = (await readFile17(daemonLogPath, "utf8")).slice(-500);
16324
+ earlyOutput = (await readFile18(daemonLogPath, "utf8")).slice(-500);
16042
16325
  } catch {
16043
16326
  }
16044
16327
  if (pid) {
@@ -16061,7 +16344,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16061
16344
  } catch {
16062
16345
  }
16063
16346
  for (const f of ["daemon.pid", "status.json", "cmd.json", "resp.json"]) {
16064
- const p = join35(this.nexusDir, f);
16347
+ const p = join36(this.nexusDir, f);
16065
16348
  if (existsSync23(p))
16066
16349
  await unlink(p).catch(() => {
16067
16350
  });
@@ -16072,11 +16355,11 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16072
16355
  const pid = this.getDaemonPid();
16073
16356
  if (!pid)
16074
16357
  return "Nexus daemon not running. Use action 'connect' to start.";
16075
- const statusFile = join35(this.nexusDir, "status.json");
16358
+ const statusFile = join36(this.nexusDir, "status.json");
16076
16359
  if (!existsSync23(statusFile))
16077
16360
  return `Daemon running (pid: ${pid}) but no status yet.`;
16078
16361
  try {
16079
- const status = JSON.parse(await readFile17(statusFile, "utf8"));
16362
+ const status = JSON.parse(await readFile18(statusFile, "utf8"));
16080
16363
  const lines = [
16081
16364
  `Nexus Status (v1.5.0)`,
16082
16365
  ` Connected: ${status.connected}`,
@@ -16087,10 +16370,10 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16087
16370
  ` Capabilities: ${(status.capabilities || []).length ? (status.capabilities || []).join(", ") : "none"}`,
16088
16371
  ` Blocked peers: ${(status.blockedPeers || []).length || 0}`
16089
16372
  ];
16090
- const walletPath = join35(this.nexusDir, "wallet.enc");
16373
+ const walletPath = join36(this.nexusDir, "wallet.enc");
16091
16374
  if (existsSync23(walletPath)) {
16092
16375
  try {
16093
- const w = JSON.parse(await readFile17(walletPath, "utf8"));
16376
+ const w = JSON.parse(await readFile18(walletPath, "utf8"));
16094
16377
  lines.push(` Wallet: ${w.address}`);
16095
16378
  } catch {
16096
16379
  lines.push(` Wallet: corrupt`);
@@ -16098,14 +16381,14 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16098
16381
  } else {
16099
16382
  lines.push(` Wallet: not configured`);
16100
16383
  }
16101
- const inboxDir = join35(this.nexusDir, "inbox");
16384
+ const inboxDir = join36(this.nexusDir, "inbox");
16102
16385
  if (existsSync23(inboxDir)) {
16103
16386
  try {
16104
- const roomDirs = await readdir3(inboxDir);
16387
+ const roomDirs = await readdir4(inboxDir);
16105
16388
  let totalMsgs = 0;
16106
16389
  for (const rd of roomDirs) {
16107
16390
  try {
16108
- totalMsgs += (await readdir3(join35(inboxDir, rd))).length;
16391
+ totalMsgs += (await readdir4(join36(inboxDir, rd))).length;
16109
16392
  } catch {
16110
16393
  }
16111
16394
  }
@@ -16152,18 +16435,18 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16152
16435
  }
16153
16436
  async doReadMessages(args) {
16154
16437
  const roomId = args.room_id;
16155
- const inboxDir = join35(this.nexusDir, "inbox");
16438
+ const inboxDir = join36(this.nexusDir, "inbox");
16156
16439
  if (roomId) {
16157
- const roomInbox = join35(inboxDir, roomId);
16440
+ const roomInbox = join36(inboxDir, roomId);
16158
16441
  if (!existsSync23(roomInbox))
16159
16442
  return `No messages in room: ${roomId}`;
16160
- const files = (await readdir3(roomInbox)).sort().slice(-20);
16443
+ const files = (await readdir4(roomInbox)).sort().slice(-20);
16161
16444
  if (files.length === 0)
16162
16445
  return `No messages in room: ${roomId}`;
16163
16446
  const messages = [`Messages in ${roomId} (last ${files.length}):`];
16164
16447
  for (const f of files) {
16165
16448
  try {
16166
- const msg = JSON.parse(await readFile17(join35(roomInbox, f), "utf8"));
16449
+ const msg = JSON.parse(await readFile18(join36(roomInbox, f), "utf8"));
16167
16450
  const sender = (msg.sender || "unknown").slice(0, 12);
16168
16451
  messages.push(` [${new Date(msg.timestamp).toLocaleTimeString()}] ${sender}...: ${msg.content}`);
16169
16452
  } catch {
@@ -16173,13 +16456,13 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16173
16456
  }
16174
16457
  if (!existsSync23(inboxDir))
16175
16458
  return "No messages received yet.";
16176
- const roomDirs = await readdir3(inboxDir);
16459
+ const roomDirs = await readdir4(inboxDir);
16177
16460
  if (roomDirs.length === 0)
16178
16461
  return "No messages received yet.";
16179
16462
  const lines = ["Inbox:"];
16180
16463
  for (const rd of roomDirs) {
16181
16464
  try {
16182
- const count = (await readdir3(join35(inboxDir, rd))).length;
16465
+ const count = (await readdir4(join36(inboxDir, rd))).length;
16183
16466
  lines.push(` ${rd}: ${count} message(s)`);
16184
16467
  } catch {
16185
16468
  }
@@ -16191,12 +16474,12 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16191
16474
  // ---------------------------------------------------------------------------
16192
16475
  async doWalletStatus() {
16193
16476
  await this.ensureDir();
16194
- const walletPath = join35(this.nexusDir, "wallet.enc");
16477
+ const walletPath = join36(this.nexusDir, "wallet.enc");
16195
16478
  if (!existsSync23(walletPath)) {
16196
16479
  return "No wallet configured. Use wallet_create to set one up.";
16197
16480
  }
16198
16481
  try {
16199
- const w = JSON.parse(await readFile17(walletPath, "utf8"));
16482
+ const w = JSON.parse(await readFile18(walletPath, "utf8"));
16200
16483
  const lines = [
16201
16484
  `Wallet Status:`,
16202
16485
  ` Address: ${w.address}`,
@@ -16230,7 +16513,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16230
16513
  }
16231
16514
  async doWalletCreate(args) {
16232
16515
  await this.ensureDir();
16233
- const walletPath = join35(this.nexusDir, "wallet.enc");
16516
+ const walletPath = join36(this.nexusDir, "wallet.enc");
16234
16517
  if (existsSync23(walletPath))
16235
16518
  return "Wallet already exists. Delete wallet.enc to create a new one.";
16236
16519
  const userAddress = args.wallet_address;
@@ -16276,7 +16559,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16276
16559
  const cipher = createCipheriv("aes-256-gcm", key, iv);
16277
16560
  let enc = cipher.update(privKeyHex, "utf8", "hex");
16278
16561
  enc += cipher.final("hex");
16279
- const x402KeyPath = join35(this.nexusDir, "x402-wallet.key");
16562
+ const x402KeyPath = join36(this.nexusDir, "x402-wallet.key");
16280
16563
  const x402Fh = await fsOpen(x402KeyPath, "w", 384);
16281
16564
  await x402Fh.writeFile("0x" + privKeyHex);
16282
16565
  await x402Fh.close();
@@ -16314,7 +16597,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16314
16597
  * Silent — no user output, just ensures the files exist.
16315
16598
  */
16316
16599
  async ensureWallet() {
16317
- const walletPath = join35(this.nexusDir, "wallet.enc");
16600
+ const walletPath = join36(this.nexusDir, "wallet.enc");
16318
16601
  if (existsSync23(walletPath))
16319
16602
  return;
16320
16603
  let address;
@@ -16338,7 +16621,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16338
16621
  const cipher = createCipheriv("aes-256-gcm", key, iv);
16339
16622
  let enc = cipher.update(privKeyHex, "utf8", "hex");
16340
16623
  enc += cipher.final("hex");
16341
- const x402KeyPath = join35(this.nexusDir, "x402-wallet.key");
16624
+ const x402KeyPath = join36(this.nexusDir, "x402-wallet.key");
16342
16625
  const x402Fh = await fsOpen(x402KeyPath, "w", 384);
16343
16626
  await x402Fh.writeFile("0x" + privKeyHex);
16344
16627
  await x402Fh.close();
@@ -16398,12 +16681,12 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16398
16681
  // ---------------------------------------------------------------------------
16399
16682
  async doLedgerStatus() {
16400
16683
  await this.ensureDir();
16401
- const ledgerPath = join35(this.nexusDir, "ledger.jsonl");
16684
+ const ledgerPath = join36(this.nexusDir, "ledger.jsonl");
16402
16685
  if (!existsSync23(ledgerPath)) {
16403
16686
  return "No ledger entries. Earnings and spending will be tracked here after x402 transactions.";
16404
16687
  }
16405
16688
  try {
16406
- const raw = await readFile17(ledgerPath, "utf8");
16689
+ const raw = await readFile18(ledgerPath, "utf8");
16407
16690
  const entries = raw.trim().split("\n").filter((l) => l.trim()).map((l) => JSON.parse(l));
16408
16691
  if (entries.length === 0) {
16409
16692
  return "Ledger is empty. No transactions recorded.";
@@ -16440,11 +16723,11 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16440
16723
  }
16441
16724
  }
16442
16725
  async getLedgerSummary() {
16443
- const ledgerPath = join35(this.nexusDir, "ledger.jsonl");
16726
+ const ledgerPath = join36(this.nexusDir, "ledger.jsonl");
16444
16727
  if (!existsSync23(ledgerPath))
16445
16728
  return null;
16446
16729
  try {
16447
- const raw = await readFile17(ledgerPath, "utf8");
16730
+ const raw = await readFile18(ledgerPath, "utf8");
16448
16731
  const entries = raw.trim().split("\n").filter((l) => l.trim()).map((l) => JSON.parse(l));
16449
16732
  let totalEarned = 0n, totalSpent = 0n;
16450
16733
  for (const e of entries) {
@@ -16465,25 +16748,25 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16465
16748
  }
16466
16749
  async appendLedger(entry) {
16467
16750
  await this.ensureDir();
16468
- const ledgerPath = join35(this.nexusDir, "ledger.jsonl");
16751
+ const ledgerPath = join36(this.nexusDir, "ledger.jsonl");
16469
16752
  const line = JSON.stringify(entry) + "\n";
16470
- await writeFile16(ledgerPath, existsSync23(ledgerPath) ? await readFile17(ledgerPath, "utf8") + line : line);
16753
+ await writeFile17(ledgerPath, existsSync23(ledgerPath) ? await readFile18(ledgerPath, "utf8") + line : line);
16471
16754
  }
16472
16755
  // ---------------------------------------------------------------------------
16473
16756
  // Step 4: Budget Policy — Spending limits and auto-approve thresholds
16474
16757
  // ---------------------------------------------------------------------------
16475
16758
  async loadBudget() {
16476
- const budgetPath = join35(this.nexusDir, "budget.json");
16759
+ const budgetPath = join36(this.nexusDir, "budget.json");
16477
16760
  if (!existsSync23(budgetPath))
16478
16761
  return null;
16479
16762
  try {
16480
- return JSON.parse(await readFile17(budgetPath, "utf8"));
16763
+ return JSON.parse(await readFile18(budgetPath, "utf8"));
16481
16764
  } catch {
16482
16765
  return null;
16483
16766
  }
16484
16767
  }
16485
16768
  async ensureDefaultBudget() {
16486
- const budgetPath = join35(this.nexusDir, "budget.json");
16769
+ const budgetPath = join36(this.nexusDir, "budget.json");
16487
16770
  if (existsSync23(budgetPath))
16488
16771
  return;
16489
16772
  const defaultBudget = {
@@ -16504,7 +16787,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16504
16787
  deniedPeers: []
16505
16788
  };
16506
16789
  await this.ensureDir();
16507
- await writeFile16(budgetPath, JSON.stringify(defaultBudget, null, 2));
16790
+ await writeFile17(budgetPath, JSON.stringify(defaultBudget, null, 2));
16508
16791
  }
16509
16792
  async doBudgetStatus() {
16510
16793
  await this.ensureDir();
@@ -16553,17 +16836,17 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16553
16836
  if (changes.length === 0) {
16554
16837
  return "No budget parameters provided. Use daily_limit, per_invoke_max, or auto_approve_below.";
16555
16838
  }
16556
- const budgetPath = join35(this.nexusDir, "budget.json");
16557
- await writeFile16(budgetPath, JSON.stringify(budget, null, 2));
16839
+ const budgetPath = join36(this.nexusDir, "budget.json");
16840
+ await writeFile17(budgetPath, JSON.stringify(budget, null, 2));
16558
16841
  return `Budget updated: ${changes.join(", ")}`;
16559
16842
  }
16560
16843
  async getTodaySpending() {
16561
- const ledgerPath = join35(this.nexusDir, "ledger.jsonl");
16844
+ const ledgerPath = join36(this.nexusDir, "ledger.jsonl");
16562
16845
  if (!existsSync23(ledgerPath))
16563
16846
  return 0;
16564
16847
  try {
16565
16848
  const todayPrefix = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
16566
- const raw = await readFile17(ledgerPath, "utf8");
16849
+ const raw = await readFile18(ledgerPath, "utf8");
16567
16850
  let total = 0;
16568
16851
  for (const line of raw.trim().split("\n")) {
16569
16852
  if (!line.trim())
@@ -16602,10 +16885,10 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16602
16885
  if (todaySpent + amountUsdc > budget.dailyLimitUsdc) {
16603
16886
  return { allowed: false, reason: `Would exceed daily limit ($${((todaySpent + amountUsdc) / 1e6).toFixed(6)} > $${(budget.dailyLimitUsdc / 1e6).toFixed(6)})` };
16604
16887
  }
16605
- const walletPath = join35(this.nexusDir, "wallet.enc");
16888
+ const walletPath = join36(this.nexusDir, "wallet.enc");
16606
16889
  if (existsSync23(walletPath)) {
16607
16890
  try {
16608
- const w = JSON.parse(await readFile17(walletPath, "utf8"));
16891
+ const w = JSON.parse(await readFile18(walletPath, "utf8"));
16609
16892
  if (w.version === 2 && w.address) {
16610
16893
  const balance = await this.queryUsdcBalance(w.address, w.chainId || 8453);
16611
16894
  if (balance !== null && Number(balance) < budget.circuitBreakerUsdc) {
@@ -16633,10 +16916,10 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16633
16916
  const budgetResult = await this.checkBudget(amountSmallest, "transfer:direct", targetAddress);
16634
16917
  if (!budgetResult.allowed)
16635
16918
  return `BLOCKED by budget policy: ${budgetResult.reason}`;
16636
- const walletPath = join35(this.nexusDir, "wallet.enc");
16919
+ const walletPath = join36(this.nexusDir, "wallet.enc");
16637
16920
  if (!existsSync23(walletPath))
16638
16921
  throw new Error("No wallet. Use wallet_create first.");
16639
- const w = JSON.parse(await readFile17(walletPath, "utf8"));
16922
+ const w = JSON.parse(await readFile18(walletPath, "utf8"));
16640
16923
  if (!w.encryptedKey)
16641
16924
  throw new Error("User-managed wallet cannot spend (no private key)");
16642
16925
  const salt = Buffer.from(w.salt, "hex");
@@ -16694,7 +16977,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16694
16977
  capability: "transfer:direct",
16695
16978
  note: "signed, awaiting submission"
16696
16979
  });
16697
- const proofFile = join35(this.nexusDir, "pending-transfer.json");
16980
+ const proofFile = join36(this.nexusDir, "pending-transfer.json");
16698
16981
  const proof = {
16699
16982
  from: account.address,
16700
16983
  to: targetAddress,
@@ -16707,7 +16990,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16707
16990
  usdcContract: USDC_ADDRESS,
16708
16991
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
16709
16992
  };
16710
- await writeFile16(proofFile, JSON.stringify(proof, null, 2));
16993
+ await writeFile17(proofFile, JSON.stringify(proof, null, 2));
16711
16994
  return [
16712
16995
  `Transfer signed (EIP-3009 TransferWithAuthorization):`,
16713
16996
  ` From: ${account.address}`,
@@ -16736,10 +17019,10 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16736
17019
  throw new Error("prompt is required");
16737
17020
  const estimatedTokens = Math.ceil(prompt.length / 4) + 1e3;
16738
17021
  let estimatedCostSmallest = 0;
16739
- const pricingPath = join35(this.nexusDir, "pricing.json");
17022
+ const pricingPath = join36(this.nexusDir, "pricing.json");
16740
17023
  if (existsSync23(pricingPath)) {
16741
17024
  try {
16742
- const pricing = JSON.parse(await readFile17(pricingPath, "utf8"));
17025
+ const pricing = JSON.parse(await readFile18(pricingPath, "utf8"));
16743
17026
  const modelPricing = (pricing.models || []).find((m) => m.model === model || m.model.startsWith(model.split(":")[0]));
16744
17027
  if (modelPricing?.pricing?.input_per_1m_tokens > 0) {
16745
17028
  estimatedCostSmallest = Math.ceil(estimatedTokens / 1e6 * modelPricing.pricing.input_per_1m_tokens * 1e6);
@@ -16856,7 +17139,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16856
17139
  const bar = (s) => "\u2588".repeat(Math.round(s / 5)) + "\u2591".repeat(20 - Math.round(s / 5));
16857
17140
  const mem = vramMb > 24e3 ? 95 : vramMb > 16e3 ? 80 : vramMb > 8e3 ? 60 : vramMb > 0 ? 40 : 20;
16858
17141
  await this.ensureDir();
16859
- await writeFile16(join35(this.nexusDir, "inference-proof.json"), JSON.stringify({
17142
+ await writeFile17(join36(this.nexusDir, "inference-proof.json"), JSON.stringify({
16860
17143
  modelName,
16861
17144
  gpuName,
16862
17145
  vramMb,
@@ -17563,6 +17846,7 @@ __export(dist_exports, {
17563
17846
  DesktopClickTool: () => DesktopClickTool,
17564
17847
  DesktopDescribeTool: () => DesktopDescribeTool,
17565
17848
  DiagnosticTool: () => DiagnosticTool,
17849
+ EmbeddingStoreTool: () => EmbeddingStoreTool,
17566
17850
  ExplorationCultureTool: () => ExplorationCultureTool,
17567
17851
  ExploreToolsTool: () => ExploreToolsTool,
17568
17852
  FactoryTool: () => FactoryTool,
@@ -17679,6 +17963,7 @@ var init_dist2 = __esm({
17679
17963
  init_identity_kernel();
17680
17964
  init_reflection_integrity();
17681
17965
  init_exploration_culture();
17966
+ init_embedding_store();
17682
17967
  init_structured_read();
17683
17968
  init_vision();
17684
17969
  init_desktop_click();
@@ -18379,12 +18664,12 @@ var init_dist3 = __esm({
18379
18664
 
18380
18665
  // packages/orchestrator/dist/promptLoader.js
18381
18666
  import { readFileSync as readFileSync18, existsSync as existsSync25 } from "node:fs";
18382
- import { join as join36, dirname as dirname12 } from "node:path";
18667
+ import { join as join37, dirname as dirname12 } from "node:path";
18383
18668
  import { fileURLToPath as fileURLToPath7 } from "node:url";
18384
18669
  function loadPrompt(promptPath, vars) {
18385
18670
  let content = cache.get(promptPath);
18386
18671
  if (content === void 0) {
18387
- const fullPath = join36(PROMPTS_DIR, promptPath);
18672
+ const fullPath = join37(PROMPTS_DIR, promptPath);
18388
18673
  if (!existsSync25(fullPath)) {
18389
18674
  throw new Error(`Prompt file not found: ${fullPath}`);
18390
18675
  }
@@ -18401,7 +18686,7 @@ var init_promptLoader = __esm({
18401
18686
  "use strict";
18402
18687
  __filename = fileURLToPath7(import.meta.url);
18403
18688
  __dirname4 = dirname12(__filename);
18404
- PROMPTS_DIR = join36(__dirname4, "..", "prompts");
18689
+ PROMPTS_DIR = join37(__dirname4, "..", "prompts");
18405
18690
  cache = /* @__PURE__ */ new Map();
18406
18691
  }
18407
18692
  });
@@ -18764,8 +19049,8 @@ var init_code_retriever = __esm({
18764
19049
  });
18765
19050
  }
18766
19051
  async getFileContent(filePath, startLine, endLine) {
18767
- const { readFile: readFile22 } = await import("node:fs/promises");
18768
- const content = await readFile22(filePath, "utf-8");
19052
+ const { readFile: readFile23 } = await import("node:fs/promises");
19053
+ const content = await readFile23(filePath, "utf-8");
18769
19054
  if (startLine === void 0)
18770
19055
  return content;
18771
19056
  const lines = content.split("\n");
@@ -18780,8 +19065,8 @@ var init_code_retriever = __esm({
18780
19065
  // packages/retrieval/dist/lexicalSearch.js
18781
19066
  import { execFile as execFile5 } from "node:child_process";
18782
19067
  import { promisify as promisify4 } from "node:util";
18783
- import { readFile as readFile18, readdir as readdir4, stat as stat3 } from "node:fs/promises";
18784
- import { join as join37, extname as extname7 } from "node:path";
19068
+ import { readFile as readFile19, readdir as readdir5, stat as stat3 } from "node:fs/promises";
19069
+ import { join as join38, extname as extname7 } from "node:path";
18785
19070
  async function searchByPath(pathPattern, options) {
18786
19071
  const allFiles = await collectFiles(options.rootDir, options.includeGlobs ?? DEFAULT_INCLUDE_GLOBS, options.excludeGlobs ?? DEFAULT_EXCLUDE_GLOBS);
18787
19072
  const pattern = options.caseInsensitive ? pathPattern.toLowerCase() : pathPattern;
@@ -18886,7 +19171,7 @@ async function searchWithNodeFallback(pattern, kind, options) {
18886
19171
  if (results.length >= maxMatches)
18887
19172
  break;
18888
19173
  try {
18889
- const content = await readFile18(filePath, "utf-8");
19174
+ const content = await readFile19(filePath, "utf-8");
18890
19175
  const contentLines = content.split("\n");
18891
19176
  for (let i = 0; i < contentLines.length; i++) {
18892
19177
  if (results.length >= maxMatches)
@@ -18914,7 +19199,7 @@ async function collectFiles(rootDir, includeGlobs, excludeGlobs) {
18914
19199
  async function walkForFiles(rootDir, dir, excludeGlobs, results) {
18915
19200
  let entries;
18916
19201
  try {
18917
- entries = await readdir4(dir, { withFileTypes: true, encoding: "utf-8" });
19202
+ entries = await readdir5(dir, { withFileTypes: true, encoding: "utf-8" });
18918
19203
  } catch {
18919
19204
  return;
18920
19205
  }
@@ -18923,7 +19208,7 @@ async function walkForFiles(rootDir, dir, excludeGlobs, results) {
18923
19208
  continue;
18924
19209
  if (excludeGlobs.some((g) => entry.name === g || matchesGlob(entry.name, g)))
18925
19210
  continue;
18926
- const absPath = join37(dir, entry.name);
19211
+ const absPath = join38(dir, entry.name);
18927
19212
  if (entry.isDirectory()) {
18928
19213
  await walkForFiles(rootDir, absPath, excludeGlobs, results);
18929
19214
  } else if (entry.isFile()) {
@@ -19229,8 +19514,8 @@ var init_graphExpand = __esm({
19229
19514
  });
19230
19515
 
19231
19516
  // packages/retrieval/dist/snippetPacker.js
19232
- import { readFile as readFile19 } from "node:fs/promises";
19233
- import { join as join38 } from "node:path";
19517
+ import { readFile as readFile20 } from "node:fs/promises";
19518
+ import { join as join39 } from "node:path";
19234
19519
  async function packSnippets(requests, opts = {}) {
19235
19520
  const maxTokens = opts.maxTokens ?? DEFAULT_MAX_TOKENS;
19236
19521
  const contextLines = opts.contextLines ?? DEFAULT_CONTEXT_LINES;
@@ -19256,10 +19541,10 @@ async function packSnippets(requests, opts = {}) {
19256
19541
  return { packed, dropped, totalTokens };
19257
19542
  }
19258
19543
  async function extractSnippet(req, repoRoot, contextLines = DEFAULT_CONTEXT_LINES) {
19259
- const absPath = req.filePath.startsWith("/") ? req.filePath : join38(repoRoot, req.filePath);
19544
+ const absPath = req.filePath.startsWith("/") ? req.filePath : join39(repoRoot, req.filePath);
19260
19545
  let content;
19261
19546
  try {
19262
- content = await readFile19(absPath, "utf-8");
19547
+ content = await readFile20(absPath, "utf-8");
19263
19548
  } catch {
19264
19549
  return null;
19265
19550
  }
@@ -21850,8 +22135,8 @@ ${marker}` : marker);
21850
22135
  return;
21851
22136
  try {
21852
22137
  const { mkdirSync: mkdirSync21, writeFileSync: writeFileSync20 } = __require("node:fs");
21853
- const { join: join62 } = __require("node:path");
21854
- const sessionDir = join62(this._workingDirectory, ".oa", "session", this._sessionId);
22138
+ const { join: join63 } = __require("node:path");
22139
+ const sessionDir = join63(this._workingDirectory, ".oa", "session", this._sessionId);
21855
22140
  mkdirSync21(sessionDir, { recursive: true });
21856
22141
  const checkpoint = {
21857
22142
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -21864,7 +22149,7 @@ ${marker}` : marker);
21864
22149
  memexEntryCount: this._memexArchive.size,
21865
22150
  fileRegistrySize: this._fileRegistry.size
21866
22151
  };
21867
- writeFileSync20(join62(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
22152
+ writeFileSync20(join63(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
21868
22153
  } catch {
21869
22154
  }
21870
22155
  }
@@ -23132,7 +23417,7 @@ ${transcript}`
23132
23417
  // packages/orchestrator/dist/nexusBackend.js
23133
23418
  import { existsSync as existsSync26, statSync as statSync9, openSync, readSync, closeSync, unlinkSync as unlinkSync4, writeFileSync as writeFileSync8 } from "node:fs";
23134
23419
  import { watch as fsWatch } from "node:fs";
23135
- import { join as join39 } from "node:path";
23420
+ import { join as join40 } from "node:path";
23136
23421
  import { tmpdir as tmpdir7 } from "node:os";
23137
23422
  import { randomBytes as randomBytes8 } from "node:crypto";
23138
23423
  var NexusAgenticBackend;
@@ -23282,7 +23567,7 @@ var init_nexusBackend = __esm({
23282
23567
  * Falls back to unary + word-split if streaming setup fails.
23283
23568
  */
23284
23569
  async *chatCompletionStream(request) {
23285
- const streamFile = join39(tmpdir7(), `nexus-stream-${randomBytes8(6).toString("hex")}.jsonl`);
23570
+ const streamFile = join40(tmpdir7(), `nexus-stream-${randomBytes8(6).toString("hex")}.jsonl`);
23286
23571
  writeFileSync8(streamFile, "", "utf8");
23287
23572
  const daemonArgs = {
23288
23573
  model: this.model,
@@ -24319,7 +24604,7 @@ __export(listen_exports, {
24319
24604
  });
24320
24605
  import { spawn as spawn15, execSync as execSync23 } from "node:child_process";
24321
24606
  import { existsSync as existsSync27, mkdirSync as mkdirSync8, writeFileSync as writeFileSync9, readdirSync as readdirSync6 } from "node:fs";
24322
- import { join as join40, dirname as dirname13 } from "node:path";
24607
+ import { join as join41, dirname as dirname13 } from "node:path";
24323
24608
  import { homedir as homedir8 } from "node:os";
24324
24609
  import { fileURLToPath as fileURLToPath8 } from "node:url";
24325
24610
  import { EventEmitter } from "node:events";
@@ -24405,12 +24690,12 @@ function findMicCaptureCommand() {
24405
24690
  function findLiveWhisperScript() {
24406
24691
  const thisDir = dirname13(fileURLToPath8(import.meta.url));
24407
24692
  const candidates = [
24408
- join40(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
24409
- join40(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
24410
- join40(thisDir, "../../execution/scripts/live-whisper.py"),
24693
+ join41(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
24694
+ join41(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
24695
+ join41(thisDir, "../../execution/scripts/live-whisper.py"),
24411
24696
  // npm install layout — scripts bundled alongside dist
24412
- join40(thisDir, "../scripts/live-whisper.py"),
24413
- join40(thisDir, "../../scripts/live-whisper.py")
24697
+ join41(thisDir, "../scripts/live-whisper.py"),
24698
+ join41(thisDir, "../../scripts/live-whisper.py")
24414
24699
  ];
24415
24700
  for (const p of candidates) {
24416
24701
  if (existsSync27(p))
@@ -24423,8 +24708,8 @@ function findLiveWhisperScript() {
24423
24708
  stdio: ["pipe", "pipe", "pipe"]
24424
24709
  }).trim();
24425
24710
  const candidates2 = [
24426
- join40(globalRoot, "open-agents-ai", "dist", "scripts", "live-whisper.py"),
24427
- join40(globalRoot, "open-agents-ai", "scripts", "live-whisper.py")
24711
+ join41(globalRoot, "open-agents-ai", "dist", "scripts", "live-whisper.py"),
24712
+ join41(globalRoot, "open-agents-ai", "scripts", "live-whisper.py")
24428
24713
  ];
24429
24714
  for (const p of candidates2) {
24430
24715
  if (existsSync27(p))
@@ -24432,11 +24717,11 @@ function findLiveWhisperScript() {
24432
24717
  }
24433
24718
  } catch {
24434
24719
  }
24435
- const nvmBase = join40(homedir8(), ".nvm", "versions", "node");
24720
+ const nvmBase = join41(homedir8(), ".nvm", "versions", "node");
24436
24721
  if (existsSync27(nvmBase)) {
24437
24722
  try {
24438
24723
  for (const ver of readdirSync6(nvmBase)) {
24439
- const p = join40(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
24724
+ const p = join41(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
24440
24725
  if (existsSync27(p))
24441
24726
  return p;
24442
24727
  }
@@ -24455,7 +24740,7 @@ function ensureTranscribeCliBackground() {
24455
24740
  timeout: 5e3,
24456
24741
  stdio: ["pipe", "pipe", "pipe"]
24457
24742
  }).trim();
24458
- if (existsSync27(join40(globalRoot, "transcribe-cli", "dist", "index.js"))) {
24743
+ if (existsSync27(join41(globalRoot, "transcribe-cli", "dist", "index.js"))) {
24459
24744
  return true;
24460
24745
  }
24461
24746
  } catch {
@@ -24678,24 +24963,24 @@ var init_listen = __esm({
24678
24963
  timeout: 5e3,
24679
24964
  stdio: ["pipe", "pipe", "pipe"]
24680
24965
  }).trim();
24681
- const tcPath = join40(globalRoot, "transcribe-cli");
24682
- if (existsSync27(join40(tcPath, "dist", "index.js"))) {
24966
+ const tcPath = join41(globalRoot, "transcribe-cli");
24967
+ if (existsSync27(join41(tcPath, "dist", "index.js"))) {
24683
24968
  const { createRequire: createRequire4 } = await import("node:module");
24684
24969
  const req = createRequire4(import.meta.url);
24685
- return req(join40(tcPath, "dist", "index.js"));
24970
+ return req(join41(tcPath, "dist", "index.js"));
24686
24971
  }
24687
24972
  } catch {
24688
24973
  }
24689
- const nvmBase = join40(homedir8(), ".nvm", "versions", "node");
24974
+ const nvmBase = join41(homedir8(), ".nvm", "versions", "node");
24690
24975
  if (existsSync27(nvmBase)) {
24691
24976
  try {
24692
24977
  const { readdirSync: readdirSync17 } = await import("node:fs");
24693
24978
  for (const ver of readdirSync17(nvmBase)) {
24694
- const tcPath = join40(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
24695
- if (existsSync27(join40(tcPath, "dist", "index.js"))) {
24979
+ const tcPath = join41(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
24980
+ if (existsSync27(join41(tcPath, "dist", "index.js"))) {
24696
24981
  const { createRequire: createRequire4 } = await import("node:module");
24697
24982
  const req = createRequire4(import.meta.url);
24698
- return req(join40(tcPath, "dist", "index.js"));
24983
+ return req(join41(tcPath, "dist", "index.js"));
24699
24984
  }
24700
24985
  }
24701
24986
  } catch {
@@ -24977,9 +25262,9 @@ transcribe-cli error: ${transcribeCliError}` : "";
24977
25262
  });
24978
25263
  if (outputDir) {
24979
25264
  const { basename: basename16 } = await import("node:path");
24980
- const transcriptDir = join40(outputDir, ".oa", "transcripts");
25265
+ const transcriptDir = join41(outputDir, ".oa", "transcripts");
24981
25266
  mkdirSync8(transcriptDir, { recursive: true });
24982
- const outFile = join40(transcriptDir, `${basename16(filePath)}.txt`);
25267
+ const outFile = join41(transcriptDir, `${basename16(filePath)}.txt`);
24983
25268
  writeFileSync9(outFile, result.text, "utf-8");
24984
25269
  }
24985
25270
  return {
@@ -30337,7 +30622,7 @@ import { randomBytes as randomBytes9 } from "node:crypto";
30337
30622
  import { URL as URL2 } from "node:url";
30338
30623
  import { loadavg, cpus, totalmem, freemem } from "node:os";
30339
30624
  import { existsSync as existsSync28, readFileSync as readFileSync19, writeFileSync as writeFileSync10, unlinkSync as unlinkSync5, mkdirSync as mkdirSync9, readdirSync as readdirSync7, statSync as statSync10 } from "node:fs";
30340
- import { join as join41 } from "node:path";
30625
+ import { join as join42 } from "node:path";
30341
30626
  function cleanForwardHeaders(raw, targetHost) {
30342
30627
  const out = {};
30343
30628
  for (const [key, value] of Object.entries(raw)) {
@@ -30365,7 +30650,7 @@ function fmtTokens(n) {
30365
30650
  }
30366
30651
  function readExposeState(stateDir) {
30367
30652
  try {
30368
- const path = join41(stateDir, STATE_FILE_NAME);
30653
+ const path = join42(stateDir, STATE_FILE_NAME);
30369
30654
  if (!existsSync28(path))
30370
30655
  return null;
30371
30656
  const raw = readFileSync19(path, "utf8");
@@ -30380,13 +30665,13 @@ function readExposeState(stateDir) {
30380
30665
  function writeExposeState(stateDir, state) {
30381
30666
  try {
30382
30667
  mkdirSync9(stateDir, { recursive: true });
30383
- writeFileSync10(join41(stateDir, STATE_FILE_NAME), JSON.stringify(state, null, 2));
30668
+ writeFileSync10(join42(stateDir, STATE_FILE_NAME), JSON.stringify(state, null, 2));
30384
30669
  } catch {
30385
30670
  }
30386
30671
  }
30387
30672
  function removeExposeState(stateDir) {
30388
30673
  try {
30389
- unlinkSync5(join41(stateDir, STATE_FILE_NAME));
30674
+ unlinkSync5(join42(stateDir, STATE_FILE_NAME));
30390
30675
  } catch {
30391
30676
  }
30392
30677
  }
@@ -30475,7 +30760,7 @@ async function collectSystemMetricsAsync() {
30475
30760
  }
30476
30761
  function readP2PExposeState(stateDir) {
30477
30762
  try {
30478
- const path = join41(stateDir, P2P_STATE_FILE_NAME);
30763
+ const path = join42(stateDir, P2P_STATE_FILE_NAME);
30479
30764
  if (!existsSync28(path))
30480
30765
  return null;
30481
30766
  const raw = readFileSync19(path, "utf8");
@@ -30490,13 +30775,13 @@ function readP2PExposeState(stateDir) {
30490
30775
  function writeP2PExposeState(stateDir, state) {
30491
30776
  try {
30492
30777
  mkdirSync9(stateDir, { recursive: true });
30493
- writeFileSync10(join41(stateDir, P2P_STATE_FILE_NAME), JSON.stringify(state, null, 2));
30778
+ writeFileSync10(join42(stateDir, P2P_STATE_FILE_NAME), JSON.stringify(state, null, 2));
30494
30779
  } catch {
30495
30780
  }
30496
30781
  }
30497
30782
  function removeP2PExposeState(stateDir) {
30498
30783
  try {
30499
- unlinkSync5(join41(stateDir, P2P_STATE_FILE_NAME));
30784
+ unlinkSync5(join42(stateDir, P2P_STATE_FILE_NAME));
30500
30785
  } catch {
30501
30786
  }
30502
30787
  }
@@ -31344,7 +31629,7 @@ ${this.formatConnectionInfo()}`);
31344
31629
  throw new Error(`Expose failed: ${exposeResult.error}`);
31345
31630
  }
31346
31631
  const nexusDir = this._nexusTool.getNexusDir();
31347
- const statusPath = join41(nexusDir, "status.json");
31632
+ const statusPath = join42(nexusDir, "status.json");
31348
31633
  for (let i = 0; i < 80; i++) {
31349
31634
  try {
31350
31635
  const raw = readFileSync19(statusPath, "utf8");
@@ -31378,7 +31663,7 @@ ${this.formatConnectionInfo()}`);
31378
31663
  });
31379
31664
  }
31380
31665
  try {
31381
- const invocDir = join41(nexusDir, "invocations");
31666
+ const invocDir = join42(nexusDir, "invocations");
31382
31667
  if (existsSync28(invocDir)) {
31383
31668
  this._prevInvocCount = readdirSync7(invocDir).filter((f) => f.endsWith(".json")).length;
31384
31669
  this._stats.totalRequests = this._prevInvocCount;
@@ -31408,7 +31693,7 @@ ${this.formatConnectionInfo()}`);
31408
31693
  if (!state)
31409
31694
  return null;
31410
31695
  const nexusDir = nexusTool.getNexusDir();
31411
- const statusPath = join41(nexusDir, "status.json");
31696
+ const statusPath = join42(nexusDir, "status.json");
31412
31697
  try {
31413
31698
  if (!existsSync28(statusPath)) {
31414
31699
  removeP2PExposeState(stateDir);
@@ -31467,7 +31752,7 @@ ${this.formatConnectionInfo()}`);
31467
31752
  let lastMeteringLineCount = 0;
31468
31753
  this._activityPollTimer = setInterval(() => {
31469
31754
  try {
31470
- const invocDir = join41(nexusDir, "invocations");
31755
+ const invocDir = join42(nexusDir, "invocations");
31471
31756
  if (!existsSync28(invocDir))
31472
31757
  return;
31473
31758
  const files = readdirSync7(invocDir).filter((f) => f.endsWith(".json"));
@@ -31483,13 +31768,13 @@ ${this.formatConnectionInfo()}`);
31483
31768
  let recentActive = 0;
31484
31769
  for (const f of files.slice(-10)) {
31485
31770
  try {
31486
- const st = statSync10(join41(invocDir, f));
31771
+ const st = statSync10(join42(invocDir, f));
31487
31772
  if (now - st.mtimeMs < 1e4)
31488
31773
  recentActive++;
31489
31774
  } catch {
31490
31775
  }
31491
31776
  }
31492
- const meteringFile = join41(nexusDir, "metering.jsonl");
31777
+ const meteringFile = join42(nexusDir, "metering.jsonl");
31493
31778
  let meteringLines = lastMeteringLineCount;
31494
31779
  try {
31495
31780
  if (existsSync28(meteringFile)) {
@@ -31519,7 +31804,7 @@ ${this.formatConnectionInfo()}`);
31519
31804
  this._activityPollTimer.unref();
31520
31805
  this._pollTimer = setInterval(() => {
31521
31806
  try {
31522
- const statusPath = join41(nexusDir, "status.json");
31807
+ const statusPath = join42(nexusDir, "status.json");
31523
31808
  if (existsSync28(statusPath)) {
31524
31809
  const status = JSON.parse(readFileSync19(statusPath, "utf8"));
31525
31810
  if (status.peerId && !this._peerId) {
@@ -31530,7 +31815,7 @@ ${this.formatConnectionInfo()}`);
31530
31815
  } catch {
31531
31816
  }
31532
31817
  try {
31533
- const invocDir = join41(nexusDir, "invocations");
31818
+ const invocDir = join42(nexusDir, "invocations");
31534
31819
  if (existsSync28(invocDir)) {
31535
31820
  const files = readdirSync7(invocDir);
31536
31821
  const invocCount = files.filter((f) => f.endsWith(".json")).length;
@@ -31542,7 +31827,7 @@ ${this.formatConnectionInfo()}`);
31542
31827
  } catch {
31543
31828
  }
31544
31829
  try {
31545
- const meteringFile = join41(nexusDir, "metering.jsonl");
31830
+ const meteringFile = join42(nexusDir, "metering.jsonl");
31546
31831
  if (existsSync28(meteringFile)) {
31547
31832
  const content = readFileSync19(meteringFile, "utf8");
31548
31833
  if (content.length > lastMeteringSize) {
@@ -31754,7 +32039,7 @@ var init_types = __esm({
31754
32039
  // packages/cli/dist/tui/p2p/secret-vault.js
31755
32040
  import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes10, scryptSync as scryptSync2, createHash as createHash2 } from "node:crypto";
31756
32041
  import { readFileSync as readFileSync20, writeFileSync as writeFileSync11, existsSync as existsSync29, mkdirSync as mkdirSync10 } from "node:fs";
31757
- import { join as join42, dirname as dirname14 } from "node:path";
32042
+ import { join as join43, dirname as dirname14 } from "node:path";
31758
32043
  var PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, CIPHER_ALGO, SALT_LEN, IV_LEN, KEY_LEN, SecretVault;
31759
32044
  var init_secret_vault = __esm({
31760
32045
  "packages/cli/dist/tui/p2p/secret-vault.js"() {
@@ -33091,13 +33376,13 @@ async function fetchPeerModels(peerId, authKey) {
33091
33376
  try {
33092
33377
  const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
33093
33378
  const { existsSync: existsSync45, readFileSync: readFileSync33 } = await import("node:fs");
33094
- const { join: join62 } = await import("node:path");
33379
+ const { join: join63 } = await import("node:path");
33095
33380
  const cwd4 = process.cwd();
33096
33381
  const nexusTool = new NexusTool2(cwd4);
33097
33382
  const nexusDir = nexusTool.getNexusDir();
33098
33383
  let isLocalPeer = false;
33099
33384
  try {
33100
- const statusPath = join62(nexusDir, "status.json");
33385
+ const statusPath = join63(nexusDir, "status.json");
33101
33386
  if (existsSync45(statusPath)) {
33102
33387
  const status = JSON.parse(readFileSync33(statusPath, "utf8"));
33103
33388
  if (status.peerId === peerId)
@@ -33106,7 +33391,7 @@ async function fetchPeerModels(peerId, authKey) {
33106
33391
  } catch {
33107
33392
  }
33108
33393
  if (isLocalPeer) {
33109
- const pricingPath = join62(nexusDir, "pricing.json");
33394
+ const pricingPath = join63(nexusDir, "pricing.json");
33110
33395
  if (existsSync45(pricingPath)) {
33111
33396
  try {
33112
33397
  const pricing = JSON.parse(readFileSync33(pricingPath, "utf8"));
@@ -33123,7 +33408,7 @@ async function fetchPeerModels(peerId, authKey) {
33123
33408
  }
33124
33409
  }
33125
33410
  }
33126
- const cachePath = join62(nexusDir, "peer-models-cache.json");
33411
+ const cachePath = join63(nexusDir, "peer-models-cache.json");
33127
33412
  if (existsSync45(cachePath)) {
33128
33413
  try {
33129
33414
  const cache4 = JSON.parse(readFileSync33(cachePath, "utf8"));
@@ -33241,7 +33526,7 @@ async function fetchPeerModels(peerId, authKey) {
33241
33526
  } catch {
33242
33527
  }
33243
33528
  if (isLocalPeer) {
33244
- const pricingPath = join62(nexusDir, "pricing.json");
33529
+ const pricingPath = join63(nexusDir, "pricing.json");
33245
33530
  if (existsSync45(pricingPath)) {
33246
33531
  try {
33247
33532
  const pricing = JSON.parse(readFileSync33(pricingPath, "utf8"));
@@ -33514,12 +33799,12 @@ var init_render2 = __esm({
33514
33799
 
33515
33800
  // packages/prompts/dist/promptLoader.js
33516
33801
  import { readFileSync as readFileSync21, existsSync as existsSync30 } from "node:fs";
33517
- import { join as join43, dirname as dirname15 } from "node:path";
33802
+ import { join as join44, dirname as dirname15 } from "node:path";
33518
33803
  import { fileURLToPath as fileURLToPath9 } from "node:url";
33519
33804
  function loadPrompt2(promptPath, vars) {
33520
33805
  let content = cache2.get(promptPath);
33521
33806
  if (content === void 0) {
33522
- const fullPath = join43(PROMPTS_DIR2, promptPath);
33807
+ const fullPath = join44(PROMPTS_DIR2, promptPath);
33523
33808
  if (!existsSync30(fullPath)) {
33524
33809
  throw new Error(`Prompt file not found: ${fullPath}`);
33525
33810
  }
@@ -33536,8 +33821,8 @@ var init_promptLoader2 = __esm({
33536
33821
  "use strict";
33537
33822
  __filename2 = fileURLToPath9(import.meta.url);
33538
33823
  __dirname5 = dirname15(__filename2);
33539
- devPath = join43(__dirname5, "..", "templates");
33540
- publishedPath = join43(__dirname5, "..", "prompts", "templates");
33824
+ devPath = join44(__dirname5, "..", "templates");
33825
+ publishedPath = join44(__dirname5, "..", "prompts", "templates");
33541
33826
  PROMPTS_DIR2 = existsSync30(devPath) ? devPath : publishedPath;
33542
33827
  cache2 = /* @__PURE__ */ new Map();
33543
33828
  }
@@ -33649,7 +33934,7 @@ var init_task_templates = __esm({
33649
33934
  });
33650
33935
 
33651
33936
  // packages/prompts/dist/index.js
33652
- import { join as join44, dirname as dirname16 } from "node:path";
33937
+ import { join as join45, dirname as dirname16 } from "node:path";
33653
33938
  import { fileURLToPath as fileURLToPath10 } from "node:url";
33654
33939
  var _dir, _packageRoot;
33655
33940
  var init_dist6 = __esm({
@@ -33660,21 +33945,21 @@ var init_dist6 = __esm({
33660
33945
  init_task_templates();
33661
33946
  init_render2();
33662
33947
  _dir = dirname16(fileURLToPath10(import.meta.url));
33663
- _packageRoot = join44(_dir, "..");
33948
+ _packageRoot = join45(_dir, "..");
33664
33949
  }
33665
33950
  });
33666
33951
 
33667
33952
  // packages/cli/dist/tui/oa-directory.js
33668
33953
  import { existsSync as existsSync31, mkdirSync as mkdirSync11, readFileSync as readFileSync22, writeFileSync as writeFileSync12, readdirSync as readdirSync8, statSync as statSync11, unlinkSync as unlinkSync6 } from "node:fs";
33669
- import { join as join45, relative as relative2, basename as basename9, extname as extname8 } from "node:path";
33954
+ import { join as join46, relative as relative2, basename as basename9, extname as extname8 } from "node:path";
33670
33955
  import { homedir as homedir9 } from "node:os";
33671
33956
  function initOaDirectory(repoRoot) {
33672
- const oaPath = join45(repoRoot, OA_DIR);
33957
+ const oaPath = join46(repoRoot, OA_DIR);
33673
33958
  for (const sub of SUBDIRS) {
33674
- mkdirSync11(join45(oaPath, sub), { recursive: true });
33959
+ mkdirSync11(join46(oaPath, sub), { recursive: true });
33675
33960
  }
33676
33961
  try {
33677
- const gitignorePath = join45(repoRoot, ".gitignore");
33962
+ const gitignorePath = join46(repoRoot, ".gitignore");
33678
33963
  const settingsPattern = ".oa/settings.json";
33679
33964
  if (existsSync31(gitignorePath)) {
33680
33965
  const content = readFileSync22(gitignorePath, "utf-8");
@@ -33687,10 +33972,10 @@ function initOaDirectory(repoRoot) {
33687
33972
  return oaPath;
33688
33973
  }
33689
33974
  function hasOaDirectory(repoRoot) {
33690
- return existsSync31(join45(repoRoot, OA_DIR, "index"));
33975
+ return existsSync31(join46(repoRoot, OA_DIR, "index"));
33691
33976
  }
33692
33977
  function loadProjectSettings(repoRoot) {
33693
- const settingsPath = join45(repoRoot, OA_DIR, "settings.json");
33978
+ const settingsPath = join46(repoRoot, OA_DIR, "settings.json");
33694
33979
  try {
33695
33980
  if (existsSync31(settingsPath)) {
33696
33981
  return JSON.parse(readFileSync22(settingsPath, "utf-8"));
@@ -33700,14 +33985,14 @@ function loadProjectSettings(repoRoot) {
33700
33985
  return {};
33701
33986
  }
33702
33987
  function saveProjectSettings(repoRoot, settings) {
33703
- const oaPath = join45(repoRoot, OA_DIR);
33988
+ const oaPath = join46(repoRoot, OA_DIR);
33704
33989
  mkdirSync11(oaPath, { recursive: true });
33705
33990
  const existing = loadProjectSettings(repoRoot);
33706
33991
  const merged = { ...existing, ...settings };
33707
- writeFileSync12(join45(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
33992
+ writeFileSync12(join46(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
33708
33993
  }
33709
33994
  function loadGlobalSettings() {
33710
- const settingsPath = join45(homedir9(), ".open-agents", "settings.json");
33995
+ const settingsPath = join46(homedir9(), ".open-agents", "settings.json");
33711
33996
  try {
33712
33997
  if (existsSync31(settingsPath)) {
33713
33998
  return JSON.parse(readFileSync22(settingsPath, "utf-8"));
@@ -33717,11 +34002,11 @@ function loadGlobalSettings() {
33717
34002
  return {};
33718
34003
  }
33719
34004
  function saveGlobalSettings(settings) {
33720
- const dir = join45(homedir9(), ".open-agents");
34005
+ const dir = join46(homedir9(), ".open-agents");
33721
34006
  mkdirSync11(dir, { recursive: true });
33722
34007
  const existing = loadGlobalSettings();
33723
34008
  const merged = { ...existing, ...settings };
33724
- writeFileSync12(join45(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
34009
+ writeFileSync12(join46(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
33725
34010
  }
33726
34011
  function resolveSettings(repoRoot) {
33727
34012
  const global = loadGlobalSettings();
@@ -33736,7 +34021,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
33736
34021
  while (dir && !visited.has(dir)) {
33737
34022
  visited.add(dir);
33738
34023
  for (const name of CONTEXT_FILES) {
33739
- const filePath = join45(dir, name);
34024
+ const filePath = join46(dir, name);
33740
34025
  const normalizedName = name.toLowerCase();
33741
34026
  if (existsSync31(filePath) && !seen.has(filePath)) {
33742
34027
  seen.add(filePath);
@@ -33755,7 +34040,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
33755
34040
  }
33756
34041
  }
33757
34042
  }
33758
- const projectMap = join45(dir, OA_DIR, "context", "project-map.md");
34043
+ const projectMap = join46(dir, OA_DIR, "context", "project-map.md");
33759
34044
  if (existsSync31(projectMap) && !seen.has(projectMap)) {
33760
34045
  seen.add(projectMap);
33761
34046
  try {
@@ -33771,7 +34056,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
33771
34056
  } catch {
33772
34057
  }
33773
34058
  }
33774
- const parent = join45(dir, "..");
34059
+ const parent = join46(dir, "..");
33775
34060
  if (parent === dir)
33776
34061
  break;
33777
34062
  dir = parent;
@@ -33789,7 +34074,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
33789
34074
  return found;
33790
34075
  }
33791
34076
  function readIndexMeta(repoRoot) {
33792
- const metaPath = join45(repoRoot, OA_DIR, "index", "meta.json");
34077
+ const metaPath = join46(repoRoot, OA_DIR, "index", "meta.json");
33793
34078
  try {
33794
34079
  return JSON.parse(readFileSync22(metaPath, "utf-8"));
33795
34080
  } catch {
@@ -33842,28 +34127,28 @@ ${tree}\`\`\`
33842
34127
  sections.push("");
33843
34128
  }
33844
34129
  const content = sections.join("\n");
33845
- const contextDir = join45(repoRoot, OA_DIR, "context");
34130
+ const contextDir = join46(repoRoot, OA_DIR, "context");
33846
34131
  mkdirSync11(contextDir, { recursive: true });
33847
- writeFileSync12(join45(contextDir, "project-map.md"), content, "utf-8");
34132
+ writeFileSync12(join46(contextDir, "project-map.md"), content, "utf-8");
33848
34133
  return content;
33849
34134
  }
33850
34135
  function saveSession(repoRoot, session) {
33851
- const historyDir = join45(repoRoot, OA_DIR, "history");
34136
+ const historyDir = join46(repoRoot, OA_DIR, "history");
33852
34137
  mkdirSync11(historyDir, { recursive: true });
33853
- writeFileSync12(join45(historyDir, `${session.id}.json`), JSON.stringify(session, null, 2), "utf-8");
34138
+ writeFileSync12(join46(historyDir, `${session.id}.json`), JSON.stringify(session, null, 2), "utf-8");
33854
34139
  }
33855
34140
  function loadRecentSessions(repoRoot, limit = 5) {
33856
- const historyDir = join45(repoRoot, OA_DIR, "history");
34141
+ const historyDir = join46(repoRoot, OA_DIR, "history");
33857
34142
  if (!existsSync31(historyDir))
33858
34143
  return [];
33859
34144
  try {
33860
34145
  const files = readdirSync8(historyDir).filter((f) => f.endsWith(".json") && f !== "pending-task.json").map((f) => {
33861
- const stat5 = statSync11(join45(historyDir, f));
34146
+ const stat5 = statSync11(join46(historyDir, f));
33862
34147
  return { file: f, mtime: stat5.mtimeMs };
33863
34148
  }).sort((a, b) => b.mtime - a.mtime).slice(0, limit);
33864
34149
  return files.map((f) => {
33865
34150
  try {
33866
- return JSON.parse(readFileSync22(join45(historyDir, f.file), "utf-8"));
34151
+ return JSON.parse(readFileSync22(join46(historyDir, f.file), "utf-8"));
33867
34152
  } catch {
33868
34153
  return null;
33869
34154
  }
@@ -33873,12 +34158,12 @@ function loadRecentSessions(repoRoot, limit = 5) {
33873
34158
  }
33874
34159
  }
33875
34160
  function savePendingTask(repoRoot, task) {
33876
- const historyDir = join45(repoRoot, OA_DIR, "history");
34161
+ const historyDir = join46(repoRoot, OA_DIR, "history");
33877
34162
  mkdirSync11(historyDir, { recursive: true });
33878
- writeFileSync12(join45(historyDir, PENDING_TASK_FILE), JSON.stringify(task, null, 2) + "\n", "utf-8");
34163
+ writeFileSync12(join46(historyDir, PENDING_TASK_FILE), JSON.stringify(task, null, 2) + "\n", "utf-8");
33879
34164
  }
33880
34165
  function loadPendingTask(repoRoot) {
33881
- const filePath = join45(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
34166
+ const filePath = join46(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
33882
34167
  try {
33883
34168
  if (!existsSync31(filePath))
33884
34169
  return null;
@@ -33893,9 +34178,9 @@ function loadPendingTask(repoRoot) {
33893
34178
  }
33894
34179
  }
33895
34180
  function saveSessionContext(repoRoot, entry) {
33896
- const contextDir = join45(repoRoot, OA_DIR, "context");
34181
+ const contextDir = join46(repoRoot, OA_DIR, "context");
33897
34182
  mkdirSync11(contextDir, { recursive: true });
33898
- const filePath = join45(contextDir, CONTEXT_SAVE_FILE);
34183
+ const filePath = join46(contextDir, CONTEXT_SAVE_FILE);
33899
34184
  let ctx;
33900
34185
  try {
33901
34186
  if (existsSync31(filePath)) {
@@ -33914,7 +34199,7 @@ function saveSessionContext(repoRoot, entry) {
33914
34199
  writeFileSync12(filePath, JSON.stringify(ctx, null, 2) + "\n", "utf-8");
33915
34200
  }
33916
34201
  function loadSessionContext(repoRoot) {
33917
- const filePath = join45(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
34202
+ const filePath = join46(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
33918
34203
  try {
33919
34204
  if (!existsSync31(filePath))
33920
34205
  return null;
@@ -33965,7 +34250,7 @@ function detectManifests(repoRoot) {
33965
34250
  { file: "docker-compose.yaml", type: "Docker Compose" }
33966
34251
  ];
33967
34252
  for (const check of checks) {
33968
- const filePath = join45(repoRoot, check.file);
34253
+ const filePath = join46(repoRoot, check.file);
33969
34254
  if (existsSync31(filePath)) {
33970
34255
  let name;
33971
34256
  if (check.nameField) {
@@ -33999,7 +34284,7 @@ function findKeyFiles(repoRoot) {
33999
34284
  { pattern: "CLAUDE.md", description: "Claude Code context" }
34000
34285
  ];
34001
34286
  for (const check of checks) {
34002
- if (existsSync31(join45(repoRoot, check.pattern))) {
34287
+ if (existsSync31(join46(repoRoot, check.pattern))) {
34003
34288
  keyFiles.push({ path: check.pattern, description: check.description });
34004
34289
  }
34005
34290
  }
@@ -34025,12 +34310,12 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
34025
34310
  if (entry.isDirectory()) {
34026
34311
  let fileCount = 0;
34027
34312
  try {
34028
- fileCount = readdirSync8(join45(root, entry.name)).filter((f) => !f.startsWith(".")).length;
34313
+ fileCount = readdirSync8(join46(root, entry.name)).filter((f) => !f.startsWith(".")).length;
34029
34314
  } catch {
34030
34315
  }
34031
34316
  result += `${prefix}${connector}${entry.name}/ (${fileCount})
34032
34317
  `;
34033
- result += buildDirTree(join45(root, entry.name), maxDepth, childPrefix, depth + 1);
34318
+ result += buildDirTree(join46(root, entry.name), maxDepth, childPrefix, depth + 1);
34034
34319
  } else if (depth < maxDepth) {
34035
34320
  result += `${prefix}${connector}${entry.name}
34036
34321
  `;
@@ -34050,7 +34335,7 @@ function loadUsageFile(filePath) {
34050
34335
  return { records: [] };
34051
34336
  }
34052
34337
  function saveUsageFile(filePath, data) {
34053
- const dir = join45(filePath, "..");
34338
+ const dir = join46(filePath, "..");
34054
34339
  mkdirSync11(dir, { recursive: true });
34055
34340
  writeFileSync12(filePath, JSON.stringify(data, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
34056
34341
  }
@@ -34080,15 +34365,15 @@ function recordUsage(kind, value, opts) {
34080
34365
  }
34081
34366
  saveUsageFile(filePath, data);
34082
34367
  };
34083
- update(join45(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
34368
+ update(join46(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
34084
34369
  if (opts?.repoRoot) {
34085
- update(join45(opts.repoRoot, OA_DIR, USAGE_HISTORY_FILE));
34370
+ update(join46(opts.repoRoot, OA_DIR, USAGE_HISTORY_FILE));
34086
34371
  }
34087
34372
  }
34088
34373
  function loadUsageHistory(kind, repoRoot) {
34089
- const globalPath = join45(homedir9(), ".open-agents", USAGE_HISTORY_FILE);
34374
+ const globalPath = join46(homedir9(), ".open-agents", USAGE_HISTORY_FILE);
34090
34375
  const globalData = loadUsageFile(globalPath);
34091
- const localData = repoRoot ? loadUsageFile(join45(repoRoot, OA_DIR, USAGE_HISTORY_FILE)) : { records: [] };
34376
+ const localData = repoRoot ? loadUsageFile(join46(repoRoot, OA_DIR, USAGE_HISTORY_FILE)) : { records: [] };
34092
34377
  const map = /* @__PURE__ */ new Map();
34093
34378
  for (const r of globalData.records) {
34094
34379
  if (r.kind !== kind)
@@ -34119,9 +34404,9 @@ function deleteUsageRecord(kind, value, repoRoot) {
34119
34404
  saveUsageFile(filePath, data);
34120
34405
  }
34121
34406
  };
34122
- remove(join45(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
34407
+ remove(join46(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
34123
34408
  if (repoRoot) {
34124
- remove(join45(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
34409
+ remove(join46(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
34125
34410
  }
34126
34411
  }
34127
34412
  var OA_DIR, SUBDIRS, CONTEXT_FILES, PENDING_TASK_FILE, CONTEXT_SAVE_FILE, MAX_CONTEXT_ENTRIES, SKIP_DIRS, USAGE_HISTORY_FILE, MAX_HISTORY_RECORDS;
@@ -34172,7 +34457,7 @@ import * as readline from "node:readline";
34172
34457
  import { execSync as execSync25, spawn as spawn18, exec as exec2 } from "node:child_process";
34173
34458
  import { promisify as promisify5 } from "node:util";
34174
34459
  import { existsSync as existsSync32, writeFileSync as writeFileSync13, readFileSync as readFileSync23, appendFileSync as appendFileSync2, mkdirSync as mkdirSync12 } from "node:fs";
34175
- import { join as join46 } from "node:path";
34460
+ import { join as join47 } from "node:path";
34176
34461
  import { homedir as homedir10, platform } from "node:os";
34177
34462
  function detectSystemSpecs() {
34178
34463
  let totalRamGB = 0;
@@ -35213,9 +35498,9 @@ async function doSetup(config, rl) {
35213
35498
  `PARAMETER num_predict ${numPredict}`,
35214
35499
  `PARAMETER stop "<|endoftext|>"`
35215
35500
  ].join("\n");
35216
- const modelDir2 = join46(homedir10(), ".open-agents", "models");
35501
+ const modelDir2 = join47(homedir10(), ".open-agents", "models");
35217
35502
  mkdirSync12(modelDir2, { recursive: true });
35218
- const modelfilePath = join46(modelDir2, `Modelfile.${customName}`);
35503
+ const modelfilePath = join47(modelDir2, `Modelfile.${customName}`);
35219
35504
  writeFileSync13(modelfilePath, modelfileContent + "\n", "utf8");
35220
35505
  process.stdout.write(` ${c2.dim("Creating model...")} `);
35221
35506
  execSync25(`ollama create ${customName} -f ${modelfilePath}`, {
@@ -35261,7 +35546,7 @@ async function isModelAvailable(config) {
35261
35546
  }
35262
35547
  function isFirstRun() {
35263
35548
  try {
35264
- return !existsSync32(join46(homedir10(), ".open-agents", "config.json"));
35549
+ return !existsSync32(join47(homedir10(), ".open-agents", "config.json"));
35265
35550
  } catch {
35266
35551
  return true;
35267
35552
  }
@@ -35298,7 +35583,7 @@ function detectPkgManager() {
35298
35583
  return null;
35299
35584
  }
35300
35585
  function getVenvDir() {
35301
- return join46(homedir10(), ".open-agents", "venv");
35586
+ return join47(homedir10(), ".open-agents", "venv");
35302
35587
  }
35303
35588
  function hasVenvModule() {
35304
35589
  try {
@@ -35310,7 +35595,7 @@ function hasVenvModule() {
35310
35595
  }
35311
35596
  function ensureVenv(log) {
35312
35597
  const venvDir = getVenvDir();
35313
- const venvPip = join46(venvDir, "bin", "pip");
35598
+ const venvPip = join47(venvDir, "bin", "pip");
35314
35599
  if (existsSync32(venvPip))
35315
35600
  return venvDir;
35316
35601
  log("Creating Python venv for vision deps...");
@@ -35323,9 +35608,9 @@ function ensureVenv(log) {
35323
35608
  return null;
35324
35609
  }
35325
35610
  try {
35326
- mkdirSync12(join46(homedir10(), ".open-agents"), { recursive: true });
35611
+ mkdirSync12(join47(homedir10(), ".open-agents"), { recursive: true });
35327
35612
  execSync25(`python3 -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
35328
- execSync25(`"${join46(venvDir, "bin", "pip")}" install --upgrade pip`, {
35613
+ execSync25(`"${join47(venvDir, "bin", "pip")}" install --upgrade pip`, {
35329
35614
  stdio: "pipe",
35330
35615
  timeout: 6e4
35331
35616
  });
@@ -35516,11 +35801,11 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
35516
35801
  }
35517
35802
  }
35518
35803
  const venvDir = getVenvDir();
35519
- const venvBin = join46(venvDir, "bin");
35520
- const venvMoondream = join46(venvBin, "moondream-station");
35804
+ const venvBin = join47(venvDir, "bin");
35805
+ const venvMoondream = join47(venvBin, "moondream-station");
35521
35806
  const venv = ensureVenv(log);
35522
35807
  if (venv && !hasCmd("moondream-station") && !existsSync32(venvMoondream)) {
35523
- const venvPip = join46(venvBin, "pip");
35808
+ const venvPip = join47(venvBin, "pip");
35524
35809
  log("Installing moondream-station in ~/.open-agents/venv...");
35525
35810
  try {
35526
35811
  execSync25(`"${venvPip}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
@@ -35541,8 +35826,8 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
35541
35826
  }
35542
35827
  }
35543
35828
  if (venv) {
35544
- const venvPython = join46(venvBin, "python");
35545
- const venvPip2 = join46(venvBin, "pip");
35829
+ const venvPython = join47(venvBin, "python");
35830
+ const venvPip2 = join47(venvBin, "pip");
35546
35831
  let ocrStackInstalled = false;
35547
35832
  try {
35548
35833
  execSync25(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
@@ -35686,9 +35971,9 @@ async function createExpandedVariantAsync(baseModel, specs, sizeGB, kvBytesPerTo
35686
35971
  `PARAMETER num_predict ${numPredict}`,
35687
35972
  `PARAMETER stop "<|endoftext|>"`
35688
35973
  ].join("\n");
35689
- const modelDir2 = join46(homedir10(), ".open-agents", "models");
35974
+ const modelDir2 = join47(homedir10(), ".open-agents", "models");
35690
35975
  mkdirSync12(modelDir2, { recursive: true });
35691
- const modelfilePath = join46(modelDir2, `Modelfile.${customName}`);
35976
+ const modelfilePath = join47(modelDir2, `Modelfile.${customName}`);
35692
35977
  writeFileSync13(modelfilePath, modelfileContent + "\n", "utf8");
35693
35978
  await execAsync(`ollama create ${customName} -f ${modelfilePath}`, {
35694
35979
  timeout: 12e4
@@ -35763,8 +36048,8 @@ async function ensureNeovim() {
35763
36048
  const platform5 = process.platform;
35764
36049
  const arch = process.arch;
35765
36050
  if (platform5 === "linux") {
35766
- const binDir = join46(homedir10(), ".local", "bin");
35767
- const nvimDest = join46(binDir, "nvim");
36051
+ const binDir = join47(homedir10(), ".local", "bin");
36052
+ const nvimDest = join47(binDir, "nvim");
35768
36053
  try {
35769
36054
  mkdirSync12(binDir, { recursive: true });
35770
36055
  } catch {
@@ -35835,7 +36120,7 @@ async function ensureNeovim() {
35835
36120
  }
35836
36121
  function ensurePathInShellRc(binDir) {
35837
36122
  const shell = process.env.SHELL ?? "";
35838
- const rcFile = shell.includes("zsh") ? join46(homedir10(), ".zshrc") : join46(homedir10(), ".bashrc");
36123
+ const rcFile = shell.includes("zsh") ? join47(homedir10(), ".zshrc") : join47(homedir10(), ".bashrc");
35839
36124
  try {
35840
36125
  const rcContent = existsSync32(rcFile) ? readFileSync23(rcFile, "utf8") : "";
35841
36126
  if (rcContent.includes(binDir))
@@ -36607,7 +36892,7 @@ var init_drop_panel = __esm({
36607
36892
  // packages/cli/dist/tui/neovim-mode.js
36608
36893
  import { existsSync as existsSync34, unlinkSync as unlinkSync7 } from "node:fs";
36609
36894
  import { tmpdir as tmpdir8 } from "node:os";
36610
- import { join as join47 } from "node:path";
36895
+ import { join as join48 } from "node:path";
36611
36896
  import { execSync as execSync26 } from "node:child_process";
36612
36897
  function isNeovimActive() {
36613
36898
  return _state !== null && !_state.cleanedUp;
@@ -36655,7 +36940,7 @@ async function startNeovimMode(opts) {
36655
36940
  );
36656
36941
  } catch {
36657
36942
  }
36658
- const socketPath = join47(tmpdir8(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
36943
+ const socketPath = join48(tmpdir8(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
36659
36944
  try {
36660
36945
  if (existsSync34(socketPath))
36661
36946
  unlinkSync7(socketPath);
@@ -37007,7 +37292,7 @@ __export(voice_exports, {
37007
37292
  resetNarrationContext: () => resetNarrationContext
37008
37293
  });
37009
37294
  import { existsSync as existsSync35, mkdirSync as mkdirSync13, writeFileSync as writeFileSync14, readFileSync as readFileSync24, unlinkSync as unlinkSync8, readdirSync as readdirSync9, renameSync, statSync as statSync12 } from "node:fs";
37010
- import { join as join48 } from "node:path";
37295
+ import { join as join49 } from "node:path";
37011
37296
  import { homedir as homedir11, tmpdir as tmpdir9, platform as platform2 } from "node:os";
37012
37297
  import { execSync as execSync27, spawn as nodeSpawn } from "node:child_process";
37013
37298
  import { createRequire } from "node:module";
@@ -37029,34 +37314,34 @@ function listVoiceModels() {
37029
37314
  }));
37030
37315
  }
37031
37316
  function voiceDir() {
37032
- return join48(homedir11(), ".open-agents", "voice");
37317
+ return join49(homedir11(), ".open-agents", "voice");
37033
37318
  }
37034
37319
  function modelsDir() {
37035
- return join48(voiceDir(), "models");
37320
+ return join49(voiceDir(), "models");
37036
37321
  }
37037
37322
  function modelDir(id) {
37038
- return join48(modelsDir(), id);
37323
+ return join49(modelsDir(), id);
37039
37324
  }
37040
37325
  function modelOnnxPath(id) {
37041
- return join48(modelDir(id), "model.onnx");
37326
+ return join49(modelDir(id), "model.onnx");
37042
37327
  }
37043
37328
  function modelConfigPath(id) {
37044
- return join48(modelDir(id), "config.json");
37329
+ return join49(modelDir(id), "config.json");
37045
37330
  }
37046
37331
  function luxttsVenvDir() {
37047
- return join48(voiceDir(), "luxtts-venv");
37332
+ return join49(voiceDir(), "luxtts-venv");
37048
37333
  }
37049
37334
  function luxttsVenvPy() {
37050
- return platform2() === "win32" ? join48(luxttsVenvDir(), "Scripts", "python.exe") : join48(luxttsVenvDir(), "bin", "python3");
37335
+ return platform2() === "win32" ? join49(luxttsVenvDir(), "Scripts", "python.exe") : join49(luxttsVenvDir(), "bin", "python3");
37051
37336
  }
37052
37337
  function luxttsRepoDir() {
37053
- return join48(voiceDir(), "LuxTTS");
37338
+ return join49(voiceDir(), "LuxTTS");
37054
37339
  }
37055
37340
  function luxttsCloneRefsDir() {
37056
- return join48(voiceDir(), "clone-refs");
37341
+ return join49(voiceDir(), "clone-refs");
37057
37342
  }
37058
37343
  function luxttsInferScript() {
37059
- return join48(voiceDir(), "luxtts-infer.py");
37344
+ return join49(voiceDir(), "luxtts-infer.py");
37060
37345
  }
37061
37346
  function emotionToPitchBias(emotion, stark = false, autist = false) {
37062
37347
  if (autist)
@@ -37864,7 +38149,7 @@ var init_voice = __esm({
37864
38149
  const refsDir = luxttsCloneRefsDir();
37865
38150
  const targets = ["glados", "overwatch"];
37866
38151
  for (const modelId of targets) {
37867
- const refFile = join48(refsDir, `${modelId}-ref.wav`);
38152
+ const refFile = join49(refsDir, `${modelId}-ref.wav`);
37868
38153
  if (existsSync35(refFile))
37869
38154
  continue;
37870
38155
  try {
@@ -37944,7 +38229,7 @@ var init_voice = __esm({
37944
38229
  }
37945
38230
  p = p.replace(/\\ /g, " ");
37946
38231
  if (p.startsWith("~/") || p === "~") {
37947
- p = join48(homedir11(), p.slice(1));
38232
+ p = join49(homedir11(), p.slice(1));
37948
38233
  }
37949
38234
  if (!existsSync35(p)) {
37950
38235
  return `File not found: ${p}
@@ -37958,7 +38243,7 @@ var init_voice = __esm({
37958
38243
  const srcName = (audioPath.split("/").pop() ?? "clone").replace(/\.[^.]+$/, "").replace(/[^a-zA-Z0-9_-]/g, "-");
37959
38244
  const ts = Date.now().toString(36);
37960
38245
  const destFilename = `clone-${srcName}-${ts}.${ext}`;
37961
- const destPath = join48(refsDir, destFilename);
38246
+ const destPath = join49(refsDir, destFilename);
37962
38247
  try {
37963
38248
  const data = readFileSync24(audioPath);
37964
38249
  writeFileSync14(destPath, data);
@@ -38003,7 +38288,7 @@ var init_voice = __esm({
38003
38288
  const refsDir = luxttsCloneRefsDir();
38004
38289
  if (!existsSync35(refsDir))
38005
38290
  mkdirSync13(refsDir, { recursive: true });
38006
- const destPath = join48(refsDir, `${sourceModelId}-ref.wav`);
38291
+ const destPath = join49(refsDir, `${sourceModelId}-ref.wav`);
38007
38292
  const sampleRate = this.config?.audio?.sample_rate ?? 22050;
38008
38293
  this.writeWav(audioData, sampleRate, destPath);
38009
38294
  this.luxttsCloneRef = destPath;
@@ -38019,7 +38304,7 @@ var init_voice = __esm({
38019
38304
  // -------------------------------------------------------------------------
38020
38305
  /** Metadata file for friendly names of clone refs */
38021
38306
  static cloneMetaFile() {
38022
- return join48(luxttsCloneRefsDir(), "meta.json");
38307
+ return join49(luxttsCloneRefsDir(), "meta.json");
38023
38308
  }
38024
38309
  loadCloneMeta() {
38025
38310
  const p = _VoiceEngine.cloneMetaFile();
@@ -38053,7 +38338,7 @@ var init_voice = __esm({
38053
38338
  return _VoiceEngine.AUDIO_EXTS.has(ext);
38054
38339
  });
38055
38340
  return files.map((f) => {
38056
- const p = join48(dir, f);
38341
+ const p = join49(dir, f);
38057
38342
  let size = 0;
38058
38343
  try {
38059
38344
  size = statSync12(p).size;
@@ -38070,7 +38355,7 @@ var init_voice = __esm({
38070
38355
  }
38071
38356
  /** Delete a clone reference file by filename. Returns true if deleted. */
38072
38357
  deleteCloneRef(filename) {
38073
- const p = join48(luxttsCloneRefsDir(), filename);
38358
+ const p = join49(luxttsCloneRefsDir(), filename);
38074
38359
  if (!existsSync35(p))
38075
38360
  return false;
38076
38361
  try {
@@ -38095,7 +38380,7 @@ var init_voice = __esm({
38095
38380
  }
38096
38381
  /** Set the active clone reference by filename. */
38097
38382
  setActiveCloneRef(filename) {
38098
- const p = join48(luxttsCloneRefsDir(), filename);
38383
+ const p = join49(luxttsCloneRefsDir(), filename);
38099
38384
  if (!existsSync35(p))
38100
38385
  return `File not found: ${filename}`;
38101
38386
  this.luxttsCloneRef = p;
@@ -38381,7 +38666,7 @@ var init_voice = __esm({
38381
38666
  }
38382
38667
  this.onPCMOutput(Buffer.from(int16.buffer), sampleRate);
38383
38668
  }
38384
- const wavPath = join48(tmpdir9(), `oa-voice-${Date.now()}.wav`);
38669
+ const wavPath = join49(tmpdir9(), `oa-voice-${Date.now()}.wav`);
38385
38670
  this.writeWav(audioData, sampleRate, wavPath);
38386
38671
  await this.playWav(wavPath);
38387
38672
  try {
@@ -38724,7 +39009,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
38724
39009
  const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
38725
39010
  const mlxVoice = model.mlxVoice ?? "af_heart";
38726
39011
  const mlxLangCode = model.mlxLangCode ?? "a";
38727
- const wavPath = join48(tmpdir9(), `oa-mlx-${Date.now()}.wav`);
39012
+ const wavPath = join49(tmpdir9(), `oa-mlx-${Date.now()}.wav`);
38728
39013
  const pyScript = [
38729
39014
  "import sys, json",
38730
39015
  "from mlx_audio.tts import generate as tts_gen",
@@ -38792,7 +39077,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
38792
39077
  const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
38793
39078
  const mlxVoice = model.mlxVoice ?? "af_heart";
38794
39079
  const mlxLangCode = model.mlxLangCode ?? "a";
38795
- const wavPath = join48(tmpdir9(), `oa-mlx-buf-${Date.now()}.wav`);
39080
+ const wavPath = join49(tmpdir9(), `oa-mlx-buf-${Date.now()}.wav`);
38796
39081
  const pyScript = [
38797
39082
  "import sys, json",
38798
39083
  "from mlx_audio.tts import generate as tts_gen",
@@ -38903,7 +39188,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
38903
39188
  }
38904
39189
  }
38905
39190
  const repoDir = luxttsRepoDir();
38906
- if (!existsSync35(join48(repoDir, "zipvoice", "luxvoice.py"))) {
39191
+ if (!existsSync35(join49(repoDir, "zipvoice", "luxvoice.py"))) {
38907
39192
  renderInfo(" Cloning LuxTTS repository...");
38908
39193
  try {
38909
39194
  if (existsSync35(repoDir)) {
@@ -38952,7 +39237,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
38952
39237
  if (!existsSync35(refsDir))
38953
39238
  return;
38954
39239
  for (const name of ["custom-clone.wav", "custom-clone.mp3", "glados-ref.wav", "overwatch-ref.wav"]) {
38955
- const p = join48(refsDir, name);
39240
+ const p = join49(refsDir, name);
38956
39241
  if (existsSync35(p)) {
38957
39242
  this.luxttsCloneRef = p;
38958
39243
  return;
@@ -39149,7 +39434,7 @@ if __name__ == '__main__':
39149
39434
  const ready = await this.ensureLuxttsDaemon();
39150
39435
  if (!ready)
39151
39436
  return;
39152
- const wavPath = join48(tmpdir9(), `oa-luxtts-${Date.now()}.wav`);
39437
+ const wavPath = join49(tmpdir9(), `oa-luxtts-${Date.now()}.wav`);
39153
39438
  try {
39154
39439
  await this.luxttsRequest({
39155
39440
  action: "synthesize",
@@ -39223,7 +39508,7 @@ if __name__ == '__main__':
39223
39508
  const ready = await this.ensureLuxttsDaemon();
39224
39509
  if (!ready)
39225
39510
  return null;
39226
- const wavPath = join48(tmpdir9(), `oa-luxtts-buf-${Date.now()}.wav`);
39511
+ const wavPath = join49(tmpdir9(), `oa-luxtts-buf-${Date.now()}.wav`);
39227
39512
  try {
39228
39513
  await this.luxttsRequest({
39229
39514
  action: "synthesize",
@@ -39253,7 +39538,7 @@ if __name__ == '__main__':
39253
39538
  return;
39254
39539
  const arch = process.arch;
39255
39540
  mkdirSync13(voiceDir(), { recursive: true });
39256
- const pkgPath = join48(voiceDir(), "package.json");
39541
+ const pkgPath = join49(voiceDir(), "package.json");
39257
39542
  const expectedDeps = {
39258
39543
  "onnxruntime-node": "^1.21.0",
39259
39544
  "phonemizer": "^1.2.1"
@@ -39275,17 +39560,17 @@ if __name__ == '__main__':
39275
39560
  dependencies: expectedDeps
39276
39561
  }, null, 2));
39277
39562
  }
39278
- const voiceRequire = createRequire(join48(voiceDir(), "index.js"));
39563
+ const voiceRequire = createRequire(join49(voiceDir(), "index.js"));
39279
39564
  const probeOnnx = () => {
39280
39565
  try {
39281
- const result = execSync27(`node -e "try { require('onnxruntime-node'); console.log('OK'); } catch(e) { console.log('FAIL:' + e.message); }"`, { cwd: voiceDir(), stdio: "pipe", timeout: 15e3, env: { ...process.env, NODE_PATH: join48(voiceDir(), "node_modules") } });
39566
+ const result = execSync27(`node -e "try { require('onnxruntime-node'); console.log('OK'); } catch(e) { console.log('FAIL:' + e.message); }"`, { cwd: voiceDir(), stdio: "pipe", timeout: 15e3, env: { ...process.env, NODE_PATH: join49(voiceDir(), "node_modules") } });
39282
39567
  const output = result.toString().trim();
39283
39568
  return output === "OK";
39284
39569
  } catch {
39285
39570
  return false;
39286
39571
  }
39287
39572
  };
39288
- const onnxNodeModules = join48(voiceDir(), "node_modules", "onnxruntime-node");
39573
+ const onnxNodeModules = join49(voiceDir(), "node_modules", "onnxruntime-node");
39289
39574
  const onnxInstalled = existsSync35(onnxNodeModules);
39290
39575
  if (onnxInstalled && !probeOnnx()) {
39291
39576
  throw new Error(`Voice synthesis unavailable: ONNX runtime crashes on this CPU (${process.platform}-${arch}). This is a known issue with some ARM SoCs where the CPU vendor is not recognized. Voice feedback will be disabled but all other features work normally.`);
@@ -41629,8 +41914,8 @@ async function handlePeerEndpoint(peerId, authKey, ctx, local) {
41629
41914
  if (models.length > 0) {
41630
41915
  try {
41631
41916
  const { writeFileSync: writeFileSync20, mkdirSync: mkdirSync21 } = await import("node:fs");
41632
- const { join: join62, dirname: dirname20 } = await import("node:path");
41633
- const cachePath = join62(ctx.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
41917
+ const { join: join63, dirname: dirname20 } = await import("node:path");
41918
+ const cachePath = join63(ctx.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
41634
41919
  mkdirSync21(dirname20(cachePath), { recursive: true });
41635
41920
  writeFileSync20(cachePath, JSON.stringify({
41636
41921
  peerId,
@@ -41831,14 +42116,14 @@ async function handleUpdate(subcommand, ctx) {
41831
42116
  try {
41832
42117
  const { createRequire: createRequire4 } = await import("node:module");
41833
42118
  const { fileURLToPath: fileURLToPath14 } = await import("node:url");
41834
- const { dirname: dirname20, join: join62 } = await import("node:path");
42119
+ const { dirname: dirname20, join: join63 } = await import("node:path");
41835
42120
  const { existsSync: existsSync45 } = await import("node:fs");
41836
42121
  const req = createRequire4(import.meta.url);
41837
42122
  const thisDir = dirname20(fileURLToPath14(import.meta.url));
41838
42123
  const candidates = [
41839
- join62(thisDir, "..", "package.json"),
41840
- join62(thisDir, "..", "..", "package.json"),
41841
- join62(thisDir, "..", "..", "..", "package.json")
42124
+ join63(thisDir, "..", "package.json"),
42125
+ join63(thisDir, "..", "..", "package.json"),
42126
+ join63(thisDir, "..", "..", "..", "package.json")
41842
42127
  ];
41843
42128
  for (const pkgPath of candidates) {
41844
42129
  if (existsSync45(pkgPath)) {
@@ -42556,7 +42841,7 @@ var init_commands = __esm({
42556
42841
 
42557
42842
  // packages/cli/dist/tui/project-context.js
42558
42843
  import { existsSync as existsSync36, readFileSync as readFileSync25, readdirSync as readdirSync10 } from "node:fs";
42559
- import { join as join49, basename as basename10 } from "node:path";
42844
+ import { join as join50, basename as basename10 } from "node:path";
42560
42845
  import { execSync as execSync28 } from "node:child_process";
42561
42846
  import { homedir as homedir12, platform as platform3, release } from "node:os";
42562
42847
  function getModelTier(modelName) {
@@ -42591,7 +42876,7 @@ function loadProjectMap(repoRoot) {
42591
42876
  if (!hasOaDirectory(repoRoot)) {
42592
42877
  initOaDirectory(repoRoot);
42593
42878
  }
42594
- const mapPath = join49(repoRoot, OA_DIR, "context", "project-map.md");
42879
+ const mapPath = join50(repoRoot, OA_DIR, "context", "project-map.md");
42595
42880
  if (existsSync36(mapPath)) {
42596
42881
  try {
42597
42882
  const content = readFileSync25(mapPath, "utf-8");
@@ -42635,17 +42920,17 @@ ${log}`);
42635
42920
  }
42636
42921
  function loadMemoryContext(repoRoot) {
42637
42922
  const sections = [];
42638
- const oaMemDir = join49(repoRoot, OA_DIR, "memory");
42923
+ const oaMemDir = join50(repoRoot, OA_DIR, "memory");
42639
42924
  const oaEntries = loadMemoryDir(oaMemDir, "project");
42640
42925
  if (oaEntries)
42641
42926
  sections.push(oaEntries);
42642
- const legacyMemDir = join49(repoRoot, ".open-agents", "memory");
42927
+ const legacyMemDir = join50(repoRoot, ".open-agents", "memory");
42643
42928
  if (legacyMemDir !== oaMemDir && existsSync36(legacyMemDir)) {
42644
42929
  const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
42645
42930
  if (legacyEntries)
42646
42931
  sections.push(legacyEntries);
42647
42932
  }
42648
- const globalMemDir = join49(homedir12(), ".open-agents", "memory");
42933
+ const globalMemDir = join50(homedir12(), ".open-agents", "memory");
42649
42934
  const globalEntries = loadMemoryDir(globalMemDir, "global");
42650
42935
  if (globalEntries)
42651
42936
  sections.push(globalEntries);
@@ -42659,7 +42944,7 @@ function loadMemoryDir(memDir, scope) {
42659
42944
  const files = readdirSync10(memDir).filter((f) => f.endsWith(".json"));
42660
42945
  for (const file of files.slice(0, 10)) {
42661
42946
  try {
42662
- const raw = readFileSync25(join49(memDir, file), "utf-8");
42947
+ const raw = readFileSync25(join50(memDir, file), "utf-8");
42663
42948
  const entries = JSON.parse(raw);
42664
42949
  const topic = basename10(file, ".json");
42665
42950
  const keys = Object.keys(entries);
@@ -43683,9 +43968,9 @@ var init_carousel = __esm({
43683
43968
 
43684
43969
  // packages/cli/dist/tui/carousel-descriptors.js
43685
43970
  import { existsSync as existsSync37, readFileSync as readFileSync26, writeFileSync as writeFileSync15, mkdirSync as mkdirSync14, readdirSync as readdirSync11 } from "node:fs";
43686
- import { join as join50, basename as basename11 } from "node:path";
43971
+ import { join as join51, basename as basename11 } from "node:path";
43687
43972
  function loadToolProfile(repoRoot) {
43688
- const filePath = join50(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
43973
+ const filePath = join51(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
43689
43974
  try {
43690
43975
  if (!existsSync37(filePath))
43691
43976
  return null;
@@ -43695,9 +43980,9 @@ function loadToolProfile(repoRoot) {
43695
43980
  }
43696
43981
  }
43697
43982
  function saveToolProfile(repoRoot, profile) {
43698
- const contextDir = join50(repoRoot, OA_DIR, "context");
43983
+ const contextDir = join51(repoRoot, OA_DIR, "context");
43699
43984
  mkdirSync14(contextDir, { recursive: true });
43700
- writeFileSync15(join50(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
43985
+ writeFileSync15(join51(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
43701
43986
  }
43702
43987
  function categorizeToolCall(toolName) {
43703
43988
  for (const cat of TOOL_CATEGORIES) {
@@ -43755,7 +44040,7 @@ function weightedColor(profile) {
43755
44040
  return selectedCat.colors[Math.floor(Math.random() * selectedCat.colors.length)];
43756
44041
  }
43757
44042
  function loadCachedDescriptors(repoRoot) {
43758
- const filePath = join50(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
44043
+ const filePath = join51(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
43759
44044
  try {
43760
44045
  if (!existsSync37(filePath))
43761
44046
  return null;
@@ -43766,14 +44051,14 @@ function loadCachedDescriptors(repoRoot) {
43766
44051
  }
43767
44052
  }
43768
44053
  function saveCachedDescriptors(repoRoot, phrases, sourceHash) {
43769
- const contextDir = join50(repoRoot, OA_DIR, "context");
44054
+ const contextDir = join51(repoRoot, OA_DIR, "context");
43770
44055
  mkdirSync14(contextDir, { recursive: true });
43771
44056
  const cached = {
43772
44057
  phrases,
43773
44058
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
43774
44059
  sourceHash
43775
44060
  };
43776
- writeFileSync15(join50(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
44061
+ writeFileSync15(join51(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
43777
44062
  }
43778
44063
  function generateDescriptors(repoRoot) {
43779
44064
  const profile = loadToolProfile(repoRoot);
@@ -43821,7 +44106,7 @@ function generateDescriptors(repoRoot) {
43821
44106
  return phrases;
43822
44107
  }
43823
44108
  function extractFromPackageJson(repoRoot, tags) {
43824
- const pkgPath = join50(repoRoot, "package.json");
44109
+ const pkgPath = join51(repoRoot, "package.json");
43825
44110
  try {
43826
44111
  if (!existsSync37(pkgPath))
43827
44112
  return;
@@ -43869,7 +44154,7 @@ function extractFromManifests(repoRoot, tags) {
43869
44154
  { file: ".github/workflows", tag: "ci/cd" }
43870
44155
  ];
43871
44156
  for (const check of manifestChecks) {
43872
- if (existsSync37(join50(repoRoot, check.file))) {
44157
+ if (existsSync37(join51(repoRoot, check.file))) {
43873
44158
  tags.push(check.tag);
43874
44159
  }
43875
44160
  }
@@ -43891,7 +44176,7 @@ function extractFromSessions(repoRoot, tags) {
43891
44176
  }
43892
44177
  }
43893
44178
  function extractFromMemory(repoRoot, tags) {
43894
- const memoryDir = join50(repoRoot, OA_DIR, "memory");
44179
+ const memoryDir = join51(repoRoot, OA_DIR, "memory");
43895
44180
  try {
43896
44181
  if (!existsSync37(memoryDir))
43897
44182
  return;
@@ -43900,7 +44185,7 @@ function extractFromMemory(repoRoot, tags) {
43900
44185
  const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
43901
44186
  tags.push(topic);
43902
44187
  try {
43903
- const data = JSON.parse(readFileSync26(join50(memoryDir, file), "utf-8"));
44188
+ const data = JSON.parse(readFileSync26(join51(memoryDir, file), "utf-8"));
43904
44189
  if (data && typeof data === "object") {
43905
44190
  const keys = Object.keys(data).slice(0, 3);
43906
44191
  for (const key of keys) {
@@ -44523,10 +44808,10 @@ var init_stream_renderer = __esm({
44523
44808
 
44524
44809
  // packages/cli/dist/tui/edit-history.js
44525
44810
  import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync15 } from "node:fs";
44526
- import { join as join51 } from "node:path";
44811
+ import { join as join52 } from "node:path";
44527
44812
  function createEditHistoryLogger(repoRoot, sessionId) {
44528
- const historyDir = join51(repoRoot, ".oa", "history");
44529
- const logPath = join51(historyDir, "edits.jsonl");
44813
+ const historyDir = join52(repoRoot, ".oa", "history");
44814
+ const logPath = join52(historyDir, "edits.jsonl");
44530
44815
  try {
44531
44816
  mkdirSync15(historyDir, { recursive: true });
44532
44817
  } catch {
@@ -44638,12 +44923,12 @@ var init_edit_history = __esm({
44638
44923
 
44639
44924
  // packages/cli/dist/tui/promptLoader.js
44640
44925
  import { readFileSync as readFileSync27, existsSync as existsSync38 } from "node:fs";
44641
- import { join as join52, dirname as dirname17 } from "node:path";
44926
+ import { join as join53, dirname as dirname17 } from "node:path";
44642
44927
  import { fileURLToPath as fileURLToPath11 } from "node:url";
44643
44928
  function loadPrompt3(promptPath, vars) {
44644
44929
  let content = cache3.get(promptPath);
44645
44930
  if (content === void 0) {
44646
- const fullPath = join52(PROMPTS_DIR3, promptPath);
44931
+ const fullPath = join53(PROMPTS_DIR3, promptPath);
44647
44932
  if (!existsSync38(fullPath)) {
44648
44933
  throw new Error(`Prompt file not found: ${fullPath}`);
44649
44934
  }
@@ -44660,8 +44945,8 @@ var init_promptLoader3 = __esm({
44660
44945
  "use strict";
44661
44946
  __filename3 = fileURLToPath11(import.meta.url);
44662
44947
  __dirname6 = dirname17(__filename3);
44663
- devPath2 = join52(__dirname6, "..", "..", "prompts");
44664
- publishedPath2 = join52(__dirname6, "..", "prompts");
44948
+ devPath2 = join53(__dirname6, "..", "..", "prompts");
44949
+ publishedPath2 = join53(__dirname6, "..", "prompts");
44665
44950
  PROMPTS_DIR3 = existsSync38(devPath2) ? devPath2 : publishedPath2;
44666
44951
  cache3 = /* @__PURE__ */ new Map();
44667
44952
  }
@@ -44669,10 +44954,10 @@ var init_promptLoader3 = __esm({
44669
44954
 
44670
44955
  // packages/cli/dist/tui/dream-engine.js
44671
44956
  import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync16, readFileSync as readFileSync28, existsSync as existsSync39, cpSync, rmSync, readdirSync as readdirSync12 } from "node:fs";
44672
- import { join as join53, basename as basename12 } from "node:path";
44957
+ import { join as join54, basename as basename12 } from "node:path";
44673
44958
  import { execSync as execSync29 } from "node:child_process";
44674
44959
  function loadAutoresearchMemory(repoRoot) {
44675
- const memoryPath = join53(repoRoot, ".oa", "memory", "autoresearch.json");
44960
+ const memoryPath = join54(repoRoot, ".oa", "memory", "autoresearch.json");
44676
44961
  if (!existsSync39(memoryPath))
44677
44962
  return "";
44678
44963
  try {
@@ -44866,12 +45151,12 @@ var init_dream_engine = __esm({
44866
45151
  const content = String(args["content"] ?? "");
44867
45152
  if (!rawPath)
44868
45153
  return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
44869
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join53(this.autoresearchDir, basename12(rawPath)) : join53(this.autoresearchDir, rawPath);
45154
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join54(this.autoresearchDir, basename12(rawPath)) : join54(this.autoresearchDir, rawPath);
44870
45155
  if (!targetPath.startsWith(this.autoresearchDir)) {
44871
45156
  return { success: false, output: "", error: "Autoresearch mode: writes are confined to .oa/autoresearch/", durationMs: Date.now() - start };
44872
45157
  }
44873
45158
  try {
44874
- const dir = join53(targetPath, "..");
45159
+ const dir = join54(targetPath, "..");
44875
45160
  mkdirSync16(dir, { recursive: true });
44876
45161
  writeFileSync16(targetPath, content, "utf-8");
44877
45162
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
@@ -44901,7 +45186,7 @@ var init_dream_engine = __esm({
44901
45186
  const rawPath = String(args["path"] ?? "");
44902
45187
  const oldStr = String(args["old_string"] ?? "");
44903
45188
  const newStr = String(args["new_string"] ?? "");
44904
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join53(this.autoresearchDir, basename12(rawPath)) : join53(this.autoresearchDir, rawPath);
45189
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join54(this.autoresearchDir, basename12(rawPath)) : join54(this.autoresearchDir, rawPath);
44905
45190
  if (!targetPath.startsWith(this.autoresearchDir)) {
44906
45191
  return { success: false, output: "", error: "Autoresearch mode: edits are confined to .oa/autoresearch/", durationMs: Date.now() - start };
44907
45192
  }
@@ -44955,12 +45240,12 @@ var init_dream_engine = __esm({
44955
45240
  const content = String(args["content"] ?? "");
44956
45241
  if (!rawPath)
44957
45242
  return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
44958
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join53(this.dreamsDir, basename12(rawPath)) : join53(this.dreamsDir, rawPath);
45243
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join54(this.dreamsDir, basename12(rawPath)) : join54(this.dreamsDir, rawPath);
44959
45244
  if (!targetPath.startsWith(this.dreamsDir)) {
44960
45245
  return { success: false, output: "", error: "Dream mode: writes are confined to .oa/dreams/", durationMs: Date.now() - start };
44961
45246
  }
44962
45247
  try {
44963
- const dir = join53(targetPath, "..");
45248
+ const dir = join54(targetPath, "..");
44964
45249
  mkdirSync16(dir, { recursive: true });
44965
45250
  writeFileSync16(targetPath, content, "utf-8");
44966
45251
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
@@ -44990,7 +45275,7 @@ var init_dream_engine = __esm({
44990
45275
  const rawPath = String(args["path"] ?? "");
44991
45276
  const oldStr = String(args["old_string"] ?? "");
44992
45277
  const newStr = String(args["new_string"] ?? "");
44993
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join53(this.dreamsDir, basename12(rawPath)) : join53(this.dreamsDir, rawPath);
45278
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join54(this.dreamsDir, basename12(rawPath)) : join54(this.dreamsDir, rawPath);
44994
45279
  if (!targetPath.startsWith(this.dreamsDir)) {
44995
45280
  return { success: false, output: "", error: "Dream mode: edits are confined to .oa/dreams/", durationMs: Date.now() - start };
44996
45281
  }
@@ -45057,7 +45342,7 @@ var init_dream_engine = __esm({
45057
45342
  constructor(config, repoRoot) {
45058
45343
  this.config = config;
45059
45344
  this.repoRoot = repoRoot;
45060
- this.dreamsDir = join53(repoRoot, ".oa", "dreams");
45345
+ this.dreamsDir = join54(repoRoot, ".oa", "dreams");
45061
45346
  this.state = {
45062
45347
  mode: "default",
45063
45348
  active: false,
@@ -45141,7 +45426,7 @@ ${result.summary}`;
45141
45426
  if (mode !== "default" || cycle === totalCycles) {
45142
45427
  renderDreamContraction(cycle);
45143
45428
  const cycleSummary = this.buildCycleSummary(cycle, previousFindings);
45144
- const summaryPath = join53(this.dreamsDir, `cycle-${cycle}-summary.md`);
45429
+ const summaryPath = join54(this.dreamsDir, `cycle-${cycle}-summary.md`);
45145
45430
  writeFileSync16(summaryPath, cycleSummary, "utf-8");
45146
45431
  }
45147
45432
  if (mode === "lucid" && !this.abortController.signal.aborted) {
@@ -45354,7 +45639,7 @@ After synthesis, call task_complete with the final prioritized summary.`, toolMo
45354
45639
  }
45355
45640
  /** Build role-specific tool sets for swarm agents */
45356
45641
  buildSwarmTools(role, _workspace) {
45357
- const autoresearchDir = join53(this.repoRoot, ".oa", "autoresearch");
45642
+ const autoresearchDir = join54(this.repoRoot, ".oa", "autoresearch");
45358
45643
  const taskComplete = this.createSwarmTaskCompleteTool(role);
45359
45644
  switch (role) {
45360
45645
  case "researcher": {
@@ -45718,7 +46003,7 @@ INSTRUCTIONS:
45718
46003
  2. Summarize the key learnings and next steps
45719
46004
 
45720
46005
  Call task_complete with a human-readable summary of the autoresearch session.`, workspace, onEvent);
45721
- const reportPath = join53(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
46006
+ const reportPath = join54(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
45722
46007
  const report = `# Autoresearch Swarm Report \u2014 Cycle ${cycleNum}
45723
46008
 
45724
46009
  **Date**: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
@@ -45807,7 +46092,7 @@ ${summaryResult}
45807
46092
  }
45808
46093
  /** Save workspace backup for lucid mode */
45809
46094
  saveVersionCheckpoint(cycle) {
45810
- const checkpointDir = join53(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
46095
+ const checkpointDir = join54(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
45811
46096
  try {
45812
46097
  mkdirSync16(checkpointDir, { recursive: true });
45813
46098
  try {
@@ -45826,10 +46111,10 @@ ${summaryResult}
45826
46111
  encoding: "utf-8",
45827
46112
  timeout: 5e3
45828
46113
  }).trim();
45829
- writeFileSync16(join53(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
45830
- writeFileSync16(join53(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
45831
- writeFileSync16(join53(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
45832
- writeFileSync16(join53(checkpointDir, "checkpoint.json"), JSON.stringify({
46114
+ writeFileSync16(join54(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
46115
+ writeFileSync16(join54(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
46116
+ writeFileSync16(join54(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
46117
+ writeFileSync16(join54(checkpointDir, "checkpoint.json"), JSON.stringify({
45833
46118
  cycle,
45834
46119
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
45835
46120
  gitHash,
@@ -45837,7 +46122,7 @@ ${summaryResult}
45837
46122
  }, null, 2), "utf-8");
45838
46123
  renderInfo(`Checkpoint saved: cycle ${cycle} (${gitHash.slice(0, 8)})`);
45839
46124
  } catch {
45840
- writeFileSync16(join53(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
46125
+ writeFileSync16(join54(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
45841
46126
  renderInfo(`Checkpoint saved: cycle ${cycle} (no git)`);
45842
46127
  }
45843
46128
  } catch (err) {
@@ -45895,14 +46180,14 @@ ${files.map((f) => `- [\`${f}\`](./${f})`).join("\n")}
45895
46180
  ---
45896
46181
  *Auto-generated by open-agents dream engine*
45897
46182
  `;
45898
- writeFileSync16(join53(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
46183
+ writeFileSync16(join54(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
45899
46184
  } catch {
45900
46185
  }
45901
46186
  }
45902
46187
  /** Save dream state for resume/inspection */
45903
46188
  saveDreamState() {
45904
46189
  try {
45905
- writeFileSync16(join53(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
46190
+ writeFileSync16(join54(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
45906
46191
  } catch {
45907
46192
  }
45908
46193
  }
@@ -46277,7 +46562,7 @@ var init_bless_engine = __esm({
46277
46562
 
46278
46563
  // packages/cli/dist/tui/dmn-engine.js
46279
46564
  import { existsSync as existsSync40, readFileSync as readFileSync29, writeFileSync as writeFileSync17, mkdirSync as mkdirSync17, readdirSync as readdirSync13, unlinkSync as unlinkSync9 } from "node:fs";
46280
- import { join as join54, basename as basename13 } from "node:path";
46565
+ import { join as join55, basename as basename13 } from "node:path";
46281
46566
  function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
46282
46567
  const competenceReport = competence.length > 0 ? competence.map((c3) => {
46283
46568
  const rate = c3.attempts > 0 ? Math.round(c3.successes / c3.attempts * 100) : 0;
@@ -46390,8 +46675,8 @@ var init_dmn_engine = __esm({
46390
46675
  constructor(config, repoRoot) {
46391
46676
  this.config = config;
46392
46677
  this.repoRoot = repoRoot;
46393
- this.stateDir = join54(repoRoot, ".oa", "dmn");
46394
- this.historyDir = join54(repoRoot, ".oa", "dmn", "cycles");
46678
+ this.stateDir = join55(repoRoot, ".oa", "dmn");
46679
+ this.historyDir = join55(repoRoot, ".oa", "dmn", "cycles");
46395
46680
  mkdirSync17(this.historyDir, { recursive: true });
46396
46681
  this.loadState();
46397
46682
  }
@@ -46981,8 +47266,8 @@ OUTPUT: Call task_complete with JSON:
46981
47266
  async gatherMemoryTopics() {
46982
47267
  const topics = [];
46983
47268
  const dirs = [
46984
- join54(this.repoRoot, ".oa", "memory"),
46985
- join54(this.repoRoot, ".open-agents", "memory")
47269
+ join55(this.repoRoot, ".oa", "memory"),
47270
+ join55(this.repoRoot, ".open-agents", "memory")
46986
47271
  ];
46987
47272
  for (const dir of dirs) {
46988
47273
  if (!existsSync40(dir))
@@ -47001,7 +47286,7 @@ OUTPUT: Call task_complete with JSON:
47001
47286
  }
47002
47287
  // ── State persistence ─────────────────────────────────────────────────
47003
47288
  loadState() {
47004
- const path = join54(this.stateDir, "state.json");
47289
+ const path = join55(this.stateDir, "state.json");
47005
47290
  if (existsSync40(path)) {
47006
47291
  try {
47007
47292
  this.state = JSON.parse(readFileSync29(path, "utf-8"));
@@ -47011,19 +47296,19 @@ OUTPUT: Call task_complete with JSON:
47011
47296
  }
47012
47297
  saveState() {
47013
47298
  try {
47014
- writeFileSync17(join54(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
47299
+ writeFileSync17(join55(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
47015
47300
  } catch {
47016
47301
  }
47017
47302
  }
47018
47303
  saveCycleResult(result) {
47019
47304
  try {
47020
47305
  const filename = `cycle-${result.cycleNumber}-${Date.now()}.json`;
47021
- writeFileSync17(join54(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
47306
+ writeFileSync17(join55(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
47022
47307
  const files = readdirSync13(this.historyDir).filter((f) => f.startsWith("cycle-") && f.endsWith(".json")).sort();
47023
47308
  if (files.length > 50) {
47024
47309
  for (const old of files.slice(0, files.length - 50)) {
47025
47310
  try {
47026
- unlinkSync9(join54(this.historyDir, old));
47311
+ unlinkSync9(join55(this.historyDir, old));
47027
47312
  } catch {
47028
47313
  }
47029
47314
  }
@@ -47037,7 +47322,7 @@ OUTPUT: Call task_complete with JSON:
47037
47322
 
47038
47323
  // packages/cli/dist/tui/snr-engine.js
47039
47324
  import { existsSync as existsSync41, readdirSync as readdirSync14, readFileSync as readFileSync30 } from "node:fs";
47040
- import { join as join55, basename as basename14 } from "node:path";
47325
+ import { join as join56, basename as basename14 } from "node:path";
47041
47326
  function computeDPrime(signalScores, noiseScores) {
47042
47327
  if (signalScores.length === 0 || noiseScores.length === 0)
47043
47328
  return 0;
@@ -47277,8 +47562,8 @@ Call task_complete with the JSON array when done.`, onEvent)
47277
47562
  loadMemoryEntries(topics) {
47278
47563
  const entries = [];
47279
47564
  const dirs = [
47280
- join55(this.repoRoot, ".oa", "memory"),
47281
- join55(this.repoRoot, ".open-agents", "memory")
47565
+ join56(this.repoRoot, ".oa", "memory"),
47566
+ join56(this.repoRoot, ".open-agents", "memory")
47282
47567
  ];
47283
47568
  for (const dir of dirs) {
47284
47569
  if (!existsSync41(dir))
@@ -47290,7 +47575,7 @@ Call task_complete with the JSON array when done.`, onEvent)
47290
47575
  if (topics.length > 0 && !topics.includes(topic))
47291
47576
  continue;
47292
47577
  try {
47293
- const data = JSON.parse(readFileSync30(join55(dir, f), "utf-8"));
47578
+ const data = JSON.parse(readFileSync30(join56(dir, f), "utf-8"));
47294
47579
  for (const [key, val] of Object.entries(data)) {
47295
47580
  const value = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
47296
47581
  entries.push({ topic, key, value });
@@ -47858,7 +48143,7 @@ var init_tool_policy = __esm({
47858
48143
 
47859
48144
  // packages/cli/dist/tui/telegram-bridge.js
47860
48145
  import { mkdirSync as mkdirSync18, existsSync as existsSync42, unlinkSync as unlinkSync10, readdirSync as readdirSync15, statSync as statSync13 } from "node:fs";
47861
- import { join as join56, resolve as resolve28 } from "node:path";
48146
+ import { join as join57, resolve as resolve28 } from "node:path";
47862
48147
  import { writeFile as writeFileAsync } from "node:fs/promises";
47863
48148
  function convertMarkdownToTelegramHTML(md) {
47864
48149
  let html = md;
@@ -48623,7 +48908,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
48623
48908
  return null;
48624
48909
  const buffer = Buffer.from(await res.arrayBuffer());
48625
48910
  const fileName = `${Date.now()}-${fileId.slice(0, 8)}${extension}`;
48626
- const localPath = join56(this.mediaCacheDir, fileName);
48911
+ const localPath = join57(this.mediaCacheDir, fileName);
48627
48912
  await writeFileAsync(localPath, buffer);
48628
48913
  return localPath;
48629
48914
  } catch {
@@ -49274,7 +49559,7 @@ var init_braille_spinner = __esm({
49274
49559
  // packages/cli/dist/tui/system-metrics.js
49275
49560
  import { loadavg as loadavg3, cpus as cpus3, totalmem as totalmem4, freemem as freemem3, platform as platform4 } from "node:os";
49276
49561
  import { exec as exec3 } from "node:child_process";
49277
- import { readFile as readFile20 } from "node:fs/promises";
49562
+ import { readFile as readFile21 } from "node:fs/promises";
49278
49563
  function formatRate(bytesPerSec) {
49279
49564
  if (bytesPerSec < 1024)
49280
49565
  return `${Math.round(bytesPerSec)}B`;
@@ -49286,7 +49571,7 @@ function formatRate(bytesPerSec) {
49286
49571
  }
49287
49572
  async function readProcNetDev() {
49288
49573
  try {
49289
- const data = await readFile20("/proc/net/dev", "utf8");
49574
+ const data = await readFile21("/proc/net/dev", "utf8");
49290
49575
  let rxTotal = 0;
49291
49576
  let txTotal = 0;
49292
49577
  for (const line of data.split("\n")) {
@@ -51061,7 +51346,7 @@ var init_status_bar = __esm({
51061
51346
  import * as readline2 from "node:readline";
51062
51347
  import { Writable } from "node:stream";
51063
51348
  import { cwd } from "node:process";
51064
- import { resolve as resolve29, join as join57, dirname as dirname18, extname as extname10 } from "node:path";
51349
+ import { resolve as resolve29, join as join58, dirname as dirname18, extname as extname10 } from "node:path";
51065
51350
  import { createRequire as createRequire2 } from "node:module";
51066
51351
  import { fileURLToPath as fileURLToPath12 } from "node:url";
51067
51352
  import { readFileSync as readFileSync32, writeFileSync as writeFileSync18, appendFileSync as appendFileSync4, rmSync as rmSync2, readdirSync as readdirSync16, mkdirSync as mkdirSync19 } from "node:fs";
@@ -51085,9 +51370,9 @@ function getVersion3() {
51085
51370
  const require2 = createRequire2(import.meta.url);
51086
51371
  const thisDir = dirname18(fileURLToPath12(import.meta.url));
51087
51372
  const candidates = [
51088
- join57(thisDir, "..", "package.json"),
51089
- join57(thisDir, "..", "..", "package.json"),
51090
- join57(thisDir, "..", "..", "..", "package.json")
51373
+ join58(thisDir, "..", "package.json"),
51374
+ join58(thisDir, "..", "..", "package.json"),
51375
+ join58(thisDir, "..", "..", "..", "package.json")
51091
51376
  ];
51092
51377
  for (const pkgPath of candidates) {
51093
51378
  if (existsSync43(pkgPath)) {
@@ -51188,6 +51473,8 @@ function buildTools(repoRoot, config, contextWindowSize) {
51188
51473
  new ReflectionIntegrityTool(repoRoot),
51189
51474
  // Exploration & Culture — COHERE Layer 8 (ARCHE)
51190
51475
  new ExplorationCultureTool(repoRoot),
51476
+ // Embedding Store — COHERE Private Brain semantic retrieval
51477
+ new EmbeddingStoreTool(repoRoot),
51191
51478
  // Structured file reading (CSV, JSON, Markdown, binary detection)
51192
51479
  new StructuredReadTool(repoRoot),
51193
51480
  // Vision tools (Moondream — desktop awareness + point-and-click)
@@ -51307,15 +51594,15 @@ Use task_status("${taskId}") or task_output("${taskId}") to check progress.`
51307
51594
  function gatherMemorySnippets(root) {
51308
51595
  const snippets = [];
51309
51596
  const dirs = [
51310
- join57(root, ".oa", "memory"),
51311
- join57(root, ".open-agents", "memory")
51597
+ join58(root, ".oa", "memory"),
51598
+ join58(root, ".open-agents", "memory")
51312
51599
  ];
51313
51600
  for (const dir of dirs) {
51314
51601
  if (!existsSync43(dir))
51315
51602
  continue;
51316
51603
  try {
51317
51604
  for (const f of readdirSync16(dir).filter((f2) => f2.endsWith(".json"))) {
51318
- const data = JSON.parse(readFileSync32(join57(dir, f), "utf-8"));
51605
+ const data = JSON.parse(readFileSync32(join58(dir, f), "utf-8"));
51319
51606
  for (const val of Object.values(data)) {
51320
51607
  const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
51321
51608
  if (v.length > 10)
@@ -52364,7 +52651,7 @@ async function startInteractive(config, repoPath) {
52364
52651
  let p2pGateway = null;
52365
52652
  let peerMesh = null;
52366
52653
  let inferenceRouter = null;
52367
- const secretVault = new SecretVault(join57(repoRoot, ".oa", "vault.enc"));
52654
+ const secretVault = new SecretVault(join58(repoRoot, ".oa", "vault.enc"));
52368
52655
  let adminSessionKey = null;
52369
52656
  const callSubAgents = /* @__PURE__ */ new Map();
52370
52657
  const streamRenderer = new StreamRenderer();
@@ -52573,8 +52860,8 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
52573
52860
  const hits = allCompletions.filter((c3) => c3.toLowerCase().startsWith(lower));
52574
52861
  return [hits, line];
52575
52862
  }
52576
- const HISTORY_DIR = join57(homedir13(), ".open-agents");
52577
- const HISTORY_FILE = join57(HISTORY_DIR, "repl-history");
52863
+ const HISTORY_DIR = join58(homedir13(), ".open-agents");
52864
+ const HISTORY_FILE = join58(HISTORY_DIR, "repl-history");
52578
52865
  const MAX_HISTORY_LINES = 500;
52579
52866
  let savedHistory = [];
52580
52867
  try {
@@ -52784,7 +53071,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
52784
53071
  } catch {
52785
53072
  }
52786
53073
  try {
52787
- const oaDir = join57(repoRoot, ".oa");
53074
+ const oaDir = join58(repoRoot, ".oa");
52788
53075
  const reconnected = await ExposeGateway.checkAndReconnect(oaDir, {
52789
53076
  onInfo: (msg) => writeContent(() => renderInfo(msg)),
52790
53077
  onError: (msg) => writeContent(() => renderWarning(msg))
@@ -52807,7 +53094,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
52807
53094
  } catch {
52808
53095
  }
52809
53096
  try {
52810
- const oaDir = join57(repoRoot, ".oa");
53097
+ const oaDir = join58(repoRoot, ".oa");
52811
53098
  const reconnectedP2P = await ExposeP2PGateway.checkAndReconnect(oaDir, new NexusTool(repoRoot), {
52812
53099
  onInfo: (msg) => writeContent(() => renderInfo(msg)),
52813
53100
  onError: (msg) => writeContent(() => renderWarning(msg))
@@ -53626,7 +53913,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
53626
53913
  kind,
53627
53914
  targetUrl,
53628
53915
  authKey,
53629
- stateDir: join57(repoRoot, ".oa"),
53916
+ stateDir: join58(repoRoot, ".oa"),
53630
53917
  passthrough: passthrough ?? false,
53631
53918
  loadbalance: loadbalance ?? false,
53632
53919
  endpointAuth: passthrough ? currentConfig.apiKey : void 0,
@@ -53674,7 +53961,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
53674
53961
  await tunnelGateway.stop();
53675
53962
  tunnelGateway = null;
53676
53963
  }
53677
- const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join57(repoRoot, ".oa") });
53964
+ const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join58(repoRoot, ".oa") });
53678
53965
  newTunnel.on("stats", (stats) => {
53679
53966
  statusBar.setExposeStatus({
53680
53967
  status: stats.status,
@@ -53936,7 +54223,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
53936
54223
  }
53937
54224
  },
53938
54225
  destroyProject() {
53939
- const oaPath = join57(repoRoot, OA_DIR);
54226
+ const oaPath = join58(repoRoot, OA_DIR);
53940
54227
  if (existsSync43(oaPath)) {
53941
54228
  try {
53942
54229
  rmSync2(oaPath, { recursive: true, force: true });
@@ -54869,9 +55156,9 @@ var init_run = __esm({
54869
55156
  // packages/indexer/dist/codebase-indexer.js
54870
55157
  import { glob } from "glob";
54871
55158
  import ignore from "ignore";
54872
- import { readFile as readFile21, stat as stat4 } from "node:fs/promises";
55159
+ import { readFile as readFile22, stat as stat4 } from "node:fs/promises";
54873
55160
  import { createHash as createHash4 } from "node:crypto";
54874
- import { join as join58, relative as relative3, extname as extname11, basename as basename15 } from "node:path";
55161
+ import { join as join59, relative as relative3, extname as extname11, basename as basename15 } from "node:path";
54875
55162
  var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
54876
55163
  var init_codebase_indexer = __esm({
54877
55164
  "packages/indexer/dist/codebase-indexer.js"() {
@@ -54915,7 +55202,7 @@ var init_codebase_indexer = __esm({
54915
55202
  const ig = ignore.default();
54916
55203
  if (this.config.respectGitignore) {
54917
55204
  try {
54918
- const gitignoreContent = await readFile21(join58(this.config.rootDir, ".gitignore"), "utf-8");
55205
+ const gitignoreContent = await readFile22(join59(this.config.rootDir, ".gitignore"), "utf-8");
54919
55206
  ig.add(gitignoreContent);
54920
55207
  } catch {
54921
55208
  }
@@ -54930,12 +55217,12 @@ var init_codebase_indexer = __esm({
54930
55217
  for (const relativePath of files) {
54931
55218
  if (ig.ignores(relativePath))
54932
55219
  continue;
54933
- const fullPath = join58(this.config.rootDir, relativePath);
55220
+ const fullPath = join59(this.config.rootDir, relativePath);
54934
55221
  try {
54935
55222
  const fileStat = await stat4(fullPath);
54936
55223
  if (fileStat.size > this.config.maxFileSize)
54937
55224
  continue;
54938
- const content = await readFile21(fullPath);
55225
+ const content = await readFile22(fullPath);
54939
55226
  const hash = createHash4("sha256").update(content).digest("hex");
54940
55227
  const ext = extname11(relativePath);
54941
55228
  indexed.push({
@@ -54976,7 +55263,7 @@ var init_codebase_indexer = __esm({
54976
55263
  if (!child) {
54977
55264
  child = {
54978
55265
  name: part,
54979
- path: join58(current.path, part),
55266
+ path: join59(current.path, part),
54980
55267
  type: "directory",
54981
55268
  children: []
54982
55269
  };
@@ -55317,7 +55604,7 @@ var config_exports = {};
55317
55604
  __export(config_exports, {
55318
55605
  configCommand: () => configCommand
55319
55606
  });
55320
- import { join as join59, resolve as resolve31 } from "node:path";
55607
+ import { join as join60, resolve as resolve31 } from "node:path";
55321
55608
  import { homedir as homedir14 } from "node:os";
55322
55609
  import { cwd as cwd3 } from "node:process";
55323
55610
  function redactIfSensitive(key, value) {
@@ -55400,7 +55687,7 @@ function handleShow(opts, config) {
55400
55687
  }
55401
55688
  }
55402
55689
  printSection("Config File");
55403
- printInfo(`~/.open-agents/config.json (${join59(homedir14(), ".open-agents", "config.json")})`);
55690
+ printInfo(`~/.open-agents/config.json (${join60(homedir14(), ".open-agents", "config.json")})`);
55404
55691
  printSection("Priority Chain");
55405
55692
  printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
55406
55693
  printInfo(" 2. Project .oa/settings.json (--local)");
@@ -55439,7 +55726,7 @@ function handleSet(opts, _config) {
55439
55726
  const coerced = coerceForSettings(key, value);
55440
55727
  saveProjectSettings(repoRoot, { [key]: coerced });
55441
55728
  printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value)}`);
55442
- printInfo(`Saved to ${join59(repoRoot, ".oa", "settings.json")}`);
55729
+ printInfo(`Saved to ${join60(repoRoot, ".oa", "settings.json")}`);
55443
55730
  printInfo("This override applies only when running in this workspace.");
55444
55731
  } catch (err) {
55445
55732
  printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
@@ -55698,7 +55985,7 @@ __export(eval_exports, {
55698
55985
  });
55699
55986
  import { tmpdir as tmpdir10 } from "node:os";
55700
55987
  import { mkdirSync as mkdirSync20, writeFileSync as writeFileSync19 } from "node:fs";
55701
- import { join as join60 } from "node:path";
55988
+ import { join as join61 } from "node:path";
55702
55989
  async function evalCommand(opts, config) {
55703
55990
  const suiteName = opts.suite ?? "basic";
55704
55991
  const suite = SUITES[suiteName];
@@ -55823,9 +56110,9 @@ async function evalCommand(opts, config) {
55823
56110
  process.exit(failed > 0 ? 1 : 0);
55824
56111
  }
55825
56112
  function createTempEvalRepo() {
55826
- const dir = join60(tmpdir10(), `open-agents-eval-${Date.now()}`);
56113
+ const dir = join61(tmpdir10(), `open-agents-eval-${Date.now()}`);
55827
56114
  mkdirSync20(dir, { recursive: true });
55828
- writeFileSync19(join60(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
56115
+ writeFileSync19(join61(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
55829
56116
  return dir;
55830
56117
  }
55831
56118
  var BASIC_SUITE, FULL_SUITE, SUITES;
@@ -55885,7 +56172,7 @@ init_updater();
55885
56172
  import { parseArgs as nodeParseArgs2 } from "node:util";
55886
56173
  import { createRequire as createRequire3 } from "node:module";
55887
56174
  import { fileURLToPath as fileURLToPath13 } from "node:url";
55888
- import { dirname as dirname19, join as join61 } from "node:path";
56175
+ import { dirname as dirname19, join as join62 } from "node:path";
55889
56176
 
55890
56177
  // packages/cli/dist/cli.js
55891
56178
  import { createInterface } from "node:readline";
@@ -55992,7 +56279,7 @@ init_output();
55992
56279
  function getVersion4() {
55993
56280
  try {
55994
56281
  const require2 = createRequire3(import.meta.url);
55995
- const pkgPath = join61(dirname19(fileURLToPath13(import.meta.url)), "..", "package.json");
56282
+ const pkgPath = join62(dirname19(fileURLToPath13(import.meta.url)), "..", "package.json");
55996
56283
  const pkg = require2(pkgPath);
55997
56284
  return pkg.version;
55998
56285
  } catch {