open-agents-ai 0.114.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 +756 -399
  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";
@@ -15510,9 +15793,10 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15510
15793
  "budget_status",
15511
15794
  "budget_set",
15512
15795
  "spend",
15513
- "remote_infer"
15796
+ "remote_infer",
15797
+ "cohere_status"
15514
15798
  ],
15515
- description: "The nexus action. MUST call 'connect' first (spawns daemon). Then: join_room, send_message, discover_peers, expose, status, etc."
15799
+ description: "The nexus action. MUST call 'connect' first (spawns daemon). Then: join_room, send_message, discover_peers, expose, status, cohere_status, etc."
15516
15800
  },
15517
15801
  room_id: {
15518
15802
  type: "string",
@@ -15614,7 +15898,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15614
15898
  }
15615
15899
  async ensureDir() {
15616
15900
  if (!existsSync23(this.nexusDir)) {
15617
- await mkdir12(this.nexusDir, { recursive: true });
15901
+ await mkdir13(this.nexusDir, { recursive: true });
15618
15902
  }
15619
15903
  }
15620
15904
  async execute(args) {
@@ -15722,6 +16006,9 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15722
16006
  case "remote_infer":
15723
16007
  result = await this.doRemoteInfer(args);
15724
16008
  break;
16009
+ case "cohere_status":
16010
+ result = await this.doCohereSummary();
16011
+ break;
15725
16012
  default:
15726
16013
  return { success: false, output: "", error: `Unknown nexus action: ${action}`, durationMs: Date.now() - start };
15727
16014
  }
@@ -15734,7 +16021,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15734
16021
  // Daemon management
15735
16022
  // =========================================================================
