open-agents-ai 0.107.0 → 0.109.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -7547,6 +7547,8 @@ var init_repl = __esm({
7547
7547
  subCallCount = 0;
7548
7548
  maxSubCalls;
7549
7549
  execTimeout;
7550
+ /** Trajectory log for fine-tuning data collection (COHERE §Archive, RLM paper §4) */
7551
+ trajectory = [];
7550
7552
  constructor(cwd4, options) {
7551
7553
  this.cwd = cwd4;
7552
7554
  this.llmQueryHandler = options?.llmQueryHandler ?? null;
@@ -7557,10 +7559,20 @@ var init_repl = __esm({
7557
7559
  setLlmQueryHandler(handler) {
7558
7560
  this.llmQueryHandler = handler;
7559
7561
  }
7562
+ /** Callback for retrieving externalized handle content (RLM Context OS) */
7563
+ handleResolver = null;
7564
+ /** Set the handle resolver for retrieve() in the REPL (COHERE Layer 2) */
7565
+ setHandleResolver(resolver) {
7566
+ this.handleResolver = resolver;
7567
+ }
7560
7568
  /** Get the number of sub-calls made this session */
7561
7569
  getSubCallCount() {
7562
7570
  return this.subCallCount;
7563
7571
  }
7572
+ /** Get the trajectory log for fine-tuning data collection */
7573
+ getTrajectory() {
7574
+ return [...this.trajectory];
7575
+ }
7564
7576
  /**
7565
7577
  * Pre-load a large context string into the REPL as the `context` variable.
7566
7578
  * Used by prompt externalization (RLM paper §2, Principle 1: symbolic handle).
@@ -7615,7 +7627,15 @@ except NameError:
7615
7627
  await this.startProcess();
7616
7628
  }
7617
7629
  const result = await this.executeCode(code);
7618
- return { ...result, durationMs: performance.now() - start };
7630
+ const dur = performance.now() - start;
7631
+ this.trajectory.push({
7632
+ type: "repl_exec",
7633
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
7634
+ input: code.slice(0, 1e3),
7635
+ output: result.output.slice(0, 500),
7636
+ durationMs: dur
7637
+ });
7638
+ return { ...result, durationMs: dur };
7619
7639
  } catch (err) {
7620
7640
  const msg = err instanceof Error ? err.message : String(err);
7621
7641
  return { success: false, output: `REPL error: ${msg}`, error: msg, durationMs: performance.now() - start };
@@ -7684,6 +7704,74 @@ def llm_query(prompt, context=""):
7684
7704
  finally:
7685
7705
  sock.close()
7686
7706
 
7707
+ def retrieve(handle_id):
7708
+ """Retrieve full content of an externalized tool output by its handle ID.
7709
+ Use this to access large outputs that were stored as handles instead of
7710
+ being shown inline. Returns the full content as a string.
7711
+ Args:
7712
+ handle_id: The handle ID (e.g., 'a1b2c3d4')
7713
+ Returns: Full content string, or error message if not found
7714
+ """
7715
+ sock_path = os.environ.get("OA_LLM_QUERY_SOCKET", "")
7716
+ if not sock_path:
7717
+ return "[retrieve unavailable: no IPC socket]"
7718
+ sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
7719
+ try:
7720
+ sock.connect(sock_path)
7721
+ request = json.dumps({"op": "retrieve", "handle_id": str(handle_id)})
7722
+ data = request.encode("utf-8")
7723
+ sock.sendall(len(data).to_bytes(4, "big") + data)
7724
+ length_bytes = b""
7725
+ while len(length_bytes) < 4:
7726
+ chunk = sock.recv(4 - len(length_bytes))
7727
+ if not chunk:
7728
+ return "[retrieve: connection closed]"
7729
+ length_bytes += chunk
7730
+ resp_len = int.from_bytes(length_bytes, "big")
7731
+ resp_data = b""
7732
+ while len(resp_data) < resp_len:
7733
+ chunk = sock.recv(min(resp_len - len(resp_data), 65536))
7734
+ if not chunk:
7735
+ break
7736
+ resp_data += chunk
7737
+ result = json.loads(resp_data.decode("utf-8"))
7738
+ if "error" in result:
7739
+ return f"[retrieve error: {result['error']}]"
7740
+ return result.get("content", "")
7741
+ except Exception as e:
7742
+ return f"[retrieve error: {e}]"
7743
+ finally:
7744
+ sock.close()
7745
+
7746
+ def parallel_llm_query(queries):
7747
+ """Run multiple llm_query calls in parallel using threads.
7748
+ SPRINT-style parallel reasoning (arxiv:2506.05745, COHERE Layer 3).
7749
+ Args:
7750
+ queries: List of (prompt, context) tuples or list of prompt strings
7751
+ Returns: List of response strings in the same order
7752
+ Example:
7753
+ results = parallel_llm_query([
7754
+ ("Summarize this section", chunk1),
7755
+ ("Summarize this section", chunk2),
7756
+ ("Summarize this section", chunk3),
7757
+ ])
7758
+ """
7759
+ from concurrent.futures import ThreadPoolExecutor, as_completed
7760
+ def _run(item):
7761
+ if isinstance(item, (list, tuple)) and len(item) >= 2:
7762
+ return llm_query(item[0], item[1])
7763
+ return llm_query(str(item))
7764
+ results = [None] * len(queries)
7765
+ with ThreadPoolExecutor(max_workers=min(len(queries), 8)) as executor:
7766
+ futures = {executor.submit(_run, q): i for i, q in enumerate(queries)}
7767
+ for future in as_completed(futures):
7768
+ idx = futures[future]
7769
+ try:
7770
+ results[idx] = future.result()
7771
+ except Exception as e:
7772
+ results[idx] = f"[parallel_llm_query error: {e}]"
7773
+ return results
7774
+
7687
7775
  # Signal REPL ready
7688
7776
  print("__OA_REPL_READY__")
7689
7777
  `.trim();
@@ -7725,14 +7813,35 @@ print("__OA_REPL_READY__")
7725
7813
  let response;
7726
7814
  try {
7727
7815
  const req = JSON.parse(msgData);
7728
- if (!this.llmQueryHandler) {
7729
- response = { error: "llm_query handler not configured" };
7730
- } else if (this.subCallCount >= this.maxSubCalls) {
7731
- response = { error: `Sub-call limit reached (${this.maxSubCalls})` };
7816
+ if (req.op === "retrieve") {
7817
+ if (!this.handleResolver) {
7818
+ response = { error: "Handle resolver not configured" };
7819
+ } else {
7820
+ const content = this.handleResolver(req.handle_id ?? "");
7821
+ if (content !== null) {
7822
+ response = { content };
7823
+ } else {
7824
+ response = { error: `Handle '${req.handle_id}' not found` };
7825
+ }
7826
+ }
7732
7827
  } else {
7733
- this.subCallCount++;
7734
- const result = await this.llmQueryHandler(req.prompt, req.context);
7735
- response = { response: result };
7828
+ if (!this.llmQueryHandler) {
7829
+ response = { error: "llm_query handler not configured" };
7830
+ } else if (this.subCallCount >= this.maxSubCalls) {
7831
+ response = { error: `Sub-call limit reached (${this.maxSubCalls})` };
7832
+ } else {
7833
+ this.subCallCount++;
7834
+ const queryStart = performance.now();
7835
+ const result = await this.llmQueryHandler(req.prompt ?? "", req.context);
7836
+ response = { response: result };
7837
+ this.trajectory.push({
7838
+ type: "llm_query",
7839
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
7840
+ input: JSON.stringify({ prompt: req.prompt, context: (req.context ?? "").slice(0, 200) }),
7841
+ output: result.slice(0, 500),
7842
+ durationMs: performance.now() - queryStart
7843
+ });
7844
+ }
7736
7845
  }
7737
7846
  } catch (err) {
7738
7847
  response = { error: err instanceof Error ? err.message : String(err) };
@@ -7852,14 +7961,279 @@ print("${sentinel}")
7852
7961
  }
7853
7962
  this.ipcPath = null;
7854
7963
  }
7964
+ if (this.trajectory.length > 0) {
7965
+ try {
7966
+ const { mkdirSync: mkFs, writeFileSync: writeFs } = await import("node:fs");
7967
+ const trajDir = join18(this.cwd, ".oa", "rlm-trajectories");
7968
+ mkFs(trajDir, { recursive: true });
7969
+ const trajFile = join18(trajDir, `trajectory-${Date.now()}.jsonl`);
7970
+ const lines = this.trajectory.map((e) => JSON.stringify(e)).join("\n");
7971
+ writeFs(trajFile, lines + "\n", "utf8");
7972
+ } catch {
7973
+ }
7974
+ }
7855
7975
  this.subCallCount = 0;
7976
+ this.trajectory = [];
7977
+ }
7978
+ };
7979
+ }
7980
+ });
7981
+
7982
+ // packages/execution/dist/tools/memory-metabolism.js
7983
+ import { readFile as readFile8, writeFile as writeFile8, mkdir as mkdir4 } from "node:fs/promises";
7984
+ import { join as join19 } from "node:path";
7985
+ var MemoryMetabolismTool;
7986
+ var init_memory_metabolism = __esm({
7987
+ "packages/execution/dist/tools/memory-metabolism.js"() {
7988
+ "use strict";
7989
+ MemoryMetabolismTool = class {
7990
+ name = "memory_metabolize";
7991
+ description = "Governed memory lifecycle \u2014 classify, score, and store memories with admission control. Supports memory types: episodic (events), semantic (facts), procedural (recipes/patterns), normative (values/rules), quarantine (uncertain). Memories are scored for novelty, utility, confidence, and identity relevance. Use this for important learnings that should persist. (COHERE Layer 5, arxiv:2512.13564)";
7992
+ parameters = {
7993
+ type: "object",
7994
+ properties: {
7995
+ op: {
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)"
7999
+ },
8000
+ memory_type: {
8001
+ type: "string",
8002
+ enum: ["episodic", "semantic", "procedural", "normative", "quarantine"],
8003
+ description: "Memory classification type"
8004
+ },
8005
+ content: {
8006
+ type: "string",
8007
+ description: "Memory content to store"
8008
+ },
8009
+ source: {
8010
+ type: "string",
8011
+ description: "What generated this memory (tool name, event, etc.)"
8012
+ },
8013
+ id: {
8014
+ type: "string",
8015
+ description: "Memory ID (for promote/forget operations)"
8016
+ }
8017
+ },
8018
+ required: ["op"]
8019
+ };
8020
+ cwd;
8021
+ constructor(cwd4) {
8022
+ this.cwd = cwd4;
8023
+ }
8024
+ async execute(args) {
8025
+ const op = String(args.op ?? "");
8026
+ const start = performance.now();
8027
+ try {
8028
+ switch (op) {
8029
+ case "admit":
8030
+ return await this.admitMemory(args, start);
8031
+ case "consolidate":
8032
+ return await this.consolidateMemories(start);
8033
+ case "list":
8034
+ return await this.listMemories(args, start);
8035
+ case "promote":
8036
+ return await this.promoteMemory(args, start);
8037
+ case "forget":
8038
+ return await this.forgetMemory(args, start);
8039
+ default:
8040
+ return { success: false, output: `Unknown op: ${op}`, error: "Invalid operation", durationMs: performance.now() - start };
8041
+ }
8042
+ } catch (err) {
8043
+ return { success: false, output: `Error: ${err instanceof Error ? err.message : String(err)}`, durationMs: performance.now() - start };
8044
+ }
8045
+ }
8046
+ // ── Admit ────────────────────────────────────────────────────────────────
8047
+ async admitMemory(args, start) {
8048
+ const content = String(args.content ?? "");
8049
+ const memType = args.memory_type ?? "episodic";
8050
+ const source = String(args.source ?? "user");
8051
+ if (!content.trim()) {
8052
+ return { success: false, output: "No content provided", error: "Empty content", durationMs: performance.now() - start };
8053
+ }
8054
+ const scores = this.scoreMemory(content, memType, source);
8055
+ const admissionThreshold = 0.3;
8056
+ const avgScore = (scores.novelty + scores.utility + scores.confidence + scores.identityRelevance) / 4;
8057
+ const admitted = avgScore >= admissionThreshold;
8058
+ const item = {
8059
+ id: `mem-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`,
8060
+ type: memType,
8061
+ content,
8062
+ sourceTrace: source,
8063
+ scores,
8064
+ decision: {
8065
+ action: admitted ? "admit" : "quarantine",
8066
+ reason: admitted ? `Admitted: avg score ${avgScore.toFixed(2)} >= ${admissionThreshold}` : `Quarantined: avg score ${avgScore.toFixed(2)} < ${admissionThreshold}`
8067
+ },
8068
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
8069
+ lastAccessedAt: (/* @__PURE__ */ new Date()).toISOString(),
8070
+ accessCount: 0
8071
+ };
8072
+ const metaDir = join19(this.cwd, ".oa", "memory", "metabolism");
8073
+ await mkdir4(metaDir, { recursive: true });
8074
+ const store = await this.loadStore(metaDir);
8075
+ store.push(item);
8076
+ await this.saveStore(metaDir, store);
8077
+ return {
8078
+ success: true,
8079
+ output: `Memory ${item.decision.action}: [${item.id}] type=${memType} scores={novelty:${scores.novelty.toFixed(2)} utility:${scores.utility.toFixed(2)} confidence:${scores.confidence.toFixed(2)} identity:${scores.identityRelevance.toFixed(2)}} avg=${avgScore.toFixed(2)} \u2014 ${item.decision.reason}`,
8080
+ durationMs: performance.now() - start
8081
+ };
8082
+ }
8083
+ // ── Consolidate ──────────────────────────────────────────────────────────
8084
+ async consolidateMemories(start) {
8085
+ const trajDir = join19(this.cwd, ".oa", "rlm-trajectories");
8086
+ let lessons = [];
8087
+ try {
8088
+ const { readdirSync: readdirSync17, readFileSync: readFileSync33 } = await import("node:fs");
8089
+ const files = readdirSync17(trajDir).filter((f) => f.endsWith(".jsonl")).sort().reverse().slice(0, 3);
8090
+ for (const file of files) {
8091
+ const lines = readFileSync33(join19(trajDir, file), "utf8").split("\n").filter((l) => l.trim());
8092
+ for (const line of lines) {
8093
+ try {
8094
+ const entry = JSON.parse(line);
8095
+ if (entry.type === "llm_query") {
8096
+ lessons.push({
8097
+ type: "strategy",
8098
+ description: `Used llm_query for: ${entry.input.slice(0, 100)}`,
8099
+ context: entry.output.slice(0, 200),
8100
+ confidence: 0.7
8101
+ });
8102
+ } else if (entry.type === "repl_exec" && entry.output.includes("Error")) {
8103
+ lessons.push({
8104
+ type: "recovery",
8105
+ description: `REPL error encountered: ${entry.output.slice(0, 100)}`,
8106
+ context: entry.input.slice(0, 200),
8107
+ confidence: 0.5
8108
+ });
8109
+ }
8110
+ } catch {
8111
+ }
8112
+ }
8113
+ }
8114
+ } catch {
8115
+ }
8116
+ if (lessons.length > 0) {
8117
+ const metaDir = join19(this.cwd, ".oa", "memory", "metabolism");
8118
+ await mkdir4(metaDir, { recursive: true });
8119
+ const store = await this.loadStore(metaDir);
8120
+ for (const lesson of lessons.slice(0, 10)) {
8121
+ store.push({
8122
+ id: `lesson-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`,
8123
+ type: lesson.type === "recovery" ? "procedural" : "procedural",
8124
+ content: `${lesson.description}
8125
+ Context: ${lesson.context}`,
8126
+ sourceTrace: "trajectory-consolidation",
8127
+ scores: { novelty: 0.6, utility: 0.7, confidence: lesson.confidence, identityRelevance: 0.3 },
8128
+ decision: { action: "admit", reason: "Extracted from RLM trajectory" },
8129
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
8130
+ lastAccessedAt: (/* @__PURE__ */ new Date()).toISOString(),
8131
+ accessCount: 0
8132
+ });
8133
+ }
8134
+ await this.saveStore(metaDir, store);
8135
+ }
8136
+ return {
8137
+ success: true,
8138
+ output: `Consolidated ${lessons.length} lessons from recent trajectories.
8139
+ ` + lessons.map((l, i) => ` ${i + 1}. [${l.type}] ${l.description}`).join("\n"),
8140
+ durationMs: performance.now() - start
8141
+ };
8142
+ }
8143
+ // ── List ─────────────────────────────────────────────────────────────────
8144
+ async listMemories(args, start) {
8145
+ const filterType = args.memory_type;
8146
+ const metaDir = join19(this.cwd, ".oa", "memory", "metabolism");
8147
+ const store = await this.loadStore(metaDir);
8148
+ const filtered = filterType ? store.filter((m) => m.type === filterType) : store;
8149
+ if (filtered.length === 0) {
8150
+ return { success: true, output: "No memories stored yet.", durationMs: performance.now() - start };
8151
+ }
8152
+ const lines = filtered.map((m) => `[${m.id}] type=${m.type} action=${m.decision.action} created=${m.createdAt.slice(0, 10)} accesses=${m.accessCount}
8153
+ ${m.content.slice(0, 100)}${m.content.length > 100 ? "..." : ""}`);
8154
+ return {
8155
+ success: true,
8156
+ output: `Memory store (${filtered.length}${filterType ? ` ${filterType}` : ""} entries):
8157
+ ${lines.join("\n")}`,
8158
+ durationMs: performance.now() - start
8159
+ };
8160
+ }
8161
+ // ── Promote ──────────────────────────────────────────────────────────────
8162
+ async promoteMemory(args, start) {
8163
+ const id = String(args.id ?? "");
8164
+ const newType = args.memory_type;
8165
+ if (!id || !newType) {
8166
+ return { success: false, output: "id and memory_type required", durationMs: performance.now() - start };
8167
+ }
8168
+ const metaDir = join19(this.cwd, ".oa", "memory", "metabolism");
8169
+ const store = await this.loadStore(metaDir);
8170
+ const item = store.find((m) => m.id === id);
8171
+ if (!item) {
8172
+ return { success: false, output: `Memory ${id} not found`, durationMs: performance.now() - start };
8173
+ }
8174
+ const oldType = item.type;
8175
+ item.type = newType;
8176
+ item.decision = { action: "promote", reason: `Promoted from ${oldType} to ${newType}` };
8177
+ await this.saveStore(metaDir, store);
8178
+ return {
8179
+ success: true,
8180
+ output: `Promoted ${id}: ${oldType} \u2192 ${newType}`,
8181
+ durationMs: performance.now() - start
8182
+ };
8183
+ }
8184
+ // ── Forget ───────────────────────────────────────────────────────────────
8185
+ async forgetMemory(args, start) {
8186
+ const id = String(args.id ?? "");
8187
+ if (!id) {
8188
+ return { success: false, output: "id required", durationMs: performance.now() - start };
8189
+ }
8190
+ const metaDir = join19(this.cwd, ".oa", "memory", "metabolism");
8191
+ const store = await this.loadStore(metaDir);
8192
+ const idx = store.findIndex((m) => m.id === id);
8193
+ if (idx === -1) {
8194
+ return { success: false, output: `Memory ${id} not found`, durationMs: performance.now() - start };
8195
+ }
8196
+ const removed = store.splice(idx, 1)[0];
8197
+ await this.saveStore(metaDir, store);
8198
+ return {
8199
+ success: true,
8200
+ output: `Forgotten: [${removed.id}] ${removed.content.slice(0, 60)}`,
8201
+ durationMs: performance.now() - start
8202
+ };
8203
+ }
8204
+ // ── Scoring ──────────────────────────────────────────────────────────────
8205
+ scoreMemory(content, type, source) {
8206
+ const words = content.split(/\s+/).length;
8207
+ const hasCode = /```|def |function |import |require/.test(content);
8208
+ const hasError = /error|fail|bug|fix/i.test(content);
8209
+ const hasPattern = /pattern|strategy|approach|lesson|tip/i.test(content);
8210
+ return {
8211
+ novelty: Math.min(1, words / 100),
8212
+ // longer = likely more novel
8213
+ utility: hasCode ? 0.8 : hasPattern ? 0.7 : hasError ? 0.6 : 0.4,
8214
+ confidence: source === "trajectory-consolidation" ? 0.7 : source === "user" ? 0.9 : 0.5,
8215
+ identityRelevance: type === "normative" ? 0.9 : type === "procedural" ? 0.6 : type === "semantic" ? 0.5 : 0.3
8216
+ };
8217
+ }
8218
+ // ── Store I/O ────────────────────────────────────────────────────────────
8219
+ async loadStore(dir) {
8220
+ try {
8221
+ const raw = await readFile8(join19(dir, "store.json"), "utf8");
8222
+ return JSON.parse(raw);
8223
+ } catch {
8224
+ return [];
8225
+ }
8226
+ }
8227
+ async saveStore(dir, items) {
8228
+ await mkdir4(dir, { recursive: true });
8229
+ await writeFile8(join19(dir, "store.json"), JSON.stringify(items, null, 2), "utf8");
7856
8230
  }
7857
8231
  };
7858
8232
  }
7859
8233
  });
7860
8234
 
7861
8235
  // packages/execution/dist/tools/structured-read.js
7862
- import { readFile as readFile8, stat as stat2 } from "node:fs/promises";
8236
+ import { readFile as readFile9, stat as stat2 } from "node:fs/promises";
7863
8237
  import { resolve as resolve15, extname as extname5 } from "node:path";
7864
8238
  function parseCSV(text, separator = ",") {
7865
8239
  const lines = text.split("\n").filter((l) => l.trim() !== "");
@@ -8054,7 +8428,7 @@ var init_structured_read = __esm({
8054
8428
  }
8055
8429
  }
8056
8430
  if (format === "xlsx" || format === "pdf" || format === "docx" || format === "auto") {
8057
- const buffer = await readFile8(fullPath);
8431
+ const buffer = await readFile9(fullPath);
8058
8432
  const detected = detectBinaryFormat(buffer);
8059
8433
  if (detected === "xlsx") {
8060
8434
  return {
@@ -8099,7 +8473,7 @@ Or install mammoth for programmatic access.`,
8099
8473
  }
8100
8474
  }
8101
8475
  }