15736
16023
  getDaemonPid() {
15737
- const pidFile = join35(this.nexusDir, "daemon.pid");
16024
+ const pidFile = join36(this.nexusDir, "daemon.pid");
15738
16025
  if (!existsSync23(pidFile))
15739
16026
  return null;
15740
16027
  try {
@@ -15760,12 +16047,12 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15760
16047
  throw new Error("Nexus daemon not running. Use action 'connect' first.");
15761
16048
  }
15762
16049
  const cmdId = randomBytes7(8).toString("hex");
15763
- const cmdFile = join35(this.nexusDir, "cmd.json");
15764
- const respFile = join35(this.nexusDir, "resp.json");
16050
+ const cmdFile = join36(this.nexusDir, "cmd.json");
16051
+ const respFile = join36(this.nexusDir, "resp.json");
15765
16052
  if (existsSync23(respFile))
15766
16053
  await unlink(respFile).catch(() => {
15767
16054
  });
15768
- await writeFile16(cmdFile, JSON.stringify({ id: cmdId, action, args }, null, 2));
16055
+ await writeFile17(cmdFile, JSON.stringify({ id: cmdId, action, args }, null, 2));
15769
16056
  const pollMs = 50;
15770
16057
  const polls = Math.ceil(timeoutMs / pollMs);
15771
16058
  let resolved = false;
@@ -15797,7 +16084,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15797
16084
  if (!existsSync23(respFile))
15798
16085
  continue;
15799
16086
  try {
15800
- const resp = JSON.parse(await readFile17(respFile, "utf8"));
16087
+ const resp = JSON.parse(await readFile18(respFile, "utf8"));
15801
16088
  if (resp.id === cmdId) {
15802
16089
  resolved = true;
15803
16090
  return resp.output || (resp.ok ? "OK" : "Failed");
@@ -15820,7 +16107,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15820
16107
  }
15821
16108
  if (existsSync23(respFile)) {
15822
16109
  try {
15823
- const resp = JSON.parse(await readFile17(respFile, "utf8"));
16110
+ const resp = JSON.parse(await readFile18(respFile, "utf8"));
15824
16111
  if (resp.id === cmdId) {
15825
16112
  return resp.output || (resp.ok ? "OK" : "Failed");
15826
16113
  }
@@ -15845,7 +16132,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15845
16132
  const currentScriptHash = createHash("sha256").update(DAEMON_SCRIPT).digest("hex").slice(0, 16);
15846
16133
  const existingPid = this.getDaemonPid();
15847
16134
  if (existingPid) {
15848
- const daemonPath2 = join35(this.nexusDir, "nexus-daemon.mjs");
16135
+ const daemonPath2 = join36(this.nexusDir, "nexus-daemon.mjs");
15849
16136
  let needsRestart = true;
15850
16137
  if (existsSync23(daemonPath2)) {
15851
16138
  try {
@@ -15869,16 +16156,16 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15869
16156
  } catch {
15870
16157
  }
15871
16158
  for (const f of ["daemon.pid", "status.json", "cmd.json", "resp.json"]) {
15872
- const p = join35(this.nexusDir, f);
16159
+ const p = join36(this.nexusDir, f);
15873
16160
  if (existsSync23(p))
15874
16161
  await unlink(p).catch(() => {
15875
16162
  });
15876
16163
  }
15877
16164
  } else {
15878
- const statusFile2 = join35(this.nexusDir, "status.json");
16165
+ const statusFile2 = join36(this.nexusDir, "status.json");
15879
16166
  if (existsSync23(statusFile2)) {
15880
16167
  try {
15881
- const status = JSON.parse(await readFile17(statusFile2, "utf8"));
16168
+ const status = JSON.parse(await readFile18(statusFile2, "utf8"));
15882
16169
  if (status.connected && status.peerId) {
15883
16170
  await this.ensureWallet();
15884
16171
  return `Already connected (pid: ${existingPid}, peerId: ${status.peerId})`;
@@ -15894,7 +16181,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15894
16181
  }
15895
16182
  }
15896
16183
  for (const f of ["daemon.pid", "status.json", "cmd.json", "resp.json"]) {
15897
- const p = join35(this.nexusDir, f);
16184
+ const p = join36(this.nexusDir, f);
15898
16185
  if (existsSync23(p))
15899
16186
  await unlink(p).catch(() => {
15900
16187
  });
@@ -15912,7 +16199,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15912
16199
  });
15913
16200
  });
15914
16201
  try {
15915
- const nexusPkg = join35(nodeModulesDir, "open-agents-nexus", "package.json");
16202
+ const nexusPkg = join36(nodeModulesDir, "open-agents-nexus", "package.json");
15916
16203
  if (existsSync23(nexusPkg)) {
15917
16204
  nexusResolved = true;
15918
16205
  try {
@@ -15923,7 +16210,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15923
16210
  } else {
15924
16211
  try {
15925
16212
  const globalDir = await execAsync2("npm root -g", { timeout: 5e3 });
15926
- const globalPkg = join35(globalDir, "open-agents-nexus", "package.json");
16213
+ const globalPkg = join36(globalDir, "open-agents-nexus", "package.json");
15927
16214
  if (existsSync23(globalPkg)) {
15928
16215
  nexusResolved = true;
15929
16216
  try {
@@ -15968,8 +16255,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15968
16255
  }
15969
16256
  }
15970
16257
  await this.ensureWallet();
15971
- const daemonPath = join35(this.nexusDir, "nexus-daemon.mjs");
15972
- await writeFile16(daemonPath, DAEMON_SCRIPT);
16258
+ const daemonPath = join36(this.nexusDir, "nexus-daemon.mjs");
16259
+ await writeFile17(daemonPath, DAEMON_SCRIPT);
15973
16260
  const agentName = args.agent_name || "open-agents-node";
15974
16261
  const agentType = args.agent_type || "general";
15975
16262
  const nodePaths = [nodeModulesDir];
@@ -15979,8 +16266,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15979
16266
  } catch {
15980
16267
  }
15981
16268
  const { openSync: openSync2, closeSync: closeSync2 } = await import("node:fs");
15982
- const daemonLogPath = join35(this.nexusDir, "daemon.log");
15983
- const daemonErrPath = join35(this.nexusDir, "daemon.err");
16269
+ const daemonLogPath = join36(this.nexusDir, "daemon.log");
16270
+ const daemonErrPath = join36(this.nexusDir, "daemon.err");
15984
16271
  const outFd = openSync2(daemonLogPath, "w");
15985
16272
  const errFd = openSync2(daemonErrPath, "w");
15986
16273
  const child = spawn12("node", [daemonPath, this.nexusDir, agentName, agentType], {
@@ -15998,16 +16285,16 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15998
16285
  closeSync2(errFd);
15999
16286
  } catch {
16000
16287
  }
16001
- const statusFile = join35(this.nexusDir, "status.json");
16288
+ const statusFile = join36(this.nexusDir, "status.json");
16002
16289
  for (let i = 0; i < 40; i++) {
16003
16290
  await new Promise((r) => setTimeout(r, 500));
16004
16291
  if (existsSync23(statusFile)) {
16005
16292
  try {
16006
- const status = JSON.parse(await readFile17(statusFile, "utf8"));
16293
+ const status = JSON.parse(await readFile18(statusFile, "utf8"));
16007
16294
  if (status.error) {
16008
16295
  let errTail = "";
16009
16296
  try {
16010
- errTail = (await readFile17(daemonErrPath, "utf8")).slice(-300);
16297
+ errTail = (await readFile18(daemonErrPath, "utf8")).slice(-300);
16011
16298
  } catch {
16012
16299
  }
16013
16300
  return `Nexus daemon failed to connect: ${status.error}${errTail ? "\n" + errTail : ""}`;
@@ -16029,12 +16316,12 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16029
16316
  const pid = this.getDaemonPid();
16030
16317
  let earlyError = "";
16031
16318
  try {
16032
- earlyError = (await readFile17(daemonErrPath, "utf8")).slice(-500);
16319
+ earlyError = (await readFile18(daemonErrPath, "utf8")).slice(-500);
16033
16320
  } catch {
16034
16321
  }
16035
16322
  let earlyOutput = "";
16036
16323
  try {
16037
- earlyOutput = (await readFile17(daemonLogPath, "utf8")).slice(-500);
16324
+ earlyOutput = (await readFile18(daemonLogPath, "utf8")).slice(-500);
16038
16325
  } catch {
16039
16326
  }
16040
16327
  if (pid) {
@@ -16057,7 +16344,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16057
16344
  } catch {
16058
16345
  }
16059
16346
  for (const f of ["daemon.pid", "status.json", "cmd.json", "resp.json"]) {
16060
- const p = join35(this.nexusDir, f);
16347
+ const p = join36(this.nexusDir, f);
16061
16348
  if (existsSync23(p))
16062
16349
  await unlink(p).catch(() => {
16063
16350
  });
@@ -16068,11 +16355,11 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16068
16355
  const pid = this.getDaemonPid();
16069
16356
  if (!pid)
16070
16357
  return "Nexus daemon not running. Use action 'connect' to start.";
16071
- const statusFile = join35(this.nexusDir, "status.json");
16358
+ const statusFile = join36(this.nexusDir, "status.json");
16072
16359
  if (!existsSync23(statusFile))
16073
16360
  return `Daemon running (pid: ${pid}) but no status yet.`;
16074
16361
  try {
16075
- const status = JSON.parse(await readFile17(statusFile, "utf8"));
16362
+ const status = JSON.parse(await readFile18(statusFile, "utf8"));
16076
16363
  const lines = [
16077
16364
  `Nexus Status (v1.5.0)`,
16078
16365
  ` Connected: ${status.connected}`,
@@ -16083,10 +16370,10 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16083
16370
  ` Capabilities: ${(status.capabilities || []).length ? (status.capabilities || []).join(", ") : "none"}`,
16084
16371
  ` Blocked peers: ${(status.blockedPeers || []).length || 0}`
16085
16372
  ];
16086
- const walletPath = join35(this.nexusDir, "wallet.enc");
16373
+ const walletPath = join36(this.nexusDir, "wallet.enc");
16087
16374
  if (existsSync23(walletPath)) {
16088
16375
  try {
16089
- const w = JSON.parse(await readFile17(walletPath, "utf8"));
16376
+ const w = JSON.parse(await readFile18(walletPath, "utf8"));
16090
16377
  lines.push(` Wallet: ${w.address}`);
16091
16378
  } catch {
16092
16379
  lines.push(` Wallet: corrupt`);
@@ -16094,14 +16381,14 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16094
16381
  } else {
16095
16382
  lines.push(` Wallet: not configured`);
16096
16383
  }
16097
- const inboxDir = join35(this.nexusDir, "inbox");
16384
+ const inboxDir = join36(this.nexusDir, "inbox");
16098
16385
  if (existsSync23(inboxDir)) {
16099
16386
  try {
16100
- const roomDirs = await readdir3(inboxDir);
16387
+ const roomDirs = await readdir4(inboxDir);
16101
16388
  let totalMsgs = 0;
16102
16389
  for (const rd of roomDirs) {
16103
16390
  try {
16104
- totalMsgs += (await readdir3(join35(inboxDir, rd))).length;
16391
+ totalMsgs += (await readdir4(join36(inboxDir, rd))).length;
16105
16392
  } catch {
16106
16393
  }
16107
16394
  }
@@ -16148,18 +16435,18 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16148
16435
  }
16149
16436
  async doReadMessages(args) {
16150
16437
  const roomId = args.room_id;
16151
- const inboxDir = join35(this.nexusDir, "inbox");
16438
+ const inboxDir = join36(this.nexusDir, "inbox");
16152
16439
  if (roomId) {
16153
- const roomInbox = join35(inboxDir, roomId);
16440
+ const roomInbox = join36(inboxDir, roomId);
16154
16441
  if (!existsSync23(roomInbox))
16155
16442
  return `No messages in room: ${roomId}`;
16156
- const files = (await readdir3(roomInbox)).sort().slice(-20);
16443
+ const files = (await readdir4(roomInbox)).sort().slice(-20);
16157
16444
  if (files.length === 0)
16158
16445
  return `No messages in room: ${roomId}`;
16159
16446
  const messages = [`Messages in ${roomId} (last ${files.length}):`];
16160
16447
  for (const f of files) {
16161
16448
  try {
16162
- const msg = JSON.parse(await readFile17(join35(roomInbox, f), "utf8"));
16449
+ const msg = JSON.parse(await readFile18(join36(roomInbox, f), "utf8"));
16163
16450
  const sender = (msg.sender || "unknown").slice(0, 12);
16164
16451
  messages.push(` [${new Date(msg.timestamp).toLocaleTimeString()}] ${sender}...: ${msg.content}`);
16165
16452
  } catch {
@@ -16169,13 +16456,13 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16169
16456
  }
16170
16457
  if (!existsSync23(inboxDir))
16171
16458
  return "No messages received yet.";
16172
- const roomDirs = await readdir3(inboxDir);
16459
+ const roomDirs = await readdir4(inboxDir);
16173
16460
  if (roomDirs.length === 0)
16174
16461
  return "No messages received yet.";
16175
16462
  const lines = ["Inbox:"];
16176
16463
  for (const rd of roomDirs) {
16177
16464
  try {
16178
- const count = (await readdir3(join35(inboxDir, rd))).length;
16465
+ const count = (await readdir4(join36(inboxDir, rd))).length;
16179
16466
  lines.push(` ${rd}: ${count} message(s)`);
16180
16467
  } catch {
16181
16468
  }
@@ -16187,12 +16474,12 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16187
16474
  // ---------------------------------------------------------------------------
16188
16475
  async doWalletStatus() {
16189
16476
  await this.ensureDir();
16190
- const walletPath = join35(this.nexusDir, "wallet.enc");
16477
+ const walletPath = join36(this.nexusDir, "wallet.enc");
16191
16478
  if (!existsSync23(walletPath)) {
16192
16479
  return "No wallet configured. Use wallet_create to set one up.";
16193
16480
  }
16194
16481
  try {
16195
- const w = JSON.parse(await readFile17(walletPath, "utf8"));
16482
+ const w = JSON.parse(await readFile18(walletPath, "utf8"));
16196
16483
  const lines = [
16197
16484
  `Wallet Status:`,
16198
16485
  ` Address: ${w.address}`,
@@ -16226,7 +16513,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16226
16513
  }
16227
16514
  async doWalletCreate(args) {
16228
16515
  await this.ensureDir();
16229
- const walletPath = join35(this.nexusDir, "wallet.enc");
16516
+ const walletPath = join36(this.nexusDir, "wallet.enc");
16230
16517
  if (existsSync23(walletPath))
16231
16518
  return "Wallet already exists. Delete wallet.enc to create a new one.";
16232
16519
  const userAddress = args.wallet_address;
@@ -16272,7 +16559,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16272
16559
  const cipher = createCipheriv("aes-256-gcm", key, iv);
16273
16560
  let enc = cipher.update(privKeyHex, "utf8", "hex");
16274
16561
  enc += cipher.final("hex");
16275
- const x402KeyPath = join35(this.nexusDir, "x402-wallet.key");
16562
+ const x402KeyPath = join36(this.nexusDir, "x402-wallet.key");
16276
16563
  const x402Fh = await fsOpen(x402KeyPath, "w", 384);
16277
16564
  await x402Fh.writeFile("0x" + privKeyHex);
16278
16565
  await x402Fh.close();
@@ -16310,7 +16597,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16310
16597
  * Silent — no user output, just ensures the files exist.
16311
16598
  */
16312
16599
  async ensureWallet() {
16313
- const walletPath = join35(this.nexusDir, "wallet.enc");
16600
+ const walletPath = join36(this.nexusDir, "wallet.enc");
16314
16601
  if (existsSync23(walletPath))
16315
16602
  return;
16316
16603
  let address;
@@ -16334,7 +16621,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16334
16621
  const cipher = createCipheriv("aes-256-gcm", key, iv);
16335
16622
  let enc = cipher.update(privKeyHex, "utf8", "hex");
16336
16623
  enc += cipher.final("hex");
16337
- const x402KeyPath = join35(this.nexusDir, "x402-wallet.key");
16624
+ const x402KeyPath = join36(this.nexusDir, "x402-wallet.key");
16338
16625
  const x402Fh = await fsOpen(x402KeyPath, "w", 384);
16339
16626
  await x402Fh.writeFile("0x" + privKeyHex);
16340
16627
  await x402Fh.close();
@@ -16394,12 +16681,12 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16394
16681
  // ---------------------------------------------------------------------------
16395
16682
  async doLedgerStatus() {
16396
16683
  await this.ensureDir();
16397
- const ledgerPath = join35(this.nexusDir, "ledger.jsonl");
16684
+ const ledgerPath = join36(this.nexusDir, "ledger.jsonl");
16398
16685
  if (!existsSync23(ledgerPath)) {
16399
16686
  return "No ledger entries. Earnings and spending will be tracked here after x402 transactions.";
16400
16687
  }
16401
16688
  try {
16402
- const raw = await readFile17(ledgerPath, "utf8");
16689
+ const raw = await readFile18(ledgerPath, "utf8");
16403
16690
  const entries = raw.trim().split("\n").filter((l) => l.trim()).map((l) => JSON.parse(l));
16404
16691
  if (entries.length === 0) {
16405
16692
  return "Ledger is empty. No transactions recorded.";
@@ -16436,11 +16723,11 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16436
16723
  }
16437
16724
  }
16438
16725
  async getLedgerSummary() {
16439
- const ledgerPath = join35(this.nexusDir, "ledger.jsonl");
16726
+ const ledgerPath = join36(this.nexusDir, "ledger.jsonl");
16440
16727
  if (!existsSync23(ledgerPath))
16441
16728
  return null;
16442
16729
  try {
16443
- const raw = await readFile17(ledgerPath, "utf8");
16730
+ const raw = await readFile18(ledgerPath, "utf8");
16444
16731
  const entries = raw.trim().split("\n").filter((l) => l.trim()).map((l) => JSON.parse(l));
16445
16732
  let totalEarned = 0n, totalSpent = 0n;
16446
16733
  for (const e of entries) {
@@ -16461,25 +16748,25 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16461
16748
  }
16462
16749
  async appendLedger(entry) {
16463
16750
  await this.ensureDir();
16464
- const ledgerPath = join35(this.nexusDir, "ledger.jsonl");
16751
+ const ledgerPath = join36(this.nexusDir, "ledger.jsonl");
16465
16752
  const line = JSON.stringify(entry) + "\n";
16466
- await writeFile16(ledgerPath, existsSync23(ledgerPath) ? await readFile17(ledgerPath, "utf8") + line : line);
16753
+ await writeFile17(ledgerPath, existsSync23(ledgerPath) ? await readFile18(ledgerPath, "utf8") + line : line);
16467
16754
  }
16468
16755
  // ---------------------------------------------------------------------------
16469
16756
  // Step 4: Budget Policy — Spending limits and auto-approve thresholds
16470
16757
  // ---------------------------------------------------------------------------
16471
16758
  async loadBudget() {
16472
- const budgetPath = join35(this.nexusDir, "budget.json");
16759
+ const budgetPath = join36(this.nexusDir, "budget.json");
16473
16760
  if (!existsSync23(budgetPath))
16474
16761
  return null;
16475
16762
  try {
16476
- return JSON.parse(await readFile17(budgetPath, "utf8"));
16763
+ return JSON.parse(await readFile18(budgetPath, "utf8"));
16477
16764
  } catch {
16478
16765
  return null;
16479
16766
  }
16480
16767
  }
16481
16768
  async ensureDefaultBudget() {
16482
- const budgetPath = join35(this.nexusDir, "budget.json");
16769
+ const budgetPath = join36(this.nexusDir, "budget.json");
16483
16770
  if (existsSync23(budgetPath))
16484
16771
  return;
16485
16772
  const defaultBudget = {
@@ -16500,7 +16787,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16500
16787
  deniedPeers: []
16501
16788
  };
16502
16789
  await this.ensureDir();
16503
- await writeFile16(budgetPath, JSON.stringify(defaultBudget, null, 2));
16790
+ await writeFile17(budgetPath, JSON.stringify(defaultBudget, null, 2));
16504
16791
  }
16505
16792
  async doBudgetStatus() {
16506
16793
  await this.ensureDir();
@@ -16549,17 +16836,17 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16549
16836
  if (changes.length === 0) {
16550
16837
  return "No budget parameters provided. Use daily_limit, per_invoke_max, or auto_approve_below.";
16551
16838
  }
16552
- const budgetPath = join35(this.nexusDir, "budget.json");
16553
- 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));
16554
16841
  return `Budget updated: ${changes.join(", ")}`;
16555
16842
  }
16556
16843
  async getTodaySpending() {
16557
- const ledgerPath = join35(this.nexusDir, "ledger.jsonl");
16844
+ const ledgerPath = join36(this.nexusDir, "ledger.jsonl");
16558
16845
  if (!existsSync23(ledgerPath))
16559
16846
  return 0;
16560
16847
  try {
16561
16848
  const todayPrefix = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
16562
- const raw = await readFile17(ledgerPath, "utf8");
16849
+ const raw = await readFile18(ledgerPath, "utf8");
16563
16850
  let total = 0;
16564
16851
  for (const line of raw.trim().split("\n")) {
16565
16852
  if (!line.trim())
@@ -16598,10 +16885,10 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16598
16885
  if (todaySpent + amountUsdc > budget.dailyLimitUsdc) {
16599
16886
  return { allowed: false, reason: `Would exceed daily limit ($${((todaySpent + amountUsdc) / 1e6).toFixed(6)} > $${(budget.dailyLimitUsdc / 1e6).toFixed(6)})` };
16600
16887
  }
16601
- const walletPath = join35(this.nexusDir, "wallet.enc");
16888
+ const walletPath = join36(this.nexusDir, "wallet.enc");
16602
16889
  if (existsSync23(walletPath)) {
16603
16890
  try {
16604
- const w = JSON.parse(await readFile17(walletPath, "utf8"));
16891
+ const w = JSON.parse(await readFile18(walletPath, "utf8"));
16605
16892
  if (w.version === 2 && w.address) {
16606
16893
  const balance = await this.queryUsdcBalance(w.address, w.chainId || 8453);
16607
16894
  if (balance !== null && Number(balance) < budget.circuitBreakerUsdc) {
@@ -16629,10 +16916,10 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16629
16916
  const budgetResult = await this.checkBudget(amountSmallest, "transfer:direct", targetAddress);
16630
16917
  if (!budgetResult.allowed)
16631
16918
  return `BLOCKED by budget policy: ${budgetResult.reason}`;
16632
- const walletPath = join35(this.nexusDir, "wallet.enc");
16919
+ const walletPath = join36(this.nexusDir, "wallet.enc");
16633
16920
  if (!existsSync23(walletPath))
16634
16921
  throw new Error("No wallet. Use wallet_create first.");
16635
- const w = JSON.parse(await readFile17(walletPath, "utf8"));
16922
+ const w = JSON.parse(await readFile18(walletPath, "utf8"));
16636
16923
  if (!w.encryptedKey)
16637
16924
  throw new Error("User-managed wallet cannot spend (no private key)");
16638
16925
  const salt = Buffer.from(w.salt, "hex");
@@ -16690,7 +16977,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16690
16977
  capability: "transfer:direct",
16691
16978
  note: "signed, awaiting submission"
16692
16979
  });
16693
- const proofFile = join35(this.nexusDir, "pending-transfer.json");
16980
+ const proofFile = join36(this.nexusDir, "pending-transfer.json");
16694
16981
  const proof = {
16695
16982
  from: account.address,
16696
16983
  to: targetAddress,
@@ -16703,7 +16990,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16703
16990
  usdcContract: USDC_ADDRESS,
16704
16991
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
16705
16992
  };
16706
- await writeFile16(proofFile, JSON.stringify(proof, null, 2));
16993
+ await writeFile17(proofFile, JSON.stringify(proof, null, 2));
16707
16994
  return [
16708
16995
  `Transfer signed (EIP-3009 TransferWithAuthorization):`,
16709
16996
  ` From: ${account.address}`,
@@ -16732,10 +17019,10 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16732
17019
  throw new Error("prompt is required");
16733
17020
  const estimatedTokens = Math.ceil(prompt.length / 4) + 1e3;
16734
17021
  let estimatedCostSmallest = 0;
16735
- const pricingPath = join35(this.nexusDir, "pricing.json");
17022
+ const pricingPath = join36(this.nexusDir, "pricing.json");
16736
17023
  if (existsSync23(pricingPath)) {
16737
17024
  try {
16738
- const pricing = JSON.parse(await readFile17(pricingPath, "utf8"));
17025
+ const pricing = JSON.parse(await readFile18(pricingPath, "utf8"));
16739
17026
  const modelPricing = (pricing.models || []).find((m) => m.model === model || m.model.startsWith(model.split(":")[0]));
16740
17027
  if (modelPricing?.pricing?.input_per_1m_tokens > 0) {
16741
17028
  estimatedCostSmallest = Math.ceil(estimatedTokens / 1e6 * modelPricing.pricing.input_per_1m_tokens * 1e6);
@@ -16852,7 +17139,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16852
17139
  const bar = (s) => "\u2588".repeat(Math.round(s / 5)) + "\u2591".repeat(20 - Math.round(s / 5));
16853
17140
  const mem = vramMb > 24e3 ? 95 : vramMb > 16e3 ? 80 : vramMb > 8e3 ? 60 : vramMb > 0 ? 40 : 20;
16854
17141
  await this.ensureDir();
16855
- await writeFile16(join35(this.nexusDir, "inference-proof.json"), JSON.stringify({
17142
+ await writeFile17(join36(this.nexusDir, "inference-proof.json"), JSON.stringify({
16856
17143
  modelName,
16857
17144
  gpuName,
16858
17145
  vramMb,
@@ -16870,6 +17157,72 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16870
17157
  return "Could not generate proof. Ensure Ollama is running.";
16871
17158
  }
16872
17159
  }
17160
+ // ── COHERE Financial Summary ─────────────────────────────────────────────
17161
+ /**
17162
+ * Show comprehensive COHERE financial status including wallet, budget,
17163
+ * payout equation factors, sponsor pool, and two-balance model.
17164
+ * Per Project COHERE Unified Complete §Planes 3-5.
17165
+ */
17166
+ async doCohereSummary() {
17167
+ const lines = [];
17168
+ lines.push("\u2550\u2550\u2550 COHERE Financial Status \u2550\u2550\u2550\n");
17169
+ try {
17170
+ const walletStatus = await this.doWalletStatus();
17171
+ lines.push("\u2500\u2500 Wallet \u2500\u2500");
17172
+ lines.push(walletStatus);
17173
+ lines.push("");
17174
+ } catch {
17175
+ lines.push("Wallet: not configured\n");
17176
+ }
17177
+ try {
17178
+ const budgetStatus = await this.doBudgetStatus();
17179
+ lines.push("\u2500\u2500 Budget Policy \u2500\u2500");
17180
+ lines.push(budgetStatus);
17181
+ lines.push("");
17182
+ } catch {
17183
+ lines.push("Budget: not configured\n");
17184
+ }
17185
+ try {
17186
+ const ledgerStatus = await this.doLedgerStatus();
17187
+ lines.push("\u2500\u2500 Transaction Ledger \u2500\u2500");
17188
+ lines.push(ledgerStatus);
17189
+ lines.push("");
17190
+ } catch {
17191
+ lines.push("Ledger: no transactions yet\n");
17192
+ }
17193
+ lines.push("\u2500\u2500 COHERE Revenue Split \u2500\u2500");
17194
+ lines.push(" Provider payout: 70%");
17195
+ lines.push(" Commons subsidy: 10%");
17196
+ lines.push(" Memory steward: 8%");
17197
+ lines.push(" Relay/discovery: 7%");
17198
+ lines.push(" Protocol reserve: 5%");
17199
+ lines.push("");
17200
+ lines.push("\u2500\u2500 Provider Payout Equation \u2500\u2500");
17201
+ lines.push(" provider_reward = base_compute + context_premium + streaming_bonus");
17202
+ lines.push(" + warm_bonus + qos_bonus + trust_bonus");
17203
+ lines.push(" + scarcity_bonus + sponsor_multiplier - penalties");
17204
+ lines.push(" Default rates: $0.0004/1K in, $0.0012/1K out");
17205
+ lines.push(" Bonuses: context(15%), stream(5%), warm(10%), QoS(5%), trust(10%), scarcity(20%)");
17206
+ lines.push("");
17207
+ lines.push("\u2500\u2500 Two-Balance Model \u2500\u2500");
17208
+ lines.push(" A. Cash credits: USDC-settled, withdrawable on-chain");
17209
+ lines.push(" B. Network credits: internal, for consuming inference");
17210
+ lines.push(" Earn split: 80% cash / 20% network");
17211
+ lines.push("");
17212
+ lines.push("\u2500\u2500 Routing Priority \u2500\u2500");
17213
+ lines.push(" 1. Privacy class");
17214
+ lines.push(" 2. Local availability");
17215
+ lines.push(" 3. Trust and policy fit");
17216
+ lines.push(" 4. Warmness (model already loaded)");
17217
+ lines.push(" 5. Latency");
17218
+ lines.push(" 6. Price");
17219
+ lines.push(" 7. Sponsor eligibility");
17220
+ lines.push("");
17221
+ lines.push("\u2500\u2500 Provenance \u2500\u2500");
17222
+ lines.push(" Project COHERE Unified Complete (March 2026)");
17223
+ lines.push(" Planes 1-5: Local Intelligence \u2192 P2P Transport \u2192 Market \u2192 Memory \u2192 Orchestration");
17224
+ return lines.join("\n");
17225
+ }
16873
17226
  };
16874
17227
  }
16875
17228
  });
@@ -17493,6 +17846,7 @@ __export(dist_exports, {
17493
17846
  DesktopClickTool: () => DesktopClickTool,
17494
17847
  DesktopDescribeTool: () => DesktopDescribeTool,
17495
17848
  DiagnosticTool: () => DiagnosticTool,
17849
+ EmbeddingStoreTool: () => EmbeddingStoreTool,
17496
17850
  ExplorationCultureTool: () => ExplorationCultureTool,
17497
17851
  ExploreToolsTool: () => ExploreToolsTool,
17498
17852
  FactoryTool: () => FactoryTool,
@@ -17609,6 +17963,7 @@ var init_dist2 = __esm({
17609
17963
  init_identity_kernel();
17610
17964
  init_reflection_integrity();
17611
17965
  init_exploration_culture();
17966
+ init_embedding_store();
17612
17967
  init_structured_read();
17613
17968
  init_vision();
17614
17969
  init_desktop_click();
@@ -18309,12 +18664,12 @@ var init_dist3 = __esm({
18309
18664
 
18310
18665
  // packages/orchestrator/dist/promptLoader.js
18311
18666
  import { readFileSync as readFileSync18, existsSync as existsSync25 } from "node:fs";
18312
- import { join as join36, dirname as dirname12 } from "node:path";
18667
+ import { join as join37, dirname as dirname12 } from "node:path";
18313
18668
  import { fileURLToPath as fileURLToPath7 } from "node:url";
18314
18669
  function loadPrompt(promptPath, vars) {
18315
18670
  let content = cache.get(promptPath);
18316
18671
  if (content === void 0) {
18317
- const fullPath = join36(PROMPTS_DIR, promptPath);
18672
+ const fullPath = join37(PROMPTS_DIR, promptPath);
18318
18673
  if (!existsSync25(fullPath)) {
18319
18674
  throw new Error(`Prompt file not found: ${fullPath}`);
18320
18675
  }
@@ -18331,7 +18686,7 @@ var init_promptLoader = __esm({
18331
18686
  "use strict";
18332
18687
  __filename = fileURLToPath7(import.meta.url);
18333
18688
  __dirname4 = dirname12(__filename);
18334
- PROMPTS_DIR = join36(__dirname4, "..", "prompts");
18689
+ PROMPTS_DIR = join37(__dirname4, "..", "prompts");
18335
18690
  cache = /* @__PURE__ */ new Map();
18336
18691
  }
18337
18692
  });
@@ -18694,8 +19049,8 @@ var init_code_retriever = __esm({
18694
19049
  });
18695
19050
  }
18696
19051
  async getFileContent(filePath, startLine, endLine) {
18697
- const { readFile: readFile22 } = await import("node:fs/promises");
18698
- const content = await readFile22(filePath, "utf-8");
19052
+ const { readFile: readFile23 } = await import("node:fs/promises");
19053
+ const content = await readFile23(filePath, "utf-8");
18699
19054
  if (startLine === void 0)
18700
19055
  return content;
18701
19056
  const lines = content.split("\n");
@@ -18710,8 +19065,8 @@ var init_code_retriever = __esm({
18710
19065
  // packages/retrieval/dist/lexicalSearch.js
18711
19066
  import { execFile as execFile5 } from "node:child_process";
18712
19067
  import { promisify as promisify4 } from "node:util";
18713
- import { readFile as readFile18, readdir as readdir4, stat as stat3 } from "node:fs/promises";
18714
- 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";
18715
19070
  async function searchByPath(pathPattern, options) {
18716
19071
  const allFiles = await collectFiles(options.rootDir, options.includeGlobs ?? DEFAULT_INCLUDE_GLOBS, options.excludeGlobs ?? DEFAULT_EXCLUDE_GLOBS);
18717
19072
  const pattern = options.caseInsensitive ? pathPattern.toLowerCase() : pathPattern;
@@ -18816,7 +19171,7 @@ async function searchWithNodeFallback(pattern, kind, options) {
18816
19171
  if (results.length >= maxMatches)
18817
19172
  break;
18818
19173
  try {
18819
- const content = await readFile18(filePath, "utf-8");
19174
+ const content = await readFile19(filePath, "utf-8");
18820
19175
  const contentLines = content.split("\n");
18821
19176
  for (let i = 0; i < contentLines.length; i++) {
18822
19177
  if (results.length >= maxMatches)
@@ -18844,7 +19199,7 @@ async function collectFiles(rootDir, includeGlobs, excludeGlobs) {
18844
19199
  async function walkForFiles(rootDir, dir, excludeGlobs, results) {
18845
19200
  let entries;
18846
19201
  try {
18847
- entries = await readdir4(dir, { withFileTypes: true, encoding: "utf-8" });
19202
+ entries = await readdir5(dir, { withFileTypes: true, encoding: "utf-8" });
18848
19203
  } catch {
18849
19204
  return;
18850
19205
  }
@@ -18853,7 +19208,7 @@ async function walkForFiles(rootDir, dir, excludeGlobs, results) {
18853
19208
  continue;
18854
19209
  if (excludeGlobs.some((g) => entry.name === g || matchesGlob(entry.name, g)))
18855
19210
  continue;
18856
- const absPath = join37(dir, entry.name);
19211
+ const absPath = join38(dir, entry.name);
18857
19212
  if (entry.isDirectory()) {
18858
19213
  await walkForFiles(rootDir, absPath, excludeGlobs, results);
18859
19214
  } else if (entry.isFile()) {
@@ -19159,8 +19514,8 @@ var init_graphExpand = __esm({
19159
19514
  });
19160
19515
 
19161
19516
  // packages/retrieval/dist/snippetPacker.js
19162
- import { readFile as readFile19 } from "node:fs/promises";
19163
- import { join as join38 } from "node:path";
19517
+ import { readFile as readFile20 } from "node:fs/promises";
19518
+ import { join as join39 } from "node:path";
19164
19519
  async function packSnippets(requests, opts = {}) {
19165
19520
  const maxTokens = opts.maxTokens ?? DEFAULT_MAX_TOKENS;
19166
19521
  const contextLines = opts.contextLines ?? DEFAULT_CONTEXT_LINES;
@@ -19186,10 +19541,10 @@ async function packSnippets(requests, opts = {}) {
19186
19541
  return { packed, dropped, totalTokens };
19187
19542
  }
19188
19543
  async function extractSnippet(req, repoRoot, contextLines = DEFAULT_CONTEXT_LINES) {
19189
- const absPath = req.filePath.startsWith("/") ? req.filePath : join38(repoRoot, req.filePath);
19544
+ const absPath = req.filePath.startsWith("/") ? req.filePath : join39(repoRoot, req.filePath);
19190
19545
  let content;
19191
19546
  try {
19192
- content = await readFile19(absPath, "utf-8");
19547
+ content = await readFile20(absPath, "utf-8");
19193
19548
  } catch {
19194
19549
  return null;
19195
19550
  }
@@ -21780,8 +22135,8 @@ ${marker}` : marker);
21780
22135
  return;
21781
22136
  try {
21782
22137
  const { mkdirSync: mkdirSync21, writeFileSync: writeFileSync20 } = __require("node:fs");
21783
- const { join: join62 } = __require("node:path");
21784
- 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);
21785
22140
  mkdirSync21(sessionDir, { recursive: true });
21786
22141
  const checkpoint = {
21787
22142
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -21794,7 +22149,7 @@ ${marker}` : marker);
21794
22149
  memexEntryCount: this._memexArchive.size,
21795
22150
  fileRegistrySize: this._fileRegistry.size
21796
22151
  };
21797
- writeFileSync20(join62(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
22152
+ writeFileSync20(join63(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
21798
22153
  } catch {
21799
22154
  }
21800
22155
  }
@@ -23062,7 +23417,7 @@ ${transcript}`
23062
23417
  // packages/orchestrator/dist/nexusBackend.js
23063
23418
  import { existsSync as existsSync26, statSync as statSync9, openSync, readSync, closeSync, unlinkSync as unlinkSync4, writeFileSync as writeFileSync8 } from "node:fs";
23064
23419
  import { watch as fsWatch } from "node:fs";
23065
- import { join as join39 } from "node:path";
23420
+ import { join as join40 } from "node:path";
23066
23421
  import { tmpdir as tmpdir7 } from "node:os";
23067
23422
  import { randomBytes as randomBytes8 } from "node:crypto";
23068
23423
  var NexusAgenticBackend;
@@ -23212,7 +23567,7 @@ var init_nexusBackend = __esm({
23212
23567
  * Falls back to unary + word-split if streaming setup fails.
23213
23568
  */
23214
23569
  async *chatCompletionStream(request) {
23215
- const streamFile = join39(tmpdir7(), `nexus-stream-${randomBytes8(6).toString("hex")}.jsonl`);
23570
+ const streamFile = join40(tmpdir7(), `nexus-stream-${randomBytes8(6).toString("hex")}.jsonl`);
23216
23571
  writeFileSync8(streamFile, "", "utf8");
23217
23572
  const daemonArgs = {
23218
23573
  model: this.model,
@@ -24249,7 +24604,7 @@ __export(listen_exports, {
24249
24604
  });
24250
24605
  import { spawn as spawn15, execSync as execSync23 } from "node:child_process";
24251
24606
  import { existsSync as existsSync27, mkdirSync as mkdirSync8, writeFileSync as writeFileSync9, readdirSync as readdirSync6 } from "node:fs";
24252
- import { join as join40, dirname as dirname13 } from "node:path";
24607
+ import { join as join41, dirname as dirname13 } from "node:path";
24253
24608
  import { homedir as homedir8 } from "node:os";
24254
24609
  import { fileURLToPath as fileURLToPath8 } from "node:url";
24255
24610
  import { EventEmitter } from "node:events";
@@ -24335,12 +24690,12 @@ function findMicCaptureCommand() {
24335
24690
  function findLiveWhisperScript() {
24336
24691
  const thisDir = dirname13(fileURLToPath8(import.meta.url));
24337
24692
  const candidates = [
24338
- join40(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
24339
- join40(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
24340
- 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"),
24341
24696
  // npm install layout — scripts bundled alongside dist
24342
- join40(thisDir, "../scripts/live-whisper.py"),
24343
- join40(thisDir, "../../scripts/live-whisper.py")
24697
+ join41(thisDir, "../scripts/live-whisper.py"),
24698
+ join41(thisDir, "../../scripts/live-whisper.py")
24344
24699
  ];
24345
24700
  for (const p of candidates) {
24346
24701
  if (existsSync27(p))
@@ -24353,8 +24708,8 @@ function findLiveWhisperScript() {
24353
24708
  stdio: ["pipe", "pipe", "pipe"]
24354
24709
  }).trim();
24355
24710
  const candidates2 = [
24356
- join40(globalRoot, "open-agents-ai", "dist", "scripts", "live-whisper.py"),
24357
- 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")
24358
24713
  ];
24359
24714
  for (const p of candidates2) {
24360
24715
  if (existsSync27(p))
@@ -24362,11 +24717,11 @@ function findLiveWhisperScript() {
24362
24717
  }
24363
24718
  } catch {
24364
24719
  }
24365
- const nvmBase = join40(homedir8(), ".nvm", "versions", "node");
24720
+ const nvmBase = join41(homedir8(), ".nvm", "versions", "node");
24366
24721
  if (existsSync27(nvmBase)) {
24367
24722
  try {
24368
24723
  for (const ver of readdirSync6(nvmBase)) {
24369
- 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");
24370
24725
  if (existsSync27(p))
24371
24726
  return p;
24372
24727
  }
@@ -24385,7 +24740,7 @@ function ensureTranscribeCliBackground() {
24385
24740
  timeout: 5e3,
24386
24741
  stdio: ["pipe", "pipe", "pipe"]
24387
24742
  }).trim();
24388
- if (existsSync27(join40(globalRoot, "transcribe-cli", "dist", "index.js"))) {
24743
+ if (existsSync27(join41(globalRoot, "transcribe-cli", "dist", "index.js"))) {
24389
24744
  return true;
24390
24745
  }
24391
24746
  } catch {
@@ -24608,24 +24963,24 @@ var init_listen = __esm({
24608
24963
  timeout: 5e3,
24609
24964
  stdio: ["pipe", "pipe", "pipe"]
24610
24965
  }).trim();
24611
- const tcPath = join40(globalRoot, "transcribe-cli");
24612
- if (existsSync27(join40(tcPath, "dist", "index.js"))) {
24966
+ const tcPath = join41(globalRoot, "transcribe-cli");
24967
+ if (existsSync27(join41(tcPath, "dist", "index.js"))) {
24613
24968
  const { createRequire: createRequire4 } = await import("node:module");
24614
24969
  const req = createRequire4(import.meta.url);
24615
- return req(join40(tcPath, "dist", "index.js"));
24970
+ return req(join41(tcPath, "dist", "index.js"));
24616
24971
  }
24617
24972
  } catch {
24618
24973
  }
24619
- const nvmBase = join40(homedir8(), ".nvm", "versions", "node");
24974
+ const nvmBase = join41(homedir8(), ".nvm", "versions", "node");
24620
24975
  if (existsSync27(nvmBase)) {
24621
24976
  try {
24622
24977
  const { readdirSync: readdirSync17 } = await import("node:fs");
24623
24978
  for (const ver of readdirSync17(nvmBase)) {
24624
- const tcPath = join40(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
24625
- 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"))) {
24626
24981
  const { createRequire: createRequire4 } = await import("node:module");
24627
24982
  const req = createRequire4(import.meta.url);
24628
- return req(join40(tcPath, "dist", "index.js"));
24983
+ return req(join41(tcPath, "dist", "index.js"));
24629
24984
  }
24630
24985
  }
24631
24986
  } catch {
@@ -24907,9 +25262,9 @@ transcribe-cli error: ${transcribeCliError}` : "";
24907
25262
  });
24908
25263
  if (outputDir) {
24909
25264
  const { basename: basename16 } = await import("node:path");
24910
- const transcriptDir = join40(outputDir, ".oa", "transcripts");
25265
+ const transcriptDir = join41(outputDir, ".oa", "transcripts");
24911
25266
  mkdirSync8(transcriptDir, { recursive: true });
24912
- const outFile = join40(transcriptDir, `${basename16(filePath)}.txt`);
25267
+ const outFile = join41(transcriptDir, `${basename16(filePath)}.txt`);
24913
25268
  writeFileSync9(outFile, result.text, "utf-8");
24914
25269
  }
24915
25270
  return {
@@ -30267,7 +30622,7 @@ import { randomBytes as randomBytes9 } from "node:crypto";
30267
30622
  import { URL as URL2 } from "node:url";
30268
30623
  import { loadavg, cpus, totalmem, freemem } from "node:os";
30269
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";
30270
- import { join as join41 } from "node:path";
30625
+ import { join as join42 } from "node:path";
30271
30626
  function cleanForwardHeaders(raw, targetHost) {
30272
30627
  const out = {};
30273
30628
  for (const [key, value] of Object.entries(raw)) {
@@ -30295,7 +30650,7 @@ function fmtTokens(n) {
30295
30650
  }
30296
30651
  function readExposeState(stateDir) {
30297
30652
  try {
30298
- const path = join41(stateDir, STATE_FILE_NAME);
30653
+ const path = join42(stateDir, STATE_FILE_NAME);
30299
30654
  if (!existsSync28(path))
30300
30655
  return null;
30301
30656
  const raw = readFileSync19(path, "utf8");
@@ -30310,13 +30665,13 @@ function readExposeState(stateDir) {
30310
30665
  function writeExposeState(stateDir, state) {
30311
30666
  try {
30312
30667
  mkdirSync9(stateDir, { recursive: true });
30313
- writeFileSync10(join41(stateDir, STATE_FILE_NAME), JSON.stringify(state, null, 2));
30668
+ writeFileSync10(join42(stateDir, STATE_FILE_NAME), JSON.stringify(state, null, 2));
30314
30669
  } catch {
30315
30670
  }
30316
30671
  }
30317
30672
  function removeExposeState(stateDir) {
30318
30673
  try {
30319
- unlinkSync5(join41(stateDir, STATE_FILE_NAME));
30674
+ unlinkSync5(join42(stateDir, STATE_FILE_NAME));
30320
30675
  } catch {
30321
30676
  }
30322
30677
  }
@@ -30405,7 +30760,7 @@ async function collectSystemMetricsAsync() {
30405
30760
  }
30406
30761
  function readP2PExposeState(stateDir) {
30407
30762
  try {
30408
- const path = join41(stateDir, P2P_STATE_FILE_NAME);
30763
+ const path = join42(stateDir, P2P_STATE_FILE_NAME);
30409
30764
  if (!existsSync28(path))
30410
30765
  return null;
30411
30766
  const raw = readFileSync19(path, "utf8");
@@ -30420,13 +30775,13 @@ function readP2PExposeState(stateDir) {
30420
30775
  function writeP2PExposeState(stateDir, state) {
30421
30776
  try {
30422
30777
  mkdirSync9(stateDir, { recursive: true });
30423
- 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));
30424
30779
  } catch {
30425
30780
  }
30426
30781
  }
30427
30782
  function removeP2PExposeState(stateDir) {
30428
30783
  try {
30429
- unlinkSync5(join41(stateDir, P2P_STATE_FILE_NAME));
30784
+ unlinkSync5(join42(stateDir, P2P_STATE_FILE_NAME));
30430
30785
  } catch {
30431
30786
  }
30432
30787
  }
@@ -31274,7 +31629,7 @@ ${this.formatConnectionInfo()}`);
31274
31629
  throw new Error(`Expose failed: ${exposeResult.error}`);
31275
31630
  }
31276
31631
  const nexusDir = this._nexusTool.getNexusDir();
31277
- const statusPath = join41(nexusDir, "status.json");
31632
+ const statusPath = join42(nexusDir, "status.json");
31278
31633
  for (let i = 0; i < 80; i++) {
31279
31634
  try {
31280
31635
  const raw = readFileSync19(statusPath, "utf8");
@@ -31308,7 +31663,7 @@ ${this.formatConnectionInfo()}`);
31308
31663
  });
31309
31664
  }
31310
31665
  try {
31311
- const invocDir = join41(nexusDir, "invocations");
31666
+ const invocDir = join42(nexusDir, "invocations");
31312
31667
  if (existsSync28(invocDir)) {
31313
31668
  this._prevInvocCount = readdirSync7(invocDir).filter((f) => f.endsWith(".json")).length;
31314
31669
  this._stats.totalRequests = this._prevInvocCount;
@@ -31338,7 +31693,7 @@ ${this.formatConnectionInfo()}`);
31338
31693
  if (!state)
31339
31694
  return null;
31340
31695
  const nexusDir = nexusTool.getNexusDir();
31341
- const statusPath = join41(nexusDir, "status.json");
31696
+ const statusPath = join42(nexusDir, "status.json");
31342
31697
  try {
31343
31698
  if (!existsSync28(statusPath)) {
31344
31699
  removeP2PExposeState(stateDir);
@@ -31397,7 +31752,7 @@ ${this.formatConnectionInfo()}`);
31397
31752
  let lastMeteringLineCount = 0;
31398
31753
  this._activityPollTimer = setInterval(() => {
31399
31754
  try {
31400
- const invocDir = join41(nexusDir, "invocations");
31755
+ const invocDir = join42(nexusDir, "invocations");
31401
31756
  if (!existsSync28(invocDir))
31402
31757
  return;
31403
31758
  const files = readdirSync7(invocDir).filter((f) => f.endsWith(".json"));
@@ -31413,13 +31768,13 @@ ${this.formatConnectionInfo()}`);
31413
31768
  let recentActive = 0;
31414
31769
  for (const f of files.slice(-10)) {
31415
31770
  try {
31416
- const st = statSync10(join41(invocDir, f));
31771
+ const st = statSync10(join42(invocDir, f));
31417
31772
  if (now - st.mtimeMs < 1e4)
31418
31773
  recentActive++;
31419
31774
  } catch {
31420
31775
  }
31421
31776
  }
31422
- const meteringFile = join41(nexusDir, "metering.jsonl");
31777
+ const meteringFile = join42(nexusDir, "metering.jsonl");
31423
31778
  let meteringLines = lastMeteringLineCount;
31424
31779
  try {
31425
31780
  if (existsSync28(meteringFile)) {
@@ -31449,7 +31804,7 @@ ${this.formatConnectionInfo()}`);
31449
31804
  this._activityPollTimer.unref();
31450
31805
  this._pollTimer = setInterval(() => {
31451
31806
  try {
31452
- const statusPath = join41(nexusDir, "status.json");
31807
+ const statusPath = join42(nexusDir, "status.json");
31453
31808
  if (existsSync28(statusPath)) {
31454
31809
  const status = JSON.parse(readFileSync19(statusPath, "utf8"));
31455
31810
  if (status.peerId && !this._peerId) {
@@ -31460,7 +31815,7 @@ ${this.formatConnectionInfo()}`);
31460
31815
  } catch {
31461
31816
  }
31462
31817
  try {
31463
- const invocDir = join41(nexusDir, "invocations");
31818
+ const invocDir = join42(nexusDir, "invocations");
31464
31819
  if (existsSync28(invocDir)) {
31465
31820
  const files = readdirSync7(invocDir);
31466
31821
  const invocCount = files.filter((f) => f.endsWith(".json")).length;
@@ -31472,7 +31827,7 @@ ${this.formatConnectionInfo()}`);
31472
31827
  } catch {
31473
31828
  }
31474
31829
  try {
31475
- const meteringFile = join41(nexusDir, "metering.jsonl");
31830
+ const meteringFile = join42(nexusDir, "metering.jsonl");
31476
31831
  if (existsSync28(meteringFile)) {
31477
31832
  const content = readFileSync19(meteringFile, "utf8");
31478
31833
  if (content.length > lastMeteringSize) {
@@ -31684,7 +32039,7 @@ var init_types = __esm({
31684
32039
  // packages/cli/dist/tui/p2p/secret-vault.js
31685
32040
  import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes10, scryptSync as scryptSync2, createHash as createHash2 } from "node:crypto";
31686
32041
  import { readFileSync as readFileSync20, writeFileSync as writeFileSync11, existsSync as existsSync29, mkdirSync as mkdirSync10 } from "node:fs";
31687
- import { join as join42, dirname as dirname14 } from "node:path";
32042
+ import { join as join43, dirname as dirname14 } from "node:path";
31688
32043
  var PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, CIPHER_ALGO, SALT_LEN, IV_LEN, KEY_LEN, SecretVault;
31689
32044
  var init_secret_vault = __esm({
31690
32045
  "packages/cli/dist/tui/p2p/secret-vault.js"() {
@@ -33021,13 +33376,13 @@ async function fetchPeerModels(peerId, authKey) {
33021
33376
  try {
33022
33377
  const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
33023
33378
  const { existsSync: existsSync45, readFileSync: readFileSync33 } = await import("node:fs");
33024
- const { join: join62 } = await import("node:path");
33379
+ const { join: join63 } = await import("node:path");
33025
33380
  const cwd4 = process.cwd();
33026
33381
  const nexusTool = new NexusTool2(cwd4);
33027
33382
  const nexusDir = nexusTool.getNexusDir();
33028
33383
  let isLocalPeer = false;
33029
33384
  try {
33030
- const statusPath = join62(nexusDir, "status.json");
33385
+ const statusPath = join63(nexusDir, "status.json");
33031
33386
  if (existsSync45(statusPath)) {
33032
33387
  const status = JSON.parse(readFileSync33(statusPath, "utf8"));
33033
33388
  if (status.peerId === peerId)
@@ -33036,7 +33391,7 @@ async function fetchPeerModels(peerId, authKey) {
33036
33391
  } catch {
33037
33392
  }
33038
33393
  if (isLocalPeer) {
33039
- const pricingPath = join62(nexusDir, "pricing.json");
33394
+ const pricingPath = join63(nexusDir, "pricing.json");
33040
33395
  if (existsSync45(pricingPath)) {
33041
33396
  try {
33042
33397
  const pricing = JSON.parse(readFileSync33(pricingPath, "utf8"));
@@ -33053,7 +33408,7 @@ async function fetchPeerModels(peerId, authKey) {
33053
33408
  }
33054
33409
  }
33055
33410
  }
33056
- const cachePath = join62(nexusDir, "peer-models-cache.json");
33411
+ const cachePath = join63(nexusDir, "peer-models-cache.json");
33057
33412
  if (existsSync45(cachePath)) {
33058
33413
  try {
33059
33414
  const cache4 = JSON.parse(readFileSync33(cachePath, "utf8"));
@@ -33171,7 +33526,7 @@ async function fetchPeerModels(peerId, authKey) {
33171
33526
  } catch {
33172
33527
  }
33173
33528
  if (isLocalPeer) {
33174
- const pricingPath = join62(nexusDir, "pricing.json");
33529
+ const pricingPath = join63(nexusDir, "pricing.json");
33175
33530
  if (existsSync45(pricingPath)) {
33176
33531
  try {
33177
33532
  const pricing = JSON.parse(readFileSync33(pricingPath, "utf8"));
@@ -33444,12 +33799,12 @@ var init_render2 = __esm({
33444
33799
 
33445
33800
  // packages/prompts/dist/promptLoader.js
33446
33801
  import { readFileSync as readFileSync21, existsSync as existsSync30 } from "node:fs";
33447
- import { join as join43, dirname as dirname15 } from "node:path";
33802
+ import { join as join44, dirname as dirname15 } from "node:path";
33448
33803
  import { fileURLToPath as fileURLToPath9 } from "node:url";
33449
33804
  function loadPrompt2(promptPath, vars) {
33450
33805
  let content = cache2.get(promptPath);
33451
33806
  if (content === void 0) {
33452
- const fullPath = join43(PROMPTS_DIR2, promptPath);
33807
+ const fullPath = join44(PROMPTS_DIR2, promptPath);
33453
33808
  if (!existsSync30(fullPath)) {
33454
33809
  throw new Error(`Prompt file not found: ${fullPath}`);
33455
33810
  }
@@ -33466,8 +33821,8 @@ var init_promptLoader2 = __esm({
33466
33821
  "use strict";
33467
33822
  __filename2 = fileURLToPath9(import.meta.url);
33468
33823
  __dirname5 = dirname15(__filename2);
33469
- devPath = join43(__dirname5, "..", "templates");
33470
- publishedPath = join43(__dirname5, "..", "prompts", "templates");
33824
+ devPath = join44(__dirname5, "..", "templates");
33825
+ publishedPath = join44(__dirname5, "..", "prompts", "templates");
33471
33826
  PROMPTS_DIR2 = existsSync30(devPath) ? devPath : publishedPath;
33472
33827
  cache2 = /* @__PURE__ */ new Map();
33473
33828
  }
@@ -33579,7 +33934,7 @@ var init_task_templates = __esm({
33579
33934
  });
33580
33935
 
33581
33936
  // packages/prompts/dist/index.js
33582
- import { join as join44, dirname as dirname16 } from "node:path";
33937
+ import { join as join45, dirname as dirname16 } from "node:path";
33583
33938
  import { fileURLToPath as fileURLToPath10 } from "node:url";
33584
33939
  var _dir, _packageRoot;
33585
33940
  var init_dist6 = __esm({
@@ -33590,21 +33945,21 @@ var init_dist6 = __esm({
33590
33945
  init_task_templates();
33591
33946
  init_render2();
33592
33947
  _dir = dirname16(fileURLToPath10(import.meta.url));
33593
- _packageRoot = join44(_dir, "..");
33948
+ _packageRoot = join45(_dir, "..");
33594
33949
  }
33595
33950
  });
33596
33951
 
33597
33952
  // packages/cli/dist/tui/oa-directory.js
33598
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";
33599
- 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";
33600
33955
  import { homedir as homedir9 } from "node:os";
33601
33956
  function initOaDirectory(repoRoot) {
33602
- const oaPath = join45(repoRoot, OA_DIR);
33957
+ const oaPath = join46(repoRoot, OA_DIR);
33603
33958
  for (const sub of SUBDIRS) {
33604
- mkdirSync11(join45(oaPath, sub), { recursive: true });
33959
+ mkdirSync11(join46(oaPath, sub), { recursive: true });
33605
33960
  }
33606
33961
  try {
33607
- const gitignorePath = join45(repoRoot, ".gitignore");
33962
+ const gitignorePath = join46(repoRoot, ".gitignore");
33608
33963
  const settingsPattern = ".oa/settings.json";
33609
33964
  if (existsSync31(gitignorePath)) {
33610
33965
  const content = readFileSync22(gitignorePath, "utf-8");
@@ -33617,10 +33972,10 @@ function initOaDirectory(repoRoot) {
33617
33972
  return oaPath;
33618
33973
  }
33619
33974
  function hasOaDirectory(repoRoot) {
33620
- return existsSync31(join45(repoRoot, OA_DIR, "index"));
33975
+ return existsSync31(join46(repoRoot, OA_DIR, "index"));
33621
33976
  }
33622
33977
  function loadProjectSettings(repoRoot) {
33623
- const settingsPath = join45(repoRoot, OA_DIR, "settings.json");
33978
+ const settingsPath = join46(repoRoot, OA_DIR, "settings.json");
33624
33979
  try {
33625
33980
  if (existsSync31(settingsPath)) {
33626
33981
  return JSON.parse(readFileSync22(settingsPath, "utf-8"));
@@ -33630,14 +33985,14 @@ function loadProjectSettings(repoRoot) {
33630
33985
  return {};
33631
33986
  }
33632
33987
  function saveProjectSettings(repoRoot, settings) {
33633
- const oaPath = join45(repoRoot, OA_DIR);
33988
+ const oaPath = join46(repoRoot, OA_DIR);
33634
33989
  mkdirSync11(oaPath, { recursive: true });
33635
33990
  const existing = loadProjectSettings(repoRoot);
33636
33991
  const merged = { ...existing, ...settings };
33637
- 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 });
33638
33993
  }
33639
33994
  function loadGlobalSettings() {
33640
- const settingsPath = join45(homedir9(), ".open-agents", "settings.json");
33995
+ const settingsPath = join46(homedir9(), ".open-agents", "settings.json");
33641
33996
  try {
33642
33997
  if (existsSync31(settingsPath)) {
33643
33998
  return JSON.parse(readFileSync22(settingsPath, "utf-8"));
@@ -33647,11 +34002,11 @@ function loadGlobalSettings() {
33647
34002
  return {};
33648
34003
  }
33649
34004
  function saveGlobalSettings(settings) {
33650
- const dir = join45(homedir9(), ".open-agents");
34005
+ const dir = join46(homedir9(), ".open-agents");
33651
34006
  mkdirSync11(dir, { recursive: true });
33652
34007
  const existing = loadGlobalSettings();
33653
34008
  const merged = { ...existing, ...settings };
33654
- 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 });
33655
34010
  }
33656
34011
  function resolveSettings(repoRoot) {
33657
34012
  const global = loadGlobalSettings();
@@ -33666,7 +34021,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
33666
34021
  while (dir && !visited.has(dir)) {
33667
34022
  visited.add(dir);
33668
34023
  for (const name of CONTEXT_FILES) {
33669
- const filePath = join45(dir, name);
34024
+ const filePath = join46(dir, name);
33670
34025
  const normalizedName = name.toLowerCase();
33671
34026
  if (existsSync31(filePath) && !seen.has(filePath)) {
33672
34027
  seen.add(filePath);
@@ -33685,7 +34040,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
33685
34040
  }
33686
34041
  }
33687
34042
  }
33688
- const projectMap = join45(dir, OA_DIR, "context", "project-map.md");
34043
+ const projectMap = join46(dir, OA_DIR, "context", "project-map.md");
33689
34044
  if (existsSync31(projectMap) && !seen.has(projectMap)) {
33690
34045
  seen.add(projectMap);
33691
34046
  try {
@@ -33701,7 +34056,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
33701
34056
  } catch {
33702
34057
  }
33703
34058
  }
33704
- const parent = join45(dir, "..");
34059
+ const parent = join46(dir, "..");
33705
34060
  if (parent === dir)
33706
34061
  break;
33707
34062
  dir = parent;
@@ -33719,7 +34074,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
33719
34074
  return found;
33720
34075
  }
33721
34076
  function readIndexMeta(repoRoot) {
33722
- const metaPath = join45(repoRoot, OA_DIR, "index", "meta.json");
34077
+ const metaPath = join46(repoRoot, OA_DIR, "index", "meta.json");
33723
34078
  try {
33724
34079
  return JSON.parse(readFileSync22(metaPath, "utf-8"));
33725
34080
  } catch {
@@ -33772,28 +34127,28 @@ ${tree}\`\`\`
33772
34127
  sections.push("");
33773
34128
  }
33774
34129
  const content = sections.join("\n");
33775
- const contextDir = join45(repoRoot, OA_DIR, "context");
34130
+ const contextDir = join46(repoRoot, OA_DIR, "context");
33776
34131
  mkdirSync11(contextDir, { recursive: true });
33777
- writeFileSync12(join45(contextDir, "project-map.md"), content, "utf-8");
34132
+ writeFileSync12(join46(contextDir, "project-map.md"), content, "utf-8");
33778
34133
  return content;
33779
34134
  }
33780
34135
  function saveSession(repoRoot, session) {
33781
- const historyDir = join45(repoRoot, OA_DIR, "history");
34136
+ const historyDir = join46(repoRoot, OA_DIR, "history");
33782
34137
  mkdirSync11(historyDir, { recursive: true });
33783
- 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");
33784
34139
  }
33785
34140
  function loadRecentSessions(repoRoot, limit = 5) {
33786
- const historyDir = join45(repoRoot, OA_DIR, "history");
34141
+ const historyDir = join46(repoRoot, OA_DIR, "history");
33787
34142
  if (!existsSync31(historyDir))
33788
34143
  return [];
33789
34144
  try {
33790
34145
  const files = readdirSync8(historyDir).filter((f) => f.endsWith(".json") && f !== "pending-task.json").map((f) => {
33791
- const stat5 = statSync11(join45(historyDir, f));
34146
+ const stat5 = statSync11(join46(historyDir, f));
33792
34147
  return { file: f, mtime: stat5.mtimeMs };
33793
34148
  }).sort((a, b) => b.mtime - a.mtime).slice(0, limit);
33794
34149
  return files.map((f) => {
33795
34150
  try {
33796
- return JSON.parse(readFileSync22(join45(historyDir, f.file), "utf-8"));
34151
+ return JSON.parse(readFileSync22(join46(historyDir, f.file), "utf-8"));
33797
34152
  } catch {
33798
34153
  return null;
33799
34154
  }
@@ -33803,12 +34158,12 @@ function loadRecentSessions(repoRoot, limit = 5) {
33803
34158
  }
33804
34159
  }
33805
34160
  function savePendingTask(repoRoot, task) {
33806
- const historyDir = join45(repoRoot, OA_DIR, "history");
34161
+ const historyDir = join46(repoRoot, OA_DIR, "history");
33807
34162
  mkdirSync11(historyDir, { recursive: true });
33808
- 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");
33809
34164
  }
33810
34165
  function loadPendingTask(repoRoot) {
33811
- const filePath = join45(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
34166
+ const filePath = join46(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
33812
34167
  try {
33813
34168
  if (!existsSync31(filePath))
33814
34169
  return null;
@@ -33823,9 +34178,9 @@ function loadPendingTask(repoRoot) {
33823
34178
  }
33824
34179
  }
33825
34180
  function saveSessionContext(repoRoot, entry) {
33826
- const contextDir = join45(repoRoot, OA_DIR, "context");
34181
+ const contextDir = join46(repoRoot, OA_DIR, "context");
33827
34182
  mkdirSync11(contextDir, { recursive: true });
33828
- const filePath = join45(contextDir, CONTEXT_SAVE_FILE);
34183
+ const filePath = join46(contextDir, CONTEXT_SAVE_FILE);
33829
34184
  let ctx;
33830
34185
  try {
33831
34186
  if (existsSync31(filePath)) {
@@ -33844,7 +34199,7 @@ function saveSessionContext(repoRoot, entry) {
33844
34199
  writeFileSync12(filePath, JSON.stringify(ctx, null, 2) + "\n", "utf-8");
33845
34200
  }
33846
34201
  function loadSessionContext(repoRoot) {
33847
- const filePath = join45(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
34202
+ const filePath = join46(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
33848
34203
  try {
33849
34204
  if (!existsSync31(filePath))
33850
34205
  return null;
@@ -33895,7 +34250,7 @@ function detectManifests(repoRoot) {
33895
34250
  { file: "docker-compose.yaml", type: "Docker Compose" }
33896
34251
  ];
33897
34252
  for (const check of checks) {
33898
- const filePath = join45(repoRoot, check.file);
34253
+ const filePath = join46(repoRoot, check.file);
33899
34254
  if (existsSync31(filePath)) {
33900
34255
  let name;
33901
34256
  if (check.nameField) {
@@ -33929,7 +34284,7 @@ function findKeyFiles(repoRoot) {
33929
34284
  { pattern: "CLAUDE.md", description: "Claude Code context" }
33930
34285
  ];
33931
34286
  for (const check of checks) {
33932
- if (existsSync31(join45(repoRoot, check.pattern))) {
34287
+ if (existsSync31(join46(repoRoot, check.pattern))) {
33933
34288
  keyFiles.push({ path: check.pattern, description: check.description });
33934
34289
  }
33935
34290
  }
@@ -33955,12 +34310,12 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
33955
34310
  if (entry.isDirectory()) {
33956
34311
  let fileCount = 0;
33957
34312
  try {
33958
- fileCount = readdirSync8(join45(root, entry.name)).filter((f) => !f.startsWith(".")).length;
34313
+ fileCount = readdirSync8(join46(root, entry.name)).filter((f) => !f.startsWith(".")).length;
33959
34314
  } catch {
33960
34315
  }
33961
34316
  result += `${prefix}${connector}${entry.name}/ (${fileCount})
33962
34317
  `;
33963
- result += buildDirTree(join45(root, entry.name), maxDepth, childPrefix, depth + 1);
34318
+ result += buildDirTree(join46(root, entry.name), maxDepth, childPrefix, depth + 1);
33964
34319
  } else if (depth < maxDepth) {
33965
34320
  result += `${prefix}${connector}${entry.name}
33966
34321
  `;
@@ -33980,7 +34335,7 @@ function loadUsageFile(filePath) {
33980
34335
  return { records: [] };
33981
34336
  }
33982
34337
  function saveUsageFile(filePath, data) {
33983
- const dir = join45(filePath, "..");
34338
+ const dir = join46(filePath, "..");
33984
34339
  mkdirSync11(dir, { recursive: true });
33985
34340
  writeFileSync12(filePath, JSON.stringify(data, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
33986
34341
  }
@@ -34010,15 +34365,15 @@ function recordUsage(kind, value, opts) {
34010
34365
  }
34011
34366
  saveUsageFile(filePath, data);
34012
34367
  };
34013
- update(join45(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
34368
+ update(join46(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
34014
34369
  if (opts?.repoRoot) {
34015
- update(join45(opts.repoRoot, OA_DIR, USAGE_HISTORY_FILE));
34370
+ update(join46(opts.repoRoot, OA_DIR, USAGE_HISTORY_FILE));
34016
34371
  }
34017
34372
  }
34018
34373
  function loadUsageHistory(kind, repoRoot) {
34019
- const globalPath = join45(homedir9(), ".open-agents", USAGE_HISTORY_FILE);
34374
+ const globalPath = join46(homedir9(), ".open-agents", USAGE_HISTORY_FILE);
34020
34375
  const globalData = loadUsageFile(globalPath);
34021
- 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: [] };
34022
34377
  const map = /* @__PURE__ */ new Map();
34023
34378
  for (const r of globalData.records) {
34024
34379
  if (r.kind !== kind)
@@ -34049,9 +34404,9 @@ function deleteUsageRecord(kind, value, repoRoot) {
34049
34404
  saveUsageFile(filePath, data);
34050
34405
  }
34051
34406
  };
34052
- remove(join45(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
34407
+ remove(join46(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
34053
34408
  if (repoRoot) {
34054
- remove(join45(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
34409
+ remove(join46(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
34055
34410
  }
34056
34411
  }
34057
34412
  var OA_DIR, SUBDIRS, CONTEXT_FILES, PENDING_TASK_FILE, CONTEXT_SAVE_FILE, MAX_CONTEXT_ENTRIES, SKIP_DIRS, USAGE_HISTORY_FILE, MAX_HISTORY_RECORDS;
@@ -34102,7 +34457,7 @@ import * as readline from "node:readline";
34102
34457
  import { execSync as execSync25, spawn as spawn18, exec as exec2 } from "node:child_process";
34103
34458
  import { promisify as promisify5 } from "node:util";
34104
34459
  import { existsSync as existsSync32, writeFileSync as writeFileSync13, readFileSync as readFileSync23, appendFileSync as appendFileSync2, mkdirSync as mkdirSync12 } from "node:fs";
34105
- import { join as join46 } from "node:path";
34460
+ import { join as join47 } from "node:path";
34106
34461
  import { homedir as homedir10, platform } from "node:os";
34107
34462
  function detectSystemSpecs() {
34108
34463
  let totalRamGB = 0;
@@ -35143,9 +35498,9 @@ async function doSetup(config, rl) {
35143
35498
  `PARAMETER num_predict ${numPredict}`,
35144
35499
  `PARAMETER stop "<|endoftext|>"`
35145
35500
  ].join("\n");
35146
- const modelDir2 = join46(homedir10(), ".open-agents", "models");
35501
+ const modelDir2 = join47(homedir10(), ".open-agents", "models");
35147
35502
  mkdirSync12(modelDir2, { recursive: true });
35148
- const modelfilePath = join46(modelDir2, `Modelfile.${customName}`);
35503
+ const modelfilePath = join47(modelDir2, `Modelfile.${customName}`);
35149
35504
  writeFileSync13(modelfilePath, modelfileContent + "\n", "utf8");
35150
35505
  process.stdout.write(` ${c2.dim("Creating model...")} `);
35151
35506
  execSync25(`ollama create ${customName} -f ${modelfilePath}`, {
@@ -35191,7 +35546,7 @@ async function isModelAvailable(config) {
35191
35546
  }
35192
35547
  function isFirstRun() {
35193
35548
  try {
35194
- return !existsSync32(join46(homedir10(), ".open-agents", "config.json"));
35549
+ return !existsSync32(join47(homedir10(), ".open-agents", "config.json"));
35195
35550
  } catch {
35196
35551
  return true;
35197
35552
  }
@@ -35228,7 +35583,7 @@ function detectPkgManager() {
35228
35583
  return null;
35229
35584
  }
35230
35585
  function getVenvDir() {
35231
- return join46(homedir10(), ".open-agents", "venv");
35586
+ return join47(homedir10(), ".open-agents", "venv");
35232
35587
  }
35233
35588
  function hasVenvModule() {
35234
35589
  try {
@@ -35240,7 +35595,7 @@ function hasVenvModule() {
35240
35595
  }
35241
35596
  function ensureVenv(log) {
35242
35597
  const venvDir = getVenvDir();
35243
- const venvPip = join46(venvDir, "bin", "pip");
35598
+ const venvPip = join47(venvDir, "bin", "pip");
35244
35599
  if (existsSync32(venvPip))
35245
35600
  return venvDir;
35246
35601
  log("Creating Python venv for vision deps...");
@@ -35253,9 +35608,9 @@ function ensureVenv(log) {
35253
35608
  return null;
35254
35609
  }
35255
35610
  try {
35256
- mkdirSync12(join46(homedir10(), ".open-agents"), { recursive: true });
35611
+ mkdirSync12(join47(homedir10(), ".open-agents"), { recursive: true });
35257
35612
  execSync25(`python3 -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
35258
- execSync25(`"${join46(venvDir, "bin", "pip")}" install --upgrade pip`, {
35613
+ execSync25(`"${join47(venvDir, "bin", "pip")}" install --upgrade pip`, {
35259
35614
  stdio: "pipe",
35260
35615
  timeout: 6e4
35261
35616
  });
@@ -35446,11 +35801,11 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
35446
35801
  }
35447
35802
  }
35448
35803
  const venvDir = getVenvDir();
35449
- const venvBin = join46(venvDir, "bin");
35450
- const venvMoondream = join46(venvBin, "moondream-station");
35804
+ const venvBin = join47(venvDir, "bin");
35805
+ const venvMoondream = join47(venvBin, "moondream-station");
35451
35806
  const venv = ensureVenv(log);
35452
35807
  if (venv && !hasCmd("moondream-station") && !existsSync32(venvMoondream)) {
35453
- const venvPip = join46(venvBin, "pip");
35808
+ const venvPip = join47(venvBin, "pip");
35454
35809
  log("Installing moondream-station in ~/.open-agents/venv...");
35455
35810
  try {
35456
35811
  execSync25(`"${venvPip}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
@@ -35471,8 +35826,8 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
35471
35826
  }
35472
35827
  }
35473
35828
  if (venv) {
35474
- const venvPython = join46(venvBin, "python");
35475
- const venvPip2 = join46(venvBin, "pip");
35829
+ const venvPython = join47(venvBin, "python");
35830
+ const venvPip2 = join47(venvBin, "pip");
35476
35831
  let ocrStackInstalled = false;
35477
35832
  try {
35478
35833
  execSync25(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
@@ -35616,9 +35971,9 @@ async function createExpandedVariantAsync(baseModel, specs, sizeGB, kvBytesPerTo
35616
35971
  `PARAMETER num_predict ${numPredict}`,
35617
35972
  `PARAMETER stop "<|endoftext|>"`
35618
35973
  ].join("\n");
35619
- const modelDir2 = join46(homedir10(), ".open-agents", "models");
35974
+ const modelDir2 = join47(homedir10(), ".open-agents", "models");
35620
35975
  mkdirSync12(modelDir2, { recursive: true });
35621
- const modelfilePath = join46(modelDir2, `Modelfile.${customName}`);
35976
+ const modelfilePath = join47(modelDir2, `Modelfile.${customName}`);
35622
35977
  writeFileSync13(modelfilePath, modelfileContent + "\n", "utf8");
35623
35978
  await execAsync(`ollama create ${customName} -f ${modelfilePath}`, {
35624
35979
  timeout: 12e4
@@ -35693,8 +36048,8 @@ async function ensureNeovim() {
35693
36048
  const platform5 = process.platform;
35694
36049
  const arch = process.arch;
35695
36050
  if (platform5 === "linux") {
35696
- const binDir = join46(homedir10(), ".local", "bin");
35697
- const nvimDest = join46(binDir, "nvim");
36051
+ const binDir = join47(homedir10(), ".local", "bin");
36052
+ const nvimDest = join47(binDir, "nvim");
35698
36053
  try {
35699
36054
  mkdirSync12(binDir, { recursive: true });
35700
36055
  } catch {
@@ -35765,7 +36120,7 @@ async function ensureNeovim() {
35765
36120
  }
35766
36121
  function ensurePathInShellRc(binDir) {
35767
36122
  const shell = process.env.SHELL ?? "";
35768
- const rcFile = shell.includes("zsh") ? join46(homedir10(), ".zshrc") : join46(homedir10(), ".bashrc");
36123
+ const rcFile = shell.includes("zsh") ? join47(homedir10(), ".zshrc") : join47(homedir10(), ".bashrc");
35769
36124
  try {
35770
36125
  const rcContent = existsSync32(rcFile) ? readFileSync23(rcFile, "utf8") : "";
35771
36126
  if (rcContent.includes(binDir))
@@ -36537,7 +36892,7 @@ var init_drop_panel = __esm({
36537
36892
  // packages/cli/dist/tui/neovim-mode.js
36538
36893
  import { existsSync as existsSync34, unlinkSync as unlinkSync7 } from "node:fs";
36539
36894
  import { tmpdir as tmpdir8 } from "node:os";
36540
- import { join as join47 } from "node:path";
36895
+ import { join as join48 } from "node:path";
36541
36896
  import { execSync as execSync26 } from "node:child_process";
36542
36897
  function isNeovimActive() {
36543
36898
  return _state !== null && !_state.cleanedUp;
@@ -36585,7 +36940,7 @@ async function startNeovimMode(opts) {
36585
36940
  );
36586
36941
  } catch {
36587
36942
  }
36588
- const socketPath = join47(tmpdir8(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
36943
+ const socketPath = join48(tmpdir8(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
36589
36944
  try {
36590
36945
  if (existsSync34(socketPath))
36591
36946
  unlinkSync7(socketPath);
@@ -36937,7 +37292,7 @@ __export(voice_exports, {
36937
37292
  resetNarrationContext: () => resetNarrationContext
36938
37293
  });
36939
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";
36940
- import { join as join48 } from "node:path";
37295
+ import { join as join49 } from "node:path";
36941
37296
  import { homedir as homedir11, tmpdir as tmpdir9, platform as platform2 } from "node:os";
36942
37297
  import { execSync as execSync27, spawn as nodeSpawn } from "node:child_process";
36943
37298
  import { createRequire } from "node:module";
@@ -36959,34 +37314,34 @@ function listVoiceModels() {
36959
37314
  }));
36960
37315
  }
36961
37316
  function voiceDir() {
36962
- return join48(homedir11(), ".open-agents", "voice");
37317
+ return join49(homedir11(), ".open-agents", "voice");
36963
37318
  }
36964
37319
  function modelsDir() {
36965
- return join48(voiceDir(), "models");
37320
+ return join49(voiceDir(), "models");
36966
37321
  }
36967
37322
  function modelDir(id) {
36968
- return join48(modelsDir(), id);
37323
+ return join49(modelsDir(), id);
36969
37324
  }
36970
37325
  function modelOnnxPath(id) {
36971
- return join48(modelDir(id), "model.onnx");
37326
+ return join49(modelDir(id), "model.onnx");
36972
37327
  }
36973
37328
  function modelConfigPath(id) {
36974
- return join48(modelDir(id), "config.json");
37329
+ return join49(modelDir(id), "config.json");
36975
37330
  }
36976
37331
  function luxttsVenvDir() {
36977
- return join48(voiceDir(), "luxtts-venv");
37332
+ return join49(voiceDir(), "luxtts-venv");
36978
37333
  }
36979
37334
  function luxttsVenvPy() {
36980
- 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");
36981
37336
  }
36982
37337
  function luxttsRepoDir() {
36983
- return join48(voiceDir(), "LuxTTS");
37338
+ return join49(voiceDir(), "LuxTTS");
36984
37339
  }
36985
37340
  function luxttsCloneRefsDir() {
36986
- return join48(voiceDir(), "clone-refs");
37341
+ return join49(voiceDir(), "clone-refs");
36987
37342
  }
36988
37343
  function luxttsInferScript() {
36989
- return join48(voiceDir(), "luxtts-infer.py");
37344
+ return join49(voiceDir(), "luxtts-infer.py");
36990
37345
  }
36991
37346
  function emotionToPitchBias(emotion, stark = false, autist = false) {
36992
37347
  if (autist)
@@ -37794,7 +38149,7 @@ var init_voice = __esm({
37794
38149
  const refsDir = luxttsCloneRefsDir();
37795
38150
  const targets = ["glados", "overwatch"];
37796
38151
  for (const modelId of targets) {
37797
- const refFile = join48(refsDir, `${modelId}-ref.wav`);
38152
+ const refFile = join49(refsDir, `${modelId}-ref.wav`);
37798
38153
  if (existsSync35(refFile))
37799
38154
  continue;
37800
38155
  try {
@@ -37874,7 +38229,7 @@ var init_voice = __esm({
37874
38229
  }
37875
38230
  p = p.replace(/\\ /g, " ");
37876
38231
  if (p.startsWith("~/") || p === "~") {
37877
- p = join48(homedir11(), p.slice(1));
38232
+ p = join49(homedir11(), p.slice(1));
37878
38233
  }
37879
38234
  if (!existsSync35(p)) {
37880
38235
  return `File not found: ${p}
@@ -37888,7 +38243,7 @@ var init_voice = __esm({
37888
38243
  const srcName = (audioPath.split("/").pop() ?? "clone").replace(/\.[^.]+$/, "").replace(/[^a-zA-Z0-9_-]/g, "-");
37889
38244
  const ts = Date.now().toString(36);
37890
38245
  const destFilename = `clone-${srcName}-${ts}.${ext}`;
37891
- const destPath = join48(refsDir, destFilename);
38246
+ const destPath = join49(refsDir, destFilename);
37892
38247
  try {
37893
38248
  const data = readFileSync24(audioPath);
37894
38249
  writeFileSync14(destPath, data);
@@ -37933,7 +38288,7 @@ var init_voice = __esm({
37933
38288
  const refsDir = luxttsCloneRefsDir();
37934
38289
  if (!existsSync35(refsDir))
37935
38290
  mkdirSync13(refsDir, { recursive: true });
37936
- const destPath = join48(refsDir, `${sourceModelId}-ref.wav`);
38291
+ const destPath = join49(refsDir, `${sourceModelId}-ref.wav`);
37937
38292
  const sampleRate = this.config?.audio?.sample_rate ?? 22050;
37938
38293
  this.writeWav(audioData, sampleRate, destPath);
37939
38294
  this.luxttsCloneRef = destPath;
@@ -37949,7 +38304,7 @@ var init_voice = __esm({
37949
38304
  // -------------------------------------------------------------------------
37950
38305
  /** Metadata file for friendly names of clone refs */
37951
38306
  static cloneMetaFile() {
37952
- return join48(luxttsCloneRefsDir(), "meta.json");
38307
+ return join49(luxttsCloneRefsDir(), "meta.json");
37953
38308
  }
37954
38309
  loadCloneMeta() {
37955
38310
  const p = _VoiceEngine.cloneMetaFile();
@@ -37983,7 +38338,7 @@ var init_voice = __esm({
37983
38338
  return _VoiceEngine.AUDIO_EXTS.has(ext);
37984
38339
  });
37985
38340
  return files.map((f) => {
37986
- const p = join48(dir, f);
38341
+ const p = join49(dir, f);
37987
38342
  let size = 0;
37988
38343
  try {
37989
38344
  size = statSync12(p).size;
@@ -38000,7 +38355,7 @@ var init_voice = __esm({
38000
38355
  }
38001
38356
  /** Delete a clone reference file by filename. Returns true if deleted. */
38002
38357
  deleteCloneRef(filename) {
38003
- const p = join48(luxttsCloneRefsDir(), filename);
38358
+ const p = join49(luxttsCloneRefsDir(), filename);
38004
38359
  if (!existsSync35(p))
38005
38360
  return false;
38006
38361
  try {
@@ -38025,7 +38380,7 @@ var init_voice = __esm({
38025
38380
  }
38026
38381
  /** Set the active clone reference by filename. */
38027
38382
  setActiveCloneRef(filename) {
38028
- const p = join48(luxttsCloneRefsDir(), filename);
38383
+ const p = join49(luxttsCloneRefsDir(), filename);
38029
38384
  if (!existsSync35(p))
38030
38385
  return `File not found: ${filename}`;
38031
38386
  this.luxttsCloneRef = p;
@@ -38311,7 +38666,7 @@ var init_voice = __esm({
38311
38666
  }
38312
38667
  this.onPCMOutput(Buffer.from(int16.buffer), sampleRate);
38313
38668
  }
38314
- const wavPath = join48(tmpdir9(), `oa-voice-${Date.now()}.wav`);
38669
+ const wavPath = join49(tmpdir9(), `oa-voice-${Date.now()}.wav`);
38315
38670
  this.writeWav(audioData, sampleRate, wavPath);
38316
38671
  await this.playWav(wavPath);
38317
38672
  try {
@@ -38654,7 +39009,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
38654
39009
  const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
38655
39010
  const mlxVoice = model.mlxVoice ?? "af_heart";
38656
39011
  const mlxLangCode = model.mlxLangCode ?? "a";
38657
- const wavPath = join48(tmpdir9(), `oa-mlx-${Date.now()}.wav`);
39012
+ const wavPath = join49(tmpdir9(), `oa-mlx-${Date.now()}.wav`);
38658
39013
  const pyScript = [
38659
39014
  "import sys, json",
38660
39015
  "from mlx_audio.tts import generate as tts_gen",
@@ -38722,7 +39077,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
38722
39077
  const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
38723
39078
  const mlxVoice = model.mlxVoice ?? "af_heart";
38724
39079
  const mlxLangCode = model.mlxLangCode ?? "a";
38725
- const wavPath = join48(tmpdir9(), `oa-mlx-buf-${Date.now()}.wav`);
39080
+ const wavPath = join49(tmpdir9(), `oa-mlx-buf-${Date.now()}.wav`);
38726
39081
  const pyScript = [
38727
39082
  "import sys, json",
38728
39083
  "from mlx_audio.tts import generate as tts_gen",
@@ -38833,7 +39188,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
38833
39188
  }
38834
39189
  }
38835
39190
  const repoDir = luxttsRepoDir();
38836
- if (!existsSync35(join48(repoDir, "zipvoice", "luxvoice.py"))) {
39191
+ if (!existsSync35(join49(repoDir, "zipvoice", "luxvoice.py"))) {
38837
39192
  renderInfo(" Cloning LuxTTS repository...");
38838
39193
  try {
38839
39194
  if (existsSync35(repoDir)) {
@@ -38882,7 +39237,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
38882
39237
  if (!existsSync35(refsDir))
38883
39238
  return;
38884
39239
  for (const name of ["custom-clone.wav", "custom-clone.mp3", "glados-ref.wav", "overwatch-ref.wav"]) {
38885
- const p = join48(refsDir, name);
39240
+ const p = join49(refsDir, name);
38886
39241
  if (existsSync35(p)) {
38887
39242
  this.luxttsCloneRef = p;
38888
39243
  return;
@@ -39079,7 +39434,7 @@ if __name__ == '__main__':
39079
39434
  const ready = await this.ensureLuxttsDaemon();
39080
39435
  if (!ready)
39081
39436
  return;
39082
- const wavPath = join48(tmpdir9(), `oa-luxtts-${Date.now()}.wav`);
39437
+ const wavPath = join49(tmpdir9(), `oa-luxtts-${Date.now()}.wav`);
39083
39438
  try {
39084
39439
  await this.luxttsRequest({
39085
39440
  action: "synthesize",
@@ -39153,7 +39508,7 @@ if __name__ == '__main__':
39153
39508
  const ready = await this.ensureLuxttsDaemon();
39154
39509
  if (!ready)
39155
39510
  return null;
39156
- const wavPath = join48(tmpdir9(), `oa-luxtts-buf-${Date.now()}.wav`);
39511
+ const wavPath = join49(tmpdir9(), `oa-luxtts-buf-${Date.now()}.wav`);
39157
39512
  try {
39158
39513
  await this.luxttsRequest({
39159
39514
  action: "synthesize",
@@ -39183,7 +39538,7 @@ if __name__ == '__main__':
39183
39538
  return;
39184
39539
  const arch = process.arch;
39185
39540
  mkdirSync13(voiceDir(), { recursive: true });
39186
- const pkgPath = join48(voiceDir(), "package.json");
39541
+ const pkgPath = join49(voiceDir(), "package.json");
39187
39542
  const expectedDeps = {
39188
39543
  "onnxruntime-node": "^1.21.0",
39189
39544
  "phonemizer": "^1.2.1"
@@ -39205,17 +39560,17 @@ if __name__ == '__main__':
39205
39560
  dependencies: expectedDeps
39206
39561
  }, null, 2));
39207
39562
  }
39208
- const voiceRequire = createRequire(join48(voiceDir(), "index.js"));
39563
+ const voiceRequire = createRequire(join49(voiceDir(), "index.js"));
39209
39564
  const probeOnnx = () => {
39210
39565
  try {
39211
- 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") } });
39212
39567
  const output = result.toString().trim();
39213
39568
  return output === "OK";
39214
39569
  } catch {
39215
39570
  return false;
39216
39571
  }
39217
39572
  };
39218
- const onnxNodeModules = join48(voiceDir(), "node_modules", "onnxruntime-node");
39573
+ const onnxNodeModules = join49(voiceDir(), "node_modules", "onnxruntime-node");
39219
39574
  const onnxInstalled = existsSync35(onnxNodeModules);
39220
39575
  if (onnxInstalled && !probeOnnx()) {
39221
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.`);
@@ -41559,8 +41914,8 @@ async function handlePeerEndpoint(peerId, authKey, ctx, local) {
41559
41914
  if (models.length > 0) {
41560
41915
  try {
41561
41916
  const { writeFileSync: writeFileSync20, mkdirSync: mkdirSync21 } = await import("node:fs");
41562
- const { join: join62, dirname: dirname20 } = await import("node:path");
41563
- 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");
41564
41919
  mkdirSync21(dirname20(cachePath), { recursive: true });
41565
41920
  writeFileSync20(cachePath, JSON.stringify({
41566
41921
  peerId,
@@ -41761,14 +42116,14 @@ async function handleUpdate(subcommand, ctx) {
41761
42116
  try {
41762
42117
  const { createRequire: createRequire4 } = await import("node:module");
41763
42118
  const { fileURLToPath: fileURLToPath14 } = await import("node:url");
41764
- const { dirname: dirname20, join: join62 } = await import("node:path");
42119
+ const { dirname: dirname20, join: join63 } = await import("node:path");
41765
42120
  const { existsSync: existsSync45 } = await import("node:fs");
41766
42121
  const req = createRequire4(import.meta.url);
41767
42122
  const thisDir = dirname20(fileURLToPath14(import.meta.url));
41768
42123
  const candidates = [
41769
- join62(thisDir, "..", "package.json"),
41770
- join62(thisDir, "..", "..", "package.json"),
41771
- join62(thisDir, "..", "..", "..", "package.json")
42124
+ join63(thisDir, "..", "package.json"),
42125
+ join63(thisDir, "..", "..", "package.json"),
42126
+ join63(thisDir, "..", "..", "..", "package.json")
41772
42127
  ];
41773
42128
  for (const pkgPath of candidates) {
41774
42129
  if (existsSync45(pkgPath)) {
@@ -42486,7 +42841,7 @@ var init_commands = __esm({
42486
42841
 
42487
42842
  // packages/cli/dist/tui/project-context.js
42488
42843
  import { existsSync as existsSync36, readFileSync as readFileSync25, readdirSync as readdirSync10 } from "node:fs";
42489
- import { join as join49, basename as basename10 } from "node:path";
42844
+ import { join as join50, basename as basename10 } from "node:path";
42490
42845
  import { execSync as execSync28 } from "node:child_process";
42491
42846
  import { homedir as homedir12, platform as platform3, release } from "node:os";
42492
42847
  function getModelTier(modelName) {
@@ -42521,7 +42876,7 @@ function loadProjectMap(repoRoot) {
42521
42876
  if (!hasOaDirectory(repoRoot)) {
42522
42877
  initOaDirectory(repoRoot);
42523
42878
  }
42524
- const mapPath = join49(repoRoot, OA_DIR, "context", "project-map.md");
42879
+ const mapPath = join50(repoRoot, OA_DIR, "context", "project-map.md");
42525
42880
  if (existsSync36(mapPath)) {
42526
42881
  try {
42527
42882
  const content = readFileSync25(mapPath, "utf-8");
@@ -42565,17 +42920,17 @@ ${log}`);
42565
42920
  }
42566
42921
  function loadMemoryContext(repoRoot) {
42567
42922
  const sections = [];
42568
- const oaMemDir = join49(repoRoot, OA_DIR, "memory");
42923
+ const oaMemDir = join50(repoRoot, OA_DIR, "memory");
42569
42924
  const oaEntries = loadMemoryDir(oaMemDir, "project");
42570
42925
  if (oaEntries)
42571
42926
  sections.push(oaEntries);
42572
- const legacyMemDir = join49(repoRoot, ".open-agents", "memory");
42927
+ const legacyMemDir = join50(repoRoot, ".open-agents", "memory");
42573
42928
  if (legacyMemDir !== oaMemDir && existsSync36(legacyMemDir)) {
42574
42929
  const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
42575
42930
  if (legacyEntries)
42576
42931
  sections.push(legacyEntries);
42577
42932
  }
42578
- const globalMemDir = join49(homedir12(), ".open-agents", "memory");
42933
+ const globalMemDir = join50(homedir12(), ".open-agents", "memory");
42579
42934
  const globalEntries = loadMemoryDir(globalMemDir, "global");
42580
42935
  if (globalEntries)
42581
42936
  sections.push(globalEntries);
@@ -42589,7 +42944,7 @@ function loadMemoryDir(memDir, scope) {
42589
42944
  const files = readdirSync10(memDir).filter((f) => f.endsWith(".json"));
42590
42945
  for (const file of files.slice(0, 10)) {
42591
42946
  try {
42592
- const raw = readFileSync25(join49(memDir, file), "utf-8");
42947
+ const raw = readFileSync25(join50(memDir, file), "utf-8");
42593
42948
  const entries = JSON.parse(raw);
42594
42949
  const topic = basename10(file, ".json");
42595
42950
  const keys = Object.keys(entries);
@@ -43613,9 +43968,9 @@ var init_carousel = __esm({
43613
43968
 
43614
43969
  // packages/cli/dist/tui/carousel-descriptors.js
43615
43970
  import { existsSync as existsSync37, readFileSync as readFileSync26, writeFileSync as writeFileSync15, mkdirSync as mkdirSync14, readdirSync as readdirSync11 } from "node:fs";
43616
- import { join as join50, basename as basename11 } from "node:path";
43971
+ import { join as join51, basename as basename11 } from "node:path";
43617
43972
  function loadToolProfile(repoRoot) {
43618
- const filePath = join50(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
43973
+ const filePath = join51(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
43619
43974
  try {
43620
43975
  if (!existsSync37(filePath))
43621
43976
  return null;
@@ -43625,9 +43980,9 @@ function loadToolProfile(repoRoot) {
43625
43980
  }
43626
43981
  }
43627
43982
  function saveToolProfile(repoRoot, profile) {
43628
- const contextDir = join50(repoRoot, OA_DIR, "context");
43983
+ const contextDir = join51(repoRoot, OA_DIR, "context");
43629
43984
  mkdirSync14(contextDir, { recursive: true });
43630
- 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");
43631
43986
  }
43632
43987
  function categorizeToolCall(toolName) {
43633
43988
  for (const cat of TOOL_CATEGORIES) {
@@ -43685,7 +44040,7 @@ function weightedColor(profile) {
43685
44040
  return selectedCat.colors[Math.floor(Math.random() * selectedCat.colors.length)];
43686
44041
  }
43687
44042
  function loadCachedDescriptors(repoRoot) {
43688
- const filePath = join50(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
44043
+ const filePath = join51(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
43689
44044
  try {
43690
44045
  if (!existsSync37(filePath))
43691
44046
  return null;
@@ -43696,14 +44051,14 @@ function loadCachedDescriptors(repoRoot) {
43696
44051
  }
43697
44052
  }
43698
44053
  function saveCachedDescriptors(repoRoot, phrases, sourceHash) {
43699
- const contextDir = join50(repoRoot, OA_DIR, "context");
44054
+ const contextDir = join51(repoRoot, OA_DIR, "context");
43700
44055
  mkdirSync14(contextDir, { recursive: true });
43701
44056
  const cached = {
43702
44057
  phrases,
43703
44058
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
43704
44059
  sourceHash
43705
44060
  };
43706
- 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");
43707
44062
  }
43708
44063
  function generateDescriptors(repoRoot) {
43709
44064
  const profile = loadToolProfile(repoRoot);
@@ -43751,7 +44106,7 @@ function generateDescriptors(repoRoot) {
43751
44106
  return phrases;
43752
44107
  }
43753
44108
  function extractFromPackageJson(repoRoot, tags) {
43754
- const pkgPath = join50(repoRoot, "package.json");
44109
+ const pkgPath = join51(repoRoot, "package.json");
43755
44110
  try {
43756
44111
  if (!existsSync37(pkgPath))
43757
44112
  return;
@@ -43799,7 +44154,7 @@ function extractFromManifests(repoRoot, tags) {
43799
44154
  { file: ".github/workflows", tag: "ci/cd" }
43800
44155
  ];
43801
44156
  for (const check of manifestChecks) {
43802
- if (existsSync37(join50(repoRoot, check.file))) {
44157
+ if (existsSync37(join51(repoRoot, check.file))) {
43803
44158
  tags.push(check.tag);
43804
44159
  }
43805
44160
  }
@@ -43821,7 +44176,7 @@ function extractFromSessions(repoRoot, tags) {
43821
44176
  }
43822
44177
  }
43823
44178
  function extractFromMemory(repoRoot, tags) {
43824
- const memoryDir = join50(repoRoot, OA_DIR, "memory");
44179
+ const memoryDir = join51(repoRoot, OA_DIR, "memory");
43825
44180
  try {
43826
44181
  if (!existsSync37(memoryDir))
43827
44182
  return;
@@ -43830,7 +44185,7 @@ function extractFromMemory(repoRoot, tags) {
43830
44185
  const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
43831
44186
  tags.push(topic);
43832
44187
  try {
43833
- const data = JSON.parse(readFileSync26(join50(memoryDir, file), "utf-8"));
44188
+ const data = JSON.parse(readFileSync26(join51(memoryDir, file), "utf-8"));
43834
44189
  if (data && typeof data === "object") {
43835
44190
  const keys = Object.keys(data).slice(0, 3);
43836
44191
  for (const key of keys) {
@@ -44453,10 +44808,10 @@ var init_stream_renderer = __esm({
44453
44808
 
44454
44809
  // packages/cli/dist/tui/edit-history.js
44455
44810
  import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync15 } from "node:fs";
44456
- import { join as join51 } from "node:path";
44811
+ import { join as join52 } from "node:path";
44457
44812
  function createEditHistoryLogger(repoRoot, sessionId) {
44458
- const historyDir = join51(repoRoot, ".oa", "history");
44459
- const logPath = join51(historyDir, "edits.jsonl");
44813
+ const historyDir = join52(repoRoot, ".oa", "history");
44814
+ const logPath = join52(historyDir, "edits.jsonl");
44460
44815
  try {
44461
44816
  mkdirSync15(historyDir, { recursive: true });
44462
44817
  } catch {
@@ -44568,12 +44923,12 @@ var init_edit_history = __esm({
44568
44923
 
44569
44924
  // packages/cli/dist/tui/promptLoader.js
44570
44925
  import { readFileSync as readFileSync27, existsSync as existsSync38 } from "node:fs";
44571
- import { join as join52, dirname as dirname17 } from "node:path";
44926
+ import { join as join53, dirname as dirname17 } from "node:path";
44572
44927
  import { fileURLToPath as fileURLToPath11 } from "node:url";
44573
44928
  function loadPrompt3(promptPath, vars) {
44574
44929
  let content = cache3.get(promptPath);
44575
44930
  if (content === void 0) {
44576
- const fullPath = join52(PROMPTS_DIR3, promptPath);
44931
+ const fullPath = join53(PROMPTS_DIR3, promptPath);
44577
44932
  if (!existsSync38(fullPath)) {
44578
44933
  throw new Error(`Prompt file not found: ${fullPath}`);
44579
44934
  }
@@ -44590,8 +44945,8 @@ var init_promptLoader3 = __esm({
44590
44945
  "use strict";
44591
44946
  __filename3 = fileURLToPath11(import.meta.url);
44592
44947
  __dirname6 = dirname17(__filename3);
44593
- devPath2 = join52(__dirname6, "..", "..", "prompts");
44594
- publishedPath2 = join52(__dirname6, "..", "prompts");
44948
+ devPath2 = join53(__dirname6, "..", "..", "prompts");
44949
+ publishedPath2 = join53(__dirname6, "..", "prompts");
44595
44950
  PROMPTS_DIR3 = existsSync38(devPath2) ? devPath2 : publishedPath2;
44596
44951
  cache3 = /* @__PURE__ */ new Map();
44597
44952
  }
@@ -44599,10 +44954,10 @@ var init_promptLoader3 = __esm({
44599
44954
 
44600
44955
  // packages/cli/dist/tui/dream-engine.js
44601
44956
  import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync16, readFileSync as readFileSync28, existsSync as existsSync39, cpSync, rmSync, readdirSync as readdirSync12 } from "node:fs";
44602
- import { join as join53, basename as basename12 } from "node:path";
44957
+ import { join as join54, basename as basename12 } from "node:path";
44603
44958
  import { execSync as execSync29 } from "node:child_process";
44604
44959
  function loadAutoresearchMemory(repoRoot) {
44605
- const memoryPath = join53(repoRoot, ".oa", "memory", "autoresearch.json");
44960
+ const memoryPath = join54(repoRoot, ".oa", "memory", "autoresearch.json");
44606
44961
  if (!existsSync39(memoryPath))
44607
44962
  return "";
44608
44963
  try {
@@ -44796,12 +45151,12 @@ var init_dream_engine = __esm({
44796
45151
  const content = String(args["content"] ?? "");
44797
45152
  if (!rawPath)
44798
45153
  return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
44799
- 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);
44800
45155
  if (!targetPath.startsWith(this.autoresearchDir)) {
44801
45156
  return { success: false, output: "", error: "Autoresearch mode: writes are confined to .oa/autoresearch/", durationMs: Date.now() - start };
44802
45157
  }
44803
45158
  try {
44804
- const dir = join53(targetPath, "..");
45159
+ const dir = join54(targetPath, "..");
44805
45160
  mkdirSync16(dir, { recursive: true });
44806
45161
  writeFileSync16(targetPath, content, "utf-8");
44807
45162
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
@@ -44831,7 +45186,7 @@ var init_dream_engine = __esm({
44831
45186
  const rawPath = String(args["path"] ?? "");
44832
45187
  const oldStr = String(args["old_string"] ?? "");
44833
45188
  const newStr = String(args["new_string"] ?? "");
44834
- 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);
44835
45190
  if (!targetPath.startsWith(this.autoresearchDir)) {
44836
45191
  return { success: false, output: "", error: "Autoresearch mode: edits are confined to .oa/autoresearch/", durationMs: Date.now() - start };
44837
45192
  }
@@ -44885,12 +45240,12 @@ var init_dream_engine = __esm({
44885
45240
  const content = String(args["content"] ?? "");
44886
45241
  if (!rawPath)
44887
45242
  return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
44888
- 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);
44889
45244
  if (!targetPath.startsWith(this.dreamsDir)) {
44890
45245
  return { success: false, output: "", error: "Dream mode: writes are confined to .oa/dreams/", durationMs: Date.now() - start };
44891
45246
  }
44892
45247
  try {
44893
- const dir = join53(targetPath, "..");
45248
+ const dir = join54(targetPath, "..");
44894
45249
  mkdirSync16(dir, { recursive: true });
44895
45250
  writeFileSync16(targetPath, content, "utf-8");
44896
45251
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
@@ -44920,7 +45275,7 @@ var init_dream_engine = __esm({
44920
45275
  const rawPath = String(args["path"] ?? "");
44921
45276
  const oldStr = String(args["old_string"] ?? "");
44922
45277
  const newStr = String(args["new_string"] ?? "");
44923
- 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);
44924
45279
  if (!targetPath.startsWith(this.dreamsDir)) {
44925
45280
  return { success: false, output: "", error: "Dream mode: edits are confined to .oa/dreams/", durationMs: Date.now() - start };
44926
45281
  }
@@ -44987,7 +45342,7 @@ var init_dream_engine = __esm({
44987
45342
  constructor(config, repoRoot) {
44988
45343
  this.config = config;
44989
45344
  this.repoRoot = repoRoot;
44990
- this.dreamsDir = join53(repoRoot, ".oa", "dreams");
45345
+ this.dreamsDir = join54(repoRoot, ".oa", "dreams");
44991
45346
  this.state = {
44992
45347
  mode: "default",
44993
45348
  active: false,
@@ -45071,7 +45426,7 @@ ${result.summary}`;
45071
45426
  if (mode !== "default" || cycle === totalCycles) {
45072
45427
  renderDreamContraction(cycle);
45073
45428
  const cycleSummary = this.buildCycleSummary(cycle, previousFindings);
45074
- const summaryPath = join53(this.dreamsDir, `cycle-${cycle}-summary.md`);
45429
+ const summaryPath = join54(this.dreamsDir, `cycle-${cycle}-summary.md`);
45075
45430
  writeFileSync16(summaryPath, cycleSummary, "utf-8");
45076
45431
  }
45077
45432
  if (mode === "lucid" && !this.abortController.signal.aborted) {
@@ -45284,7 +45639,7 @@ After synthesis, call task_complete with the final prioritized summary.`, toolMo
45284
45639
  }
45285
45640
  /** Build role-specific tool sets for swarm agents */
45286
45641
  buildSwarmTools(role, _workspace) {
45287
- const autoresearchDir = join53(this.repoRoot, ".oa", "autoresearch");
45642
+ const autoresearchDir = join54(this.repoRoot, ".oa", "autoresearch");
45288
45643
  const taskComplete = this.createSwarmTaskCompleteTool(role);
45289
45644
  switch (role) {
45290
45645
  case "researcher": {
@@ -45648,7 +46003,7 @@ INSTRUCTIONS:
45648
46003
  2. Summarize the key learnings and next steps
45649
46004
 
45650
46005
  Call task_complete with a human-readable summary of the autoresearch session.`, workspace, onEvent);
45651
- const reportPath = join53(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
46006
+ const reportPath = join54(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
45652
46007
  const report = `# Autoresearch Swarm Report \u2014 Cycle ${cycleNum}
45653
46008
 
45654
46009
  **Date**: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
@@ -45737,7 +46092,7 @@ ${summaryResult}
45737
46092
  }
45738
46093
  /** Save workspace backup for lucid mode */
45739
46094
  saveVersionCheckpoint(cycle) {
45740
- const checkpointDir = join53(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
46095
+ const checkpointDir = join54(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
45741
46096
  try {
45742
46097
  mkdirSync16(checkpointDir, { recursive: true });
45743
46098
  try {
@@ -45756,10 +46111,10 @@ ${summaryResult}
45756
46111
  encoding: "utf-8",
45757
46112
  timeout: 5e3
45758
46113
  }).trim();
45759
- writeFileSync16(join53(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
45760
- writeFileSync16(join53(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
45761
- writeFileSync16(join53(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
45762
- 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({
45763
46118
  cycle,
45764
46119
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
45765
46120
  gitHash,
@@ -45767,7 +46122,7 @@ ${summaryResult}
45767
46122
  }, null, 2), "utf-8");
45768
46123
  renderInfo(`Checkpoint saved: cycle ${cycle} (${gitHash.slice(0, 8)})`);
45769
46124
  } catch {
45770
- 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");
45771
46126
  renderInfo(`Checkpoint saved: cycle ${cycle} (no git)`);
45772
46127
  }
45773
46128
  } catch (err) {
@@ -45825,14 +46180,14 @@ ${files.map((f) => `- [\`${f}\`](./${f})`).join("\n")}
45825
46180
  ---
45826
46181
  *Auto-generated by open-agents dream engine*
45827
46182
  `;
45828
- writeFileSync16(join53(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
46183
+ writeFileSync16(join54(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
45829
46184
  } catch {
45830
46185
  }
45831
46186
  }
45832
46187
  /** Save dream state for resume/inspection */
45833
46188
  saveDreamState() {
45834
46189
  try {
45835
- 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");
45836
46191
  } catch {
45837
46192
  }
45838
46193
  }
@@ -46207,7 +46562,7 @@ var init_bless_engine = __esm({
46207
46562
 
46208
46563
  // packages/cli/dist/tui/dmn-engine.js
46209
46564
  import { existsSync as existsSync40, readFileSync as readFileSync29, writeFileSync as writeFileSync17, mkdirSync as mkdirSync17, readdirSync as readdirSync13, unlinkSync as unlinkSync9 } from "node:fs";
46210
- import { join as join54, basename as basename13 } from "node:path";
46565
+ import { join as join55, basename as basename13 } from "node:path";
46211
46566
  function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
46212
46567
  const competenceReport = competence.length > 0 ? competence.map((c3) => {
46213
46568
  const rate = c3.attempts > 0 ? Math.round(c3.successes / c3.attempts * 100) : 0;
@@ -46320,8 +46675,8 @@ var init_dmn_engine = __esm({
46320
46675
  constructor(config, repoRoot) {
46321
46676
  this.config = config;
46322
46677
  this.repoRoot = repoRoot;
46323
- this.stateDir = join54(repoRoot, ".oa", "dmn");
46324
- this.historyDir = join54(repoRoot, ".oa", "dmn", "cycles");
46678
+ this.stateDir = join55(repoRoot, ".oa", "dmn");
46679
+ this.historyDir = join55(repoRoot, ".oa", "dmn", "cycles");
46325
46680
  mkdirSync17(this.historyDir, { recursive: true });
46326
46681
  this.loadState();
46327
46682
  }
@@ -46911,8 +47266,8 @@ OUTPUT: Call task_complete with JSON:
46911
47266
  async gatherMemoryTopics() {
46912
47267
  const topics = [];
46913
47268
  const dirs = [
46914
- join54(this.repoRoot, ".oa", "memory"),
46915
- join54(this.repoRoot, ".open-agents", "memory")
47269
+ join55(this.repoRoot, ".oa", "memory"),
47270
+ join55(this.repoRoot, ".open-agents", "memory")
46916
47271
  ];
46917
47272
  for (const dir of dirs) {
46918
47273
  if (!existsSync40(dir))
@@ -46931,7 +47286,7 @@ OUTPUT: Call task_complete with JSON:
46931
47286
  }
46932
47287
  // ── State persistence ─────────────────────────────────────────────────
46933
47288
  loadState() {
46934
- const path = join54(this.stateDir, "state.json");
47289
+ const path = join55(this.stateDir, "state.json");
46935
47290
  if (existsSync40(path)) {
46936
47291
  try {
46937
47292
  this.state = JSON.parse(readFileSync29(path, "utf-8"));
@@ -46941,19 +47296,19 @@ OUTPUT: Call task_complete with JSON:
46941
47296
  }
46942
47297
  saveState() {
46943
47298
  try {
46944
- 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");
46945
47300
  } catch {
46946
47301
  }
46947
47302
  }
46948
47303
  saveCycleResult(result) {
46949
47304
  try {
46950
47305
  const filename = `cycle-${result.cycleNumber}-${Date.now()}.json`;
46951
- 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");
46952
47307
  const files = readdirSync13(this.historyDir).filter((f) => f.startsWith("cycle-") && f.endsWith(".json")).sort();
46953
47308
  if (files.length > 50) {
46954
47309
  for (const old of files.slice(0, files.length - 50)) {
46955
47310
  try {
46956
- unlinkSync9(join54(this.historyDir, old));
47311
+ unlinkSync9(join55(this.historyDir, old));
46957
47312
  } catch {
46958
47313
  }
46959
47314
  }
@@ -46967,7 +47322,7 @@ OUTPUT: Call task_complete with JSON:
46967
47322
 
46968
47323
  // packages/cli/dist/tui/snr-engine.js
46969
47324
  import { existsSync as existsSync41, readdirSync as readdirSync14, readFileSync as readFileSync30 } from "node:fs";
46970
- import { join as join55, basename as basename14 } from "node:path";
47325
+ import { join as join56, basename as basename14 } from "node:path";
46971
47326
  function computeDPrime(signalScores, noiseScores) {
46972
47327
  if (signalScores.length === 0 || noiseScores.length === 0)
46973
47328
  return 0;
@@ -47207,8 +47562,8 @@ Call task_complete with the JSON array when done.`, onEvent)
47207
47562
  loadMemoryEntries(topics) {
47208
47563
  const entries = [];
47209
47564
  const dirs = [
47210
- join55(this.repoRoot, ".oa", "memory"),
47211
- join55(this.repoRoot, ".open-agents", "memory")
47565
+ join56(this.repoRoot, ".oa", "memory"),
47566
+ join56(this.repoRoot, ".open-agents", "memory")
47212
47567
  ];
47213
47568
  for (const dir of dirs) {
47214
47569
  if (!existsSync41(dir))
@@ -47220,7 +47575,7 @@ Call task_complete with the JSON array when done.`, onEvent)
47220
47575
  if (topics.length > 0 && !topics.includes(topic))
47221
47576
  continue;
47222
47577
  try {
47223
- const data = JSON.parse(readFileSync30(join55(dir, f), "utf-8"));
47578
+ const data = JSON.parse(readFileSync30(join56(dir, f), "utf-8"));
47224
47579
  for (const [key, val] of Object.entries(data)) {
47225
47580
  const value = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
47226
47581
  entries.push({ topic, key, value });
@@ -47788,7 +48143,7 @@ var init_tool_policy = __esm({
47788
48143
 
47789
48144
  // packages/cli/dist/tui/telegram-bridge.js
47790
48145
  import { mkdirSync as mkdirSync18, existsSync as existsSync42, unlinkSync as unlinkSync10, readdirSync as readdirSync15, statSync as statSync13 } from "node:fs";
47791
- import { join as join56, resolve as resolve28 } from "node:path";
48146
+ import { join as join57, resolve as resolve28 } from "node:path";
47792
48147
  import { writeFile as writeFileAsync } from "node:fs/promises";
47793
48148
  function convertMarkdownToTelegramHTML(md) {
47794
48149
  let html = md;
@@ -48553,7 +48908,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
48553
48908
  return null;
48554
48909
  const buffer = Buffer.from(await res.arrayBuffer());
48555
48910
  const fileName = `${Date.now()}-${fileId.slice(0, 8)}${extension}`;
48556
- const localPath = join56(this.mediaCacheDir, fileName);
48911
+ const localPath = join57(this.mediaCacheDir, fileName);
48557
48912
  await writeFileAsync(localPath, buffer);
48558
48913
  return localPath;
48559
48914
  } catch {
@@ -49204,7 +49559,7 @@ var init_braille_spinner = __esm({
49204
49559
  // packages/cli/dist/tui/system-metrics.js
49205
49560
  import { loadavg as loadavg3, cpus as cpus3, totalmem as totalmem4, freemem as freemem3, platform as platform4 } from "node:os";
49206
49561
  import { exec as exec3 } from "node:child_process";
49207
- import { readFile as readFile20 } from "node:fs/promises";
49562
+ import { readFile as readFile21 } from "node:fs/promises";
49208
49563
  function formatRate(bytesPerSec) {
49209
49564
  if (bytesPerSec < 1024)
49210
49565
  return `${Math.round(bytesPerSec)}B`;
@@ -49216,7 +49571,7 @@ function formatRate(bytesPerSec) {
49216
49571
  }
49217
49572
  async function readProcNetDev() {
49218
49573
  try {
49219
- const data = await readFile20("/proc/net/dev", "utf8");
49574
+ const data = await readFile21("/proc/net/dev", "utf8");
49220
49575
  let rxTotal = 0;
49221
49576
  let txTotal = 0;
49222
49577
  for (const line of data.split("\n")) {
@@ -50991,7 +51346,7 @@ var init_status_bar = __esm({
50991
51346
  import * as readline2 from "node:readline";
50992
51347
  import { Writable } from "node:stream";
50993
51348
  import { cwd } from "node:process";
50994
- 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";
50995
51350
  import { createRequire as createRequire2 } from "node:module";
50996
51351
  import { fileURLToPath as fileURLToPath12 } from "node:url";
50997
51352
  import { readFileSync as readFileSync32, writeFileSync as writeFileSync18, appendFileSync as appendFileSync4, rmSync as rmSync2, readdirSync as readdirSync16, mkdirSync as mkdirSync19 } from "node:fs";
@@ -51015,9 +51370,9 @@ function getVersion3() {
51015
51370
  const require2 = createRequire2(import.meta.url);
51016
51371
  const thisDir = dirname18(fileURLToPath12(import.meta.url));
51017
51372
  const candidates = [
51018
- join57(thisDir, "..", "package.json"),
51019
- join57(thisDir, "..", "..", "package.json"),
51020
- join57(thisDir, "..", "..", "..", "package.json")
51373
+ join58(thisDir, "..", "package.json"),
51374
+ join58(thisDir, "..", "..", "package.json"),
51375
+ join58(thisDir, "..", "..", "..", "package.json")
51021
51376
  ];
51022
51377
  for (const pkgPath of candidates) {
51023
51378
  if (existsSync43(pkgPath)) {
@@ -51118,6 +51473,8 @@ function buildTools(repoRoot, config, contextWindowSize) {
51118
51473
  new ReflectionIntegrityTool(repoRoot),
51119
51474
  // Exploration & Culture — COHERE Layer 8 (ARCHE)
51120
51475
  new ExplorationCultureTool(repoRoot),
51476
+ // Embedding Store — COHERE Private Brain semantic retrieval
51477
+ new EmbeddingStoreTool(repoRoot),
51121
51478
  // Structured file reading (CSV, JSON, Markdown, binary detection)
51122
51479
  new StructuredReadTool(repoRoot),
51123
51480
  // Vision tools (Moondream — desktop awareness + point-and-click)
@@ -51237,15 +51594,15 @@ Use task_status("${taskId}") or task_output("${taskId}") to check progress.`
51237
51594
  function gatherMemorySnippets(root) {
51238
51595
  const snippets = [];
51239
51596
  const dirs = [
51240
- join57(root, ".oa", "memory"),
51241
- join57(root, ".open-agents", "memory")
51597
+ join58(root, ".oa", "memory"),
51598
+ join58(root, ".open-agents", "memory")
51242
51599
  ];
51243
51600
  for (const dir of dirs) {
51244
51601
  if (!existsSync43(dir))
51245
51602
  continue;
51246
51603
  try {
51247
51604
  for (const f of readdirSync16(dir).filter((f2) => f2.endsWith(".json"))) {
51248
- const data = JSON.parse(readFileSync32(join57(dir, f), "utf-8"));
51605
+ const data = JSON.parse(readFileSync32(join58(dir, f), "utf-8"));
51249
51606
  for (const val of Object.values(data)) {
51250
51607
  const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
51251
51608
  if (v.length > 10)
@@ -52294,7 +52651,7 @@ async function startInteractive(config, repoPath) {
52294
52651
  let p2pGateway = null;
52295
52652
  let peerMesh = null;
52296
52653
  let inferenceRouter = null;
52297
- const secretVault = new SecretVault(join57(repoRoot, ".oa", "vault.enc"));
52654
+ const secretVault = new SecretVault(join58(repoRoot, ".oa", "vault.enc"));
52298
52655
  let adminSessionKey = null;
52299
52656
  const callSubAgents = /* @__PURE__ */ new Map();
52300
52657
  const streamRenderer = new StreamRenderer();
@@ -52503,8 +52860,8 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
52503
52860
  const hits = allCompletions.filter((c3) => c3.toLowerCase().startsWith(lower));
52504
52861
  return [hits, line];
52505
52862
  }
52506
- const HISTORY_DIR = join57(homedir13(), ".open-agents");
52507
- 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");
52508
52865
  const MAX_HISTORY_LINES = 500;
52509
52866
  let savedHistory = [];
52510
52867
  try {
@@ -52714,7 +53071,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
52714
53071
  } catch {
52715
53072
  }
52716
53073
  try {
52717
- const oaDir = join57(repoRoot, ".oa");
53074
+ const oaDir = join58(repoRoot, ".oa");
52718
53075
  const reconnected = await ExposeGateway.checkAndReconnect(oaDir, {
52719
53076
  onInfo: (msg) => writeContent(() => renderInfo(msg)),
52720
53077
  onError: (msg) => writeContent(() => renderWarning(msg))
@@ -52737,7 +53094,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
52737
53094
  } catch {
52738
53095
  }
52739
53096
  try {
52740
- const oaDir = join57(repoRoot, ".oa");
53097
+ const oaDir = join58(repoRoot, ".oa");
52741
53098
  const reconnectedP2P = await ExposeP2PGateway.checkAndReconnect(oaDir, new NexusTool(repoRoot), {
52742
53099
  onInfo: (msg) => writeContent(() => renderInfo(msg)),
52743
53100
  onError: (msg) => writeContent(() => renderWarning(msg))
@@ -53556,7 +53913,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
53556
53913
  kind,
53557
53914
  targetUrl,
53558
53915
  authKey,
53559
- stateDir: join57(repoRoot, ".oa"),
53916
+ stateDir: join58(repoRoot, ".oa"),
53560
53917
  passthrough: passthrough ?? false,
53561
53918
  loadbalance: loadbalance ?? false,
53562
53919
  endpointAuth: passthrough ? currentConfig.apiKey : void 0,
@@ -53604,7 +53961,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
53604
53961
  await tunnelGateway.stop();
53605
53962
  tunnelGateway = null;
53606
53963
  }
53607
- 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") });
53608
53965
  newTunnel.on("stats", (stats) => {
53609
53966
  statusBar.setExposeStatus({
53610
53967
  status: stats.status,
@@ -53866,7 +54223,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
53866
54223
  }
53867
54224
  },
53868
54225
  destroyProject() {
53869
- const oaPath = join57(repoRoot, OA_DIR);
54226
+ const oaPath = join58(repoRoot, OA_DIR);
53870
54227
  if (existsSync43(oaPath)) {
53871
54228
  try {
53872
54229
  rmSync2(oaPath, { recursive: true, force: true });
@@ -54799,9 +55156,9 @@ var init_run = __esm({
54799
55156
  // packages/indexer/dist/codebase-indexer.js
54800
55157
  import { glob } from "glob";
54801
55158
  import ignore from "ignore";
54802
- import { readFile as readFile21, stat as stat4 } from "node:fs/promises";
55159
+ import { readFile as readFile22, stat as stat4 } from "node:fs/promises";
54803
55160
  import { createHash as createHash4 } from "node:crypto";
54804
- 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";
54805
55162
  var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
54806
55163
  var init_codebase_indexer = __esm({
54807
55164
  "packages/indexer/dist/codebase-indexer.js"() {
@@ -54845,7 +55202,7 @@ var init_codebase_indexer = __esm({
54845
55202
  const ig = ignore.default();
54846
55203
  if (this.config.respectGitignore) {
54847
55204
  try {
54848
- const gitignoreContent = await readFile21(join58(this.config.rootDir, ".gitignore"), "utf-8");
55205
+ const gitignoreContent = await readFile22(join59(this.config.rootDir, ".gitignore"), "utf-8");
54849
55206
  ig.add(gitignoreContent);
54850
55207
  } catch {
54851
55208
  }
@@ -54860,12 +55217,12 @@ var init_codebase_indexer = __esm({
54860
55217
  for (const relativePath of files) {
54861
55218
  if (ig.ignores(relativePath))
54862
55219
  continue;
54863
- const fullPath = join58(this.config.rootDir, relativePath);
55220
+ const fullPath = join59(this.config.rootDir, relativePath);
54864
55221
  try {
54865
55222
  const fileStat = await stat4(fullPath);
54866
55223
  if (fileStat.size > this.config.maxFileSize)
54867
55224
  continue;
54868
- const content = await readFile21(fullPath);
55225
+ const content = await readFile22(fullPath);
54869
55226
  const hash = createHash4("sha256").update(content).digest("hex");
54870
55227
  const ext = extname11(relativePath);
54871
55228
  indexed.push({
@@ -54906,7 +55263,7 @@ var init_codebase_indexer = __esm({
54906
55263
  if (!child) {
54907
55264
  child = {
54908
55265
  name: part,
54909
- path: join58(current.path, part),
55266
+ path: join59(current.path, part),
54910
55267
  type: "directory",
54911
55268
  children: []
54912
55269
  };
@@ -55247,7 +55604,7 @@ var config_exports = {};
55247
55604
  __export(config_exports, {
55248
55605
  configCommand: () => configCommand
55249
55606
  });
55250
- import { join as join59, resolve as resolve31 } from "node:path";
55607
+ import { join as join60, resolve as resolve31 } from "node:path";
55251
55608
  import { homedir as homedir14 } from "node:os";
55252
55609
  import { cwd as cwd3 } from "node:process";
55253
55610
  function redactIfSensitive(key, value) {
@@ -55330,7 +55687,7 @@ function handleShow(opts, config) {
55330
55687
  }
55331
55688
  }
55332
55689
  printSection("Config File");
55333
- printInfo(`~/.open-agents/config.json (${join59(homedir14(), ".open-agents", "config.json")})`);
55690
+ printInfo(`~/.open-agents/config.json (${join60(homedir14(), ".open-agents", "config.json")})`);
55334
55691
  printSection("Priority Chain");
55335
55692
  printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
55336
55693
  printInfo(" 2. Project .oa/settings.json (--local)");
@@ -55369,7 +55726,7 @@ function handleSet(opts, _config) {
55369
55726
  const coerced = coerceForSettings(key, value);
55370
55727
  saveProjectSettings(repoRoot, { [key]: coerced });
55371
55728
  printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value)}`);
55372
- printInfo(`Saved to ${join59(repoRoot, ".oa", "settings.json")}`);
55729
+ printInfo(`Saved to ${join60(repoRoot, ".oa", "settings.json")}`);
55373
55730
  printInfo("This override applies only when running in this workspace.");
55374
55731
  } catch (err) {
55375
55732
  printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
@@ -55628,7 +55985,7 @@ __export(eval_exports, {
55628
55985
  });
55629
55986
  import { tmpdir as tmpdir10 } from "node:os";
55630
55987
  import { mkdirSync as mkdirSync20, writeFileSync as writeFileSync19 } from "node:fs";
55631
- import { join as join60 } from "node:path";
55988
+ import { join as join61 } from "node:path";
55632
55989
  async function evalCommand(opts, config) {
55633
55990
  const suiteName = opts.suite ?? "basic";
55634
55991
  const suite = SUITES[suiteName];
@@ -55753,9 +56110,9 @@ async function evalCommand(opts, config) {
55753
56110
  process.exit(failed > 0 ? 1 : 0);
55754
56111
  }
55755
56112
  function createTempEvalRepo() {
55756
- const dir = join60(tmpdir10(), `open-agents-eval-${Date.now()}`);
56113
+ const dir = join61(tmpdir10(), `open-agents-eval-${Date.now()}`);
55757
56114
  mkdirSync20(dir, { recursive: true });
55758
- 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");
55759
56116
  return dir;
55760
56117
  }
55761
56118
  var BASIC_SUITE, FULL_SUITE, SUITES;
@@ -55815,7 +56172,7 @@ init_updater();
55815
56172
  import { parseArgs as nodeParseArgs2 } from "node:util";
55816
56173
  import { createRequire as createRequire3 } from "node:module";
55817
56174
  import { fileURLToPath as fileURLToPath13 } from "node:url";
55818
- import { dirname as dirname19, join as join61 } from "node:path";
56175
+ import { dirname as dirname19, join as join62 } from "node:path";
55819
56176
 
55820
56177
  // packages/cli/dist/cli.js
55821
56178
  import { createInterface } from "node:readline";
@@ -55922,7 +56279,7 @@ init_output();
55922
56279
  function getVersion4() {
55923
56280
  try {
55924
56281
  const require2 = createRequire3(import.meta.url);
55925
- const pkgPath = join61(dirname19(fileURLToPath13(import.meta.url)), "..", "package.json");
56282
+ const pkgPath = join62(dirname19(fileURLToPath13(import.meta.url)), "..", "package.json");
55926
56283
  const pkg = require2(pkgPath);
55927
56284
  return pkg.version;
55928
56285
  } catch {