8102
- const text = await readFile8(fullPath, "utf-8");
8476
+ const text = await readFile9(fullPath, "utf-8");
8103
8477
  switch (format) {
8104
8478
  case "csv": {
8105
8479
  const rows = parseCSV(text, ",");
@@ -8196,7 +8570,7 @@ ${parts.join("\n\n")}`,
8196
8570
  // packages/execution/dist/tools/vision.js
8197
8571
  import { readFileSync as readFileSync11, existsSync as existsSync14, statSync as statSync5 } from "node:fs";
8198
8572
  import { execSync as execSync11, spawn as spawn7 } from "node:child_process";
8199
- import { resolve as resolve16, extname as extname6, basename as basename5, dirname as dirname6, join as join19 } from "node:path";
8573
+ import { resolve as resolve16, extname as extname6, basename as basename5, dirname as dirname6, join as join20 } from "node:path";
8200
8574
  import { fileURLToPath as fileURLToPath2 } from "node:url";
8201
8575
  async function probeStation(endpoint) {
8202
8576
  try {
@@ -8211,7 +8585,7 @@ async function probeStation(endpoint) {
8211
8585
  }
8212
8586
  }
8213
8587
  function findStationBinary() {
8214
- const oaVenvPython = join19(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "python");
8588
+ const oaVenvPython = join20(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "python");
8215
8589
  if (existsSync14(oaVenvPython)) {
8216
8590
  try {
8217
8591
  execSync11(`${JSON.stringify(oaVenvPython)} -c "import moondream_station"`, { stdio: "pipe", timeout: 5e3 });
@@ -8219,7 +8593,7 @@ function findStationBinary() {
8219
8593
  } catch {
8220
8594
  }
8221
8595
  }
8222
- const oaVenvBin = join19(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "moondream-station");
8596
+ const oaVenvBin = join20(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "moondream-station");
8223
8597
  if (existsSync14(oaVenvBin))
8224
8598
  return oaVenvBin;
8225
8599
  const thisDir = dirname6(fileURLToPath2(import.meta.url));
@@ -8571,7 +8945,7 @@ ${response}`, durationMs: performance.now() - start };
8571
8945
  import { readFileSync as readFileSync12, existsSync as existsSync15 } from "node:fs";
8572
8946
  import { execSync as execSync12 } from "node:child_process";
8573
8947
  import { tmpdir as tmpdir4 } from "node:os";
8574
- import { join as join20, dirname as dirname7 } from "node:path";
8948
+ import { join as join21, dirname as dirname7 } from "node:path";
8575
8949
  import { fileURLToPath as fileURLToPath3 } from "node:url";
8576
8950
  function hasCommand2(cmd) {
8577
8951
  try {
@@ -8695,7 +9069,7 @@ for i in range(${clicks}):
8695
9069
  } catch {
8696
9070
  }
8697
9071
  try {
8698
- const venvPy = join20(__dirname2, "../../../../.moondream-venv/bin/python");
9072
+ const venvPy = join21(__dirname2, "../../../../.moondream-venv/bin/python");
8699
9073
  execSync12(`DISPLAY=:0 ${JSON.stringify(venvPy)} -c "${pyScript}"`, { stdio: "pipe", timeout: 5e3 });
8700
9074
  return;
8701
9075
  } catch {
@@ -8787,7 +9161,7 @@ var init_desktop_click = __esm({
8787
9161
  if (delayMs > 0) {
8788
9162
  await new Promise((r) => setTimeout(r, delayMs));
8789
9163
  }
8790
- const screenshotPath = join20(tmpdir4(), `oa-desktop-click-${Date.now()}.png`);
9164
+ const screenshotPath = join21(tmpdir4(), `oa-desktop-click-${Date.now()}.png`);
8791
9165
  captureScreenshot(screenshotPath);
8792
9166
  const dims = getImageDimensions2(screenshotPath);
8793
9167
  if (!dims) {
@@ -8962,7 +9336,7 @@ Screenshot: ${screenshotPath}`,
8962
9336
  if (delayMs > 0) {
8963
9337
  await new Promise((r) => setTimeout(r, delayMs));
8964
9338
  }
8965
- const screenshotPath = join20(tmpdir4(), `oa-desktop-describe-${Date.now()}.png`);
9339
+ const screenshotPath = join21(tmpdir4(), `oa-desktop-describe-${Date.now()}.png`);
8966
9340
  captureScreenshot(screenshotPath);
8967
9341
  const dims = getImageDimensions2(screenshotPath);
8968
9342
  const imageBuffer = readFileSync12(screenshotPath);
@@ -9201,7 +9575,7 @@ Language: ${language}
9201
9575
 
9202
9576
  // packages/execution/dist/tools/pdf-to-text.js
9203
9577
  import { existsSync as existsSync17, statSync as statSync7, readFileSync as readFileSync13, unlinkSync as unlinkSync3 } from "node:fs";
9204
- import { resolve as resolve18, basename as basename7, join as join21 } from "node:path";
9578
+ import { resolve as resolve18, basename as basename7, join as join22 } from "node:path";
9205
9579
  import { execSync as execSync14 } from "node:child_process";
9206
9580
  import { tmpdir as tmpdir5 } from "node:os";
9207
9581
  var PdfToTextTool;
@@ -9355,7 +9729,7 @@ ${text}`,
9355
9729
  if (!ocrCheck.available || !tesCheck.available || !gsCheck.available) {
9356
9730
  return null;
9357
9731
  }
9358
- const tmpPdf = join21(tmpdir5(), `oa-ocr-${Date.now()}.pdf`);
9732
+ const tmpPdf = join22(tmpdir5(), `oa-ocr-${Date.now()}.pdf`);
9359
9733
  try {
9360
9734
  const ocrCmd = `ocrmypdf -l ${language} --skip-text ${JSON.stringify(inputPath)} ${JSON.stringify(tmpPdf)}`;
9361
9735
  execSync14(ocrCmd, { stdio: "pipe", timeout: 6e5 });
@@ -9386,7 +9760,7 @@ ${text}`,
9386
9760
 
9387
9761
  // packages/execution/dist/tools/ocr-image-advanced.js
9388
9762
  import { existsSync as existsSync18, statSync as statSync8 } from "node:fs";
9389
- import { resolve as resolve19, basename as basename8, dirname as dirname8, join as join22 } from "node:path";
9763
+ import { resolve as resolve19, basename as basename8, dirname as dirname8, join as join23 } from "node:path";
9390
9764
  import { execSync as execSync15 } from "node:child_process";
9391
9765
  import { fileURLToPath as fileURLToPath4 } from "node:url";
9392
9766
  import { homedir as homedir7, tmpdir as tmpdir6 } from "node:os";
@@ -9404,7 +9778,7 @@ function findOcrScript() {
9404
9778
  return null;
9405
9779
  }
9406
9780
  function findPython() {
9407
- const venvPython = join22(homedir7(), ".open-agents", "venv", "bin", "python");
9781
+ const venvPython = join23(homedir7(), ".open-agents", "venv", "bin", "python");
9408
9782
  if (existsSync18(venvPython)) {
9409
9783
  try {
9410
9784
  execSync15(`${JSON.stringify(venvPython)} -c "import cv2, pytesseract, numpy, PIL"`, {
@@ -9550,7 +9924,7 @@ var init_ocr_image_advanced = __esm({
9550
9924
  cmdParts.push("--output-dir", JSON.stringify(resolve19(this.workingDir, outputDir)));
9551
9925
  let debugDir;
9552
9926
  if (debug) {
9553
- debugDir = join22(tmpdir6(), `oa-ocr-debug-${Date.now()}`);
9927
+ debugDir = join23(tmpdir6(), `oa-ocr-debug-${Date.now()}`);
9554
9928
  cmdParts.push("--debug-dir", debugDir);
9555
9929
  }
9556
9930
  try {
@@ -9649,7 +10023,7 @@ var init_ocr_image_advanced = __esm({
9649
10023
  if (region) {
9650
10024
  try {
9651
10025
  const [x, y, w, h] = region.split(",").map(Number);
9652
- const croppedPath = join22(tmpdir6(), `oa-ocr-crop-${Date.now()}.png`);
10026
+ const croppedPath = join23(tmpdir6(), `oa-ocr-crop-${Date.now()}.png`);
9653
10027
  execSync15(`convert ${JSON.stringify(imagePath)} -crop ${w}x${h}+${x}+${y} +repage ${JSON.stringify(croppedPath)}`, { stdio: "pipe", timeout: 1e4 });
9654
10028
  inputPath = croppedPath;
9655
10029
  } catch {
@@ -9690,18 +10064,18 @@ Note: Advanced Python pipeline not available \u2014 install pytesseract, opencv-
9690
10064
  // packages/execution/dist/tools/browser-action.js
9691
10065
  import { execSync as execSync16, spawn as spawn8 } from "node:child_process";
9692
10066
  import { existsSync as existsSync19, readFileSync as readFileSync14 } from "node:fs";
9693
- import { join as join23, dirname as dirname9 } from "node:path";
10067
+ import { join as join24, dirname as dirname9 } from "node:path";
9694
10068
  import { fileURLToPath as fileURLToPath5 } from "node:url";
9695
10069
  function findScrapeScript() {
9696
10070
  const candidates = [
9697
10071
  // Published npm package: dist/scripts/web_scrape.py
9698
- join23(__dirname3, "scripts", "web_scrape.py"),
10072
+ join24(__dirname3, "scripts", "web_scrape.py"),
9699
10073
  // Published npm package (from node_modules): node_modules/open-agents-ai/dist/scripts/
9700
- join23(__dirname3, "..", "node_modules", "open-agents-ai", "dist", "scripts", "web_scrape.py"),
10074
+ join24(__dirname3, "..", "node_modules", "open-agents-ai", "dist", "scripts", "web_scrape.py"),
9701
10075
  // Dev monorepo: packages/execution/src/tools/../../scripts/
9702
- join23(__dirname3, "..", "..", "scripts", "web_scrape.py"),
10076
+ join24(__dirname3, "..", "..", "scripts", "web_scrape.py"),
9703
10077
  // Dev monorepo alt: packages/execution/scripts/
9704
- join23(__dirname3, "..", "scripts", "web_scrape.py")
10078
+ join24(__dirname3, "..", "scripts", "web_scrape.py")
9705
10079
  ];
9706
10080
  return candidates.find((p) => existsSync19(p)) || candidates[0];
9707
10081
  }
@@ -9956,7 +10330,7 @@ var init_browser_action = __esm({
9956
10330
  // packages/execution/dist/tools/autoresearch.js
9957
10331
  import { execSync as execSync17, spawn as spawn9 } from "node:child_process";
9958
10332
  import { existsSync as existsSync20, readFileSync as readFileSync15, writeFileSync as writeFileSync6, mkdirSync as mkdirSync6, appendFileSync, copyFileSync } from "node:fs";
9959
- import { join as join24, resolve as resolve20, dirname as dirname10 } from "node:path";
10333
+ import { join as join25, resolve as resolve20, dirname as dirname10 } from "node:path";
9960
10334
  import { fileURLToPath as fileURLToPath6 } from "node:url";
9961
10335
  function findAutoresearchScript(scriptName) {
9962
10336
  const thisDir = dirname10(fileURLToPath6(import.meta.url));
@@ -10058,7 +10432,7 @@ Requires: NVIDIA GPU, Python 3.10+, uv (astral.sh package manager).`;
10058
10432
  async execute(args) {
10059
10433
  const start = Date.now();
10060
10434
  const action = String(args["action"] ?? "status");
10061
- const workspacePath = String(args["workspace"] ?? join24(this.repoRoot, ".oa", "autoresearch"));
10435
+ const workspacePath = String(args["workspace"] ?? join25(this.repoRoot, ".oa", "autoresearch"));
10062
10436
  try {
10063
10437
  switch (action) {
10064
10438
  case "setup":
@@ -10099,13 +10473,13 @@ Requires: NVIDIA GPU, Python 3.10+, uv (astral.sh package manager).`;
10099
10473
  const prepareScript = findAutoresearchScript("autoresearch-prepare.py");
10100
10474
  const trainScript = findAutoresearchScript("autoresearch-train.py");
10101
10475
  if (prepareScript) {
10102
- copyFileSync(prepareScript, join24(workspace, "prepare.py"));
10476
+ copyFileSync(prepareScript, join25(workspace, "prepare.py"));
10103
10477
  output.push("Copied prepare.py template");
10104
10478
  } else {
10105
10479
  return { success: false, output: output.join("\n"), error: "autoresearch-prepare.py template not found in distribution", durationMs: Date.now() - start };
10106
10480
  }
10107
10481
  if (trainScript) {
10108
- copyFileSync(trainScript, join24(workspace, "train.py"));
10482
+ copyFileSync(trainScript, join25(workspace, "train.py"));
10109
10483
  output.push("Copied train.py template");
10110
10484
  } else {
10111
10485
  return { success: false, output: output.join("\n"), error: "autoresearch-train.py template not found in distribution", durationMs: Date.now() - start };
@@ -10137,7 +10511,7 @@ name = "pytorch-cu128"
10137
10511
  url = "https://download.pytorch.org/whl/cu128"
10138
10512
  explicit = true
10139
10513
  `;
10140
- writeFileSync6(join24(workspace, "pyproject.toml"), pyprojectContent, "utf-8");
10514
+ writeFileSync6(join25(workspace, "pyproject.toml"), pyprojectContent, "utf-8");
10141
10515
  output.push("Created pyproject.toml");
10142
10516
  try {
10143
10517
  execSync17("git rev-parse --git-dir", { cwd: workspace, encoding: "utf-8", timeout: 5e3 });
@@ -10179,7 +10553,7 @@ explicit = true
10179
10553
  const e = err;
10180
10554
  output.push(`Data prep warning: ${(e.stderr ?? e.stdout ?? "failed").slice(0, 500)}`);
10181
10555
  }
10182
- const tsvPath = join24(workspace, "results.tsv");
10556
+ const tsvPath = join25(workspace, "results.tsv");
10183
10557
  if (!existsSync20(tsvPath)) {
10184
10558
  writeFileSync6(tsvPath, "commit val_bpb memory_gb status description\n", "utf-8");
10185
10559
  output.push("Created results.tsv");
@@ -10201,10 +10575,10 @@ Next steps:
10201
10575
  }
10202
10576
  // ── Run experiment ─────────────────────────────────────────────────────
10203
10577
  async run(workspace, args, start) {
10204
- if (!existsSync20(join24(workspace, "train.py"))) {
10578
+ if (!existsSync20(join25(workspace, "train.py"))) {
10205
10579
  return { success: false, output: "", error: `No train.py found in ${workspace}. Run autoresearch(action="setup") first.`, durationMs: Date.now() - start };
10206
10580
  }
10207
- if (!existsSync20(join24(workspace, ".venv")) && existsSync20(join24(workspace, "pyproject.toml"))) {
10581
+ if (!existsSync20(join25(workspace, ".venv")) && existsSync20(join25(workspace, "pyproject.toml"))) {
10208
10582
  try {
10209
10583
  execSync17("uv sync 2>&1", { cwd: workspace, encoding: "utf-8", timeout: 3e5 });
10210
10584
  } catch {
@@ -10212,7 +10586,7 @@ Next steps:
10212
10586
  }
10213
10587
  const timeoutMin = Number(args["timeout_minutes"] ?? 10);
10214
10588
  const timeoutMs = timeoutMin * 60 * 1e3;
10215
- const logPath = join24(workspace, "run.log");
10589
+ const logPath = join25(workspace, "run.log");
10216
10590
  return new Promise((resolveResult) => {
10217
10591
  const proc = spawn9("uv", ["run", "train.py"], {
10218
10592
  cwd: workspace,
@@ -10283,7 +10657,7 @@ ${fullLog.slice(-2e3)}`,
10283
10657
  return;
10284
10658
  }
10285
10659
  try {
10286
- writeFileSync6(join24(workspace, ".last-result.json"), JSON.stringify(result, null, 2), "utf-8");
10660
+ writeFileSync6(join25(workspace, ".last-result.json"), JSON.stringify(result, null, 2), "utf-8");
10287
10661
  } catch {
10288
10662
  }
10289
10663
  const memGB = (result.peak_vram_mb / 1024).toFixed(1);
@@ -10319,7 +10693,7 @@ ${fullLog.slice(-2e3)}`,
10319
10693
  }
10320
10694
  // ── Results ────────────────────────────────────────────────────────────
10321
10695
  getResults(workspace, start) {
10322
- const tsvPath = join24(workspace, "results.tsv");
10696
+ const tsvPath = join25(workspace, "results.tsv");
10323
10697
  if (!existsSync20(tsvPath)) {
10324
10698
  return { success: false, output: "", error: `No results.tsv found. Run autoresearch(action="setup") first.`, durationMs: Date.now() - start };
10325
10699
  }
@@ -10346,7 +10720,7 @@ ${fullLog.slice(-2e3)}`,
10346
10720
  // ── Status ─────────────────────────────────────────────────────────────
10347
10721
  getStatus(workspace, start) {
10348
10722
  const output = [];
10349
- if (!existsSync20(join24(workspace, "train.py"))) {
10723
+ if (!existsSync20(join25(workspace, "train.py"))) {
10350
10724
  return {
10351
10725
  success: true,
10352
10726
  output: `Autoresearch workspace not initialized at ${workspace}.
@@ -10369,7 +10743,7 @@ Run autoresearch(action="setup") to begin.`,
10369
10743
  } catch {
10370
10744
  output.push("GPU: not detected");
10371
10745
  }
10372
- const lastResultPath = join24(workspace, ".last-result.json");
10746
+ const lastResultPath = join25(workspace, ".last-result.json");
10373
10747
  if (existsSync20(lastResultPath)) {
10374
10748
  try {
10375
10749
  const last = JSON.parse(readFileSync15(lastResultPath, "utf-8"));
@@ -10377,20 +10751,20 @@ Run autoresearch(action="setup") to begin.`,
10377
10751
  } catch {
10378
10752
  }
10379
10753
  }
10380
- const tsvPath = join24(workspace, "results.tsv");
10754
+ const tsvPath = join25(workspace, "results.tsv");
10381
10755
  if (existsSync20(tsvPath)) {
10382
10756
  const lines = readFileSync15(tsvPath, "utf-8").trim().split("\n");
10383
10757
  output.push(`Experiments recorded: ${lines.length - 1}`);
10384
10758
  }
10385
- const cacheDir = join24(process.env["HOME"] ?? "~", ".cache", "autoresearch");
10759
+ const cacheDir = join25(process.env["HOME"] ?? "~", ".cache", "autoresearch");
10386
10760
  output.push(`Data cache: ${existsSync20(cacheDir) ? "present" : "not found"} (${cacheDir})`);
10387
10761
  return { success: true, output: output.join("\n"), durationMs: Date.now() - start };
10388
10762
  }
10389
10763
  // ── Keep / Discard ─────────────────────────────────────────────────────
10390
10764
  keepExperiment(workspace, args, start) {
10391
10765
  const desc = String(args["description"] ?? "experiment");
10392
- const tsvPath = join24(workspace, "results.tsv");
10393
- const lastResultPath = join24(workspace, ".last-result.json");
10766
+ const tsvPath = join25(workspace, "results.tsv");
10767
+ const lastResultPath = join25(workspace, ".last-result.json");
10394
10768
  let valBpb = args["val_bpb"];
10395
10769
  let memGb = args["memory_gb"];
10396
10770
  if ((valBpb === void 0 || memGb === void 0) && existsSync20(lastResultPath)) {
@@ -10428,8 +10802,8 @@ Branch advanced. Ready for next experiment.`,
10428
10802
  }
10429
10803
  discardExperiment(workspace, args, start) {
10430
10804
  const desc = String(args["description"] ?? "experiment");
10431
- const tsvPath = join24(workspace, "results.tsv");
10432
- const lastResultPath = join24(workspace, ".last-result.json");
10805
+ const tsvPath = join25(workspace, "results.tsv");
10806
+ const lastResultPath = join25(workspace, ".last-result.json");
10433
10807
  let valBpb = args["val_bpb"];
10434
10808
  let memGb = args["memory_gb"];
10435
10809
  if ((valBpb === void 0 || memGb === void 0) && existsSync20(lastResultPath)) {
@@ -10475,8 +10849,8 @@ train.py reverted to last kept state. Ready for next experiment.`,
10475
10849
 
10476
10850
  // packages/execution/dist/tools/scheduler.js
10477
10851
  import { execSync as execSync18, exec as execCb } from "node:child_process";
10478
- import { readFile as readFile9, writeFile as writeFile8, mkdir as mkdir4 } from "node:fs/promises";
10479
- import { resolve as resolve21, join as join25 } from "node:path";
10852
+ import { readFile as readFile10, writeFile as writeFile9, mkdir as mkdir5 } from "node:fs/promises";
10853
+ import { resolve as resolve21, join as join26 } from "node:path";
10480
10854
  import { randomBytes as randomBytes3 } from "node:crypto";
10481
10855
  function isValidCron(expr) {
10482
10856
  const parts = expr.trim().split(/\s+/);
@@ -10560,7 +10934,7 @@ function installCronJob(task, workingDir) {
10560
10934
  const lines = getCurrentCrontab();
10561
10935
  const oaBin = findOaBinary();
10562
10936
  const logDir = resolve21(workingDir, ".oa", "scheduled", "logs");
10563
- const logFile = join25(logDir, `${task.id}.log`);
10937
+ const logFile = join26(logDir, `${task.id}.log`);
10564
10938
  const storeFile = resolve21(workingDir, ".oa", "scheduled", "tasks.json");
10565
10939
  const taskEscaped = task.task.replace(/'/g, "'\\''");
10566
10940
  const taskId = task.id;
@@ -10593,7 +10967,7 @@ function listCronJobs() {
10593
10967
  async function loadStore(workingDir) {
10594
10968
  const storePath = resolve21(workingDir, ".oa", "scheduled", "tasks.json");
10595
10969
  try {
10596
- const raw = await readFile9(storePath, "utf-8");
10970
+ const raw = await readFile10(storePath, "utf-8");
10597
10971
  return JSON.parse(raw);
10598
10972
  } catch {
10599
10973
  return { tasks: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
@@ -10601,10 +10975,10 @@ async function loadStore(workingDir) {
10601
10975
  }
10602
10976
  async function saveStore(workingDir, store) {
10603
10977
  const dir = resolve21(workingDir, ".oa", "scheduled");
10604
- await mkdir4(dir, { recursive: true });
10605
- await mkdir4(join25(dir, "logs"), { recursive: true });
10978
+ await mkdir5(dir, { recursive: true });
10979
+ await mkdir5(join26(dir, "logs"), { recursive: true });
10606
10980
  store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
10607
- await writeFile8(join25(dir, "tasks.json"), JSON.stringify(store, null, 2), "utf-8");
10981
+ await writeFile9(join26(dir, "tasks.json"), JSON.stringify(store, null, 2), "utf-8");
10608
10982
  }
10609
10983
  var SCHEDULE_PRESETS, CRON_MARKER, SchedulerTool;
10610
10984
  var init_scheduler = __esm({
@@ -10824,7 +11198,7 @@ var init_scheduler = __esm({
10824
11198
  return { success: false, output: "", error: "id is required for logs action", durationMs: performance.now() - start };
10825
11199
  const logFile = resolve21(this.workingDir, ".oa", "scheduled", "logs", `${id}.log`);
10826
11200
  try {
10827
- const raw = await readFile9(logFile, "utf-8");
11201
+ const raw = await readFile10(logFile, "utf-8");
10828
11202
  const truncated = raw.length > 1e4 ? "...(truncated)\n" + raw.slice(-1e4) : raw;
10829
11203
  return { success: true, output: `Logs for ${id}:
10830
11204
  ${truncated}`, durationMs: performance.now() - start };
@@ -10837,8 +11211,8 @@ ${truncated}`, durationMs: performance.now() - start };
10837
11211
  });
10838
11212
 
10839
11213
  // packages/execution/dist/tools/reminder.js
10840
- import { readFile as readFile10, writeFile as writeFile9, mkdir as mkdir5 } from "node:fs/promises";
10841
- import { resolve as resolve22, join as join26 } from "node:path";
11214
+ import { readFile as readFile11, writeFile as writeFile10, mkdir as mkdir6 } from "node:fs/promises";
11215
+ import { resolve as resolve22, join as join27 } from "node:path";
10842
11216
  import { randomBytes as randomBytes4 } from "node:crypto";
10843
11217
  function parseDueTime(due) {
10844
11218
  const lower = due.toLowerCase().trim();
@@ -10889,13 +11263,13 @@ function parseDueTime(due) {
10889
11263
  }
10890
11264
  async function getStorePath(workingDir) {
10891
11265
  const dir = resolve22(workingDir, ".oa", "scheduled");
10892
- await mkdir5(dir, { recursive: true });
10893
- return join26(dir, STORE_FILE);
11266
+ await mkdir6(dir, { recursive: true });
11267
+ return join27(dir, STORE_FILE);
10894
11268
  }
10895
11269
  async function loadReminderStore(workingDir) {
10896
11270
  const storePath = await getStorePath(workingDir);
10897
11271
  try {
10898
- const raw = await readFile10(storePath, "utf-8");
11272
+ const raw = await readFile11(storePath, "utf-8");
10899
11273
  return JSON.parse(raw);
10900
11274
  } catch {
10901
11275
  return { reminders: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
@@ -10904,7 +11278,7 @@ async function loadReminderStore(workingDir) {
10904
11278
  async function saveReminderStore(workingDir, store) {
10905
11279
  const storePath = await getStorePath(workingDir);
10906
11280
  store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
10907
- await writeFile9(storePath, JSON.stringify(store, null, 2), "utf-8");
11281
+ await writeFile10(storePath, JSON.stringify(store, null, 2), "utf-8");
10908
11282
  }
10909
11283
  async function getDueReminders(workingDir) {
10910
11284
  const store = await loadReminderStore(workingDir);
@@ -11150,13 +11524,13 @@ var init_reminder = __esm({
11150
11524
  });
11151
11525
 
11152
11526
  // packages/execution/dist/tools/agenda.js
11153
- import { readFile as readFile11, writeFile as writeFile10, mkdir as mkdir6 } from "node:fs/promises";
11154
- import { resolve as resolve23, join as join27 } from "node:path";
11527
+ import { readFile as readFile12, writeFile as writeFile11, mkdir as mkdir7 } from "node:fs/promises";
11528
+ import { resolve as resolve23, join as join28 } from "node:path";
11155
11529
  import { randomBytes as randomBytes5 } from "node:crypto";
11156
11530
  async function loadAttentionStore(workingDir) {
11157
11531
  const storePath = resolve23(workingDir, ".oa", "scheduled", "attention.json");
11158
11532
  try {
11159
- const raw = await readFile11(storePath, "utf-8");
11533
+ const raw = await readFile12(storePath, "utf-8");
11160
11534
  return JSON.parse(raw);
11161
11535
  } catch {
11162
11536
  return { items: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
@@ -11164,9 +11538,9 @@ async function loadAttentionStore(workingDir) {
11164
11538
  }
11165
11539
  async function saveAttentionStore(workingDir, store) {
11166
11540
  const dir = resolve23(workingDir, ".oa", "scheduled");
11167
- await mkdir6(dir, { recursive: true });
11541
+ await mkdir7(dir, { recursive: true });
11168
11542
  store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
11169
- await writeFile10(join27(dir, "attention.json"), JSON.stringify(store, null, 2), "utf-8");
11543
+ await writeFile11(join28(dir, "attention.json"), JSON.stringify(store, null, 2), "utf-8");
11170
11544
  }
11171
11545
  async function getActiveAttentionItems(workingDir) {
11172
11546
  const store = await loadAttentionStore(workingDir);
@@ -11462,7 +11836,7 @@ ${sections.join("\n")}`,
11462
11836
  async loadScheduleStore() {
11463
11837
  try {
11464
11838
  const storePath = resolve23(this.workingDir, ".oa", "scheduled", "tasks.json");
11465
- const raw = await readFile11(storePath, "utf-8");
11839
+ const raw = await readFile12(storePath, "utf-8");
11466
11840
  const store = JSON.parse(raw);
11467
11841
  return store.tasks ?? [];
11468
11842
  } catch {
@@ -11476,7 +11850,7 @@ ${sections.join("\n")}`,
11476
11850
  // packages/execution/dist/tools/opencode.js
11477
11851
  import { execSync as execSync19, spawn as spawn10 } from "node:child_process";
11478
11852
  import { existsSync as existsSync21 } from "node:fs";
11479
- import { join as join28, resolve as resolve24 } from "node:path";
11853
+ import { join as join29, resolve as resolve24 } from "node:path";
11480
11854
  function findOpencode() {
11481
11855
  for (const cmd of ["opencode"]) {
11482
11856
  try {
@@ -11488,8 +11862,8 @@ function findOpencode() {
11488
11862
  }
11489
11863
  const homeDir = process.env.HOME || process.env.USERPROFILE || "";
11490
11864
  const candidates = [
11491
- join28(homeDir, ".opencode", "bin", "opencode"),
11492
- join28(homeDir, "bin", "opencode"),
11865
+ join29(homeDir, ".opencode", "bin", "opencode"),
11866
+ join29(homeDir, "bin", "opencode"),
11493
11867
  "/usr/local/bin/opencode"
11494
11868
  ];
11495
11869
  for (const p of candidates) {
@@ -11750,7 +12124,7 @@ var init_opencode = __esm({
11750
12124
  // packages/execution/dist/tools/factory.js
11751
12125
  import { execSync as execSync20, spawn as spawn11 } from "node:child_process";
11752
12126
  import { existsSync as existsSync22 } from "node:fs";
11753
- import { join as join29 } from "node:path";
12127
+ import { join as join30 } from "node:path";
11754
12128
  function findDroid() {
11755
12129
  for (const cmd of ["droid"]) {
11756
12130
  try {
@@ -11762,8 +12136,8 @@ function findDroid() {
11762
12136
  }
11763
12137
  const homeDir = process.env.HOME || process.env.USERPROFILE || "";
11764
12138
  const candidates = [
11765
- join29(homeDir, ".factory", "bin", "droid"),
11766
- join29(homeDir, "bin", "droid"),
12139
+ join30(homeDir, ".factory", "bin", "droid"),
12140
+ join30(homeDir, "bin", "droid"),
11767
12141
  "/usr/local/bin/droid"
11768
12142
  ];
11769
12143
  for (const p of candidates) {
@@ -12058,8 +12432,8 @@ var init_factory = __esm({
12058
12432
 
12059
12433
  // packages/execution/dist/tools/cron-agent.js
12060
12434
  import { execSync as execSync21 } from "node:child_process";
12061
- import { readFile as readFile12, writeFile as writeFile11, mkdir as mkdir7 } from "node:fs/promises";
12062
- import { resolve as resolve25, join as join30 } from "node:path";
12435
+ import { readFile as readFile13, writeFile as writeFile12, mkdir as mkdir8 } from "node:fs/promises";
12436
+ import { resolve as resolve25, join as join31 } from "node:path";
12063
12437
  import { randomBytes as randomBytes6 } from "node:crypto";
12064
12438
  function isValidCron2(expr) {
12065
12439
  const parts = expr.trim().split(/\s+/);
@@ -12145,7 +12519,7 @@ function installCronAgentJob(job, workingDir) {
12145
12519
  const lines = getCurrentCrontab2();
12146
12520
  const oaBin = findOaBinary2();
12147
12521
  const logDir = resolve25(workingDir, ".oa", "cron-agents", "logs");
12148
- const logFile = join30(logDir, `${job.id}.log`);
12522
+ const logFile = join31(logDir, `${job.id}.log`);
12149
12523
  const storeFile = resolve25(workingDir, ".oa", "cron-agents", "store.json");
12150
12524
  const taskEscaped = job.task.replace(/'/g, "'\\''");
12151
12525
  const jobId = job.id;
@@ -12175,7 +12549,7 @@ function removeCronAgentJob(jobId) {
12175
12549
  async function loadStore2(workingDir) {
12176
12550
  const storePath = resolve25(workingDir, ".oa", "cron-agents", "store.json");
12177
12551
  try {
12178
- const raw = await readFile12(storePath, "utf-8");
12552
+ const raw = await readFile13(storePath, "utf-8");
12179
12553
  return JSON.parse(raw);
12180
12554
  } catch {
12181
12555
  return { jobs: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
@@ -12183,10 +12557,10 @@ async function loadStore2(workingDir) {
12183
12557
  }
12184
12558
  async function saveStore2(workingDir, store) {
12185
12559
  const dir = resolve25(workingDir, ".oa", "cron-agents");
12186
- await mkdir7(dir, { recursive: true });
12187
- await mkdir7(join30(dir, "logs"), { recursive: true });
12560
+ await mkdir8(dir, { recursive: true });
12561
+ await mkdir8(join31(dir, "logs"), { recursive: true });
12188
12562
  store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
12189
- await writeFile11(join30(dir, "store.json"), JSON.stringify(store, null, 2), "utf-8");
12563
+ await writeFile12(join31(dir, "store.json"), JSON.stringify(store, null, 2), "utf-8");
12190
12564
  }
12191
12565
  var LONG_HORIZON_PRESETS, CRON_AGENT_MARKER, CronAgentTool;
12192
12566
  var init_cron_agent = __esm({
@@ -12451,7 +12825,7 @@ var init_cron_agent = __esm({
12451
12825
  return { success: false, output: "", error: "id is required", durationMs: performance.now() - start };
12452
12826
  const logFile = resolve25(this.workingDir, ".oa", "cron-agents", "logs", `${id}.log`);
12453
12827
  try {
12454
- const raw = await readFile12(logFile, "utf-8");
12828
+ const raw = await readFile13(logFile, "utf-8");
12455
12829
  const truncated = raw.length > 2e4 ? "...(truncated)\n" + raw.slice(-2e4) : raw;
12456
12830
  return { success: true, output: `Logs for ${id}:
12457
12831
  ${truncated}`, durationMs: performance.now() - start };
@@ -12522,9 +12896,9 @@ ${truncated}`, durationMs: performance.now() - start };
12522
12896
  });
12523
12897
 
12524
12898
  // packages/execution/dist/tools/nexus.js
12525
- import { readFile as readFile13, writeFile as writeFile12, mkdir as mkdir8, chmod, unlink, readdir as readdir3, open as fsOpen } from "node:fs/promises";
12899
+ import { readFile as readFile14, writeFile as writeFile13, mkdir as mkdir9, chmod, unlink, readdir as readdir3, open as fsOpen } from "node:fs/promises";
12526
12900
  import { existsSync as existsSync23, readFileSync as readFileSync16, watch as fsWatchLocal } from "node:fs";
12527
- import { resolve as resolve26, join as join31 } from "node:path";
12901
+ import { resolve as resolve26, join as join32 } from "node:path";
12528
12902
  import { randomBytes as randomBytes7, createCipheriv, createDecipheriv, scryptSync, createHash } from "node:crypto";
12529
12903
  import { execSync as execSync22, spawn as spawn12 } from "node:child_process";
12530
12904
  import { hostname, userInfo } from "node:os";
@@ -14497,7 +14871,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14497
14871
  }
14498
14872
  async ensureDir() {
14499
14873
  if (!existsSync23(this.nexusDir)) {
14500
- await mkdir8(this.nexusDir, { recursive: true });
14874
+ await mkdir9(this.nexusDir, { recursive: true });
14501
14875
  }
14502
14876
  }
14503
14877
  async execute(args) {
@@ -14617,7 +14991,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14617
14991
  // Daemon management
14618
14992
  // =========================================================================
14619
14993
  getDaemonPid() {
14620
- const pidFile = join31(this.nexusDir, "daemon.pid");
14994
+ const pidFile = join32(this.nexusDir, "daemon.pid");
14621
14995
  if (!existsSync23(pidFile))
14622
14996
  return null;
14623
14997
  try {
@@ -14643,12 +15017,12 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14643
15017
  throw new Error("Nexus daemon not running. Use action 'connect' first.");
14644
15018
  }
14645
15019
  const cmdId = randomBytes7(8).toString("hex");
14646
- const cmdFile = join31(this.nexusDir, "cmd.json");
14647
- const respFile = join31(this.nexusDir, "resp.json");
15020
+ const cmdFile = join32(this.nexusDir, "cmd.json");
15021
+ const respFile = join32(this.nexusDir, "resp.json");
14648
15022
  if (existsSync23(respFile))
14649
15023
  await unlink(respFile).catch(() => {
14650
15024
  });
14651
- await writeFile12(cmdFile, JSON.stringify({ id: cmdId, action, args }, null, 2));
15025
+ await writeFile13(cmdFile, JSON.stringify({ id: cmdId, action, args }, null, 2));
14652
15026
  const pollMs = 50;
14653
15027
  const polls = Math.ceil(timeoutMs / pollMs);
14654
15028
  let resolved = false;
@@ -14680,7 +15054,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14680
15054
  if (!existsSync23(respFile))
14681
15055
  continue;
14682
15056
  try {
14683
- const resp = JSON.parse(await readFile13(respFile, "utf8"));
15057
+ const resp = JSON.parse(await readFile14(respFile, "utf8"));
14684
15058
  if (resp.id === cmdId) {
14685
15059
  resolved = true;
14686
15060
  return resp.output || (resp.ok ? "OK" : "Failed");
@@ -14703,7 +15077,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14703
15077
  }
14704
15078
  if (existsSync23(respFile)) {
14705
15079
  try {
14706
- const resp = JSON.parse(await readFile13(respFile, "utf8"));
15080
+ const resp = JSON.parse(await readFile14(respFile, "utf8"));
14707
15081
  if (resp.id === cmdId) {
14708
15082
  return resp.output || (resp.ok ? "OK" : "Failed");
14709
15083
  }
@@ -14728,7 +15102,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14728
15102
  const currentScriptHash = createHash("sha256").update(DAEMON_SCRIPT).digest("hex").slice(0, 16);
14729
15103
  const existingPid = this.getDaemonPid();
14730
15104
  if (existingPid) {
14731
- const daemonPath2 = join31(this.nexusDir, "nexus-daemon.mjs");
15105
+ const daemonPath2 = join32(this.nexusDir, "nexus-daemon.mjs");
14732
15106
  let needsRestart = true;
14733
15107
  if (existsSync23(daemonPath2)) {
14734
15108
  try {
@@ -14752,16 +15126,16 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14752
15126
  } catch {
14753
15127
  }
14754
15128
  for (const f of ["daemon.pid", "status.json", "cmd.json", "resp.json"]) {
14755
- const p = join31(this.nexusDir, f);
15129
+ const p = join32(this.nexusDir, f);
14756
15130
  if (existsSync23(p))
14757
15131
  await unlink(p).catch(() => {
14758
15132
  });
14759
15133
  }
14760
15134
  } else {
14761
- const statusFile2 = join31(this.nexusDir, "status.json");
15135
+ const statusFile2 = join32(this.nexusDir, "status.json");
14762
15136
  if (existsSync23(statusFile2)) {
14763
15137
  try {
14764
- const status = JSON.parse(await readFile13(statusFile2, "utf8"));
15138
+ const status = JSON.parse(await readFile14(statusFile2, "utf8"));
14765
15139
  if (status.connected && status.peerId) {
14766
15140
  await this.ensureWallet();
14767
15141
  return `Already connected (pid: ${existingPid}, peerId: ${status.peerId})`;
@@ -14777,7 +15151,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14777
15151
  }
14778
15152
  }
14779
15153
  for (const f of ["daemon.pid", "status.json", "cmd.json", "resp.json"]) {
14780
- const p = join31(this.nexusDir, f);
15154
+ const p = join32(this.nexusDir, f);
14781
15155
  if (existsSync23(p))
14782
15156
  await unlink(p).catch(() => {
14783
15157
  });
@@ -14795,7 +15169,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14795
15169
  });
14796
15170
  });
14797
15171
  try {
14798
- const nexusPkg = join31(nodeModulesDir, "open-agents-nexus", "package.json");
15172
+ const nexusPkg = join32(nodeModulesDir, "open-agents-nexus", "package.json");
14799
15173
  if (existsSync23(nexusPkg)) {
14800
15174
  nexusResolved = true;
14801
15175
  try {
@@ -14806,7 +15180,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14806
15180
  } else {
14807
15181
  try {
14808
15182
  const globalDir = await execAsync2("npm root -g", { timeout: 5e3 });
14809
- const globalPkg = join31(globalDir, "open-agents-nexus", "package.json");
15183
+ const globalPkg = join32(globalDir, "open-agents-nexus", "package.json");
14810
15184
  if (existsSync23(globalPkg)) {
14811
15185
  nexusResolved = true;
14812
15186
  try {
@@ -14851,8 +15225,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14851
15225
  }
14852
15226
  }
14853
15227
  await this.ensureWallet();
14854
- const daemonPath = join31(this.nexusDir, "nexus-daemon.mjs");
14855
- await writeFile12(daemonPath, DAEMON_SCRIPT);
15228
+ const daemonPath = join32(this.nexusDir, "nexus-daemon.mjs");
15229
+ await writeFile13(daemonPath, DAEMON_SCRIPT);
14856
15230
  const agentName = args.agent_name || "open-agents-node";
14857
15231
  const agentType = args.agent_type || "general";
14858
15232
  const nodePaths = [nodeModulesDir];
@@ -14862,8 +15236,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14862
15236
  } catch {
14863
15237
  }
14864
15238
  const { openSync: openSync2, closeSync: closeSync2 } = await import("node:fs");
14865
- const daemonLogPath = join31(this.nexusDir, "daemon.log");
14866
- const daemonErrPath = join31(this.nexusDir, "daemon.err");
15239
+ const daemonLogPath = join32(this.nexusDir, "daemon.log");
15240
+ const daemonErrPath = join32(this.nexusDir, "daemon.err");
14867
15241
  const outFd = openSync2(daemonLogPath, "w");
14868
15242
  const errFd = openSync2(daemonErrPath, "w");
14869
15243
  const child = spawn12("node", [daemonPath, this.nexusDir, agentName, agentType], {
@@ -14881,16 +15255,16 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14881
15255
  closeSync2(errFd);
14882
15256
  } catch {
14883
15257
  }
14884
- const statusFile = join31(this.nexusDir, "status.json");
15258
+ const statusFile = join32(this.nexusDir, "status.json");
14885
15259
  for (let i = 0; i < 40; i++) {
14886
15260
  await new Promise((r) => setTimeout(r, 500));
14887
15261
  if (existsSync23(statusFile)) {
14888
15262
  try {
14889
- const status = JSON.parse(await readFile13(statusFile, "utf8"));
15263
+ const status = JSON.parse(await readFile14(statusFile, "utf8"));
14890
15264
  if (status.error) {
14891
15265
  let errTail = "";
14892
15266
  try {
14893
- errTail = (await readFile13(daemonErrPath, "utf8")).slice(-300);
15267
+ errTail = (await readFile14(daemonErrPath, "utf8")).slice(-300);
14894
15268
  } catch {
14895
15269
  }
14896
15270
  return `Nexus daemon failed to connect: ${status.error}${errTail ? "\n" + errTail : ""}`;
@@ -14912,12 +15286,12 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14912
15286
  const pid = this.getDaemonPid();
14913
15287
  let earlyError = "";
14914
15288
  try {
14915
- earlyError = (await readFile13(daemonErrPath, "utf8")).slice(-500);
15289
+ earlyError = (await readFile14(daemonErrPath, "utf8")).slice(-500);
14916
15290
  } catch {
14917
15291
  }
14918
15292
  let earlyOutput = "";
14919
15293
  try {
14920
- earlyOutput = (await readFile13(daemonLogPath, "utf8")).slice(-500);
15294
+ earlyOutput = (await readFile14(daemonLogPath, "utf8")).slice(-500);
14921
15295
  } catch {
14922
15296
  }
14923
15297
  if (pid) {
@@ -14940,7 +15314,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14940
15314
  } catch {
14941
15315
  }
14942
15316
  for (const f of ["daemon.pid", "status.json", "cmd.json", "resp.json"]) {
14943
- const p = join31(this.nexusDir, f);
15317
+ const p = join32(this.nexusDir, f);
14944
15318
  if (existsSync23(p))
14945
15319
  await unlink(p).catch(() => {
14946
15320
  });
@@ -14951,11 +15325,11 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14951
15325
  const pid = this.getDaemonPid();
14952
15326
  if (!pid)
14953
15327
  return "Nexus daemon not running. Use action 'connect' to start.";
14954
- const statusFile = join31(this.nexusDir, "status.json");
15328
+ const statusFile = join32(this.nexusDir, "status.json");
14955
15329
  if (!existsSync23(statusFile))
14956
15330
  return `Daemon running (pid: ${pid}) but no status yet.`;
14957
15331
  try {
14958
- const status = JSON.parse(await readFile13(statusFile, "utf8"));
15332
+ const status = JSON.parse(await readFile14(statusFile, "utf8"));
14959
15333
  const lines = [
14960
15334
  `Nexus Status (v1.5.0)`,
14961
15335
  ` Connected: ${status.connected}`,
@@ -14966,10 +15340,10 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14966
15340
  ` Capabilities: ${(status.capabilities || []).length ? (status.capabilities || []).join(", ") : "none"}`,
14967
15341
  ` Blocked peers: ${(status.blockedPeers || []).length || 0}`
14968
15342
  ];
14969
- const walletPath = join31(this.nexusDir, "wallet.enc");
15343
+ const walletPath = join32(this.nexusDir, "wallet.enc");
14970
15344
  if (existsSync23(walletPath)) {
14971
15345
  try {
14972
- const w = JSON.parse(await readFile13(walletPath, "utf8"));
15346
+ const w = JSON.parse(await readFile14(walletPath, "utf8"));
14973
15347
  lines.push(` Wallet: ${w.address}`);
14974
15348
  } catch {
14975
15349
  lines.push(` Wallet: corrupt`);
@@ -14977,14 +15351,14 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14977
15351
  } else {
14978
15352
  lines.push(` Wallet: not configured`);
14979
15353
  }
14980
- const inboxDir = join31(this.nexusDir, "inbox");
15354
+ const inboxDir = join32(this.nexusDir, "inbox");
14981
15355
  if (existsSync23(inboxDir)) {
14982
15356
  try {
14983
15357
  const roomDirs = await readdir3(inboxDir);
14984
15358
  let totalMsgs = 0;
14985
15359
  for (const rd of roomDirs) {
14986
15360
  try {
14987
- totalMsgs += (await readdir3(join31(inboxDir, rd))).length;
15361
+ totalMsgs += (await readdir3(join32(inboxDir, rd))).length;
14988
15362
  } catch {
14989
15363
  }
14990
15364
  }
@@ -15031,9 +15405,9 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15031
15405
  }
15032
15406
  async doReadMessages(args) {
15033
15407
  const roomId = args.room_id;
15034
- const inboxDir = join31(this.nexusDir, "inbox");
15408
+ const inboxDir = join32(this.nexusDir, "inbox");
15035
15409
  if (roomId) {
15036
- const roomInbox = join31(inboxDir, roomId);
15410
+ const roomInbox = join32(inboxDir, roomId);
15037
15411
  if (!existsSync23(roomInbox))
15038
15412
  return `No messages in room: ${roomId}`;
15039
15413
  const files = (await readdir3(roomInbox)).sort().slice(-20);
@@ -15042,7 +15416,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15042
15416
  const messages = [`Messages in ${roomId} (last ${files.length}):`];
15043
15417
  for (const f of files) {
15044
15418
  try {
15045
- const msg = JSON.parse(await readFile13(join31(roomInbox, f), "utf8"));
15419
+ const msg = JSON.parse(await readFile14(join32(roomInbox, f), "utf8"));
15046
15420
  const sender = (msg.sender || "unknown").slice(0, 12);
15047
15421
  messages.push(` [${new Date(msg.timestamp).toLocaleTimeString()}] ${sender}...: ${msg.content}`);
15048
15422
  } catch {
@@ -15058,7 +15432,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15058
15432
  const lines = ["Inbox:"];
15059
15433
  for (const rd of roomDirs) {
15060
15434
  try {
15061
- const count = (await readdir3(join31(inboxDir, rd))).length;
15435
+ const count = (await readdir3(join32(inboxDir, rd))).length;
15062
15436
  lines.push(` ${rd}: ${count} message(s)`);
15063
15437
  } catch {
15064
15438
  }
@@ -15070,12 +15444,12 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15070
15444
  // ---------------------------------------------------------------------------
15071
15445
  async doWalletStatus() {
15072
15446
  await this.ensureDir();
15073
- const walletPath = join31(this.nexusDir, "wallet.enc");
15447
+ const walletPath = join32(this.nexusDir, "wallet.enc");
15074
15448
  if (!existsSync23(walletPath)) {
15075
15449
  return "No wallet configured. Use wallet_create to set one up.";
15076
15450
  }
15077
15451
  try {
15078
- const w = JSON.parse(await readFile13(walletPath, "utf8"));
15452
+ const w = JSON.parse(await readFile14(walletPath, "utf8"));
15079
15453
  const lines = [
15080
15454
  `Wallet Status:`,
15081
15455
  ` Address: ${w.address}`,
@@ -15109,7 +15483,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15109
15483
  }
15110
15484
  async doWalletCreate(args) {
15111
15485
  await this.ensureDir();
15112
- const walletPath = join31(this.nexusDir, "wallet.enc");
15486
+ const walletPath = join32(this.nexusDir, "wallet.enc");
15113
15487
  if (existsSync23(walletPath))
15114
15488
  return "Wallet already exists. Delete wallet.enc to create a new one.";
15115
15489
  const userAddress = args.wallet_address;
@@ -15155,7 +15529,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15155
15529
  const cipher = createCipheriv("aes-256-gcm", key, iv);
15156
15530
  let enc = cipher.update(privKeyHex, "utf8", "hex");
15157
15531
  enc += cipher.final("hex");
15158
- const x402KeyPath = join31(this.nexusDir, "x402-wallet.key");
15532
+ const x402KeyPath = join32(this.nexusDir, "x402-wallet.key");
15159
15533
  const x402Fh = await fsOpen(x402KeyPath, "w", 384);
15160
15534
  await x402Fh.writeFile("0x" + privKeyHex);
15161
15535
  await x402Fh.close();
@@ -15193,7 +15567,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15193
15567
  * Silent — no user output, just ensures the files exist.
15194
15568
  */
15195
15569
  async ensureWallet() {
15196
- const walletPath = join31(this.nexusDir, "wallet.enc");
15570
+ const walletPath = join32(this.nexusDir, "wallet.enc");
15197
15571
  if (existsSync23(walletPath))
15198
15572
  return;
15199
15573
  let address;
@@ -15217,7 +15591,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15217
15591
  const cipher = createCipheriv("aes-256-gcm", key, iv);
15218
15592
  let enc = cipher.update(privKeyHex, "utf8", "hex");
15219
15593
  enc += cipher.final("hex");
15220
- const x402KeyPath = join31(this.nexusDir, "x402-wallet.key");
15594
+ const x402KeyPath = join32(this.nexusDir, "x402-wallet.key");
15221
15595
  const x402Fh = await fsOpen(x402KeyPath, "w", 384);
15222
15596
  await x402Fh.writeFile("0x" + privKeyHex);
15223
15597
  await x402Fh.close();
@@ -15277,12 +15651,12 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15277
15651
  // ---------------------------------------------------------------------------
15278
15652
  async doLedgerStatus() {
15279
15653
  await this.ensureDir();
15280
- const ledgerPath = join31(this.nexusDir, "ledger.jsonl");
15654
+ const ledgerPath = join32(this.nexusDir, "ledger.jsonl");
15281
15655
  if (!existsSync23(ledgerPath)) {
15282
15656
  return "No ledger entries. Earnings and spending will be tracked here after x402 transactions.";
15283
15657
  }
15284
15658
  try {
15285
- const raw = await readFile13(ledgerPath, "utf8");
15659
+ const raw = await readFile14(ledgerPath, "utf8");
15286
15660
  const entries = raw.trim().split("\n").filter((l) => l.trim()).map((l) => JSON.parse(l));
15287
15661
  if (entries.length === 0) {
15288
15662
  return "Ledger is empty. No transactions recorded.";
@@ -15319,11 +15693,11 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15319
15693
  }
15320
15694
  }
15321
15695
  async getLedgerSummary() {
15322
- const ledgerPath = join31(this.nexusDir, "ledger.jsonl");
15696
+ const ledgerPath = join32(this.nexusDir, "ledger.jsonl");
15323
15697
  if (!existsSync23(ledgerPath))
15324
15698
  return null;
15325
15699
  try {
15326
- const raw = await readFile13(ledgerPath, "utf8");
15700
+ const raw = await readFile14(ledgerPath, "utf8");
15327
15701
  const entries = raw.trim().split("\n").filter((l) => l.trim()).map((l) => JSON.parse(l));
15328
15702
  let totalEarned = 0n, totalSpent = 0n;
15329
15703
  for (const e of entries) {
@@ -15344,25 +15718,25 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15344
15718
  }
15345
15719
  async appendLedger(entry) {
15346
15720
  await this.ensureDir();
15347
- const ledgerPath = join31(this.nexusDir, "ledger.jsonl");
15721
+ const ledgerPath = join32(this.nexusDir, "ledger.jsonl");
15348
15722
  const line = JSON.stringify(entry) + "\n";
15349
- await writeFile12(ledgerPath, existsSync23(ledgerPath) ? await readFile13(ledgerPath, "utf8") + line : line);
15723
+ await writeFile13(ledgerPath, existsSync23(ledgerPath) ? await readFile14(ledgerPath, "utf8") + line : line);
15350
15724
  }
15351
15725
  // ---------------------------------------------------------------------------
15352
15726
  // Step 4: Budget Policy — Spending limits and auto-approve thresholds
15353
15727
  // ---------------------------------------------------------------------------
15354
15728
  async loadBudget() {
15355
- const budgetPath = join31(this.nexusDir, "budget.json");
15729
+ const budgetPath = join32(this.nexusDir, "budget.json");
15356
15730
  if (!existsSync23(budgetPath))
15357
15731
  return null;
15358
15732
  try {
15359
- return JSON.parse(await readFile13(budgetPath, "utf8"));
15733
+ return JSON.parse(await readFile14(budgetPath, "utf8"));
15360
15734
  } catch {
15361
15735
  return null;
15362
15736
  }
15363
15737
  }
15364
15738
  async ensureDefaultBudget() {
15365
- const budgetPath = join31(this.nexusDir, "budget.json");
15739
+ const budgetPath = join32(this.nexusDir, "budget.json");
15366
15740
  if (existsSync23(budgetPath))
15367
15741
  return;
15368
15742
  const defaultBudget = {
@@ -15383,7 +15757,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15383
15757
  deniedPeers: []
15384
15758
  };
15385
15759
  await this.ensureDir();
15386
- await writeFile12(budgetPath, JSON.stringify(defaultBudget, null, 2));
15760
+ await writeFile13(budgetPath, JSON.stringify(defaultBudget, null, 2));
15387
15761
  }
15388
15762
  async doBudgetStatus() {
15389
15763
  await this.ensureDir();
@@ -15432,17 +15806,17 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15432
15806
  if (changes.length === 0) {
15433
15807
  return "No budget parameters provided. Use daily_limit, per_invoke_max, or auto_approve_below.";
15434
15808
  }
15435
- const budgetPath = join31(this.nexusDir, "budget.json");
15436
- await writeFile12(budgetPath, JSON.stringify(budget, null, 2));
15809
+ const budgetPath = join32(this.nexusDir, "budget.json");
15810
+ await writeFile13(budgetPath, JSON.stringify(budget, null, 2));
15437
15811
  return `Budget updated: ${changes.join(", ")}`;
15438
15812
  }
15439
15813
  async getTodaySpending() {
15440
- const ledgerPath = join31(this.nexusDir, "ledger.jsonl");
15814
+ const ledgerPath = join32(this.nexusDir, "ledger.jsonl");
15441
15815
  if (!existsSync23(ledgerPath))
15442
15816
  return 0;
15443
15817
  try {
15444
15818
  const todayPrefix = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
15445
- const raw = await readFile13(ledgerPath, "utf8");
15819
+ const raw = await readFile14(ledgerPath, "utf8");
15446
15820
  let total = 0;
15447
15821
  for (const line of raw.trim().split("\n")) {
15448
15822
  if (!line.trim())
@@ -15481,10 +15855,10 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15481
15855
  if (todaySpent + amountUsdc > budget.dailyLimitUsdc) {
15482
15856
  return { allowed: false, reason: `Would exceed daily limit ($${((todaySpent + amountUsdc) / 1e6).toFixed(6)} > $${(budget.dailyLimitUsdc / 1e6).toFixed(6)})` };
15483
15857
  }
15484
- const walletPath = join31(this.nexusDir, "wallet.enc");
15858
+ const walletPath = join32(this.nexusDir, "wallet.enc");
15485
15859
  if (existsSync23(walletPath)) {
15486
15860
  try {
15487
- const w = JSON.parse(await readFile13(walletPath, "utf8"));
15861
+ const w = JSON.parse(await readFile14(walletPath, "utf8"));
15488
15862
  if (w.version === 2 && w.address) {
15489
15863
  const balance = await this.queryUsdcBalance(w.address, w.chainId || 8453);
15490
15864
  if (balance !== null && Number(balance) < budget.circuitBreakerUsdc) {
@@ -15512,10 +15886,10 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15512
15886
  const budgetResult = await this.checkBudget(amountSmallest, "transfer:direct", targetAddress);
15513
15887
  if (!budgetResult.allowed)
15514
15888
  return `BLOCKED by budget policy: ${budgetResult.reason}`;
15515
- const walletPath = join31(this.nexusDir, "wallet.enc");
15889
+ const walletPath = join32(this.nexusDir, "wallet.enc");
15516
15890
  if (!existsSync23(walletPath))
15517
15891
  throw new Error("No wallet. Use wallet_create first.");
15518
- const w = JSON.parse(await readFile13(walletPath, "utf8"));
15892
+ const w = JSON.parse(await readFile14(walletPath, "utf8"));
15519
15893
  if (!w.encryptedKey)
15520
15894
  throw new Error("User-managed wallet cannot spend (no private key)");
15521
15895
  const salt = Buffer.from(w.salt, "hex");
@@ -15573,7 +15947,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15573
15947
  capability: "transfer:direct",
15574
15948
  note: "signed, awaiting submission"
15575
15949
  });
15576
- const proofFile = join31(this.nexusDir, "pending-transfer.json");
15950
+ const proofFile = join32(this.nexusDir, "pending-transfer.json");
15577
15951
  const proof = {
15578
15952
  from: account.address,
15579
15953
  to: targetAddress,
@@ -15586,7 +15960,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15586
15960
  usdcContract: USDC_ADDRESS,
15587
15961
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
15588
15962
  };
15589
- await writeFile12(proofFile, JSON.stringify(proof, null, 2));
15963
+ await writeFile13(proofFile, JSON.stringify(proof, null, 2));
15590
15964
  return [
15591
15965
  `Transfer signed (EIP-3009 TransferWithAuthorization):`,
15592
15966
  ` From: ${account.address}`,
@@ -15615,10 +15989,10 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15615
15989
  throw new Error("prompt is required");
15616
15990
  const estimatedTokens = Math.ceil(prompt.length / 4) + 1e3;
15617
15991
  let estimatedCostSmallest = 0;
15618
- const pricingPath = join31(this.nexusDir, "pricing.json");
15992
+ const pricingPath = join32(this.nexusDir, "pricing.json");
15619
15993
  if (existsSync23(pricingPath)) {
15620
15994
  try {
15621
- const pricing = JSON.parse(await readFile13(pricingPath, "utf8"));
15995
+ const pricing = JSON.parse(await readFile14(pricingPath, "utf8"));
15622
15996
  const modelPricing = (pricing.models || []).find((m) => m.model === model || m.model.startsWith(model.split(":")[0]));
15623
15997
  if (modelPricing?.pricing?.input_per_1m_tokens > 0) {
15624
15998
  estimatedCostSmallest = Math.ceil(estimatedTokens / 1e6 * modelPricing.pricing.input_per_1m_tokens * 1e6);
@@ -15735,7 +16109,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15735
16109
  const bar = (s) => "\u2588".repeat(Math.round(s / 5)) + "\u2591".repeat(20 - Math.round(s / 5));
15736
16110
  const mem = vramMb > 24e3 ? 95 : vramMb > 16e3 ? 80 : vramMb > 8e3 ? 60 : vramMb > 0 ? 40 : 20;
15737
16111
  await this.ensureDir();
15738
- await writeFile12(join31(this.nexusDir, "inference-proof.json"), JSON.stringify({
16112
+ await writeFile13(join32(this.nexusDir, "inference-proof.json"), JSON.stringify({
15739
16113
  modelName,
15740
16114
  gpuName,
15741
16115
  vramMb,
@@ -16388,6 +16762,7 @@ __export(dist_exports, {
16388
16762
  ImageReadTool: () => ImageReadTool,
16389
16763
  ListDirectoryTool: () => ListDirectoryTool,
16390
16764
  ManageToolsTool: () => ManageToolsTool,
16765
+ MemoryMetabolismTool: () => MemoryMetabolismTool,
16391
16766
  MemoryReadTool: () => MemoryReadTool,
16392
16767
  MemorySearchTool: () => MemorySearchTool,
16393
16768
  MemoryWriteTool: () => MemoryWriteTool,
@@ -16484,6 +16859,7 @@ var init_dist2 = __esm({
16484
16859
  init_structured_file();
16485
16860
  init_code_sandbox();
16486
16861
  init_repl();
16862
+ init_memory_metabolism();
16487
16863
  init_structured_read();
16488
16864
  init_vision();
16489
16865
  init_desktop_click();
@@ -17184,12 +17560,12 @@ var init_dist3 = __esm({
17184
17560
 
17185
17561
  // packages/orchestrator/dist/promptLoader.js
17186
17562
  import { readFileSync as readFileSync18, existsSync as existsSync25 } from "node:fs";
17187
- import { join as join32, dirname as dirname12 } from "node:path";
17563
+ import { join as join33, dirname as dirname12 } from "node:path";
17188
17564
  import { fileURLToPath as fileURLToPath7 } from "node:url";
17189
17565
  function loadPrompt(promptPath, vars) {
17190
17566
  let content = cache.get(promptPath);
17191
17567
  if (content === void 0) {
17192
- const fullPath = join32(PROMPTS_DIR, promptPath);
17568
+ const fullPath = join33(PROMPTS_DIR, promptPath);
17193
17569
  if (!existsSync25(fullPath)) {
17194
17570
  throw new Error(`Prompt file not found: ${fullPath}`);
17195
17571
  }
@@ -17206,7 +17582,7 @@ var init_promptLoader = __esm({
17206
17582
  "use strict";
17207
17583
  __filename = fileURLToPath7(import.meta.url);
17208
17584
  __dirname4 = dirname12(__filename);
17209
- PROMPTS_DIR = join32(__dirname4, "..", "prompts");
17585
+ PROMPTS_DIR = join33(__dirname4, "..", "prompts");
17210
17586
  cache = /* @__PURE__ */ new Map();
17211
17587
  }
17212
17588
  });
@@ -17569,8 +17945,8 @@ var init_code_retriever = __esm({
17569
17945
  });
17570
17946
  }
17571
17947
  async getFileContent(filePath, startLine, endLine) {
17572
- const { readFile: readFile18 } = await import("node:fs/promises");
17573
- const content = await readFile18(filePath, "utf-8");
17948
+ const { readFile: readFile19 } = await import("node:fs/promises");
17949
+ const content = await readFile19(filePath, "utf-8");
17574
17950
  if (startLine === void 0)
17575
17951
  return content;
17576
17952
  const lines = content.split("\n");
@@ -17585,8 +17961,8 @@ var init_code_retriever = __esm({
17585
17961
  // packages/retrieval/dist/lexicalSearch.js
17586
17962
  import { execFile as execFile5 } from "node:child_process";
17587
17963
  import { promisify as promisify4 } from "node:util";
17588
- import { readFile as readFile14, readdir as readdir4, stat as stat3 } from "node:fs/promises";
17589
- import { join as join33, extname as extname7 } from "node:path";
17964
+ import { readFile as readFile15, readdir as readdir4, stat as stat3 } from "node:fs/promises";
17965
+ import { join as join34, extname as extname7 } from "node:path";
17590
17966
  async function searchByPath(pathPattern, options) {
17591
17967
  const allFiles = await collectFiles(options.rootDir, options.includeGlobs ?? DEFAULT_INCLUDE_GLOBS, options.excludeGlobs ?? DEFAULT_EXCLUDE_GLOBS);
17592
17968
  const pattern = options.caseInsensitive ? pathPattern.toLowerCase() : pathPattern;
@@ -17691,7 +18067,7 @@ async function searchWithNodeFallback(pattern, kind, options) {
17691
18067
  if (results.length >= maxMatches)
17692
18068
  break;
17693
18069
  try {
17694
- const content = await readFile14(filePath, "utf-8");
18070
+ const content = await readFile15(filePath, "utf-8");
17695
18071
  const contentLines = content.split("\n");
17696
18072
  for (let i = 0; i < contentLines.length; i++) {
17697
18073
  if (results.length >= maxMatches)
@@ -17728,7 +18104,7 @@ async function walkForFiles(rootDir, dir, excludeGlobs, results) {
17728
18104
  continue;
17729
18105
  if (excludeGlobs.some((g) => entry.name === g || matchesGlob(entry.name, g)))
17730
18106
  continue;
17731
- const absPath = join33(dir, entry.name);
18107
+ const absPath = join34(dir, entry.name);
17732
18108
  if (entry.isDirectory()) {
17733
18109
  await walkForFiles(rootDir, absPath, excludeGlobs, results);
17734
18110
  } else if (entry.isFile()) {
@@ -18034,8 +18410,8 @@ var init_graphExpand = __esm({
18034
18410
  });
18035
18411
 
18036
18412
  // packages/retrieval/dist/snippetPacker.js
18037
- import { readFile as readFile15 } from "node:fs/promises";
18038
- import { join as join34 } from "node:path";
18413
+ import { readFile as readFile16 } from "node:fs/promises";
18414
+ import { join as join35 } from "node:path";
18039
18415
  async function packSnippets(requests, opts = {}) {
18040
18416
  const maxTokens = opts.maxTokens ?? DEFAULT_MAX_TOKENS;
18041
18417
  const contextLines = opts.contextLines ?? DEFAULT_CONTEXT_LINES;
@@ -18061,10 +18437,10 @@ async function packSnippets(requests, opts = {}) {
18061
18437
  return { packed, dropped, totalTokens };
18062
18438
  }
18063
18439
  async function extractSnippet(req, repoRoot, contextLines = DEFAULT_CONTEXT_LINES) {
18064
- const absPath = req.filePath.startsWith("/") ? req.filePath : join34(repoRoot, req.filePath);
18440
+ const absPath = req.filePath.startsWith("/") ? req.filePath : join35(repoRoot, req.filePath);
18065
18441
  let content;
18066
18442
  try {
18067
- content = await readFile15(absPath, "utf-8");
18443
+ content = await readFile16(absPath, "utf-8");
18068
18444
  } catch {
18069
18445
  return null;
18070
18446
  }
@@ -19992,8 +20368,29 @@ If you're stuck, try a completely different approach. Do NOT repeat what failed
19992
20368
  }
19993
20369
  }
19994
20370
  const { toolOutputMaxChars: maxLen } = this.contextLimits();
19995
- const output = result.success ? result.output.length > maxLen ? this.foldOutput(result.output, maxLen) : result.output : `Error: ${result.error || "unknown error"}
20371
+ let output;
20372
+ if (!result.success) {
20373
+ output = `Error: ${result.error || "unknown error"}
19996
20374
  ${result.output.length > maxLen ? this.foldOutput(result.output, maxLen) : result.output}`;
20375
+ } else if (result.output.length > maxLen) {
20376
+ const handleId = this.quickHash(tc.name + String(tc.arguments?.["path"] ?? "") + String(turn));
20377
+ const lineCount = (result.output.match(/\n/g) || []).length + 1;
20378
+ const preview = result.output.slice(0, 500).replace(/\n/g, " ");
20379
+ this._memexArchive.set(handleId, {
20380
+ id: handleId,
20381
+ toolName: tc.name,
20382
+ summary: `${tc.name} output (${lineCount} lines, ${result.output.length} chars)`,
20383
+ fullContent: result.output,
20384
+ turn,
20385
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
20386
+ });
20387
+ output = `[Output externalized \u2014 ${result.output.length} chars, ${lineCount} lines]
20388
+ Handle: ${handleId}
20389
+ Preview: ${preview}...
20390
+ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or memex_retrieve(id="${handleId}")`;
20391
+ } else {
20392
+ output = result.output;
20393
+ }
19997
20394
  this.emit({
19998
20395
  type: "tool_result",
19999
20396
  toolName: tc.name,
@@ -20383,9 +20780,29 @@ Integrate this guidance into your current approach. Continue working on the task
20383
20780
  }
20384
20781
  }
20385
20782
  const { toolOutputMaxChars: maxLen2 } = this.contextLimits();
20386
- const output = result.success ? result.output.length > maxLen2 ? result.output.slice(0, maxLen2) + `
20387
- ...(truncated)` : result.output : `Error: ${result.error || "unknown error"}
20783
+ let output;
20784
+ if (!result.success) {
20785
+ output = `Error: ${result.error || "unknown error"}
20388
20786
  ${result.output}`;
20787
+ } else if (result.output.length > maxLen2) {
20788
+ const handleId = this.quickHash(tc.name + String(tc.arguments?.["path"] ?? "") + String(turn));
20789
+ const lineCount = (result.output.match(/\n/g) || []).length + 1;
20790
+ const preview = result.output.slice(0, 500).replace(/\n/g, " ");
20791
+ this._memexArchive.set(handleId, {
20792
+ id: handleId,
20793
+ toolName: tc.name,
20794
+ summary: `${tc.name} output (${lineCount} lines, ${result.output.length} chars)`,
20795
+ fullContent: result.output,
20796
+ turn,
20797
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
20798
+ });
20799
+ output = `[Output externalized \u2014 ${result.output.length} chars, ${lineCount} lines]
20800
+ Handle: ${handleId}
20801
+ Preview: ${preview}...
20802
+ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or memex_retrieve(id="${handleId}")`;
20803
+ } else {
20804
+ output = result.output;
20805
+ }
20389
20806
  this.emit({ type: "tool_result", toolName: tc.name, content: output.slice(0, 200), success: result.success, turn, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
20390
20807
  const enoentTools2 = /* @__PURE__ */ new Set(["file_read", "list_directory", "find_files"]);
20391
20808
  if (!result.success && enoentTools2.has(tc.name) && /ENOENT|no such file|does not exist|not found/i.test(result.error ?? result.output)) {
@@ -20614,8 +21031,8 @@ ${marker}` : marker);
20614
21031
  return;
20615
21032
  try {
20616
21033
  const { mkdirSync: mkdirSync21, writeFileSync: writeFileSync20 } = __require("node:fs");
20617
- const { join: join58 } = __require("node:path");
20618
- const sessionDir = join58(this._workingDirectory, ".oa", "session", this._sessionId);
21034
+ const { join: join59 } = __require("node:path");
21035
+ const sessionDir = join59(this._workingDirectory, ".oa", "session", this._sessionId);
20619
21036
  mkdirSync21(sessionDir, { recursive: true });
20620
21037
  const checkpoint = {
20621
21038
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -20628,7 +21045,7 @@ ${marker}` : marker);
20628
21045
  memexEntryCount: this._memexArchive.size,
20629
21046
  fileRegistrySize: this._fileRegistry.size
20630
21047
  };
20631
- writeFileSync20(join58(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
21048
+ writeFileSync20(join59(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
20632
21049
  } catch {
20633
21050
  }
20634
21051
  }
@@ -21896,7 +22313,7 @@ ${transcript}`
21896
22313
  // packages/orchestrator/dist/nexusBackend.js
21897
22314
  import { existsSync as existsSync26, statSync as statSync9, openSync, readSync, closeSync, unlinkSync as unlinkSync4, writeFileSync as writeFileSync8 } from "node:fs";
21898
22315
  import { watch as fsWatch } from "node:fs";
21899
- import { join as join35 } from "node:path";
22316
+ import { join as join36 } from "node:path";
21900
22317
  import { tmpdir as tmpdir7 } from "node:os";
21901
22318
  import { randomBytes as randomBytes8 } from "node:crypto";
21902
22319
  var NexusAgenticBackend;
@@ -22046,7 +22463,7 @@ var init_nexusBackend = __esm({
22046
22463
  * Falls back to unary + word-split if streaming setup fails.
22047
22464
  */
22048
22465
  async *chatCompletionStream(request) {
22049
- const streamFile = join35(tmpdir7(), `nexus-stream-${randomBytes8(6).toString("hex")}.jsonl`);
22466
+ const streamFile = join36(tmpdir7(), `nexus-stream-${randomBytes8(6).toString("hex")}.jsonl`);
22050
22467
  writeFileSync8(streamFile, "", "utf8");
22051
22468
  const daemonArgs = {
22052
22469
  model: this.model,
@@ -23083,7 +23500,7 @@ __export(listen_exports, {
23083
23500
  });
23084
23501
  import { spawn as spawn15, execSync as execSync23 } from "node:child_process";
23085
23502
  import { existsSync as existsSync27, mkdirSync as mkdirSync8, writeFileSync as writeFileSync9, readdirSync as readdirSync6 } from "node:fs";
23086
- import { join as join36, dirname as dirname13 } from "node:path";
23503
+ import { join as join37, dirname as dirname13 } from "node:path";
23087
23504
  import { homedir as homedir8 } from "node:os";
23088
23505
  import { fileURLToPath as fileURLToPath8 } from "node:url";
23089
23506
  import { EventEmitter } from "node:events";
@@ -23169,12 +23586,12 @@ function findMicCaptureCommand() {
23169
23586
  function findLiveWhisperScript() {
23170
23587
  const thisDir = dirname13(fileURLToPath8(import.meta.url));
23171
23588
  const candidates = [
23172
- join36(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
23173
- join36(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
23174
- join36(thisDir, "../../execution/scripts/live-whisper.py"),
23589
+ join37(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
23590
+ join37(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
23591
+ join37(thisDir, "../../execution/scripts/live-whisper.py"),
23175
23592
  // npm install layout — scripts bundled alongside dist
23176
- join36(thisDir, "../scripts/live-whisper.py"),
23177
- join36(thisDir, "../../scripts/live-whisper.py")
23593
+ join37(thisDir, "../scripts/live-whisper.py"),
23594
+ join37(thisDir, "../../scripts/live-whisper.py")
23178
23595
  ];
23179
23596
  for (const p of candidates) {
23180
23597
  if (existsSync27(p))
@@ -23187,8 +23604,8 @@ function findLiveWhisperScript() {
23187
23604
  stdio: ["pipe", "pipe", "pipe"]
23188
23605
  }).trim();
23189
23606
  const candidates2 = [
23190
- join36(globalRoot, "open-agents-ai", "dist", "scripts", "live-whisper.py"),
23191
- join36(globalRoot, "open-agents-ai", "scripts", "live-whisper.py")
23607
+ join37(globalRoot, "open-agents-ai", "dist", "scripts", "live-whisper.py"),
23608
+ join37(globalRoot, "open-agents-ai", "scripts", "live-whisper.py")
23192
23609
  ];
23193
23610
  for (const p of candidates2) {
23194
23611
  if (existsSync27(p))
@@ -23196,11 +23613,11 @@ function findLiveWhisperScript() {
23196
23613
  }
23197
23614
  } catch {
23198
23615
  }
23199
- const nvmBase = join36(homedir8(), ".nvm", "versions", "node");
23616
+ const nvmBase = join37(homedir8(), ".nvm", "versions", "node");
23200
23617
  if (existsSync27(nvmBase)) {
23201
23618
  try {
23202
23619
  for (const ver of readdirSync6(nvmBase)) {
23203
- const p = join36(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
23620
+ const p = join37(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
23204
23621
  if (existsSync27(p))
23205
23622
  return p;
23206
23623
  }
@@ -23219,7 +23636,7 @@ function ensureTranscribeCliBackground() {
23219
23636
  timeout: 5e3,
23220
23637
  stdio: ["pipe", "pipe", "pipe"]
23221
23638
  }).trim();
23222
- if (existsSync27(join36(globalRoot, "transcribe-cli", "dist", "index.js"))) {
23639
+ if (existsSync27(join37(globalRoot, "transcribe-cli", "dist", "index.js"))) {
23223
23640
  return true;
23224
23641
  }
23225
23642
  } catch {
@@ -23442,24 +23859,24 @@ var init_listen = __esm({
23442
23859
  timeout: 5e3,
23443
23860
  stdio: ["pipe", "pipe", "pipe"]
23444
23861
  }).trim();
23445
- const tcPath = join36(globalRoot, "transcribe-cli");
23446
- if (existsSync27(join36(tcPath, "dist", "index.js"))) {
23862
+ const tcPath = join37(globalRoot, "transcribe-cli");
23863
+ if (existsSync27(join37(tcPath, "dist", "index.js"))) {
23447
23864
  const { createRequire: createRequire4 } = await import("node:module");
23448
23865
  const req = createRequire4(import.meta.url);
23449
- return req(join36(tcPath, "dist", "index.js"));
23866
+ return req(join37(tcPath, "dist", "index.js"));
23450
23867
  }
23451
23868
  } catch {
23452
23869
  }
23453
- const nvmBase = join36(homedir8(), ".nvm", "versions", "node");
23870
+ const nvmBase = join37(homedir8(), ".nvm", "versions", "node");
23454
23871
  if (existsSync27(nvmBase)) {
23455
23872
  try {
23456
23873
  const { readdirSync: readdirSync17 } = await import("node:fs");
23457
23874
  for (const ver of readdirSync17(nvmBase)) {
23458
- const tcPath = join36(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
23459
- if (existsSync27(join36(tcPath, "dist", "index.js"))) {
23875
+ const tcPath = join37(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
23876
+ if (existsSync27(join37(tcPath, "dist", "index.js"))) {
23460
23877
  const { createRequire: createRequire4 } = await import("node:module");
23461
23878
  const req = createRequire4(import.meta.url);
23462
- return req(join36(tcPath, "dist", "index.js"));
23879
+ return req(join37(tcPath, "dist", "index.js"));
23463
23880
  }
23464
23881
  }
23465
23882
  } catch {
@@ -23741,9 +24158,9 @@ transcribe-cli error: ${transcribeCliError}` : "";
23741
24158
  });
23742
24159
  if (outputDir) {
23743
24160
  const { basename: basename16 } = await import("node:path");
23744
- const transcriptDir = join36(outputDir, ".oa", "transcripts");
24161
+ const transcriptDir = join37(outputDir, ".oa", "transcripts");
23745
24162
  mkdirSync8(transcriptDir, { recursive: true });
23746
- const outFile = join36(transcriptDir, `${basename16(filePath)}.txt`);
24163
+ const outFile = join37(transcriptDir, `${basename16(filePath)}.txt`);
23747
24164
  writeFileSync9(outFile, result.text, "utf-8");
23748
24165
  }
23749
24166
  return {
@@ -29101,7 +29518,7 @@ import { randomBytes as randomBytes9 } from "node:crypto";
29101
29518
  import { URL as URL2 } from "node:url";
29102
29519
  import { loadavg, cpus, totalmem, freemem } from "node:os";
29103
29520
  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";
29104
- import { join as join37 } from "node:path";
29521
+ import { join as join38 } from "node:path";
29105
29522
  function cleanForwardHeaders(raw, targetHost) {
29106
29523
  const out = {};
29107
29524
  for (const [key, value] of Object.entries(raw)) {
@@ -29129,7 +29546,7 @@ function fmtTokens(n) {
29129
29546
  }
29130
29547
  function readExposeState(stateDir) {
29131
29548
  try {
29132
- const path = join37(stateDir, STATE_FILE_NAME);
29549
+ const path = join38(stateDir, STATE_FILE_NAME);
29133
29550
  if (!existsSync28(path))
29134
29551
  return null;
29135
29552
  const raw = readFileSync19(path, "utf8");
@@ -29144,13 +29561,13 @@ function readExposeState(stateDir) {
29144
29561
  function writeExposeState(stateDir, state) {
29145
29562
  try {
29146
29563
  mkdirSync9(stateDir, { recursive: true });
29147
- writeFileSync10(join37(stateDir, STATE_FILE_NAME), JSON.stringify(state, null, 2));
29564
+ writeFileSync10(join38(stateDir, STATE_FILE_NAME), JSON.stringify(state, null, 2));
29148
29565
  } catch {
29149
29566
  }
29150
29567
  }
29151
29568
  function removeExposeState(stateDir) {
29152
29569
  try {
29153
- unlinkSync5(join37(stateDir, STATE_FILE_NAME));
29570
+ unlinkSync5(join38(stateDir, STATE_FILE_NAME));
29154
29571
  } catch {
29155
29572
  }
29156
29573
  }
@@ -29239,7 +29656,7 @@ async function collectSystemMetricsAsync() {
29239
29656
  }
29240
29657
  function readP2PExposeState(stateDir) {
29241
29658
  try {
29242
- const path = join37(stateDir, P2P_STATE_FILE_NAME);
29659
+ const path = join38(stateDir, P2P_STATE_FILE_NAME);
29243
29660
  if (!existsSync28(path))
29244
29661
  return null;
29245
29662
  const raw = readFileSync19(path, "utf8");
@@ -29254,13 +29671,13 @@ function readP2PExposeState(stateDir) {
29254
29671
  function writeP2PExposeState(stateDir, state) {
29255
29672
  try {
29256
29673
  mkdirSync9(stateDir, { recursive: true });
29257
- writeFileSync10(join37(stateDir, P2P_STATE_FILE_NAME), JSON.stringify(state, null, 2));
29674
+ writeFileSync10(join38(stateDir, P2P_STATE_FILE_NAME), JSON.stringify(state, null, 2));
29258
29675
  } catch {
29259
29676
  }
29260
29677
  }
29261
29678
  function removeP2PExposeState(stateDir) {
29262
29679
  try {
29263
- unlinkSync5(join37(stateDir, P2P_STATE_FILE_NAME));
29680
+ unlinkSync5(join38(stateDir, P2P_STATE_FILE_NAME));
29264
29681
  } catch {
29265
29682
  }
29266
29683
  }
@@ -30090,7 +30507,7 @@ ${this.formatConnectionInfo()}`);
30090
30507
  throw new Error(`Expose failed: ${exposeResult.error}`);
30091
30508
  }
30092
30509
  const nexusDir = this._nexusTool.getNexusDir();
30093
- const statusPath = join37(nexusDir, "status.json");
30510
+ const statusPath = join38(nexusDir, "status.json");
30094
30511
  for (let i = 0; i < 80; i++) {
30095
30512
  try {
30096
30513
  const raw = readFileSync19(statusPath, "utf8");
@@ -30124,7 +30541,7 @@ ${this.formatConnectionInfo()}`);
30124
30541
  });
30125
30542
  }
30126
30543
  try {
30127
- const invocDir = join37(nexusDir, "invocations");
30544
+ const invocDir = join38(nexusDir, "invocations");
30128
30545
  if (existsSync28(invocDir)) {
30129
30546
  this._prevInvocCount = readdirSync7(invocDir).filter((f) => f.endsWith(".json")).length;
30130
30547
  this._stats.totalRequests = this._prevInvocCount;
@@ -30154,7 +30571,7 @@ ${this.formatConnectionInfo()}`);
30154
30571
  if (!state)
30155
30572
  return null;
30156
30573
  const nexusDir = nexusTool.getNexusDir();
30157
- const statusPath = join37(nexusDir, "status.json");
30574
+ const statusPath = join38(nexusDir, "status.json");
30158
30575
  try {
30159
30576
  if (!existsSync28(statusPath)) {
30160
30577
  removeP2PExposeState(stateDir);
@@ -30213,7 +30630,7 @@ ${this.formatConnectionInfo()}`);
30213
30630
  let lastMeteringLineCount = 0;
30214
30631
  this._activityPollTimer = setInterval(() => {
30215
30632
  try {
30216
- const invocDir = join37(nexusDir, "invocations");
30633
+ const invocDir = join38(nexusDir, "invocations");
30217
30634
  if (!existsSync28(invocDir))
30218
30635
  return;
30219
30636
  const files = readdirSync7(invocDir).filter((f) => f.endsWith(".json"));
@@ -30229,13 +30646,13 @@ ${this.formatConnectionInfo()}`);
30229
30646
  let recentActive = 0;
30230
30647
  for (const f of files.slice(-10)) {
30231
30648
  try {
30232
- const st = statSync10(join37(invocDir, f));
30649
+ const st = statSync10(join38(invocDir, f));
30233
30650
  if (now - st.mtimeMs < 1e4)
30234
30651
  recentActive++;
30235
30652
  } catch {
30236
30653
  }
30237
30654
  }
30238
- const meteringFile = join37(nexusDir, "metering.jsonl");
30655
+ const meteringFile = join38(nexusDir, "metering.jsonl");
30239
30656
  let meteringLines = lastMeteringLineCount;
30240
30657
  try {
30241
30658
  if (existsSync28(meteringFile)) {
@@ -30265,7 +30682,7 @@ ${this.formatConnectionInfo()}`);
30265
30682
  this._activityPollTimer.unref();
30266
30683
  this._pollTimer = setInterval(() => {
30267
30684
  try {
30268
- const statusPath = join37(nexusDir, "status.json");
30685
+ const statusPath = join38(nexusDir, "status.json");
30269
30686
  if (existsSync28(statusPath)) {
30270
30687
  const status = JSON.parse(readFileSync19(statusPath, "utf8"));
30271
30688
  if (status.peerId && !this._peerId) {
@@ -30276,7 +30693,7 @@ ${this.formatConnectionInfo()}`);
30276
30693
  } catch {
30277
30694
  }
30278
30695
  try {
30279
- const invocDir = join37(nexusDir, "invocations");
30696
+ const invocDir = join38(nexusDir, "invocations");
30280
30697
  if (existsSync28(invocDir)) {
30281
30698
  const files = readdirSync7(invocDir);
30282
30699
  const invocCount = files.filter((f) => f.endsWith(".json")).length;
@@ -30288,7 +30705,7 @@ ${this.formatConnectionInfo()}`);
30288
30705
  } catch {
30289
30706
  }
30290
30707
  try {
30291
- const meteringFile = join37(nexusDir, "metering.jsonl");
30708
+ const meteringFile = join38(nexusDir, "metering.jsonl");
30292
30709
  if (existsSync28(meteringFile)) {
30293
30710
  const content = readFileSync19(meteringFile, "utf8");
30294
30711
  if (content.length > lastMeteringSize) {
@@ -30500,7 +30917,7 @@ var init_types = __esm({
30500
30917
  // packages/cli/dist/tui/p2p/secret-vault.js
30501
30918
  import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes10, scryptSync as scryptSync2, createHash as createHash2 } from "node:crypto";
30502
30919
  import { readFileSync as readFileSync20, writeFileSync as writeFileSync11, existsSync as existsSync29, mkdirSync as mkdirSync10 } from "node:fs";
30503
- import { join as join38, dirname as dirname14 } from "node:path";
30920
+ import { join as join39, dirname as dirname14 } from "node:path";
30504
30921
  var PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, CIPHER_ALGO, SALT_LEN, IV_LEN, KEY_LEN, SecretVault;
30505
30922
  var init_secret_vault = __esm({
30506
30923
  "packages/cli/dist/tui/p2p/secret-vault.js"() {
@@ -31837,13 +32254,13 @@ async function fetchPeerModels(peerId, authKey) {
31837
32254
  try {
31838
32255
  const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
31839
32256
  const { existsSync: existsSync45, readFileSync: readFileSync33 } = await import("node:fs");
31840
- const { join: join58 } = await import("node:path");
32257
+ const { join: join59 } = await import("node:path");
31841
32258
  const cwd4 = process.cwd();
31842
32259
  const nexusTool = new NexusTool2(cwd4);
31843
32260
  const nexusDir = nexusTool.getNexusDir();
31844
32261
  let isLocalPeer = false;
31845
32262
  try {
31846
- const statusPath = join58(nexusDir, "status.json");
32263
+ const statusPath = join59(nexusDir, "status.json");
31847
32264
  if (existsSync45(statusPath)) {
31848
32265
  const status = JSON.parse(readFileSync33(statusPath, "utf8"));
31849
32266
  if (status.peerId === peerId)
@@ -31852,7 +32269,7 @@ async function fetchPeerModels(peerId, authKey) {
31852
32269
  } catch {
31853
32270
  }
31854
32271
  if (isLocalPeer) {
31855
- const pricingPath = join58(nexusDir, "pricing.json");
32272
+ const pricingPath = join59(nexusDir, "pricing.json");
31856
32273
  if (existsSync45(pricingPath)) {
31857
32274
  try {
31858
32275
  const pricing = JSON.parse(readFileSync33(pricingPath, "utf8"));
@@ -31869,7 +32286,7 @@ async function fetchPeerModels(peerId, authKey) {
31869
32286
  }
31870
32287
  }
31871
32288
  }
31872
- const cachePath = join58(nexusDir, "peer-models-cache.json");
32289
+ const cachePath = join59(nexusDir, "peer-models-cache.json");
31873
32290
  if (existsSync45(cachePath)) {
31874
32291
  try {
31875
32292
  const cache4 = JSON.parse(readFileSync33(cachePath, "utf8"));
@@ -31987,7 +32404,7 @@ async function fetchPeerModels(peerId, authKey) {
31987
32404
  } catch {
31988
32405
  }
31989
32406
  if (isLocalPeer) {
31990
- const pricingPath = join58(nexusDir, "pricing.json");
32407
+ const pricingPath = join59(nexusDir, "pricing.json");
31991
32408
  if (existsSync45(pricingPath)) {
31992
32409
  try {
31993
32410
  const pricing = JSON.parse(readFileSync33(pricingPath, "utf8"));
@@ -32260,12 +32677,12 @@ var init_render2 = __esm({
32260
32677
 
32261
32678
  // packages/prompts/dist/promptLoader.js
32262
32679
  import { readFileSync as readFileSync21, existsSync as existsSync30 } from "node:fs";
32263
- import { join as join39, dirname as dirname15 } from "node:path";
32680
+ import { join as join40, dirname as dirname15 } from "node:path";
32264
32681
  import { fileURLToPath as fileURLToPath9 } from "node:url";
32265
32682
  function loadPrompt2(promptPath, vars) {
32266
32683
  let content = cache2.get(promptPath);
32267
32684
  if (content === void 0) {
32268
- const fullPath = join39(PROMPTS_DIR2, promptPath);
32685
+ const fullPath = join40(PROMPTS_DIR2, promptPath);
32269
32686
  if (!existsSync30(fullPath)) {
32270
32687
  throw new Error(`Prompt file not found: ${fullPath}`);
32271
32688
  }
@@ -32282,8 +32699,8 @@ var init_promptLoader2 = __esm({
32282
32699
  "use strict";
32283
32700
  __filename2 = fileURLToPath9(import.meta.url);
32284
32701
  __dirname5 = dirname15(__filename2);
32285
- devPath = join39(__dirname5, "..", "templates");
32286
- publishedPath = join39(__dirname5, "..", "prompts", "templates");
32702
+ devPath = join40(__dirname5, "..", "templates");
32703
+ publishedPath = join40(__dirname5, "..", "prompts", "templates");
32287
32704
  PROMPTS_DIR2 = existsSync30(devPath) ? devPath : publishedPath;
32288
32705
  cache2 = /* @__PURE__ */ new Map();
32289
32706
  }
@@ -32395,7 +32812,7 @@ var init_task_templates = __esm({
32395
32812
  });
32396
32813
 
32397
32814
  // packages/prompts/dist/index.js
32398
- import { join as join40, dirname as dirname16 } from "node:path";
32815
+ import { join as join41, dirname as dirname16 } from "node:path";
32399
32816
  import { fileURLToPath as fileURLToPath10 } from "node:url";
32400
32817
  var _dir, _packageRoot;
32401
32818
  var init_dist6 = __esm({
@@ -32406,21 +32823,21 @@ var init_dist6 = __esm({
32406
32823
  init_task_templates();
32407
32824
  init_render2();
32408
32825
  _dir = dirname16(fileURLToPath10(import.meta.url));
32409
- _packageRoot = join40(_dir, "..");
32826
+ _packageRoot = join41(_dir, "..");
32410
32827
  }
32411
32828
  });
32412
32829
 
32413
32830
  // packages/cli/dist/tui/oa-directory.js
32414
32831
  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";
32415
- import { join as join41, relative as relative2, basename as basename9, extname as extname8 } from "node:path";
32832
+ import { join as join42, relative as relative2, basename as basename9, extname as extname8 } from "node:path";
32416
32833
  import { homedir as homedir9 } from "node:os";
32417
32834
  function initOaDirectory(repoRoot) {
32418
- const oaPath = join41(repoRoot, OA_DIR);
32835
+ const oaPath = join42(repoRoot, OA_DIR);
32419
32836
  for (const sub of SUBDIRS) {
32420
- mkdirSync11(join41(oaPath, sub), { recursive: true });
32837
+ mkdirSync11(join42(oaPath, sub), { recursive: true });
32421
32838
  }
32422
32839
  try {
32423
- const gitignorePath = join41(repoRoot, ".gitignore");
32840
+ const gitignorePath = join42(repoRoot, ".gitignore");
32424
32841
  const settingsPattern = ".oa/settings.json";
32425
32842
  if (existsSync31(gitignorePath)) {
32426
32843
  const content = readFileSync22(gitignorePath, "utf-8");
@@ -32433,10 +32850,10 @@ function initOaDirectory(repoRoot) {
32433
32850
  return oaPath;
32434
32851
  }
32435
32852
  function hasOaDirectory(repoRoot) {
32436
- return existsSync31(join41(repoRoot, OA_DIR, "index"));
32853
+ return existsSync31(join42(repoRoot, OA_DIR, "index"));
32437
32854
  }
32438
32855
  function loadProjectSettings(repoRoot) {
32439
- const settingsPath = join41(repoRoot, OA_DIR, "settings.json");
32856
+ const settingsPath = join42(repoRoot, OA_DIR, "settings.json");
32440
32857
  try {
32441
32858
  if (existsSync31(settingsPath)) {
32442
32859
  return JSON.parse(readFileSync22(settingsPath, "utf-8"));
@@ -32446,14 +32863,14 @@ function loadProjectSettings(repoRoot) {
32446
32863
  return {};
32447
32864
  }
32448
32865
  function saveProjectSettings(repoRoot, settings) {
32449
- const oaPath = join41(repoRoot, OA_DIR);
32866
+ const oaPath = join42(repoRoot, OA_DIR);
32450
32867
  mkdirSync11(oaPath, { recursive: true });
32451
32868
  const existing = loadProjectSettings(repoRoot);
32452
32869
  const merged = { ...existing, ...settings };
32453
- writeFileSync12(join41(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
32870
+ writeFileSync12(join42(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
32454
32871
  }
32455
32872
  function loadGlobalSettings() {
32456
- const settingsPath = join41(homedir9(), ".open-agents", "settings.json");
32873
+ const settingsPath = join42(homedir9(), ".open-agents", "settings.json");
32457
32874
  try {
32458
32875
  if (existsSync31(settingsPath)) {
32459
32876
  return JSON.parse(readFileSync22(settingsPath, "utf-8"));
@@ -32463,11 +32880,11 @@ function loadGlobalSettings() {
32463
32880
  return {};
32464
32881
  }
32465
32882
  function saveGlobalSettings(settings) {
32466
- const dir = join41(homedir9(), ".open-agents");
32883
+ const dir = join42(homedir9(), ".open-agents");
32467
32884
  mkdirSync11(dir, { recursive: true });
32468
32885
  const existing = loadGlobalSettings();
32469
32886
  const merged = { ...existing, ...settings };
32470
- writeFileSync12(join41(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
32887
+ writeFileSync12(join42(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
32471
32888
  }
32472
32889
  function resolveSettings(repoRoot) {
32473
32890
  const global = loadGlobalSettings();
@@ -32482,7 +32899,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
32482
32899
  while (dir && !visited.has(dir)) {
32483
32900
  visited.add(dir);
32484
32901
  for (const name of CONTEXT_FILES) {
32485
- const filePath = join41(dir, name);
32902
+ const filePath = join42(dir, name);
32486
32903
  const normalizedName = name.toLowerCase();
32487
32904
  if (existsSync31(filePath) && !seen.has(filePath)) {
32488
32905
  seen.add(filePath);
@@ -32501,7 +32918,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
32501
32918
  }
32502
32919
  }
32503
32920
  }
32504
- const projectMap = join41(dir, OA_DIR, "context", "project-map.md");
32921
+ const projectMap = join42(dir, OA_DIR, "context", "project-map.md");
32505
32922
  if (existsSync31(projectMap) && !seen.has(projectMap)) {
32506
32923
  seen.add(projectMap);
32507
32924
  try {
@@ -32517,7 +32934,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
32517
32934
  } catch {
32518
32935
  }
32519
32936
  }
32520
- const parent = join41(dir, "..");
32937
+ const parent = join42(dir, "..");
32521
32938
  if (parent === dir)
32522
32939
  break;
32523
32940
  dir = parent;
@@ -32535,7 +32952,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
32535
32952
  return found;
32536
32953
  }
32537
32954
  function readIndexMeta(repoRoot) {
32538
- const metaPath = join41(repoRoot, OA_DIR, "index", "meta.json");
32955
+ const metaPath = join42(repoRoot, OA_DIR, "index", "meta.json");
32539
32956
  try {
32540
32957
  return JSON.parse(readFileSync22(metaPath, "utf-8"));
32541
32958
  } catch {
@@ -32588,28 +33005,28 @@ ${tree}\`\`\`
32588
33005
  sections.push("");
32589
33006
  }
32590
33007
  const content = sections.join("\n");
32591
- const contextDir = join41(repoRoot, OA_DIR, "context");
33008
+ const contextDir = join42(repoRoot, OA_DIR, "context");
32592
33009
  mkdirSync11(contextDir, { recursive: true });
32593
- writeFileSync12(join41(contextDir, "project-map.md"), content, "utf-8");
33010
+ writeFileSync12(join42(contextDir, "project-map.md"), content, "utf-8");
32594
33011
  return content;
32595
33012
  }
32596
33013
  function saveSession(repoRoot, session) {
32597
- const historyDir = join41(repoRoot, OA_DIR, "history");
33014
+ const historyDir = join42(repoRoot, OA_DIR, "history");
32598
33015
  mkdirSync11(historyDir, { recursive: true });
32599
- writeFileSync12(join41(historyDir, `${session.id}.json`), JSON.stringify(session, null, 2), "utf-8");
33016
+ writeFileSync12(join42(historyDir, `${session.id}.json`), JSON.stringify(session, null, 2), "utf-8");
32600
33017
  }
32601
33018
  function loadRecentSessions(repoRoot, limit = 5) {
32602
- const historyDir = join41(repoRoot, OA_DIR, "history");
33019
+ const historyDir = join42(repoRoot, OA_DIR, "history");
32603
33020
  if (!existsSync31(historyDir))
32604
33021
  return [];
32605
33022
  try {
32606
33023
  const files = readdirSync8(historyDir).filter((f) => f.endsWith(".json") && f !== "pending-task.json").map((f) => {
32607
- const stat5 = statSync11(join41(historyDir, f));
33024
+ const stat5 = statSync11(join42(historyDir, f));
32608
33025
  return { file: f, mtime: stat5.mtimeMs };
32609
33026
  }).sort((a, b) => b.mtime - a.mtime).slice(0, limit);
32610
33027
  return files.map((f) => {
32611
33028
  try {
32612
- return JSON.parse(readFileSync22(join41(historyDir, f.file), "utf-8"));
33029
+ return JSON.parse(readFileSync22(join42(historyDir, f.file), "utf-8"));
32613
33030
  } catch {
32614
33031
  return null;
32615
33032
  }
@@ -32619,12 +33036,12 @@ function loadRecentSessions(repoRoot, limit = 5) {
32619
33036
  }
32620
33037
  }
32621
33038
  function savePendingTask(repoRoot, task) {
32622
- const historyDir = join41(repoRoot, OA_DIR, "history");
33039
+ const historyDir = join42(repoRoot, OA_DIR, "history");
32623
33040
  mkdirSync11(historyDir, { recursive: true });
32624
- writeFileSync12(join41(historyDir, PENDING_TASK_FILE), JSON.stringify(task, null, 2) + "\n", "utf-8");
33041
+ writeFileSync12(join42(historyDir, PENDING_TASK_FILE), JSON.stringify(task, null, 2) + "\n", "utf-8");
32625
33042
  }
32626
33043
  function loadPendingTask(repoRoot) {
32627
- const filePath = join41(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
33044
+ const filePath = join42(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
32628
33045
  try {
32629
33046
  if (!existsSync31(filePath))
32630
33047
  return null;
@@ -32639,9 +33056,9 @@ function loadPendingTask(repoRoot) {
32639
33056
  }
32640
33057
  }
32641
33058
  function saveSessionContext(repoRoot, entry) {
32642
- const contextDir = join41(repoRoot, OA_DIR, "context");
33059
+ const contextDir = join42(repoRoot, OA_DIR, "context");
32643
33060
  mkdirSync11(contextDir, { recursive: true });
32644
- const filePath = join41(contextDir, CONTEXT_SAVE_FILE);
33061
+ const filePath = join42(contextDir, CONTEXT_SAVE_FILE);
32645
33062
  let ctx;
32646
33063
  try {
32647
33064
  if (existsSync31(filePath)) {
@@ -32660,7 +33077,7 @@ function saveSessionContext(repoRoot, entry) {
32660
33077
  writeFileSync12(filePath, JSON.stringify(ctx, null, 2) + "\n", "utf-8");
32661
33078
  }
32662
33079
  function loadSessionContext(repoRoot) {
32663
- const filePath = join41(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
33080
+ const filePath = join42(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
32664
33081
  try {
32665
33082
  if (!existsSync31(filePath))
32666
33083
  return null;
@@ -32711,7 +33128,7 @@ function detectManifests(repoRoot) {
32711
33128
  { file: "docker-compose.yaml", type: "Docker Compose" }
32712
33129
  ];
32713
33130
  for (const check of checks) {
32714
- const filePath = join41(repoRoot, check.file);
33131
+ const filePath = join42(repoRoot, check.file);
32715
33132
  if (existsSync31(filePath)) {
32716
33133
  let name;
32717
33134
  if (check.nameField) {
@@ -32745,7 +33162,7 @@ function findKeyFiles(repoRoot) {
32745
33162
  { pattern: "CLAUDE.md", description: "Claude Code context" }
32746
33163
  ];
32747
33164
  for (const check of checks) {
32748
- if (existsSync31(join41(repoRoot, check.pattern))) {
33165
+ if (existsSync31(join42(repoRoot, check.pattern))) {
32749
33166
  keyFiles.push({ path: check.pattern, description: check.description });
32750
33167
  }
32751
33168
  }
@@ -32771,12 +33188,12 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
32771
33188
  if (entry.isDirectory()) {
32772
33189
  let fileCount = 0;
32773
33190
  try {
32774
- fileCount = readdirSync8(join41(root, entry.name)).filter((f) => !f.startsWith(".")).length;
33191
+ fileCount = readdirSync8(join42(root, entry.name)).filter((f) => !f.startsWith(".")).length;
32775
33192
  } catch {
32776
33193
  }
32777
33194
  result += `${prefix}${connector}${entry.name}/ (${fileCount})
32778
33195
  `;
32779
- result += buildDirTree(join41(root, entry.name), maxDepth, childPrefix, depth + 1);
33196
+ result += buildDirTree(join42(root, entry.name), maxDepth, childPrefix, depth + 1);
32780
33197
  } else if (depth < maxDepth) {
32781
33198
  result += `${prefix}${connector}${entry.name}
32782
33199
  `;
@@ -32796,7 +33213,7 @@ function loadUsageFile(filePath) {
32796
33213
  return { records: [] };
32797
33214
  }
32798
33215
  function saveUsageFile(filePath, data) {
32799
- const dir = join41(filePath, "..");
33216
+ const dir = join42(filePath, "..");
32800
33217
  mkdirSync11(dir, { recursive: true });
32801
33218
  writeFileSync12(filePath, JSON.stringify(data, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
32802
33219
  }
@@ -32826,15 +33243,15 @@ function recordUsage(kind, value, opts) {
32826
33243
  }
32827
33244
  saveUsageFile(filePath, data);
32828
33245
  };
32829
- update(join41(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
33246
+ update(join42(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
32830
33247
  if (opts?.repoRoot) {
32831
- update(join41(opts.repoRoot, OA_DIR, USAGE_HISTORY_FILE));
33248
+ update(join42(opts.repoRoot, OA_DIR, USAGE_HISTORY_FILE));
32832
33249
  }
32833
33250
  }
32834
33251
  function loadUsageHistory(kind, repoRoot) {
32835
- const globalPath = join41(homedir9(), ".open-agents", USAGE_HISTORY_FILE);
33252
+ const globalPath = join42(homedir9(), ".open-agents", USAGE_HISTORY_FILE);
32836
33253
  const globalData = loadUsageFile(globalPath);
32837
- const localData = repoRoot ? loadUsageFile(join41(repoRoot, OA_DIR, USAGE_HISTORY_FILE)) : { records: [] };
33254
+ const localData = repoRoot ? loadUsageFile(join42(repoRoot, OA_DIR, USAGE_HISTORY_FILE)) : { records: [] };
32838
33255
  const map = /* @__PURE__ */ new Map();
32839
33256
  for (const r of globalData.records) {
32840
33257
  if (r.kind !== kind)
@@ -32865,9 +33282,9 @@ function deleteUsageRecord(kind, value, repoRoot) {
32865
33282
  saveUsageFile(filePath, data);
32866
33283
  }
32867
33284
  };
32868
- remove(join41(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
33285
+ remove(join42(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
32869
33286
  if (repoRoot) {
32870
- remove(join41(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
33287
+ remove(join42(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
32871
33288
  }
32872
33289
  }
32873
33290
  var OA_DIR, SUBDIRS, CONTEXT_FILES, PENDING_TASK_FILE, CONTEXT_SAVE_FILE, MAX_CONTEXT_ENTRIES, SKIP_DIRS, USAGE_HISTORY_FILE, MAX_HISTORY_RECORDS;
@@ -32918,7 +33335,7 @@ import * as readline from "node:readline";
32918
33335
  import { execSync as execSync25, spawn as spawn18, exec as exec2 } from "node:child_process";
32919
33336
  import { promisify as promisify5 } from "node:util";
32920
33337
  import { existsSync as existsSync32, writeFileSync as writeFileSync13, readFileSync as readFileSync23, appendFileSync as appendFileSync2, mkdirSync as mkdirSync12 } from "node:fs";
32921
- import { join as join42 } from "node:path";
33338
+ import { join as join43 } from "node:path";
32922
33339
  import { homedir as homedir10, platform } from "node:os";
32923
33340
  function detectSystemSpecs() {
32924
33341
  let totalRamGB = 0;
@@ -33959,9 +34376,9 @@ async function doSetup(config, rl) {
33959
34376
  `PARAMETER num_predict ${numPredict}`,
33960
34377
  `PARAMETER stop "<|endoftext|>"`
33961
34378
  ].join("\n");
33962
- const modelDir2 = join42(homedir10(), ".open-agents", "models");
34379
+ const modelDir2 = join43(homedir10(), ".open-agents", "models");
33963
34380
  mkdirSync12(modelDir2, { recursive: true });
33964
- const modelfilePath = join42(modelDir2, `Modelfile.${customName}`);
34381
+ const modelfilePath = join43(modelDir2, `Modelfile.${customName}`);
33965
34382
  writeFileSync13(modelfilePath, modelfileContent + "\n", "utf8");
33966
34383
  process.stdout.write(` ${c2.dim("Creating model...")} `);
33967
34384
  execSync25(`ollama create ${customName} -f ${modelfilePath}`, {
@@ -34007,7 +34424,7 @@ async function isModelAvailable(config) {
34007
34424
  }
34008
34425
  function isFirstRun() {
34009
34426
  try {
34010
- return !existsSync32(join42(homedir10(), ".open-agents", "config.json"));
34427
+ return !existsSync32(join43(homedir10(), ".open-agents", "config.json"));
34011
34428
  } catch {
34012
34429
  return true;
34013
34430
  }
@@ -34044,7 +34461,7 @@ function detectPkgManager() {
34044
34461
  return null;
34045
34462
  }
34046
34463
  function getVenvDir() {
34047
- return join42(homedir10(), ".open-agents", "venv");
34464
+ return join43(homedir10(), ".open-agents", "venv");
34048
34465
  }
34049
34466
  function hasVenvModule() {
34050
34467
  try {
@@ -34056,7 +34473,7 @@ function hasVenvModule() {
34056
34473
  }
34057
34474
  function ensureVenv(log) {
34058
34475
  const venvDir = getVenvDir();
34059
- const venvPip = join42(venvDir, "bin", "pip");
34476
+ const venvPip = join43(venvDir, "bin", "pip");
34060
34477
  if (existsSync32(venvPip))
34061
34478
  return venvDir;
34062
34479
  log("Creating Python venv for vision deps...");
@@ -34069,9 +34486,9 @@ function ensureVenv(log) {
34069
34486
  return null;
34070
34487
  }
34071
34488
  try {
34072
- mkdirSync12(join42(homedir10(), ".open-agents"), { recursive: true });
34489
+ mkdirSync12(join43(homedir10(), ".open-agents"), { recursive: true });
34073
34490
  execSync25(`python3 -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
34074
- execSync25(`"${join42(venvDir, "bin", "pip")}" install --upgrade pip`, {
34491
+ execSync25(`"${join43(venvDir, "bin", "pip")}" install --upgrade pip`, {
34075
34492
  stdio: "pipe",
34076
34493
  timeout: 6e4
34077
34494
  });
@@ -34262,11 +34679,11 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
34262
34679
  }
34263
34680
  }
34264
34681
  const venvDir = getVenvDir();
34265
- const venvBin = join42(venvDir, "bin");
34266
- const venvMoondream = join42(venvBin, "moondream-station");
34682
+ const venvBin = join43(venvDir, "bin");
34683
+ const venvMoondream = join43(venvBin, "moondream-station");
34267
34684
  const venv = ensureVenv(log);
34268
34685
  if (venv && !hasCmd("moondream-station") && !existsSync32(venvMoondream)) {
34269
- const venvPip = join42(venvBin, "pip");
34686
+ const venvPip = join43(venvBin, "pip");
34270
34687
  log("Installing moondream-station in ~/.open-agents/venv...");
34271
34688
  try {
34272
34689
  execSync25(`"${venvPip}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
@@ -34287,8 +34704,8 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
34287
34704
  }
34288
34705
  }
34289
34706
  if (venv) {
34290
- const venvPython = join42(venvBin, "python");
34291
- const venvPip2 = join42(venvBin, "pip");
34707
+ const venvPython = join43(venvBin, "python");
34708
+ const venvPip2 = join43(venvBin, "pip");
34292
34709
  let ocrStackInstalled = false;
34293
34710
  try {
34294
34711
  execSync25(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
@@ -34432,9 +34849,9 @@ async function createExpandedVariantAsync(baseModel, specs, sizeGB, kvBytesPerTo
34432
34849
  `PARAMETER num_predict ${numPredict}`,
34433
34850
  `PARAMETER stop "<|endoftext|>"`
34434
34851
  ].join("\n");
34435
- const modelDir2 = join42(homedir10(), ".open-agents", "models");
34852
+ const modelDir2 = join43(homedir10(), ".open-agents", "models");
34436
34853
  mkdirSync12(modelDir2, { recursive: true });
34437
- const modelfilePath = join42(modelDir2, `Modelfile.${customName}`);
34854
+ const modelfilePath = join43(modelDir2, `Modelfile.${customName}`);
34438
34855
  writeFileSync13(modelfilePath, modelfileContent + "\n", "utf8");
34439
34856
  await execAsync(`ollama create ${customName} -f ${modelfilePath}`, {
34440
34857
  timeout: 12e4
@@ -34509,8 +34926,8 @@ async function ensureNeovim() {
34509
34926
  const platform5 = process.platform;
34510
34927
  const arch = process.arch;
34511
34928
  if (platform5 === "linux") {
34512
- const binDir = join42(homedir10(), ".local", "bin");
34513
- const nvimDest = join42(binDir, "nvim");
34929
+ const binDir = join43(homedir10(), ".local", "bin");
34930
+ const nvimDest = join43(binDir, "nvim");
34514
34931
  try {
34515
34932
  mkdirSync12(binDir, { recursive: true });
34516
34933
  } catch {
@@ -34581,7 +34998,7 @@ async function ensureNeovim() {
34581
34998
  }
34582
34999
  function ensurePathInShellRc(binDir) {
34583
35000
  const shell = process.env.SHELL ?? "";
34584
- const rcFile = shell.includes("zsh") ? join42(homedir10(), ".zshrc") : join42(homedir10(), ".bashrc");
35001
+ const rcFile = shell.includes("zsh") ? join43(homedir10(), ".zshrc") : join43(homedir10(), ".bashrc");
34585
35002
  try {
34586
35003
  const rcContent = existsSync32(rcFile) ? readFileSync23(rcFile, "utf8") : "";
34587
35004
  if (rcContent.includes(binDir))
@@ -35353,7 +35770,7 @@ var init_drop_panel = __esm({
35353
35770
  // packages/cli/dist/tui/neovim-mode.js
35354
35771
  import { existsSync as existsSync34, unlinkSync as unlinkSync7 } from "node:fs";
35355
35772
  import { tmpdir as tmpdir8 } from "node:os";
35356
- import { join as join43 } from "node:path";
35773
+ import { join as join44 } from "node:path";
35357
35774
  import { execSync as execSync26 } from "node:child_process";
35358
35775
  function isNeovimActive() {
35359
35776
  return _state !== null && !_state.cleanedUp;
@@ -35401,7 +35818,7 @@ async function startNeovimMode(opts) {
35401
35818
  );
35402
35819
  } catch {
35403
35820
  }
35404
- const socketPath = join43(tmpdir8(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
35821
+ const socketPath = join44(tmpdir8(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
35405
35822
  try {
35406
35823
  if (existsSync34(socketPath))
35407
35824
  unlinkSync7(socketPath);
@@ -35753,7 +36170,7 @@ __export(voice_exports, {
35753
36170
  resetNarrationContext: () => resetNarrationContext
35754
36171
  });
35755
36172
  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";
35756
- import { join as join44 } from "node:path";
36173
+ import { join as join45 } from "node:path";
35757
36174
  import { homedir as homedir11, tmpdir as tmpdir9, platform as platform2 } from "node:os";
35758
36175
  import { execSync as execSync27, spawn as nodeSpawn } from "node:child_process";
35759
36176
  import { createRequire } from "node:module";
@@ -35775,34 +36192,34 @@ function listVoiceModels() {
35775
36192
  }));
35776
36193
  }
35777
36194
  function voiceDir() {
35778
- return join44(homedir11(), ".open-agents", "voice");
36195
+ return join45(homedir11(), ".open-agents", "voice");
35779
36196
  }
35780
36197
  function modelsDir() {
35781
- return join44(voiceDir(), "models");
36198
+ return join45(voiceDir(), "models");
35782
36199
  }
35783
36200
  function modelDir(id) {
35784
- return join44(modelsDir(), id);
36201
+ return join45(modelsDir(), id);
35785
36202
  }
35786
36203
  function modelOnnxPath(id) {
35787
- return join44(modelDir(id), "model.onnx");
36204
+ return join45(modelDir(id), "model.onnx");
35788
36205
  }
35789
36206
  function modelConfigPath(id) {
35790
- return join44(modelDir(id), "config.json");
36207
+ return join45(modelDir(id), "config.json");
35791
36208
  }
35792
36209
  function luxttsVenvDir() {
35793
- return join44(voiceDir(), "luxtts-venv");
36210
+ return join45(voiceDir(), "luxtts-venv");
35794
36211
  }
35795
36212
  function luxttsVenvPy() {
35796
- return platform2() === "win32" ? join44(luxttsVenvDir(), "Scripts", "python.exe") : join44(luxttsVenvDir(), "bin", "python3");
36213
+ return platform2() === "win32" ? join45(luxttsVenvDir(), "Scripts", "python.exe") : join45(luxttsVenvDir(), "bin", "python3");
35797
36214
  }
35798
36215
  function luxttsRepoDir() {
35799
- return join44(voiceDir(), "LuxTTS");
36216
+ return join45(voiceDir(), "LuxTTS");
35800
36217
  }
35801
36218
  function luxttsCloneRefsDir() {
35802
- return join44(voiceDir(), "clone-refs");
36219
+ return join45(voiceDir(), "clone-refs");
35803
36220
  }
35804
36221
  function luxttsInferScript() {
35805
- return join44(voiceDir(), "luxtts-infer.py");
36222
+ return join45(voiceDir(), "luxtts-infer.py");
35806
36223
  }
35807
36224
  function emotionToPitchBias(emotion, stark = false, autist = false) {
35808
36225
  if (autist)
@@ -36610,7 +37027,7 @@ var init_voice = __esm({
36610
37027
  const refsDir = luxttsCloneRefsDir();
36611
37028
  const targets = ["glados", "overwatch"];
36612
37029
  for (const modelId of targets) {
36613
- const refFile = join44(refsDir, `${modelId}-ref.wav`);
37030
+ const refFile = join45(refsDir, `${modelId}-ref.wav`);
36614
37031
  if (existsSync35(refFile))
36615
37032
  continue;
36616
37033
  try {
@@ -36690,7 +37107,7 @@ var init_voice = __esm({
36690
37107
  }
36691
37108
  p = p.replace(/\\ /g, " ");
36692
37109
  if (p.startsWith("~/") || p === "~") {
36693
- p = join44(homedir11(), p.slice(1));
37110
+ p = join45(homedir11(), p.slice(1));
36694
37111
  }
36695
37112
  if (!existsSync35(p)) {
36696
37113
  return `File not found: ${p}
@@ -36704,7 +37121,7 @@ var init_voice = __esm({
36704
37121
  const srcName = (audioPath.split("/").pop() ?? "clone").replace(/\.[^.]+$/, "").replace(/[^a-zA-Z0-9_-]/g, "-");
36705
37122
  const ts = Date.now().toString(36);
36706
37123
  const destFilename = `clone-${srcName}-${ts}.${ext}`;
36707
- const destPath = join44(refsDir, destFilename);
37124
+ const destPath = join45(refsDir, destFilename);
36708
37125
  try {
36709
37126
  const data = readFileSync24(audioPath);
36710
37127
  writeFileSync14(destPath, data);
@@ -36749,7 +37166,7 @@ var init_voice = __esm({
36749
37166
  const refsDir = luxttsCloneRefsDir();
36750
37167
  if (!existsSync35(refsDir))
36751
37168
  mkdirSync13(refsDir, { recursive: true });
36752
- const destPath = join44(refsDir, `${sourceModelId}-ref.wav`);
37169
+ const destPath = join45(refsDir, `${sourceModelId}-ref.wav`);
36753
37170
  const sampleRate = this.config?.audio?.sample_rate ?? 22050;
36754
37171
  this.writeWav(audioData, sampleRate, destPath);
36755
37172
  this.luxttsCloneRef = destPath;
@@ -36765,7 +37182,7 @@ var init_voice = __esm({
36765
37182
  // -------------------------------------------------------------------------
36766
37183
  /** Metadata file for friendly names of clone refs */
36767
37184
  static cloneMetaFile() {
36768
- return join44(luxttsCloneRefsDir(), "meta.json");
37185
+ return join45(luxttsCloneRefsDir(), "meta.json");
36769
37186
  }
36770
37187
  loadCloneMeta() {
36771
37188
  const p = _VoiceEngine.cloneMetaFile();
@@ -36799,7 +37216,7 @@ var init_voice = __esm({
36799
37216
  return _VoiceEngine.AUDIO_EXTS.has(ext);
36800
37217
  });
36801
37218
  return files.map((f) => {
36802
- const p = join44(dir, f);
37219
+ const p = join45(dir, f);
36803
37220
  let size = 0;
36804
37221
  try {
36805
37222
  size = statSync12(p).size;
@@ -36816,7 +37233,7 @@ var init_voice = __esm({
36816
37233
  }
36817
37234
  /** Delete a clone reference file by filename. Returns true if deleted. */
36818
37235
  deleteCloneRef(filename) {
36819
- const p = join44(luxttsCloneRefsDir(), filename);
37236
+ const p = join45(luxttsCloneRefsDir(), filename);
36820
37237
  if (!existsSync35(p))
36821
37238
  return false;
36822
37239
  try {
@@ -36841,7 +37258,7 @@ var init_voice = __esm({
36841
37258
  }
36842
37259
  /** Set the active clone reference by filename. */
36843
37260
  setActiveCloneRef(filename) {
36844
- const p = join44(luxttsCloneRefsDir(), filename);
37261
+ const p = join45(luxttsCloneRefsDir(), filename);
36845
37262
  if (!existsSync35(p))
36846
37263
  return `File not found: ${filename}`;
36847
37264
  this.luxttsCloneRef = p;
@@ -37127,7 +37544,7 @@ var init_voice = __esm({
37127
37544
  }
37128
37545
  this.onPCMOutput(Buffer.from(int16.buffer), sampleRate);
37129
37546
  }
37130
- const wavPath = join44(tmpdir9(), `oa-voice-${Date.now()}.wav`);
37547
+ const wavPath = join45(tmpdir9(), `oa-voice-${Date.now()}.wav`);
37131
37548
  this.writeWav(audioData, sampleRate, wavPath);
37132
37549
  await this.playWav(wavPath);
37133
37550
  try {
@@ -37470,7 +37887,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
37470
37887
  const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
37471
37888
  const mlxVoice = model.mlxVoice ?? "af_heart";
37472
37889
  const mlxLangCode = model.mlxLangCode ?? "a";
37473
- const wavPath = join44(tmpdir9(), `oa-mlx-${Date.now()}.wav`);
37890
+ const wavPath = join45(tmpdir9(), `oa-mlx-${Date.now()}.wav`);
37474
37891
  const pyScript = [
37475
37892
  "import sys, json",
37476
37893
  "from mlx_audio.tts import generate as tts_gen",
@@ -37538,7 +37955,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
37538
37955
  const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
37539
37956
  const mlxVoice = model.mlxVoice ?? "af_heart";
37540
37957
  const mlxLangCode = model.mlxLangCode ?? "a";
37541
- const wavPath = join44(tmpdir9(), `oa-mlx-buf-${Date.now()}.wav`);
37958
+ const wavPath = join45(tmpdir9(), `oa-mlx-buf-${Date.now()}.wav`);
37542
37959
  const pyScript = [
37543
37960
  "import sys, json",
37544
37961
  "from mlx_audio.tts import generate as tts_gen",
@@ -37649,7 +38066,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
37649
38066
  }
37650
38067
  }
37651
38068
  const repoDir = luxttsRepoDir();
37652
- if (!existsSync35(join44(repoDir, "zipvoice", "luxvoice.py"))) {
38069
+ if (!existsSync35(join45(repoDir, "zipvoice", "luxvoice.py"))) {
37653
38070
  renderInfo(" Cloning LuxTTS repository...");
37654
38071
  try {
37655
38072
  if (existsSync35(repoDir)) {
@@ -37698,7 +38115,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
37698
38115
  if (!existsSync35(refsDir))
37699
38116
  return;
37700
38117
  for (const name of ["custom-clone.wav", "custom-clone.mp3", "glados-ref.wav", "overwatch-ref.wav"]) {
37701
- const p = join44(refsDir, name);
38118
+ const p = join45(refsDir, name);
37702
38119
  if (existsSync35(p)) {
37703
38120
  this.luxttsCloneRef = p;
37704
38121
  return;
@@ -37895,7 +38312,7 @@ if __name__ == '__main__':
37895
38312
  const ready = await this.ensureLuxttsDaemon();
37896
38313
  if (!ready)
37897
38314
  return;
37898
- const wavPath = join44(tmpdir9(), `oa-luxtts-${Date.now()}.wav`);
38315
+ const wavPath = join45(tmpdir9(), `oa-luxtts-${Date.now()}.wav`);
37899
38316
  try {
37900
38317
  await this.luxttsRequest({
37901
38318
  action: "synthesize",
@@ -37969,7 +38386,7 @@ if __name__ == '__main__':
37969
38386
  const ready = await this.ensureLuxttsDaemon();
37970
38387
  if (!ready)
37971
38388
  return null;
37972
- const wavPath = join44(tmpdir9(), `oa-luxtts-buf-${Date.now()}.wav`);
38389
+ const wavPath = join45(tmpdir9(), `oa-luxtts-buf-${Date.now()}.wav`);
37973
38390
  try {
37974
38391
  await this.luxttsRequest({
37975
38392
  action: "synthesize",
@@ -37999,7 +38416,7 @@ if __name__ == '__main__':
37999
38416
  return;
38000
38417
  const arch = process.arch;
38001
38418
  mkdirSync13(voiceDir(), { recursive: true });
38002
- const pkgPath = join44(voiceDir(), "package.json");
38419
+ const pkgPath = join45(voiceDir(), "package.json");
38003
38420
  const expectedDeps = {
38004
38421
  "onnxruntime-node": "^1.21.0",
38005
38422
  "phonemizer": "^1.2.1"
@@ -38021,17 +38438,17 @@ if __name__ == '__main__':
38021
38438
  dependencies: expectedDeps
38022
38439
  }, null, 2));
38023
38440
  }
38024
- const voiceRequire = createRequire(join44(voiceDir(), "index.js"));
38441
+ const voiceRequire = createRequire(join45(voiceDir(), "index.js"));
38025
38442
  const probeOnnx = () => {
38026
38443
  try {
38027
- 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: join44(voiceDir(), "node_modules") } });
38444
+ 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: join45(voiceDir(), "node_modules") } });
38028
38445
  const output = result.toString().trim();
38029
38446
  return output === "OK";
38030
38447
  } catch {
38031
38448
  return false;
38032
38449
  }
38033
38450
  };
38034
- const onnxNodeModules = join44(voiceDir(), "node_modules", "onnxruntime-node");
38451
+ const onnxNodeModules = join45(voiceDir(), "node_modules", "onnxruntime-node");
38035
38452
  const onnxInstalled = existsSync35(onnxNodeModules);
38036
38453
  if (onnxInstalled && !probeOnnx()) {
38037
38454
  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.`);
@@ -40375,8 +40792,8 @@ async function handlePeerEndpoint(peerId, authKey, ctx, local) {
40375
40792
  if (models.length > 0) {
40376
40793
  try {
40377
40794
  const { writeFileSync: writeFileSync20, mkdirSync: mkdirSync21 } = await import("node:fs");
40378
- const { join: join58, dirname: dirname20 } = await import("node:path");
40379
- const cachePath = join58(ctx.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
40795
+ const { join: join59, dirname: dirname20 } = await import("node:path");
40796
+ const cachePath = join59(ctx.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
40380
40797
  mkdirSync21(dirname20(cachePath), { recursive: true });
40381
40798
  writeFileSync20(cachePath, JSON.stringify({
40382
40799
  peerId,
@@ -40577,14 +40994,14 @@ async function handleUpdate(subcommand, ctx) {
40577
40994
  try {
40578
40995
  const { createRequire: createRequire4 } = await import("node:module");
40579
40996
  const { fileURLToPath: fileURLToPath14 } = await import("node:url");
40580
- const { dirname: dirname20, join: join58 } = await import("node:path");
40997
+ const { dirname: dirname20, join: join59 } = await import("node:path");
40581
40998
  const { existsSync: existsSync45 } = await import("node:fs");
40582
40999
  const req = createRequire4(import.meta.url);
40583
41000
  const thisDir = dirname20(fileURLToPath14(import.meta.url));
40584
41001
  const candidates = [
40585
- join58(thisDir, "..", "package.json"),
40586
- join58(thisDir, "..", "..", "package.json"),
40587
- join58(thisDir, "..", "..", "..", "package.json")
41002
+ join59(thisDir, "..", "package.json"),
41003
+ join59(thisDir, "..", "..", "package.json"),
41004
+ join59(thisDir, "..", "..", "..", "package.json")
40588
41005
  ];
40589
41006
  for (const pkgPath of candidates) {
40590
41007
  if (existsSync45(pkgPath)) {
@@ -41302,7 +41719,7 @@ var init_commands = __esm({
41302
41719
 
41303
41720
  // packages/cli/dist/tui/project-context.js
41304
41721
  import { existsSync as existsSync36, readFileSync as readFileSync25, readdirSync as readdirSync10 } from "node:fs";
41305
- import { join as join45, basename as basename10 } from "node:path";
41722
+ import { join as join46, basename as basename10 } from "node:path";
41306
41723
  import { execSync as execSync28 } from "node:child_process";
41307
41724
  import { homedir as homedir12, platform as platform3, release } from "node:os";
41308
41725
  function getModelTier(modelName) {
@@ -41337,7 +41754,7 @@ function loadProjectMap(repoRoot) {
41337
41754
  if (!hasOaDirectory(repoRoot)) {
41338
41755
  initOaDirectory(repoRoot);
41339
41756
  }
41340
- const mapPath = join45(repoRoot, OA_DIR, "context", "project-map.md");
41757
+ const mapPath = join46(repoRoot, OA_DIR, "context", "project-map.md");
41341
41758
  if (existsSync36(mapPath)) {
41342
41759
  try {
41343
41760
  const content = readFileSync25(mapPath, "utf-8");
@@ -41381,17 +41798,17 @@ ${log}`);
41381
41798
  }
41382
41799
  function loadMemoryContext(repoRoot) {
41383
41800
  const sections = [];
41384
- const oaMemDir = join45(repoRoot, OA_DIR, "memory");
41801
+ const oaMemDir = join46(repoRoot, OA_DIR, "memory");
41385
41802
  const oaEntries = loadMemoryDir(oaMemDir, "project");
41386
41803
  if (oaEntries)
41387
41804
  sections.push(oaEntries);
41388
- const legacyMemDir = join45(repoRoot, ".open-agents", "memory");
41805
+ const legacyMemDir = join46(repoRoot, ".open-agents", "memory");
41389
41806
  if (legacyMemDir !== oaMemDir && existsSync36(legacyMemDir)) {
41390
41807
  const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
41391
41808
  if (legacyEntries)
41392
41809
  sections.push(legacyEntries);
41393
41810
  }
41394
- const globalMemDir = join45(homedir12(), ".open-agents", "memory");
41811
+ const globalMemDir = join46(homedir12(), ".open-agents", "memory");
41395
41812
  const globalEntries = loadMemoryDir(globalMemDir, "global");
41396
41813
  if (globalEntries)
41397
41814
  sections.push(globalEntries);
@@ -41405,7 +41822,7 @@ function loadMemoryDir(memDir, scope) {
41405
41822
  const files = readdirSync10(memDir).filter((f) => f.endsWith(".json"));
41406
41823
  for (const file of files.slice(0, 10)) {
41407
41824
  try {
41408
- const raw = readFileSync25(join45(memDir, file), "utf-8");
41825
+ const raw = readFileSync25(join46(memDir, file), "utf-8");
41409
41826
  const entries = JSON.parse(raw);
41410
41827
  const topic = basename10(file, ".json");
41411
41828
  const keys = Object.keys(entries);
@@ -42429,9 +42846,9 @@ var init_carousel = __esm({
42429
42846
 
42430
42847
  // packages/cli/dist/tui/carousel-descriptors.js
42431
42848
  import { existsSync as existsSync37, readFileSync as readFileSync26, writeFileSync as writeFileSync15, mkdirSync as mkdirSync14, readdirSync as readdirSync11 } from "node:fs";
42432
- import { join as join46, basename as basename11 } from "node:path";
42849
+ import { join as join47, basename as basename11 } from "node:path";
42433
42850
  function loadToolProfile(repoRoot) {
42434
- const filePath = join46(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
42851
+ const filePath = join47(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
42435
42852
  try {
42436
42853
  if (!existsSync37(filePath))
42437
42854
  return null;
@@ -42441,9 +42858,9 @@ function loadToolProfile(repoRoot) {
42441
42858
  }
42442
42859
  }
42443
42860
  function saveToolProfile(repoRoot, profile) {
42444
- const contextDir = join46(repoRoot, OA_DIR, "context");
42861
+ const contextDir = join47(repoRoot, OA_DIR, "context");
42445
42862
  mkdirSync14(contextDir, { recursive: true });
42446
- writeFileSync15(join46(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
42863
+ writeFileSync15(join47(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
42447
42864
  }
42448
42865
  function categorizeToolCall(toolName) {
42449
42866
  for (const cat of TOOL_CATEGORIES) {
@@ -42501,7 +42918,7 @@ function weightedColor(profile) {
42501
42918
  return selectedCat.colors[Math.floor(Math.random() * selectedCat.colors.length)];
42502
42919
  }
42503
42920
  function loadCachedDescriptors(repoRoot) {
42504
- const filePath = join46(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
42921
+ const filePath = join47(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
42505
42922
  try {
42506
42923
  if (!existsSync37(filePath))
42507
42924
  return null;
@@ -42512,14 +42929,14 @@ function loadCachedDescriptors(repoRoot) {
42512
42929
  }
42513
42930
  }
42514
42931
  function saveCachedDescriptors(repoRoot, phrases, sourceHash) {
42515
- const contextDir = join46(repoRoot, OA_DIR, "context");
42932
+ const contextDir = join47(repoRoot, OA_DIR, "context");
42516
42933
  mkdirSync14(contextDir, { recursive: true });
42517
42934
  const cached = {
42518
42935
  phrases,
42519
42936
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
42520
42937
  sourceHash
42521
42938
  };
42522
- writeFileSync15(join46(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
42939
+ writeFileSync15(join47(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
42523
42940
  }
42524
42941
  function generateDescriptors(repoRoot) {
42525
42942
  const profile = loadToolProfile(repoRoot);
@@ -42567,7 +42984,7 @@ function generateDescriptors(repoRoot) {
42567
42984
  return phrases;
42568
42985
  }
42569
42986
  function extractFromPackageJson(repoRoot, tags) {
42570
- const pkgPath = join46(repoRoot, "package.json");
42987
+ const pkgPath = join47(repoRoot, "package.json");
42571
42988
  try {
42572
42989
  if (!existsSync37(pkgPath))
42573
42990
  return;
@@ -42615,7 +43032,7 @@ function extractFromManifests(repoRoot, tags) {
42615
43032
  { file: ".github/workflows", tag: "ci/cd" }
42616
43033
  ];
42617
43034
  for (const check of manifestChecks) {
42618
- if (existsSync37(join46(repoRoot, check.file))) {
43035
+ if (existsSync37(join47(repoRoot, check.file))) {
42619
43036
  tags.push(check.tag);
42620
43037
  }
42621
43038
  }
@@ -42637,7 +43054,7 @@ function extractFromSessions(repoRoot, tags) {
42637
43054
  }
42638
43055
  }
42639
43056
  function extractFromMemory(repoRoot, tags) {
42640
- const memoryDir = join46(repoRoot, OA_DIR, "memory");
43057
+ const memoryDir = join47(repoRoot, OA_DIR, "memory");
42641
43058
  try {
42642
43059
  if (!existsSync37(memoryDir))
42643
43060
  return;
@@ -42646,7 +43063,7 @@ function extractFromMemory(repoRoot, tags) {
42646
43063
  const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
42647
43064
  tags.push(topic);
42648
43065
  try {
42649
- const data = JSON.parse(readFileSync26(join46(memoryDir, file), "utf-8"));
43066
+ const data = JSON.parse(readFileSync26(join47(memoryDir, file), "utf-8"));
42650
43067
  if (data && typeof data === "object") {
42651
43068
  const keys = Object.keys(data).slice(0, 3);
42652
43069
  for (const key of keys) {
@@ -43269,10 +43686,10 @@ var init_stream_renderer = __esm({
43269
43686
 
43270
43687
  // packages/cli/dist/tui/edit-history.js
43271
43688
  import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync15 } from "node:fs";
43272
- import { join as join47 } from "node:path";
43689
+ import { join as join48 } from "node:path";
43273
43690
  function createEditHistoryLogger(repoRoot, sessionId) {
43274
- const historyDir = join47(repoRoot, ".oa", "history");
43275
- const logPath = join47(historyDir, "edits.jsonl");
43691
+ const historyDir = join48(repoRoot, ".oa", "history");
43692
+ const logPath = join48(historyDir, "edits.jsonl");
43276
43693
  try {
43277
43694
  mkdirSync15(historyDir, { recursive: true });
43278
43695
  } catch {
@@ -43384,12 +43801,12 @@ var init_edit_history = __esm({
43384
43801
 
43385
43802
  // packages/cli/dist/tui/promptLoader.js
43386
43803
  import { readFileSync as readFileSync27, existsSync as existsSync38 } from "node:fs";
43387
- import { join as join48, dirname as dirname17 } from "node:path";
43804
+ import { join as join49, dirname as dirname17 } from "node:path";
43388
43805
  import { fileURLToPath as fileURLToPath11 } from "node:url";
43389
43806
  function loadPrompt3(promptPath, vars) {
43390
43807
  let content = cache3.get(promptPath);
43391
43808
  if (content === void 0) {
43392
- const fullPath = join48(PROMPTS_DIR3, promptPath);
43809
+ const fullPath = join49(PROMPTS_DIR3, promptPath);
43393
43810
  if (!existsSync38(fullPath)) {
43394
43811
  throw new Error(`Prompt file not found: ${fullPath}`);
43395
43812
  }
@@ -43406,8 +43823,8 @@ var init_promptLoader3 = __esm({
43406
43823
  "use strict";
43407
43824
  __filename3 = fileURLToPath11(import.meta.url);
43408
43825
  __dirname6 = dirname17(__filename3);
43409
- devPath2 = join48(__dirname6, "..", "..", "prompts");
43410
- publishedPath2 = join48(__dirname6, "..", "prompts");
43826
+ devPath2 = join49(__dirname6, "..", "..", "prompts");
43827
+ publishedPath2 = join49(__dirname6, "..", "prompts");
43411
43828
  PROMPTS_DIR3 = existsSync38(devPath2) ? devPath2 : publishedPath2;
43412
43829
  cache3 = /* @__PURE__ */ new Map();
43413
43830
  }
@@ -43415,10 +43832,10 @@ var init_promptLoader3 = __esm({
43415
43832
 
43416
43833
  // packages/cli/dist/tui/dream-engine.js
43417
43834
  import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync16, readFileSync as readFileSync28, existsSync as existsSync39, cpSync, rmSync, readdirSync as readdirSync12 } from "node:fs";
43418
- import { join as join49, basename as basename12 } from "node:path";
43835
+ import { join as join50, basename as basename12 } from "node:path";
43419
43836
  import { execSync as execSync29 } from "node:child_process";
43420
43837
  function loadAutoresearchMemory(repoRoot) {
43421
- const memoryPath = join49(repoRoot, ".oa", "memory", "autoresearch.json");
43838
+ const memoryPath = join50(repoRoot, ".oa", "memory", "autoresearch.json");
43422
43839
  if (!existsSync39(memoryPath))
43423
43840
  return "";
43424
43841
  try {
@@ -43612,12 +44029,12 @@ var init_dream_engine = __esm({
43612
44029
  const content = String(args["content"] ?? "");
43613
44030
  if (!rawPath)
43614
44031
  return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
43615
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join49(this.autoresearchDir, basename12(rawPath)) : join49(this.autoresearchDir, rawPath);
44032
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join50(this.autoresearchDir, basename12(rawPath)) : join50(this.autoresearchDir, rawPath);
43616
44033
  if (!targetPath.startsWith(this.autoresearchDir)) {
43617
44034
  return { success: false, output: "", error: "Autoresearch mode: writes are confined to .oa/autoresearch/", durationMs: Date.now() - start };
43618
44035
  }
43619
44036
  try {
43620
- const dir = join49(targetPath, "..");
44037
+ const dir = join50(targetPath, "..");
43621
44038
  mkdirSync16(dir, { recursive: true });
43622
44039
  writeFileSync16(targetPath, content, "utf-8");
43623
44040
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
@@ -43647,7 +44064,7 @@ var init_dream_engine = __esm({
43647
44064
  const rawPath = String(args["path"] ?? "");
43648
44065
  const oldStr = String(args["old_string"] ?? "");
43649
44066
  const newStr = String(args["new_string"] ?? "");
43650
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join49(this.autoresearchDir, basename12(rawPath)) : join49(this.autoresearchDir, rawPath);
44067
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join50(this.autoresearchDir, basename12(rawPath)) : join50(this.autoresearchDir, rawPath);
43651
44068
  if (!targetPath.startsWith(this.autoresearchDir)) {
43652
44069
  return { success: false, output: "", error: "Autoresearch mode: edits are confined to .oa/autoresearch/", durationMs: Date.now() - start };
43653
44070
  }
@@ -43701,12 +44118,12 @@ var init_dream_engine = __esm({
43701
44118
  const content = String(args["content"] ?? "");
43702
44119
  if (!rawPath)
43703
44120
  return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
43704
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join49(this.dreamsDir, basename12(rawPath)) : join49(this.dreamsDir, rawPath);
44121
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join50(this.dreamsDir, basename12(rawPath)) : join50(this.dreamsDir, rawPath);
43705
44122
  if (!targetPath.startsWith(this.dreamsDir)) {
43706
44123
  return { success: false, output: "", error: "Dream mode: writes are confined to .oa/dreams/", durationMs: Date.now() - start };
43707
44124
  }
43708
44125
  try {
43709
- const dir = join49(targetPath, "..");
44126
+ const dir = join50(targetPath, "..");
43710
44127
  mkdirSync16(dir, { recursive: true });
43711
44128
  writeFileSync16(targetPath, content, "utf-8");
43712
44129
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
@@ -43736,7 +44153,7 @@ var init_dream_engine = __esm({
43736
44153
  const rawPath = String(args["path"] ?? "");
43737
44154
  const oldStr = String(args["old_string"] ?? "");
43738
44155
  const newStr = String(args["new_string"] ?? "");
43739
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join49(this.dreamsDir, basename12(rawPath)) : join49(this.dreamsDir, rawPath);
44156
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join50(this.dreamsDir, basename12(rawPath)) : join50(this.dreamsDir, rawPath);
43740
44157
  if (!targetPath.startsWith(this.dreamsDir)) {
43741
44158
  return { success: false, output: "", error: "Dream mode: edits are confined to .oa/dreams/", durationMs: Date.now() - start };
43742
44159
  }
@@ -43803,7 +44220,7 @@ var init_dream_engine = __esm({
43803
44220
  constructor(config, repoRoot) {
43804
44221
  this.config = config;
43805
44222
  this.repoRoot = repoRoot;
43806
- this.dreamsDir = join49(repoRoot, ".oa", "dreams");
44223
+ this.dreamsDir = join50(repoRoot, ".oa", "dreams");
43807
44224
  this.state = {
43808
44225
  mode: "default",
43809
44226
  active: false,
@@ -43887,7 +44304,7 @@ ${result.summary}`;
43887
44304
  if (mode !== "default" || cycle === totalCycles) {
43888
44305
  renderDreamContraction(cycle);
43889
44306
  const cycleSummary = this.buildCycleSummary(cycle, previousFindings);
43890
- const summaryPath = join49(this.dreamsDir, `cycle-${cycle}-summary.md`);
44307
+ const summaryPath = join50(this.dreamsDir, `cycle-${cycle}-summary.md`);
43891
44308
  writeFileSync16(summaryPath, cycleSummary, "utf-8");
43892
44309
  }
43893
44310
  if (mode === "lucid" && !this.abortController.signal.aborted) {
@@ -44100,7 +44517,7 @@ After synthesis, call task_complete with the final prioritized summary.`, toolMo
44100
44517
  }
44101
44518
  /** Build role-specific tool sets for swarm agents */
44102
44519
  buildSwarmTools(role, _workspace) {
44103
- const autoresearchDir = join49(this.repoRoot, ".oa", "autoresearch");
44520
+ const autoresearchDir = join50(this.repoRoot, ".oa", "autoresearch");
44104
44521
  const taskComplete = this.createSwarmTaskCompleteTool(role);
44105
44522
  switch (role) {
44106
44523
  case "researcher": {
@@ -44464,7 +44881,7 @@ INSTRUCTIONS:
44464
44881
  2. Summarize the key learnings and next steps
44465
44882
 
44466
44883
  Call task_complete with a human-readable summary of the autoresearch session.`, workspace, onEvent);
44467
- const reportPath = join49(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
44884
+ const reportPath = join50(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
44468
44885
  const report = `# Autoresearch Swarm Report \u2014 Cycle ${cycleNum}
44469
44886
 
44470
44887
  **Date**: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
@@ -44553,7 +44970,7 @@ ${summaryResult}
44553
44970
  }
44554
44971
  /** Save workspace backup for lucid mode */
44555
44972
  saveVersionCheckpoint(cycle) {
44556
- const checkpointDir = join49(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
44973
+ const checkpointDir = join50(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
44557
44974
  try {
44558
44975
  mkdirSync16(checkpointDir, { recursive: true });
44559
44976
  try {
@@ -44572,10 +44989,10 @@ ${summaryResult}
44572
44989
  encoding: "utf-8",
44573
44990
  timeout: 5e3
44574
44991
  }).trim();
44575
- writeFileSync16(join49(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
44576
- writeFileSync16(join49(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
44577
- writeFileSync16(join49(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
44578
- writeFileSync16(join49(checkpointDir, "checkpoint.json"), JSON.stringify({
44992
+ writeFileSync16(join50(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
44993
+ writeFileSync16(join50(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
44994
+ writeFileSync16(join50(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
44995
+ writeFileSync16(join50(checkpointDir, "checkpoint.json"), JSON.stringify({
44579
44996
  cycle,
44580
44997
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
44581
44998
  gitHash,
@@ -44583,7 +45000,7 @@ ${summaryResult}
44583
45000
  }, null, 2), "utf-8");
44584
45001
  renderInfo(`Checkpoint saved: cycle ${cycle} (${gitHash.slice(0, 8)})`);
44585
45002
  } catch {
44586
- writeFileSync16(join49(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
45003
+ writeFileSync16(join50(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
44587
45004
  renderInfo(`Checkpoint saved: cycle ${cycle} (no git)`);
44588
45005
  }
44589
45006
  } catch (err) {
@@ -44641,14 +45058,14 @@ ${files.map((f) => `- [\`${f}\`](./${f})`).join("\n")}
44641
45058
  ---
44642
45059
  *Auto-generated by open-agents dream engine*
44643
45060
  `;
44644
- writeFileSync16(join49(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
45061
+ writeFileSync16(join50(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
44645
45062
  } catch {
44646
45063
  }
44647
45064
  }
44648
45065
  /** Save dream state for resume/inspection */
44649
45066
  saveDreamState() {
44650
45067
  try {
44651
- writeFileSync16(join49(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
45068
+ writeFileSync16(join50(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
44652
45069
  } catch {
44653
45070
  }
44654
45071
  }
@@ -45023,7 +45440,7 @@ var init_bless_engine = __esm({
45023
45440
 
45024
45441
  // packages/cli/dist/tui/dmn-engine.js
45025
45442
  import { existsSync as existsSync40, readFileSync as readFileSync29, writeFileSync as writeFileSync17, mkdirSync as mkdirSync17, readdirSync as readdirSync13, unlinkSync as unlinkSync9 } from "node:fs";
45026
- import { join as join50, basename as basename13 } from "node:path";
45443
+ import { join as join51, basename as basename13 } from "node:path";
45027
45444
  function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
45028
45445
  const competenceReport = competence.length > 0 ? competence.map((c3) => {
45029
45446
  const rate = c3.attempts > 0 ? Math.round(c3.successes / c3.attempts * 100) : 0;
@@ -45136,8 +45553,8 @@ var init_dmn_engine = __esm({
45136
45553
  constructor(config, repoRoot) {
45137
45554
  this.config = config;
45138
45555
  this.repoRoot = repoRoot;
45139
- this.stateDir = join50(repoRoot, ".oa", "dmn");
45140
- this.historyDir = join50(repoRoot, ".oa", "dmn", "cycles");
45556
+ this.stateDir = join51(repoRoot, ".oa", "dmn");
45557
+ this.historyDir = join51(repoRoot, ".oa", "dmn", "cycles");
45141
45558
  mkdirSync17(this.historyDir, { recursive: true });
45142
45559
  this.loadState();
45143
45560
  }
@@ -45727,8 +46144,8 @@ OUTPUT: Call task_complete with JSON:
45727
46144
  async gatherMemoryTopics() {
45728
46145
  const topics = [];
45729
46146
  const dirs = [
45730
- join50(this.repoRoot, ".oa", "memory"),
45731
- join50(this.repoRoot, ".open-agents", "memory")
46147
+ join51(this.repoRoot, ".oa", "memory"),
46148
+ join51(this.repoRoot, ".open-agents", "memory")
45732
46149
  ];
45733
46150
  for (const dir of dirs) {
45734
46151
  if (!existsSync40(dir))
@@ -45747,7 +46164,7 @@ OUTPUT: Call task_complete with JSON:
45747
46164
  }
45748
46165
  // ── State persistence ─────────────────────────────────────────────────
45749
46166
  loadState() {
45750
- const path = join50(this.stateDir, "state.json");
46167
+ const path = join51(this.stateDir, "state.json");
45751
46168
  if (existsSync40(path)) {
45752
46169
  try {
45753
46170
  this.state = JSON.parse(readFileSync29(path, "utf-8"));
@@ -45757,19 +46174,19 @@ OUTPUT: Call task_complete with JSON:
45757
46174
  }
45758
46175
  saveState() {
45759
46176
  try {
45760
- writeFileSync17(join50(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
46177
+ writeFileSync17(join51(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
45761
46178
  } catch {
45762
46179
  }
45763
46180
  }
45764
46181
  saveCycleResult(result) {
45765
46182
  try {
45766
46183
  const filename = `cycle-${result.cycleNumber}-${Date.now()}.json`;
45767
- writeFileSync17(join50(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
46184
+ writeFileSync17(join51(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
45768
46185
  const files = readdirSync13(this.historyDir).filter((f) => f.startsWith("cycle-") && f.endsWith(".json")).sort();
45769
46186
  if (files.length > 50) {
45770
46187
  for (const old of files.slice(0, files.length - 50)) {
45771
46188
  try {
45772
- unlinkSync9(join50(this.historyDir, old));
46189
+ unlinkSync9(join51(this.historyDir, old));
45773
46190
  } catch {
45774
46191
  }
45775
46192
  }
@@ -45783,7 +46200,7 @@ OUTPUT: Call task_complete with JSON:
45783
46200
 
45784
46201
  // packages/cli/dist/tui/snr-engine.js
45785
46202
  import { existsSync as existsSync41, readdirSync as readdirSync14, readFileSync as readFileSync30 } from "node:fs";
45786
- import { join as join51, basename as basename14 } from "node:path";
46203
+ import { join as join52, basename as basename14 } from "node:path";
45787
46204
  function computeDPrime(signalScores, noiseScores) {
45788
46205
  if (signalScores.length === 0 || noiseScores.length === 0)
45789
46206
  return 0;
@@ -46023,8 +46440,8 @@ Call task_complete with the JSON array when done.`, onEvent)
46023
46440
  loadMemoryEntries(topics) {
46024
46441
  const entries = [];
46025
46442
  const dirs = [
46026
- join51(this.repoRoot, ".oa", "memory"),
46027
- join51(this.repoRoot, ".open-agents", "memory")
46443
+ join52(this.repoRoot, ".oa", "memory"),
46444
+ join52(this.repoRoot, ".open-agents", "memory")
46028
46445
  ];
46029
46446
  for (const dir of dirs) {
46030
46447
  if (!existsSync41(dir))
@@ -46036,7 +46453,7 @@ Call task_complete with the JSON array when done.`, onEvent)
46036
46453
  if (topics.length > 0 && !topics.includes(topic))
46037
46454
  continue;
46038
46455
  try {
46039
- const data = JSON.parse(readFileSync30(join51(dir, f), "utf-8"));
46456
+ const data = JSON.parse(readFileSync30(join52(dir, f), "utf-8"));
46040
46457
  for (const [key, val] of Object.entries(data)) {
46041
46458
  const value = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
46042
46459
  entries.push({ topic, key, value });
@@ -46604,7 +47021,7 @@ var init_tool_policy = __esm({
46604
47021
 
46605
47022
  // packages/cli/dist/tui/telegram-bridge.js
46606
47023
  import { mkdirSync as mkdirSync18, existsSync as existsSync42, unlinkSync as unlinkSync10, readdirSync as readdirSync15, statSync as statSync13 } from "node:fs";
46607
- import { join as join52, resolve as resolve28 } from "node:path";
47024
+ import { join as join53, resolve as resolve28 } from "node:path";
46608
47025
  import { writeFile as writeFileAsync } from "node:fs/promises";
46609
47026
  function convertMarkdownToTelegramHTML(md) {
46610
47027
  let html = md;
@@ -47369,7 +47786,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
47369
47786
  return null;
47370
47787
  const buffer = Buffer.from(await res.arrayBuffer());
47371
47788
  const fileName = `${Date.now()}-${fileId.slice(0, 8)}${extension}`;
47372
- const localPath = join52(this.mediaCacheDir, fileName);
47789
+ const localPath = join53(this.mediaCacheDir, fileName);
47373
47790
  await writeFileAsync(localPath, buffer);
47374
47791
  return localPath;
47375
47792
  } catch {
@@ -48020,7 +48437,7 @@ var init_braille_spinner = __esm({
48020
48437
  // packages/cli/dist/tui/system-metrics.js
48021
48438
  import { loadavg as loadavg3, cpus as cpus3, totalmem as totalmem4, freemem as freemem3, platform as platform4 } from "node:os";
48022
48439
  import { exec as exec3 } from "node:child_process";
48023
- import { readFile as readFile16 } from "node:fs/promises";
48440
+ import { readFile as readFile17 } from "node:fs/promises";
48024
48441
  function formatRate(bytesPerSec) {
48025
48442
  if (bytesPerSec < 1024)
48026
48443
  return `${Math.round(bytesPerSec)}B`;
@@ -48032,7 +48449,7 @@ function formatRate(bytesPerSec) {
48032
48449
  }
48033
48450
  async function readProcNetDev() {
48034
48451
  try {
48035
- const data = await readFile16("/proc/net/dev", "utf8");
48452
+ const data = await readFile17("/proc/net/dev", "utf8");
48036
48453
  let rxTotal = 0;
48037
48454
  let txTotal = 0;
48038
48455
  for (const line of data.split("\n")) {
@@ -49807,7 +50224,7 @@ var init_status_bar = __esm({
49807
50224
  import * as readline2 from "node:readline";
49808
50225
  import { Writable } from "node:stream";
49809
50226
  import { cwd } from "node:process";
49810
- import { resolve as resolve29, join as join53, dirname as dirname18, extname as extname10 } from "node:path";
50227
+ import { resolve as resolve29, join as join54, dirname as dirname18, extname as extname10 } from "node:path";
49811
50228
  import { createRequire as createRequire2 } from "node:module";
49812
50229
  import { fileURLToPath as fileURLToPath12 } from "node:url";
49813
50230
  import { readFileSync as readFileSync32, writeFileSync as writeFileSync18, appendFileSync as appendFileSync4, rmSync as rmSync2, readdirSync as readdirSync16, mkdirSync as mkdirSync19 } from "node:fs";
@@ -49831,9 +50248,9 @@ function getVersion3() {
49831
50248
  const require2 = createRequire2(import.meta.url);
49832
50249
  const thisDir = dirname18(fileURLToPath12(import.meta.url));
49833
50250
  const candidates = [
49834
- join53(thisDir, "..", "package.json"),
49835
- join53(thisDir, "..", "..", "package.json"),
49836
- join53(thisDir, "..", "..", "..", "package.json")
50251
+ join54(thisDir, "..", "package.json"),
50252
+ join54(thisDir, "..", "..", "package.json"),
50253
+ join54(thisDir, "..", "..", "..", "package.json")
49837
50254
  ];
49838
50255
  for (const pkgPath of candidates) {
49839
50256
  if (existsSync43(pkgPath)) {
@@ -49926,6 +50343,8 @@ function buildTools(repoRoot, config, contextWindowSize) {
49926
50343
  new CodeSandboxTool(repoRoot),
49927
50344
  // Persistent Python REPL — RLM (arxiv:2512.24601)
49928
50345
  new ReplTool(repoRoot),
50346
+ // Memory Metabolism — COHERE Layer 5 (arxiv:2512.13564)
50347
+ new MemoryMetabolismTool(repoRoot),
49929
50348
  // Structured file reading (CSV, JSON, Markdown, binary detection)
49930
50349
  new StructuredReadTool(repoRoot),
49931
50350
  // Vision tools (Moondream — desktop awareness + point-and-click)
@@ -50045,15 +50464,15 @@ Use task_status("${taskId}") or task_output("${taskId}") to check progress.`
50045
50464
  function gatherMemorySnippets(root) {
50046
50465
  const snippets = [];
50047
50466
  const dirs = [
50048
- join53(root, ".oa", "memory"),
50049
- join53(root, ".open-agents", "memory")
50467
+ join54(root, ".oa", "memory"),
50468
+ join54(root, ".open-agents", "memory")
50050
50469
  ];
50051
50470
  for (const dir of dirs) {
50052
50471
  if (!existsSync43(dir))
50053
50472
  continue;
50054
50473
  try {
50055
50474
  for (const f of readdirSync16(dir).filter((f2) => f2.endsWith(".json"))) {
50056
- const data = JSON.parse(readFileSync32(join53(dir, f), "utf-8"));
50475
+ const data = JSON.parse(readFileSync32(join54(dir, f), "utf-8"));
50057
50476
  for (const val of Object.values(data)) {
50058
50477
  const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
50059
50478
  if (v.length > 10)
@@ -50290,6 +50709,14 @@ ${context}` : prompt;
50290
50709
  });
50291
50710
  }
50292
50711
  }
50712
+ for (const tool of tools) {
50713
+ if ("setHandleResolver" in tool && typeof tool.setHandleResolver === "function") {
50714
+ tool.setHandleResolver((handleId) => {
50715
+ const entry = runner.getMemexEntry(handleId);
50716
+ return entry?.fullContent ?? null;
50717
+ });
50718
+ }
50719
+ }
50293
50720
  const replToolForFinalVar = tools.find((t) => t.name === "repl_exec");
50294
50721
  if (replToolForFinalVar && "readVariable" in replToolForFinalVar) {
50295
50722
  runner.options.finalVarResolver = async (varName) => {
@@ -51067,7 +51494,7 @@ async function startInteractive(config, repoPath) {
51067
51494
  let p2pGateway = null;
51068
51495
  let peerMesh = null;
51069
51496
  let inferenceRouter = null;
51070
- const secretVault = new SecretVault(join53(repoRoot, ".oa", "vault.enc"));
51497
+ const secretVault = new SecretVault(join54(repoRoot, ".oa", "vault.enc"));
51071
51498
  let adminSessionKey = null;
51072
51499
  const callSubAgents = /* @__PURE__ */ new Map();
51073
51500
  const streamRenderer = new StreamRenderer();
@@ -51276,8 +51703,8 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
51276
51703
  const hits = allCompletions.filter((c3) => c3.toLowerCase().startsWith(lower));
51277
51704
  return [hits, line];
51278
51705
  }
51279
- const HISTORY_DIR = join53(homedir13(), ".open-agents");
51280
- const HISTORY_FILE = join53(HISTORY_DIR, "repl-history");
51706
+ const HISTORY_DIR = join54(homedir13(), ".open-agents");
51707
+ const HISTORY_FILE = join54(HISTORY_DIR, "repl-history");
51281
51708
  const MAX_HISTORY_LINES = 500;
51282
51709
  let savedHistory = [];
51283
51710
  try {
@@ -51487,7 +51914,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
51487
51914
  } catch {
51488
51915
  }
51489
51916
  try {
51490
- const oaDir = join53(repoRoot, ".oa");
51917
+ const oaDir = join54(repoRoot, ".oa");
51491
51918
  const reconnected = await ExposeGateway.checkAndReconnect(oaDir, {
51492
51919
  onInfo: (msg) => writeContent(() => renderInfo(msg)),
51493
51920
  onError: (msg) => writeContent(() => renderWarning(msg))
@@ -51510,7 +51937,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
51510
51937
  } catch {
51511
51938
  }
51512
51939
  try {
51513
- const oaDir = join53(repoRoot, ".oa");
51940
+ const oaDir = join54(repoRoot, ".oa");
51514
51941
  const reconnectedP2P = await ExposeP2PGateway.checkAndReconnect(oaDir, new NexusTool(repoRoot), {
51515
51942
  onInfo: (msg) => writeContent(() => renderInfo(msg)),
51516
51943
  onError: (msg) => writeContent(() => renderWarning(msg))
@@ -52329,7 +52756,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
52329
52756
  kind,
52330
52757
  targetUrl,
52331
52758
  authKey,
52332
- stateDir: join53(repoRoot, ".oa"),
52759
+ stateDir: join54(repoRoot, ".oa"),
52333
52760
  passthrough: passthrough ?? false,
52334
52761
  loadbalance: loadbalance ?? false,
52335
52762
  endpointAuth: passthrough ? currentConfig.apiKey : void 0,
@@ -52377,7 +52804,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
52377
52804
  await tunnelGateway.stop();
52378
52805
  tunnelGateway = null;
52379
52806
  }
52380
- const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join53(repoRoot, ".oa") });
52807
+ const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join54(repoRoot, ".oa") });
52381
52808
  newTunnel.on("stats", (stats) => {
52382
52809
  statusBar.setExposeStatus({
52383
52810
  status: stats.status,
@@ -52639,7 +53066,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
52639
53066
  }
52640
53067
  },
52641
53068
  destroyProject() {
52642
- const oaPath = join53(repoRoot, OA_DIR);
53069
+ const oaPath = join54(repoRoot, OA_DIR);
52643
53070
  if (existsSync43(oaPath)) {
52644
53071
  try {
52645
53072
  rmSync2(oaPath, { recursive: true, force: true });
@@ -53572,9 +53999,9 @@ var init_run = __esm({
53572
53999
  // packages/indexer/dist/codebase-indexer.js
53573
54000
  import { glob } from "glob";
53574
54001
  import ignore from "ignore";
53575
- import { readFile as readFile17, stat as stat4 } from "node:fs/promises";
54002
+ import { readFile as readFile18, stat as stat4 } from "node:fs/promises";
53576
54003
  import { createHash as createHash4 } from "node:crypto";
53577
- import { join as join54, relative as relative3, extname as extname11, basename as basename15 } from "node:path";
54004
+ import { join as join55, relative as relative3, extname as extname11, basename as basename15 } from "node:path";
53578
54005
  var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
53579
54006
  var init_codebase_indexer = __esm({
53580
54007
  "packages/indexer/dist/codebase-indexer.js"() {
@@ -53618,7 +54045,7 @@ var init_codebase_indexer = __esm({
53618
54045
  const ig = ignore.default();
53619
54046
  if (this.config.respectGitignore) {
53620
54047
  try {
53621
- const gitignoreContent = await readFile17(join54(this.config.rootDir, ".gitignore"), "utf-8");
54048
+ const gitignoreContent = await readFile18(join55(this.config.rootDir, ".gitignore"), "utf-8");
53622
54049
  ig.add(gitignoreContent);
53623
54050
  } catch {
53624
54051
  }
@@ -53633,12 +54060,12 @@ var init_codebase_indexer = __esm({
53633
54060
  for (const relativePath of files) {
53634
54061
  if (ig.ignores(relativePath))
53635
54062
  continue;
53636
- const fullPath = join54(this.config.rootDir, relativePath);
54063
+ const fullPath = join55(this.config.rootDir, relativePath);
53637
54064
  try {
53638
54065
  const fileStat = await stat4(fullPath);
53639
54066
  if (fileStat.size > this.config.maxFileSize)
53640
54067
  continue;
53641
- const content = await readFile17(fullPath);
54068
+ const content = await readFile18(fullPath);
53642
54069
  const hash = createHash4("sha256").update(content).digest("hex");
53643
54070
  const ext = extname11(relativePath);
53644
54071
  indexed.push({
@@ -53679,7 +54106,7 @@ var init_codebase_indexer = __esm({
53679
54106
  if (!child) {
53680
54107
  child = {
53681
54108
  name: part,
53682
- path: join54(current.path, part),
54109
+ path: join55(current.path, part),
53683
54110
  type: "directory",
53684
54111
  children: []
53685
54112
  };
@@ -54020,7 +54447,7 @@ var config_exports = {};
54020
54447
  __export(config_exports, {
54021
54448
  configCommand: () => configCommand
54022
54449
  });
54023
- import { join as join55, resolve as resolve31 } from "node:path";
54450
+ import { join as join56, resolve as resolve31 } from "node:path";
54024
54451
  import { homedir as homedir14 } from "node:os";
54025
54452
  import { cwd as cwd3 } from "node:process";
54026
54453
  function redactIfSensitive(key, value) {
@@ -54103,7 +54530,7 @@ function handleShow(opts, config) {
54103
54530
  }
54104
54531
  }
54105
54532
  printSection("Config File");
54106
- printInfo(`~/.open-agents/config.json (${join55(homedir14(), ".open-agents", "config.json")})`);
54533
+ printInfo(`~/.open-agents/config.json (${join56(homedir14(), ".open-agents", "config.json")})`);
54107
54534
  printSection("Priority Chain");
54108
54535
  printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
54109
54536
  printInfo(" 2. Project .oa/settings.json (--local)");
@@ -54142,7 +54569,7 @@ function handleSet(opts, _config) {
54142
54569
  const coerced = coerceForSettings(key, value);
54143
54570
  saveProjectSettings(repoRoot, { [key]: coerced });
54144
54571
  printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value)}`);
54145
- printInfo(`Saved to ${join55(repoRoot, ".oa", "settings.json")}`);
54572
+ printInfo(`Saved to ${join56(repoRoot, ".oa", "settings.json")}`);
54146
54573
  printInfo("This override applies only when running in this workspace.");
54147
54574
  } catch (err) {
54148
54575
  printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
@@ -54401,7 +54828,7 @@ __export(eval_exports, {
54401
54828
  });
54402
54829
  import { tmpdir as tmpdir10 } from "node:os";
54403
54830
  import { mkdirSync as mkdirSync20, writeFileSync as writeFileSync19 } from "node:fs";
54404
- import { join as join56 } from "node:path";
54831
+ import { join as join57 } from "node:path";
54405
54832
  async function evalCommand(opts, config) {
54406
54833
  const suiteName = opts.suite ?? "basic";
54407
54834
  const suite = SUITES[suiteName];
@@ -54526,9 +54953,9 @@ async function evalCommand(opts, config) {
54526
54953
  process.exit(failed > 0 ? 1 : 0);
54527
54954
  }
54528
54955
  function createTempEvalRepo() {
54529
- const dir = join56(tmpdir10(), `open-agents-eval-${Date.now()}`);
54956
+ const dir = join57(tmpdir10(), `open-agents-eval-${Date.now()}`);
54530
54957
  mkdirSync20(dir, { recursive: true });
54531
- writeFileSync19(join56(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
54958
+ writeFileSync19(join57(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
54532
54959
  return dir;
54533
54960
  }
54534
54961
  var BASIC_SUITE, FULL_SUITE, SUITES;
@@ -54588,7 +55015,7 @@ init_updater();
54588
55015
  import { parseArgs as nodeParseArgs2 } from "node:util";
54589
55016
  import { createRequire as createRequire3 } from "node:module";
54590
55017
  import { fileURLToPath as fileURLToPath13 } from "node:url";
54591
- import { dirname as dirname19, join as join57 } from "node:path";
55018
+ import { dirname as dirname19, join as join58 } from "node:path";
54592
55019
 
54593
55020
  // packages/cli/dist/cli.js
54594
55021
  import { createInterface } from "node:readline";
@@ -54695,7 +55122,7 @@ init_output();
54695
55122
  function getVersion4() {
54696
55123
  try {
54697
55124
  const require2 = createRequire3(import.meta.url);
54698
- const pkgPath = join57(dirname19(fileURLToPath13(import.meta.url)), "..", "package.json");
55125
+ const pkgPath = join58(dirname19(fileURLToPath13(import.meta.url)), "..", "package.json");
54699
55126
  const pkg = require2(pkgPath);
54700
55127
  return pkg.version;
54701
55128
  } catch {