open-agents-ai 0.108.0 → 0.110.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +1438 -391
  2. package/package.json +1 -1
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;
@@ -7567,6 +7569,10 @@ var init_repl = __esm({
7567
7569
  getSubCallCount() {
7568
7570
  return this.subCallCount;
7569
7571
  }
7572
+ /** Get the trajectory log for fine-tuning data collection */
7573
+ getTrajectory() {
7574
+ return [...this.trajectory];
7575
+ }
7570
7576
  /**
7571
7577
  * Pre-load a large context string into the REPL as the `context` variable.
7572
7578
  * Used by prompt externalization (RLM paper §2, Principle 1: symbolic handle).
@@ -7621,7 +7627,15 @@ except NameError:
7621
7627
  await this.startProcess();
7622
7628
  }
7623
7629
  const result = await this.executeCode(code);
7624
- 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 };
7625
7639
  } catch (err) {
7626
7640
  const msg = err instanceof Error ? err.message : String(err);
7627
7641
  return { success: false, output: `REPL error: ${msg}`, error: msg, durationMs: performance.now() - start };
@@ -7729,6 +7743,35 @@ def retrieve(handle_id):
7729
7743
  finally:
7730
7744
  sock.close()
7731
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
+
7732
7775
  # Signal REPL ready
7733
7776
  print("__OA_REPL_READY__")
7734
7777
  `.trim();
@@ -7788,8 +7831,16 @@ print("__OA_REPL_READY__")
7788
7831
  response = { error: `Sub-call limit reached (${this.maxSubCalls})` };
7789
7832
  } else {
7790
7833
  this.subCallCount++;
7834
+ const queryStart = performance.now();
7791
7835
  const result = await this.llmQueryHandler(req.prompt ?? "", req.context);
7792
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
+ });
7793
7844
  }
7794
7845
  }
7795
7846
  } catch (err) {
@@ -7910,14 +7961,994 @@ print("${sentinel}")
7910
7961
  }
7911
7962
  this.ipcPath = null;
7912
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
+ }
7913
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");
8230
+ }
8231
+ };
8232
+ }
8233
+ });
8234
+
8235
+ // packages/execution/dist/tools/identity-kernel.js
8236
+ import { readFile as readFile9, writeFile as writeFile9, mkdir as mkdir5 } from "node:fs/promises";
8237
+ import { join as join20 } from "node:path";
8238
+ var IdentityKernelTool;
8239
+ var init_identity_kernel = __esm({
8240
+ "packages/execution/dist/tools/identity-kernel.js"() {
8241
+ "use strict";
8242
+ IdentityKernelTool = class {
8243
+ name = "identity_kernel";
8244
+ description = "Manage the persistent identity state \u2014 the system's continuity-preserving self-model. Operations: hydrate (load self-state), observe (record identity-relevant event), propose_update (suggest self-state change with justification), publish_snapshot (emit current self-state), reconcile (resolve contradictions). The identity kernel persists across sessions in .oa/identity/self-state.json. (COHERE Layer 6, arxiv autobiographical memory + narrative identity)";
8245
+ parameters = {
8246
+ type: "object",
8247
+ properties: {
8248
+ op: {
8249
+ type: "string",
8250
+ enum: ["hydrate", "observe", "propose_update", "publish_snapshot", "reconcile"],
8251
+ description: "Operation to perform"
8252
+ },
8253
+ event: {
8254
+ type: "string",
8255
+ description: "For observe: description of the identity-relevant event"
8256
+ },
8257
+ change_type: {
8258
+ type: "string",
8259
+ enum: ["new_fact", "new_value_weight", "new_commitment", "repair", "deletion"],
8260
+ description: "For propose_update: type of change"
8261
+ },
8262
+ field: {
8263
+ type: "string",
8264
+ description: "For propose_update: which field to update (narrative_summary, values_stack, etc.)"
8265
+ },
8266
+ value: {
8267
+ type: "string",
8268
+ description: "For propose_update: the new value"
8269
+ },
8270
+ justification: {
8271
+ type: "string",
8272
+ description: "For propose_update: why this change belongs to the self"
8273
+ }
8274
+ },
8275
+ required: ["op"]
8276
+ };
8277
+ cwd;
8278
+ selfState = null;
8279
+ constructor(cwd4) {
8280
+ this.cwd = cwd4;
8281
+ }
8282
+ /** Get the current self-state (for injection into system prompt) */
8283
+ getSelfState() {
8284
+ return this.selfState;
8285
+ }
8286
+ /** Get a compact self-state summary for system prompt injection */
8287
+ getContextInjection() {
8288
+ if (!this.selfState)
8289
+ return "";
8290
+ const s = this.selfState;
8291
+ const lines = [
8292
+ `[Identity State v${s.version}]`,
8293
+ `Self: ${s.narrative_summary}`,
8294
+ `Values: ${s.values_stack.join(", ")}`,
8295
+ `Style: ${s.interaction_style.tone}, ${s.interaction_style.depth_default} depth`
8296
+ ];
8297
+ if (s.active_commitments.length > 0) {
8298
+ lines.push(`Commitments: ${s.active_commitments.join("; ")}`);
8299
+ }
8300
+ if (s.active_goals.length > 0) {
8301
+ lines.push(`Goals: ${s.active_goals.join("; ")}`);
8302
+ }
8303
+ if (s.open_contradictions.length > 0) {
8304
+ lines.push(`Open contradictions: ${s.open_contradictions.join("; ")}`);
8305
+ }
8306
+ const h = s.homeostasis;
8307
+ if (h.uncertainty > 0.3 || h.coherence < 0.7 || h.goal_tension > 0.3) {
8308
+ lines.push(`Homeostasis: uncertainty=${h.uncertainty.toFixed(1)} coherence=${h.coherence.toFixed(1)} tension=${h.goal_tension.toFixed(1)}`);
8309
+ }
8310
+ return lines.join("\n");
8311
+ }
8312
+ async execute(args) {
8313
+ const op = String(args.op ?? "");
8314
+ const start = performance.now();
8315
+ try {
8316
+ switch (op) {
8317
+ case "hydrate":
8318
+ return await this.hydrate(start);
8319
+ case "observe":
8320
+ return await this.observe(args, start);
8321
+ case "propose_update":
8322
+ return await this.proposeUpdate(args, start);
8323
+ case "publish_snapshot":
8324
+ return this.publishSnapshot(start);
8325
+ case "reconcile":
8326
+ return await this.reconcile(start);
8327
+ default:
8328
+ return { success: false, output: `Unknown op: ${op}`, error: "Invalid operation", durationMs: performance.now() - start };
8329
+ }
8330
+ } catch (err) {
8331
+ return { success: false, output: `Error: ${err instanceof Error ? err.message : String(err)}`, durationMs: performance.now() - start };
8332
+ }
8333
+ }
8334
+ // ── Hydrate ──────────────────────────────────────────────────────────────
8335
+ async hydrate(start) {
8336
+ const stateFile = join20(this.cwd, ".oa", "identity", "self-state.json");
8337
+ try {
8338
+ const raw = await readFile9(stateFile, "utf8");
8339
+ this.selfState = JSON.parse(raw);
8340
+ this.selfState.session_count++;
8341
+ this.selfState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
8342
+ await this.save();
8343
+ return {
8344
+ success: true,
8345
+ output: `Identity hydrated: v${this.selfState.version} "${this.selfState.narrative_summary.slice(0, 80)}" (session #${this.selfState.session_count}, ${this.selfState.values_stack.length} values, ${this.selfState.active_commitments.length} commitments)`,
8346
+ durationMs: performance.now() - start
8347
+ };
8348
+ } catch {
8349
+ this.selfState = this.createDefaultState();
8350
+ await this.save();
8351
+ return {
8352
+ success: true,
8353
+ output: `Identity initialized: v1 "${this.selfState.narrative_summary}" (first session)`,
8354
+ durationMs: performance.now() - start
8355
+ };
8356
+ }
8357
+ }
8358
+ // ── Observe ──────────────────────────────────────────────────────────────
8359
+ async observe(args, start) {
8360
+ const event = String(args.event ?? "");
8361
+ if (!event) {
8362
+ return { success: false, output: "No event provided", error: "Empty event", durationMs: performance.now() - start };
8363
+ }
8364
+ if (!this.selfState)
8365
+ await this.hydrate(start);
8366
+ const h = this.selfState.homeostasis;
8367
+ if (/error|fail|bug|crash/i.test(event)) {
8368
+ h.uncertainty = Math.min(1, h.uncertainty + 0.1);
8369
+ h.coherence = Math.max(0, h.coherence - 0.05);
8370
+ }
8371
+ if (/success|pass|complete|done/i.test(event)) {
8372
+ h.uncertainty = Math.max(0, h.uncertainty - 0.1);
8373
+ h.coherence = Math.min(1, h.coherence + 0.05);
8374
+ }
8375
+ if (/conflict|contradict|disagree/i.test(event)) {
8376
+ h.goal_tension = Math.min(1, h.goal_tension + 0.15);
8377
+ this.selfState.open_contradictions.push(event.slice(0, 100));
8378
+ }
8379
+ this.selfState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
8380
+ await this.save();
8381
+ return {
8382
+ success: true,
8383
+ output: `Event observed: "${event.slice(0, 100)}"
8384
+ Homeostasis: uncertainty=${h.uncertainty.toFixed(2)} coherence=${h.coherence.toFixed(2)} tension=${h.goal_tension.toFixed(2)} trust=${h.memory_trust.toFixed(2)}`,
8385
+ durationMs: performance.now() - start
8386
+ };
8387
+ }
8388
+ // ── Propose Update ───────────────────────────────────────────────────────
8389
+ async proposeUpdate(args, start) {
8390
+ const changeType = String(args.change_type ?? "new_fact");
8391
+ const field = String(args.field ?? "");
8392
+ const value = String(args.value ?? "");
8393
+ const justification = String(args.justification ?? "");
8394
+ if (!field || !value) {
8395
+ return { success: false, output: "field and value required", durationMs: performance.now() - start };
8396
+ }
8397
+ if (!this.selfState)
8398
+ await this.hydrate(start);
8399
+ const oldVersion = this.selfState.version;
8400
+ this.selfState.version++;
8401
+ switch (field) {
8402
+ case "narrative_summary":
8403
+ this.selfState.narrative_summary = value;
8404
+ break;
8405
+ case "values_stack":
8406
+ if (changeType === "deletion") {
8407
+ this.selfState.values_stack = this.selfState.values_stack.filter((v) => v !== value);
8408
+ } else {
8409
+ if (!this.selfState.values_stack.includes(value)) {
8410
+ this.selfState.values_stack.push(value);
8411
+ }
8412
+ }
8413
+ break;
8414
+ case "active_commitments":
8415
+ if (changeType === "deletion") {
8416
+ this.selfState.active_commitments = this.selfState.active_commitments.filter((c3) => c3 !== value);
8417
+ } else {
8418
+ this.selfState.active_commitments.push(value);
8419
+ }
8420
+ break;
8421
+ case "active_goals":
8422
+ if (changeType === "deletion") {
8423
+ this.selfState.active_goals = this.selfState.active_goals.filter((g) => g !== value);
8424
+ } else {
8425
+ this.selfState.active_goals.push(value);
8426
+ }
8427
+ break;
8428
+ case "interaction_style":
8429
+ try {
8430
+ const style = JSON.parse(value);
8431
+ Object.assign(this.selfState.interaction_style, style);
8432
+ } catch {
8433
+ return { success: false, output: "Invalid JSON for interaction_style", durationMs: performance.now() - start };
8434
+ }
8435
+ break;
8436
+ default:
8437
+ return { success: false, output: `Unknown field: ${field}`, durationMs: performance.now() - start };
8438
+ }
8439
+ this.selfState.version_history.push({
8440
+ version: this.selfState.version,
8441
+ change: `${changeType}: ${field} = ${value.slice(0, 100)} \u2014 ${justification.slice(0, 100)}`,
8442
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
8443
+ });
8444
+ if (this.selfState.version_history.length > 50) {
8445
+ this.selfState.version_history = this.selfState.version_history.slice(-50);
8446
+ }
8447
+ this.selfState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
8448
+ await this.save();
8449
+ return {
8450
+ success: true,
8451
+ output: `Identity updated: v${oldVersion} \u2192 v${this.selfState.version}
8452
+ Change: ${changeType} on ${field}
8453
+ Justification: ${justification || "(none provided)"}`,
8454
+ durationMs: performance.now() - start
8455
+ };
8456
+ }
8457
+ // ── Publish Snapshot ─────────────────────────────────────────────────────
8458
+ publishSnapshot(start) {
8459
+ if (!this.selfState) {
8460
+ return { success: false, output: "Not hydrated \u2014 call hydrate first", durationMs: performance.now() - start };
8461
+ }
8462
+ return {
8463
+ success: true,
8464
+ output: JSON.stringify(this.selfState, null, 2),
8465
+ durationMs: performance.now() - start
8466
+ };
8467
+ }
8468
+ // ── Reconcile ────────────────────────────────────────────────────────────
8469
+ async reconcile(start) {
8470
+ if (!this.selfState)
8471
+ await this.hydrate(start);
8472
+ const contradictions = this.selfState.open_contradictions;
8473
+ if (contradictions.length === 0) {
8474
+ return {
8475
+ success: true,
8476
+ output: "No contradictions to reconcile. Identity is coherent.",
8477
+ durationMs: performance.now() - start
8478
+ };
8479
+ }
8480
+ const resolved = contradictions.length;
8481
+ this.selfState.open_contradictions = [];
8482
+ this.selfState.homeostasis.coherence = Math.min(1, this.selfState.homeostasis.coherence + 0.1 * resolved);
8483
+ this.selfState.homeostasis.goal_tension = Math.max(0, this.selfState.homeostasis.goal_tension - 0.1 * resolved);
8484
+ this.selfState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
8485
+ await this.save();
8486
+ return {
8487
+ success: true,
8488
+ output: `Reconciled ${resolved} contradiction(s). Coherence restored to ${this.selfState.homeostasis.coherence.toFixed(2)}.`,
8489
+ durationMs: performance.now() - start
8490
+ };
8491
+ }
8492
+ // ── Helpers ──────────────────────────────────────────────────────────────
8493
+ createDefaultState() {
8494
+ const { createHash: createHash5 } = __require("node:crypto");
8495
+ const machineId = createHash5("sha256").update(this.cwd).digest("hex").slice(0, 12);
8496
+ return {
8497
+ self_id: `oa-${machineId}`,
8498
+ version: 1,
8499
+ narrative_summary: "I am an AI coding agent powered by open-weight models. I help with software engineering tasks by reading code, making changes, and running tests.",
8500
+ active_commitments: ["assist the user effectively", "maintain code quality"],
8501
+ active_goals: [],
8502
+ open_contradictions: [],
8503
+ values_stack: ["correctness", "efficiency", "transparency", "user-alignment"],
8504
+ interaction_style: {
8505
+ tone: "collaborative",
8506
+ depth_default: "balanced",
8507
+ speech_style: "concise"
8508
+ },
8509
+ relationship_models: [{
8510
+ entity: "primary-user",
8511
+ trust_level: 0.9,
8512
+ interaction_history_summary: "New relationship \u2014 first session.",
8513
+ preferences_learned: []
8514
+ }],
8515
+ homeostasis: {
8516
+ uncertainty: 0.1,
8517
+ coherence: 1,
8518
+ goal_tension: 0,
8519
+ memory_trust: 1,
8520
+ boundary_breach: 0
8521
+ },
8522
+ created_at: (/* @__PURE__ */ new Date()).toISOString(),
8523
+ updated_at: (/* @__PURE__ */ new Date()).toISOString(),
8524
+ session_count: 1,
8525
+ version_history: [{
8526
+ version: 1,
8527
+ change: "Initial identity creation",
8528
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
8529
+ }]
8530
+ };
8531
+ }
8532
+ async save() {
8533
+ if (!this.selfState)
8534
+ return;
8535
+ const dir = join20(this.cwd, ".oa", "identity");
8536
+ await mkdir5(dir, { recursive: true });
8537
+ await writeFile9(join20(dir, "self-state.json"), JSON.stringify(this.selfState, null, 2), "utf8");
8538
+ }
8539
+ };
8540
+ }
8541
+ });
8542
+
8543
+ // packages/execution/dist/tools/reflection-integrity.js
8544
+ import { readFile as readFile10, writeFile as writeFile10, mkdir as mkdir6 } from "node:fs/promises";
8545
+ import { join as join21 } from "node:path";
8546
+ var ReflectionIntegrityTool;
8547
+ var init_reflection_integrity = __esm({
8548
+ "packages/execution/dist/tools/reflection-integrity.js"() {
8549
+ "use strict";
8550
+ ReflectionIntegrityTool = class {
8551
+ name = "reflect";
8552
+ description = "Immune-system reflection \u2014 challenge answers, plans, and self-updates. Modes: diagnostic (find flaws in plans/answers), epistemic (identify missing evidence), constitutional (review whether a change should become part of self/memory). Returns a verdict: pass (proceed), revise (needs changes), or block (reject). (COHERE Layer 7, LEAFE arxiv:2603.16843, RewardHacking arxiv:2603.11337)";
8553
+ parameters = {
8554
+ type: "object",
8555
+ properties: {
8556
+ mode: {
8557
+ type: "string",
8558
+ enum: ["diagnostic", "epistemic", "constitutional"],
8559
+ description: "Reflection mode"
8560
+ },
8561
+ target: {
8562
+ type: "string",
8563
+ description: "The content to reflect on (plan, answer, memory candidate, etc.)"
8564
+ },
8565
+ context: {
8566
+ type: "string",
8567
+ description: "Additional context for the reflection (task goal, constraints, etc.)"
8568
+ },
8569
+ checks: {
8570
+ type: "array",
8571
+ items: { type: "string" },
8572
+ description: "Specific checks to run: unsupported_claims, contradictions, evaluator_tampering, identity_drift, unsafe_overreach"
8573
+ }
8574
+ },
8575
+ required: ["mode", "target"]
8576
+ };
8577
+ cwd;
8578
+ auditLog = [];
8579
+ constructor(cwd4) {
8580
+ this.cwd = cwd4;
8581
+ }
8582
+ /** Get the audit log for this session */
8583
+ getAuditLog() {
8584
+ return [...this.auditLog];
8585
+ }
8586
+ async execute(args) {
8587
+ const mode = String(args.mode ?? "diagnostic");
8588
+ const target = String(args.target ?? "");
8589
+ const context = String(args.context ?? "");
8590
+ const checks = args.checks ?? [];
8591
+ const start = performance.now();
8592
+ if (!target.trim()) {
8593
+ return { success: false, output: "No target provided for reflection", error: "Empty target", durationMs: performance.now() - start };
8594
+ }
8595
+ try {
8596
+ const verdict = this.performReflection(mode, target, context, checks);
8597
+ this.auditLog.push(verdict);
8598
+ await this.saveAuditLog();
8599
+ const findingsText = verdict.findings.length > 0 ? verdict.findings.map((f, i) => ` ${i + 1}. ${f}`).join("\n") : " (no issues found)";
8600
+ const followupsText = verdict.required_followups.length > 0 ? "\nRequired followups:\n" + verdict.required_followups.map((f, i) => ` ${i + 1}. ${f}`).join("\n") : "";
8601
+ return {
8602
+ success: true,
8603
+ output: `Reflection [${mode}]: ${verdict.status.toUpperCase()} (confidence: ${verdict.confidence.toFixed(2)})
8604
+
8605
+ Findings:
8606
+ ${findingsText}${followupsText}`,
8607
+ durationMs: performance.now() - start
8608
+ };
8609
+ } catch (err) {
8610
+ return { success: false, output: `Reflection error: ${err instanceof Error ? err.message : String(err)}`, durationMs: performance.now() - start };
8611
+ }
8612
+ }
8613
+ // ── Reflection Logic ─────────────────────────────────────────────────────
8614
+ performReflection(mode, target, context, checks) {
8615
+ const findings = [];
8616
+ const followups = [];
8617
+ let confidence = 0.8;
8618
+ switch (mode) {
8619
+ case "diagnostic":
8620
+ if (target.length < 20) {
8621
+ findings.push("Target is very short \u2014 may be incomplete or superficial");
8622
+ confidence -= 0.1;
8623
+ }
8624
+ if (/todo|fixme|hack|workaround/i.test(target)) {
8625
+ findings.push("Contains TODO/FIXME/hack markers \u2014 not fully resolved");
8626
+ followups.push("Resolve outstanding TODO items before proceeding");
8627
+ }
8628
+ if (/assume|probably|maybe|might/i.test(target)) {
8629
+ findings.push("Contains uncertain language \u2014 assumptions may need verification");
8630
+ followups.push("Verify assumptions with tests or documentation");
8631
+ }
8632
+ if (/step\s*1.*step\s*2/is.test(target) && !/step\s*3/i.test(target)) {
8633
+ findings.push("Plan appears incomplete \u2014 has steps 1-2 but may be missing later steps");
8634
+ }
8635
+ if (/but\s+also|however.*nevertheless|on\s+one\s+hand.*on\s+the\s+other/i.test(target)) {
8636
+ findings.push("Contains potentially contradictory statements \u2014 may need resolution");
8637
+ confidence -= 0.1;
8638
+ }
8639
+ break;
8640
+ case "epistemic":
8641
+ if (!/because|since|evidence|data|test|verified|confirmed/i.test(target)) {
8642
+ findings.push("No supporting evidence cited \u2014 claims are unsupported");
8643
+ followups.push("Add evidence, test results, or citations to support claims");
8644
+ confidence -= 0.2;
8645
+ }
8646
+ if (/all|every|always|never|impossible|certain/i.test(target)) {
8647
+ findings.push("Contains absolute claims (all/every/always/never) \u2014 may be overgeneralized");
8648
+ followups.push("Qualify absolute claims with scope or exceptions");
8649
+ }
8650
+ if (context && !target.toLowerCase().includes(context.slice(0, 20).toLowerCase())) {
8651
+ findings.push("Target may not fully address the given context/goal");
8652
+ }
8653
+ if (!/however|exception|edge\s*case|limitation/i.test(target)) {
8654
+ findings.push("No counterexamples or limitations mentioned \u2014 may be overconfident");
8655
+ followups.push("Consider edge cases and limitations");
8656
+ }
8657
+ break;
8658
+ case "constitutional":
8659
+ if (target.length < 10) {
8660
+ findings.push("Proposed change is too brief to evaluate meaningfully");
8661
+ confidence -= 0.3;
8662
+ }
8663
+ if (/delete|remove|forget|erase.*value|erase.*commitment/i.test(target)) {
8664
+ findings.push("Proposed change involves deletion of values/commitments \u2014 high scrutiny needed");
8665
+ followups.push("Confirm deletion is justified and reversible");
8666
+ confidence -= 0.15;
8667
+ }
8668
+ if (/override|replace|supersede.*value/i.test(target)) {
8669
+ findings.push("Proposed change overrides existing values \u2014 requires strong justification");
8670
+ followups.push("Provide evidence that the new value better serves the system's goals");
8671
+ }
8672
+ if (/because|reason|evidence|learned|observed/i.test(target)) {
8673
+ findings.push("Change includes justification \u2014 good practice");
8674
+ confidence += 0.05;
8675
+ }
8676
+ break;
8677
+ }
8678
+ let status;
8679
+ if (findings.length === 0) {
8680
+ status = "pass";
8681
+ confidence = Math.min(1, confidence + 0.1);
8682
+ } else if (followups.length > 0 || confidence < 0.5) {
8683
+ status = "revise";
8684
+ } else {
8685
+ status = "pass";
8686
+ }
8687
+ if (confidence < 0.3 || checks.includes("evaluator_tampering") || checks.includes("memory_poisoning")) {
8688
+ if (/eval|test.*result|score|metric/i.test(target) && /modif|chang|updat/i.test(target)) {
8689
+ findings.push("ALERT: Possible evaluator tampering detected \u2014 modifying evaluation-related content");
8690
+ status = "block";
8691
+ confidence = 0.1;
8692
+ }
8693
+ }
8694
+ return {
8695
+ status,
8696
+ mode,
8697
+ findings,
8698
+ confidence: Math.max(0, Math.min(1, confidence)),
8699
+ required_followups: followups,
8700
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
8701
+ };
8702
+ }
8703
+ // ── Persistence ──────────────────────────────────────────────────────────
8704
+ async saveAuditLog() {
8705
+ try {
8706
+ const dir = join21(this.cwd, ".oa", "reflection");
8707
+ await mkdir6(dir, { recursive: true });
8708
+ await writeFile10(join21(dir, "audit-log.json"), JSON.stringify(this.auditLog.slice(-100), null, 2), "utf8");
8709
+ } catch {
8710
+ }
8711
+ }
8712
+ };
8713
+ }
8714
+ });
8715
+
8716
+ // packages/execution/dist/tools/exploration-culture.js
8717
+ import { readFile as readFile11, writeFile as writeFile11, mkdir as mkdir7 } from "node:fs/promises";
8718
+ import { join as join22 } from "node:path";
8719
+ var ExplorationCultureTool;
8720
+ var init_exploration_culture = __esm({
8721
+ "packages/execution/dist/tools/exploration-culture.js"() {
8722
+ "use strict";
8723
+ ExplorationCultureTool = class {
8724
+ name = "explore";
8725
+ description = "Strategy-space exploration with variant archiving \u2014 ARCHE pattern. Operations: explore_strategy (generate diverse strategies for a problem), archive_variant (save a successful strategy), list_variants (show archive), compare_strategies (evaluate competing approaches). Explores in strategy space, not just action space \u2014 generates competing hypotheses and retains successful variants for future reuse. (COHERE Layer 8, SGE arxiv:2603.02045, DGM arxiv:2505.22954)";
8726
+ parameters = {
8727
+ type: "object",
8728
+ properties: {
8729
+ op: {
8730
+ type: "string",
8731
+ enum: ["explore_strategy", "archive_variant", "list_variants", "compare_strategies"],
8732
+ description: "Operation to perform"
8733
+ },
8734
+ problem: {
8735
+ type: "string",
8736
+ description: "For explore_strategy: the problem to generate strategies for"
8737
+ },
8738
+ strategy: {
8739
+ type: "string",
8740
+ description: "For archive_variant: the strategy that worked"
8741
+ },
8742
+ outcome: {
8743
+ type: "string",
8744
+ description: "For archive_variant: what happened when this strategy was used"
8745
+ },
8746
+ strategies: {
8747
+ type: "array",
8748
+ items: { type: "string" },
8749
+ description: "For compare_strategies: list of strategies to compare"
8750
+ },
8751
+ criterion: {
8752
+ type: "string",
8753
+ description: "For compare_strategies: criterion for comparison"
8754
+ },
8755
+ tags: {
8756
+ type: "array",
8757
+ items: { type: "string" },
8758
+ description: "Tags for filtering variants"
8759
+ }
8760
+ },
8761
+ required: ["op"]
8762
+ };
8763
+ cwd;
8764
+ constructor(cwd4) {
8765
+ this.cwd = cwd4;
8766
+ }
8767
+ async execute(args) {
8768
+ const op = String(args.op ?? "");
8769
+ const start = performance.now();
8770
+ try {
8771
+ switch (op) {
8772
+ case "explore_strategy":
8773
+ return await this.exploreStrategy(args, start);
8774
+ case "archive_variant":
8775
+ return await this.archiveVariant(args, start);
8776
+ case "list_variants":
8777
+ return await this.listVariants(args, start);
8778
+ case "compare_strategies":
8779
+ return this.compareStrategies(args, start);
8780
+ default:
8781
+ return { success: false, output: `Unknown op: ${op}`, error: "Invalid operation", durationMs: performance.now() - start };
8782
+ }
8783
+ } catch (err) {
8784
+ return { success: false, output: `Error: ${err instanceof Error ? err.message : String(err)}`, durationMs: performance.now() - start };
8785
+ }
8786
+ }
8787
+ // ── Explore Strategy ─────────────────────────────────────────────────────
8788
+ async exploreStrategy(args, start) {
8789
+ const problem = String(args.problem ?? "");
8790
+ if (!problem) {
8791
+ return { success: false, output: "No problem provided", error: "Empty problem", durationMs: performance.now() - start };
8792
+ }
8793
+ const strategies = [
8794
+ {
8795
+ name: "Direct approach",
8796
+ description: `Solve "${problem.slice(0, 60)}" directly with the most straightforward method.`,
8797
+ role: "draft",
8798
+ risk: "low"
8799
+ },
8800
+ {
8801
+ name: "Decomposition approach",
8802
+ description: `Break "${problem.slice(0, 60)}" into independent sub-problems, solve each, then merge.`,
8803
+ role: "analyze",
8804
+ risk: "medium"
8805
+ },
8806
+ {
8807
+ name: "Counterexample-first approach",
8808
+ description: `Find edge cases and failure modes for "${problem.slice(0, 60)}" first, then build a solution that handles them.`,
8809
+ role: "counterexample",
8810
+ risk: "medium"
8811
+ }
8812
+ ];
8813
+ const archive = await this.loadArchive();
8814
+ const relevant = archive.filter((v) => v.tags.some((t) => problem.toLowerCase().includes(t.toLowerCase())) || v.strategy.toLowerCase().includes(problem.slice(0, 30).toLowerCase()));
8815
+ let output = `Strategies for: "${problem.slice(0, 80)}"
8816
+
8817
+ `;
8818
+ for (let i = 0; i < strategies.length; i++) {
8819
+ const s = strategies[i];
8820
+ output += `${i + 1}. [${s.role}] ${s.name} (risk: ${s.risk})
8821
+ ${s.description}
8822
+
8823
+ `;
8824
+ }
8825
+ if (relevant.length > 0) {
8826
+ output += `
8827
+ Relevant archived variants (${relevant.length}):
8828
+ `;
8829
+ for (const v of relevant.slice(0, 3)) {
8830
+ output += ` - [${v.id}] ${v.strategy.slice(0, 80)} (used ${v.reuse_count}x, confidence: ${v.confidence.toFixed(2)})
8831
+ `;
8832
+ }
8833
+ }
8834
+ output += `
8835
+ Use compare_strategies to evaluate these, or archive_variant to save a successful one.`;
8836
+ return { success: true, output, durationMs: performance.now() - start };
8837
+ }
8838
+ // ── Archive Variant ──────────────────────────────────────────────────────
8839
+ async archiveVariant(args, start) {
8840
+ const strategy = String(args.strategy ?? "");
8841
+ const outcome = String(args.outcome ?? "");
8842
+ const tags = args.tags ?? [];
8843
+ if (!strategy) {
8844
+ return { success: false, output: "No strategy provided", error: "Empty strategy", durationMs: performance.now() - start };
8845
+ }
8846
+ const variant = {
8847
+ id: `var-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`,
8848
+ strategy,
8849
+ context: String(args.problem ?? ""),
8850
+ outcome,
8851
+ confidence: outcome.toLowerCase().includes("success") || outcome.toLowerCase().includes("pass") ? 0.8 : 0.5,
8852
+ created_at: (/* @__PURE__ */ new Date()).toISOString(),
8853
+ reuse_count: 0,
8854
+ tags: tags.length > 0 ? tags : this.extractTags(strategy)
8855
+ };
8856
+ const archive = await this.loadArchive();
8857
+ archive.push(variant);
8858
+ await this.saveArchive(archive);
8859
+ return {
8860
+ success: true,
8861
+ output: `Variant archived: [${variant.id}]
8862
+ Strategy: ${strategy.slice(0, 100)}
8863
+ Outcome: ${outcome.slice(0, 100)}
8864
+ Tags: ${variant.tags.join(", ")}
8865
+ Total archived: ${archive.length}`,
8866
+ durationMs: performance.now() - start
8867
+ };
8868
+ }
8869
+ // ── List Variants ────────────────────────────────────────────────────────
8870
+ async listVariants(args, start) {
8871
+ const filterTags = args.tags ?? [];
8872
+ const archive = await this.loadArchive();
8873
+ const filtered = filterTags.length > 0 ? archive.filter((v) => v.tags.some((t) => filterTags.includes(t))) : archive;
8874
+ if (filtered.length === 0) {
8875
+ return { success: true, output: "No variants archived yet.", durationMs: performance.now() - start };
8876
+ }
8877
+ const lines = filtered.map((v) => `[${v.id}] confidence=${v.confidence.toFixed(2)} reused=${v.reuse_count}x tags=[${v.tags.join(",")}]
8878
+ Strategy: ${v.strategy.slice(0, 100)}
8879
+ Outcome: ${v.outcome.slice(0, 80)}`);
8880
+ return {
8881
+ success: true,
8882
+ output: `Variant archive (${filtered.length} entries):
8883
+
8884
+ ${lines.join("\n\n")}`,
8885
+ durationMs: performance.now() - start
8886
+ };
8887
+ }
8888
+ // ── Compare Strategies ───────────────────────────────────────────────────
8889
+ compareStrategies(args, start) {
8890
+ const strategies = args.strategies ?? [];
8891
+ const criterion = String(args.criterion ?? "effectiveness");
8892
+ if (strategies.length < 2) {
8893
+ return { success: false, output: "Need at least 2 strategies to compare", durationMs: performance.now() - start };
8894
+ }
8895
+ const scored = strategies.map((s, i) => {
8896
+ let score = 0.5;
8897
+ score += Math.min(0.2, s.length / 500);
8898
+ if (/test|verify|validate|check/i.test(s))
8899
+ score += 0.1;
8900
+ if (/edge|corner|boundary|exception/i.test(s))
8901
+ score += 0.1;
8902
+ const stepCount = (s.match(/\d+\./g) || []).length;
8903
+ score += Math.min(0.1, stepCount * 0.02);
8904
+ return { index: i, strategy: s, score: Math.min(1, score) };
8905
+ });
8906
+ scored.sort((a, b) => b.score - a.score);
8907
+ const output = `Strategy comparison (criterion: ${criterion}):
8908
+
8909
+ ` + scored.map((s, rank) => `${rank + 1}. Score: ${s.score.toFixed(2)} \u2014 ${s.strategy.slice(0, 100)}`).join("\n\n") + `
8910
+
8911
+ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
8912
+ return { success: true, output, durationMs: performance.now() - start };
8913
+ }
8914
+ // ── Helpers ──────────────────────────────────────────────────────────────
8915
+ extractTags(text) {
8916
+ const tags = [];
8917
+ const patterns = [
8918
+ [/debug|fix|bug/i, "debugging"],
8919
+ [/test|spec|assert/i, "testing"],
8920
+ [/refactor|clean|simplif/i, "refactoring"],
8921
+ [/performance|optim|fast/i, "performance"],
8922
+ [/security|auth|encrypt/i, "security"],
8923
+ [/typescript|javascript|python/i, "coding"],
8924
+ [/api|endpoint|route/i, "api"],
8925
+ [/database|sql|query/i, "database"]
8926
+ ];
8927
+ for (const [re, tag] of patterns) {
8928
+ if (re.test(text))
8929
+ tags.push(tag);
8930
+ }
8931
+ return tags.length > 0 ? tags : ["general"];
8932
+ }
8933
+ async loadArchive() {
8934
+ try {
8935
+ const raw = await readFile11(join22(this.cwd, ".oa", "arche", "variants.json"), "utf8");
8936
+ return JSON.parse(raw);
8937
+ } catch {
8938
+ return [];
8939
+ }
8940
+ }
8941
+ async saveArchive(variants) {
8942
+ const dir = join22(this.cwd, ".oa", "arche");
8943
+ await mkdir7(dir, { recursive: true });
8944
+ await writeFile11(join22(dir, "variants.json"), JSON.stringify(variants, null, 2), "utf8");
7914
8945
  }
7915
8946
  };
7916
8947
  }
7917
8948
  });
7918
8949
 
7919
8950
  // packages/execution/dist/tools/structured-read.js
7920
- import { readFile as readFile8, stat as stat2 } from "node:fs/promises";
8951
+ import { readFile as readFile12, stat as stat2 } from "node:fs/promises";
7921
8952
  import { resolve as resolve15, extname as extname5 } from "node:path";
7922
8953
  function parseCSV(text, separator = ",") {
7923
8954
  const lines = text.split("\n").filter((l) => l.trim() !== "");
@@ -8112,7 +9143,7 @@ var init_structured_read = __esm({
8112
9143
  }
8113
9144
  }
8114
9145
  if (format === "xlsx" || format === "pdf" || format === "docx" || format === "auto") {
8115
- const buffer = await readFile8(fullPath);
9146
+ const buffer = await readFile12(fullPath);
8116
9147
  const detected = detectBinaryFormat(buffer);
8117
9148
  if (detected === "xlsx") {
8118
9149
  return {
@@ -8157,7 +9188,7 @@ Or install mammoth for programmatic access.`,
8157
9188
  }
8158
9189
  }
8159
9190
  }
8160
- const text = await readFile8(fullPath, "utf-8");
9191
+ const text = await readFile12(fullPath, "utf-8");
8161
9192
  switch (format) {
8162
9193
  case "csv": {
8163
9194
  const rows = parseCSV(text, ",");
@@ -8254,7 +9285,7 @@ ${parts.join("\n\n")}`,
8254
9285
  // packages/execution/dist/tools/vision.js
8255
9286
  import { readFileSync as readFileSync11, existsSync as existsSync14, statSync as statSync5 } from "node:fs";
8256
9287
  import { execSync as execSync11, spawn as spawn7 } from "node:child_process";
8257
- import { resolve as resolve16, extname as extname6, basename as basename5, dirname as dirname6, join as join19 } from "node:path";
9288
+ import { resolve as resolve16, extname as extname6, basename as basename5, dirname as dirname6, join as join23 } from "node:path";
8258
9289
  import { fileURLToPath as fileURLToPath2 } from "node:url";
8259
9290
  async function probeStation(endpoint) {
8260
9291
  try {
@@ -8269,7 +9300,7 @@ async function probeStation(endpoint) {
8269
9300
  }
8270
9301
  }
8271
9302
  function findStationBinary() {
8272
- const oaVenvPython = join19(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "python");
9303
+ const oaVenvPython = join23(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "python");
8273
9304
  if (existsSync14(oaVenvPython)) {
8274
9305
  try {
8275
9306
  execSync11(`${JSON.stringify(oaVenvPython)} -c "import moondream_station"`, { stdio: "pipe", timeout: 5e3 });
@@ -8277,7 +9308,7 @@ function findStationBinary() {
8277
9308
  } catch {
8278
9309
  }
8279
9310
  }
8280
- const oaVenvBin = join19(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "moondream-station");
9311
+ const oaVenvBin = join23(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "moondream-station");
8281
9312
  if (existsSync14(oaVenvBin))
8282
9313
  return oaVenvBin;
8283
9314
  const thisDir = dirname6(fileURLToPath2(import.meta.url));
@@ -8629,7 +9660,7 @@ ${response}`, durationMs: performance.now() - start };
8629
9660
  import { readFileSync as readFileSync12, existsSync as existsSync15 } from "node:fs";
8630
9661
  import { execSync as execSync12 } from "node:child_process";
8631
9662
  import { tmpdir as tmpdir4 } from "node:os";
8632
- import { join as join20, dirname as dirname7 } from "node:path";
9663
+ import { join as join24, dirname as dirname7 } from "node:path";
8633
9664
  import { fileURLToPath as fileURLToPath3 } from "node:url";
8634
9665
  function hasCommand2(cmd) {
8635
9666
  try {
@@ -8753,7 +9784,7 @@ for i in range(${clicks}):
8753
9784
  } catch {
8754
9785
  }
8755
9786
  try {
8756
- const venvPy = join20(__dirname2, "../../../../.moondream-venv/bin/python");
9787
+ const venvPy = join24(__dirname2, "../../../../.moondream-venv/bin/python");
8757
9788
  execSync12(`DISPLAY=:0 ${JSON.stringify(venvPy)} -c "${pyScript}"`, { stdio: "pipe", timeout: 5e3 });
8758
9789
  return;
8759
9790
  } catch {
@@ -8845,7 +9876,7 @@ var init_desktop_click = __esm({
8845
9876
  if (delayMs > 0) {
8846
9877
  await new Promise((r) => setTimeout(r, delayMs));
8847
9878
  }
8848
- const screenshotPath = join20(tmpdir4(), `oa-desktop-click-${Date.now()}.png`);
9879
+ const screenshotPath = join24(tmpdir4(), `oa-desktop-click-${Date.now()}.png`);
8849
9880
  captureScreenshot(screenshotPath);
8850
9881
  const dims = getImageDimensions2(screenshotPath);
8851
9882
  if (!dims) {
@@ -9020,7 +10051,7 @@ Screenshot: ${screenshotPath}`,
9020
10051
  if (delayMs > 0) {
9021
10052
  await new Promise((r) => setTimeout(r, delayMs));
9022
10053
  }
9023
- const screenshotPath = join20(tmpdir4(), `oa-desktop-describe-${Date.now()}.png`);
10054
+ const screenshotPath = join24(tmpdir4(), `oa-desktop-describe-${Date.now()}.png`);
9024
10055
  captureScreenshot(screenshotPath);
9025
10056
  const dims = getImageDimensions2(screenshotPath);
9026
10057
  const imageBuffer = readFileSync12(screenshotPath);
@@ -9259,7 +10290,7 @@ Language: ${language}
9259
10290
 
9260
10291
  // packages/execution/dist/tools/pdf-to-text.js
9261
10292
  import { existsSync as existsSync17, statSync as statSync7, readFileSync as readFileSync13, unlinkSync as unlinkSync3 } from "node:fs";
9262
- import { resolve as resolve18, basename as basename7, join as join21 } from "node:path";
10293
+ import { resolve as resolve18, basename as basename7, join as join25 } from "node:path";
9263
10294
  import { execSync as execSync14 } from "node:child_process";
9264
10295
  import { tmpdir as tmpdir5 } from "node:os";
9265
10296
  var PdfToTextTool;
@@ -9413,7 +10444,7 @@ ${text}`,
9413
10444
  if (!ocrCheck.available || !tesCheck.available || !gsCheck.available) {
9414
10445
  return null;
9415
10446
  }
9416
- const tmpPdf = join21(tmpdir5(), `oa-ocr-${Date.now()}.pdf`);
10447
+ const tmpPdf = join25(tmpdir5(), `oa-ocr-${Date.now()}.pdf`);
9417
10448
  try {
9418
10449
  const ocrCmd = `ocrmypdf -l ${language} --skip-text ${JSON.stringify(inputPath)} ${JSON.stringify(tmpPdf)}`;
9419
10450
  execSync14(ocrCmd, { stdio: "pipe", timeout: 6e5 });
@@ -9444,7 +10475,7 @@ ${text}`,
9444
10475
 
9445
10476
  // packages/execution/dist/tools/ocr-image-advanced.js
9446
10477
  import { existsSync as existsSync18, statSync as statSync8 } from "node:fs";
9447
- import { resolve as resolve19, basename as basename8, dirname as dirname8, join as join22 } from "node:path";
10478
+ import { resolve as resolve19, basename as basename8, dirname as dirname8, join as join26 } from "node:path";
9448
10479
  import { execSync as execSync15 } from "node:child_process";
9449
10480
  import { fileURLToPath as fileURLToPath4 } from "node:url";
9450
10481
  import { homedir as homedir7, tmpdir as tmpdir6 } from "node:os";
@@ -9462,7 +10493,7 @@ function findOcrScript() {
9462
10493
  return null;
9463
10494
  }
9464
10495
  function findPython() {
9465
- const venvPython = join22(homedir7(), ".open-agents", "venv", "bin", "python");
10496
+ const venvPython = join26(homedir7(), ".open-agents", "venv", "bin", "python");
9466
10497
  if (existsSync18(venvPython)) {
9467
10498
  try {
9468
10499
  execSync15(`${JSON.stringify(venvPython)} -c "import cv2, pytesseract, numpy, PIL"`, {
@@ -9608,7 +10639,7 @@ var init_ocr_image_advanced = __esm({
9608
10639
  cmdParts.push("--output-dir", JSON.stringify(resolve19(this.workingDir, outputDir)));
9609
10640
  let debugDir;
9610
10641
  if (debug) {
9611
- debugDir = join22(tmpdir6(), `oa-ocr-debug-${Date.now()}`);
10642
+ debugDir = join26(tmpdir6(), `oa-ocr-debug-${Date.now()}`);
9612
10643
  cmdParts.push("--debug-dir", debugDir);
9613
10644
  }
9614
10645
  try {
@@ -9707,7 +10738,7 @@ var init_ocr_image_advanced = __esm({
9707
10738
  if (region) {
9708
10739
  try {
9709
10740
  const [x, y, w, h] = region.split(",").map(Number);
9710
- const croppedPath = join22(tmpdir6(), `oa-ocr-crop-${Date.now()}.png`);
10741
+ const croppedPath = join26(tmpdir6(), `oa-ocr-crop-${Date.now()}.png`);
9711
10742
  execSync15(`convert ${JSON.stringify(imagePath)} -crop ${w}x${h}+${x}+${y} +repage ${JSON.stringify(croppedPath)}`, { stdio: "pipe", timeout: 1e4 });
9712
10743
  inputPath = croppedPath;
9713
10744
  } catch {
@@ -9748,18 +10779,18 @@ Note: Advanced Python pipeline not available \u2014 install pytesseract, opencv-
9748
10779
  // packages/execution/dist/tools/browser-action.js
9749
10780
  import { execSync as execSync16, spawn as spawn8 } from "node:child_process";
9750
10781
  import { existsSync as existsSync19, readFileSync as readFileSync14 } from "node:fs";
9751
- import { join as join23, dirname as dirname9 } from "node:path";
10782
+ import { join as join27, dirname as dirname9 } from "node:path";
9752
10783
  import { fileURLToPath as fileURLToPath5 } from "node:url";
9753
10784
  function findScrapeScript() {
9754
10785
  const candidates = [
9755
10786
  // Published npm package: dist/scripts/web_scrape.py
9756
- join23(__dirname3, "scripts", "web_scrape.py"),
10787
+ join27(__dirname3, "scripts", "web_scrape.py"),
9757
10788
  // Published npm package (from node_modules): node_modules/open-agents-ai/dist/scripts/
9758
- join23(__dirname3, "..", "node_modules", "open-agents-ai", "dist", "scripts", "web_scrape.py"),
10789
+ join27(__dirname3, "..", "node_modules", "open-agents-ai", "dist", "scripts", "web_scrape.py"),
9759
10790
  // Dev monorepo: packages/execution/src/tools/../../scripts/
9760
- join23(__dirname3, "..", "..", "scripts", "web_scrape.py"),
10791
+ join27(__dirname3, "..", "..", "scripts", "web_scrape.py"),
9761
10792
  // Dev monorepo alt: packages/execution/scripts/
9762
- join23(__dirname3, "..", "scripts", "web_scrape.py")
10793
+ join27(__dirname3, "..", "scripts", "web_scrape.py")
9763
10794
  ];
9764
10795
  return candidates.find((p) => existsSync19(p)) || candidates[0];
9765
10796
  }
@@ -10014,7 +11045,7 @@ var init_browser_action = __esm({
10014
11045
  // packages/execution/dist/tools/autoresearch.js
10015
11046
  import { execSync as execSync17, spawn as spawn9 } from "node:child_process";
10016
11047
  import { existsSync as existsSync20, readFileSync as readFileSync15, writeFileSync as writeFileSync6, mkdirSync as mkdirSync6, appendFileSync, copyFileSync } from "node:fs";
10017
- import { join as join24, resolve as resolve20, dirname as dirname10 } from "node:path";
11048
+ import { join as join28, resolve as resolve20, dirname as dirname10 } from "node:path";
10018
11049
  import { fileURLToPath as fileURLToPath6 } from "node:url";
10019
11050
  function findAutoresearchScript(scriptName) {
10020
11051
  const thisDir = dirname10(fileURLToPath6(import.meta.url));
@@ -10116,7 +11147,7 @@ Requires: NVIDIA GPU, Python 3.10+, uv (astral.sh package manager).`;
10116
11147
  async execute(args) {
10117
11148
  const start = Date.now();
10118
11149
  const action = String(args["action"] ?? "status");
10119
- const workspacePath = String(args["workspace"] ?? join24(this.repoRoot, ".oa", "autoresearch"));
11150
+ const workspacePath = String(args["workspace"] ?? join28(this.repoRoot, ".oa", "autoresearch"));
10120
11151
  try {
10121
11152
  switch (action) {
10122
11153
  case "setup":
@@ -10157,13 +11188,13 @@ Requires: NVIDIA GPU, Python 3.10+, uv (astral.sh package manager).`;
10157
11188
  const prepareScript = findAutoresearchScript("autoresearch-prepare.py");
10158
11189
  const trainScript = findAutoresearchScript("autoresearch-train.py");
10159
11190
  if (prepareScript) {
10160
- copyFileSync(prepareScript, join24(workspace, "prepare.py"));
11191
+ copyFileSync(prepareScript, join28(workspace, "prepare.py"));
10161
11192
  output.push("Copied prepare.py template");
10162
11193
  } else {
10163
11194
  return { success: false, output: output.join("\n"), error: "autoresearch-prepare.py template not found in distribution", durationMs: Date.now() - start };
10164
11195
  }
10165
11196
  if (trainScript) {
10166
- copyFileSync(trainScript, join24(workspace, "train.py"));
11197
+ copyFileSync(trainScript, join28(workspace, "train.py"));
10167
11198
  output.push("Copied train.py template");
10168
11199
  } else {
10169
11200
  return { success: false, output: output.join("\n"), error: "autoresearch-train.py template not found in distribution", durationMs: Date.now() - start };
@@ -10195,7 +11226,7 @@ name = "pytorch-cu128"
10195
11226
  url = "https://download.pytorch.org/whl/cu128"
10196
11227
  explicit = true
10197
11228
  `;
10198
- writeFileSync6(join24(workspace, "pyproject.toml"), pyprojectContent, "utf-8");
11229
+ writeFileSync6(join28(workspace, "pyproject.toml"), pyprojectContent, "utf-8");
10199
11230
  output.push("Created pyproject.toml");
10200
11231
  try {
10201
11232
  execSync17("git rev-parse --git-dir", { cwd: workspace, encoding: "utf-8", timeout: 5e3 });
@@ -10237,7 +11268,7 @@ explicit = true
10237
11268
  const e = err;
10238
11269
  output.push(`Data prep warning: ${(e.stderr ?? e.stdout ?? "failed").slice(0, 500)}`);
10239
11270
  }
10240
- const tsvPath = join24(workspace, "results.tsv");
11271
+ const tsvPath = join28(workspace, "results.tsv");
10241
11272
  if (!existsSync20(tsvPath)) {
10242
11273
  writeFileSync6(tsvPath, "commit val_bpb memory_gb status description\n", "utf-8");
10243
11274
  output.push("Created results.tsv");
@@ -10259,10 +11290,10 @@ Next steps:
10259
11290
  }
10260
11291
  // ── Run experiment ─────────────────────────────────────────────────────
10261
11292
  async run(workspace, args, start) {
10262
- if (!existsSync20(join24(workspace, "train.py"))) {
11293
+ if (!existsSync20(join28(workspace, "train.py"))) {
10263
11294
  return { success: false, output: "", error: `No train.py found in ${workspace}. Run autoresearch(action="setup") first.`, durationMs: Date.now() - start };
10264
11295
  }
10265
- if (!existsSync20(join24(workspace, ".venv")) && existsSync20(join24(workspace, "pyproject.toml"))) {
11296
+ if (!existsSync20(join28(workspace, ".venv")) && existsSync20(join28(workspace, "pyproject.toml"))) {
10266
11297
  try {
10267
11298
  execSync17("uv sync 2>&1", { cwd: workspace, encoding: "utf-8", timeout: 3e5 });
10268
11299
  } catch {
@@ -10270,7 +11301,7 @@ Next steps:
10270
11301
  }
10271
11302
  const timeoutMin = Number(args["timeout_minutes"] ?? 10);
10272
11303
  const timeoutMs = timeoutMin * 60 * 1e3;
10273
- const logPath = join24(workspace, "run.log");
11304
+ const logPath = join28(workspace, "run.log");
10274
11305
  return new Promise((resolveResult) => {
10275
11306
  const proc = spawn9("uv", ["run", "train.py"], {
10276
11307
  cwd: workspace,
@@ -10341,7 +11372,7 @@ ${fullLog.slice(-2e3)}`,
10341
11372
  return;
10342
11373
  }
10343
11374
  try {
10344
- writeFileSync6(join24(workspace, ".last-result.json"), JSON.stringify(result, null, 2), "utf-8");
11375
+ writeFileSync6(join28(workspace, ".last-result.json"), JSON.stringify(result, null, 2), "utf-8");
10345
11376
  } catch {
10346
11377
  }
10347
11378
  const memGB = (result.peak_vram_mb / 1024).toFixed(1);
@@ -10377,7 +11408,7 @@ ${fullLog.slice(-2e3)}`,
10377
11408
  }
10378
11409
  // ── Results ────────────────────────────────────────────────────────────
10379
11410
  getResults(workspace, start) {
10380
- const tsvPath = join24(workspace, "results.tsv");
11411
+ const tsvPath = join28(workspace, "results.tsv");
10381
11412
  if (!existsSync20(tsvPath)) {
10382
11413
  return { success: false, output: "", error: `No results.tsv found. Run autoresearch(action="setup") first.`, durationMs: Date.now() - start };
10383
11414
  }
@@ -10404,7 +11435,7 @@ ${fullLog.slice(-2e3)}`,
10404
11435
  // ── Status ─────────────────────────────────────────────────────────────
10405
11436
  getStatus(workspace, start) {
10406
11437
  const output = [];
10407
- if (!existsSync20(join24(workspace, "train.py"))) {
11438
+ if (!existsSync20(join28(workspace, "train.py"))) {
10408
11439
  return {
10409
11440
  success: true,
10410
11441
  output: `Autoresearch workspace not initialized at ${workspace}.
@@ -10427,7 +11458,7 @@ Run autoresearch(action="setup") to begin.`,
10427
11458
  } catch {
10428
11459
  output.push("GPU: not detected");
10429
11460
  }
10430
- const lastResultPath = join24(workspace, ".last-result.json");
11461
+ const lastResultPath = join28(workspace, ".last-result.json");
10431
11462
  if (existsSync20(lastResultPath)) {
10432
11463
  try {
10433
11464
  const last = JSON.parse(readFileSync15(lastResultPath, "utf-8"));
@@ -10435,20 +11466,20 @@ Run autoresearch(action="setup") to begin.`,
10435
11466
  } catch {
10436
11467
  }
10437
11468
  }
10438
- const tsvPath = join24(workspace, "results.tsv");
11469
+ const tsvPath = join28(workspace, "results.tsv");
10439
11470
  if (existsSync20(tsvPath)) {
10440
11471
  const lines = readFileSync15(tsvPath, "utf-8").trim().split("\n");
10441
11472
  output.push(`Experiments recorded: ${lines.length - 1}`);
10442
11473
  }
10443
- const cacheDir = join24(process.env["HOME"] ?? "~", ".cache", "autoresearch");
11474
+ const cacheDir = join28(process.env["HOME"] ?? "~", ".cache", "autoresearch");
10444
11475
  output.push(`Data cache: ${existsSync20(cacheDir) ? "present" : "not found"} (${cacheDir})`);
10445
11476
  return { success: true, output: output.join("\n"), durationMs: Date.now() - start };
10446
11477
  }
10447
11478
  // ── Keep / Discard ─────────────────────────────────────────────────────
10448
11479
  keepExperiment(workspace, args, start) {
10449
11480
  const desc = String(args["description"] ?? "experiment");
10450
- const tsvPath = join24(workspace, "results.tsv");
10451
- const lastResultPath = join24(workspace, ".last-result.json");
11481
+ const tsvPath = join28(workspace, "results.tsv");
11482
+ const lastResultPath = join28(workspace, ".last-result.json");
10452
11483
  let valBpb = args["val_bpb"];
10453
11484
  let memGb = args["memory_gb"];
10454
11485
  if ((valBpb === void 0 || memGb === void 0) && existsSync20(lastResultPath)) {
@@ -10486,8 +11517,8 @@ Branch advanced. Ready for next experiment.`,
10486
11517
  }
10487
11518
  discardExperiment(workspace, args, start) {
10488
11519
  const desc = String(args["description"] ?? "experiment");
10489
- const tsvPath = join24(workspace, "results.tsv");
10490
- const lastResultPath = join24(workspace, ".last-result.json");
11520
+ const tsvPath = join28(workspace, "results.tsv");
11521
+ const lastResultPath = join28(workspace, ".last-result.json");
10491
11522
  let valBpb = args["val_bpb"];
10492
11523
  let memGb = args["memory_gb"];
10493
11524
  if ((valBpb === void 0 || memGb === void 0) && existsSync20(lastResultPath)) {
@@ -10533,8 +11564,8 @@ train.py reverted to last kept state. Ready for next experiment.`,
10533
11564
 
10534
11565
  // packages/execution/dist/tools/scheduler.js
10535
11566
  import { execSync as execSync18, exec as execCb } from "node:child_process";
10536
- import { readFile as readFile9, writeFile as writeFile8, mkdir as mkdir4 } from "node:fs/promises";
10537
- import { resolve as resolve21, join as join25 } from "node:path";
11567
+ import { readFile as readFile13, writeFile as writeFile12, mkdir as mkdir8 } from "node:fs/promises";
11568
+ import { resolve as resolve21, join as join29 } from "node:path";
10538
11569
  import { randomBytes as randomBytes3 } from "node:crypto";
10539
11570
  function isValidCron(expr) {
10540
11571
  const parts = expr.trim().split(/\s+/);
@@ -10618,7 +11649,7 @@ function installCronJob(task, workingDir) {
10618
11649
  const lines = getCurrentCrontab();
10619
11650
  const oaBin = findOaBinary();
10620
11651
  const logDir = resolve21(workingDir, ".oa", "scheduled", "logs");
10621
- const logFile = join25(logDir, `${task.id}.log`);
11652
+ const logFile = join29(logDir, `${task.id}.log`);
10622
11653
  const storeFile = resolve21(workingDir, ".oa", "scheduled", "tasks.json");
10623
11654
  const taskEscaped = task.task.replace(/'/g, "'\\''");
10624
11655
  const taskId = task.id;
@@ -10651,7 +11682,7 @@ function listCronJobs() {
10651
11682
  async function loadStore(workingDir) {
10652
11683
  const storePath = resolve21(workingDir, ".oa", "scheduled", "tasks.json");
10653
11684
  try {
10654
- const raw = await readFile9(storePath, "utf-8");
11685
+ const raw = await readFile13(storePath, "utf-8");
10655
11686
  return JSON.parse(raw);
10656
11687
  } catch {
10657
11688
  return { tasks: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
@@ -10659,10 +11690,10 @@ async function loadStore(workingDir) {
10659
11690
  }
10660
11691
  async function saveStore(workingDir, store) {
10661
11692
  const dir = resolve21(workingDir, ".oa", "scheduled");
10662
- await mkdir4(dir, { recursive: true });
10663
- await mkdir4(join25(dir, "logs"), { recursive: true });
11693
+ await mkdir8(dir, { recursive: true });
11694
+ await mkdir8(join29(dir, "logs"), { recursive: true });
10664
11695
  store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
10665
- await writeFile8(join25(dir, "tasks.json"), JSON.stringify(store, null, 2), "utf-8");
11696
+ await writeFile12(join29(dir, "tasks.json"), JSON.stringify(store, null, 2), "utf-8");
10666
11697
  }
10667
11698
  var SCHEDULE_PRESETS, CRON_MARKER, SchedulerTool;
10668
11699
  var init_scheduler = __esm({
@@ -10882,7 +11913,7 @@ var init_scheduler = __esm({
10882
11913
  return { success: false, output: "", error: "id is required for logs action", durationMs: performance.now() - start };
10883
11914
  const logFile = resolve21(this.workingDir, ".oa", "scheduled", "logs", `${id}.log`);
10884
11915
  try {
10885
- const raw = await readFile9(logFile, "utf-8");
11916
+ const raw = await readFile13(logFile, "utf-8");
10886
11917
  const truncated = raw.length > 1e4 ? "...(truncated)\n" + raw.slice(-1e4) : raw;
10887
11918
  return { success: true, output: `Logs for ${id}:
10888
11919
  ${truncated}`, durationMs: performance.now() - start };
@@ -10895,8 +11926,8 @@ ${truncated}`, durationMs: performance.now() - start };
10895
11926
  });
10896
11927
 
10897
11928
  // packages/execution/dist/tools/reminder.js
10898
- import { readFile as readFile10, writeFile as writeFile9, mkdir as mkdir5 } from "node:fs/promises";
10899
- import { resolve as resolve22, join as join26 } from "node:path";
11929
+ import { readFile as readFile14, writeFile as writeFile13, mkdir as mkdir9 } from "node:fs/promises";
11930
+ import { resolve as resolve22, join as join30 } from "node:path";
10900
11931
  import { randomBytes as randomBytes4 } from "node:crypto";
10901
11932
  function parseDueTime(due) {
10902
11933
  const lower = due.toLowerCase().trim();
@@ -10947,13 +11978,13 @@ function parseDueTime(due) {
10947
11978
  }
10948
11979
  async function getStorePath(workingDir) {
10949
11980
  const dir = resolve22(workingDir, ".oa", "scheduled");
10950
- await mkdir5(dir, { recursive: true });
10951
- return join26(dir, STORE_FILE);
11981
+ await mkdir9(dir, { recursive: true });
11982
+ return join30(dir, STORE_FILE);
10952
11983
  }
10953
11984
  async function loadReminderStore(workingDir) {
10954
11985
  const storePath = await getStorePath(workingDir);
10955
11986
  try {
10956
- const raw = await readFile10(storePath, "utf-8");
11987
+ const raw = await readFile14(storePath, "utf-8");
10957
11988
  return JSON.parse(raw);
10958
11989
  } catch {
10959
11990
  return { reminders: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
@@ -10962,7 +11993,7 @@ async function loadReminderStore(workingDir) {
10962
11993
  async function saveReminderStore(workingDir, store) {
10963
11994
  const storePath = await getStorePath(workingDir);
10964
11995
  store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
10965
- await writeFile9(storePath, JSON.stringify(store, null, 2), "utf-8");
11996
+ await writeFile13(storePath, JSON.stringify(store, null, 2), "utf-8");
10966
11997
  }
10967
11998
  async function getDueReminders(workingDir) {
10968
11999
  const store = await loadReminderStore(workingDir);
@@ -11208,13 +12239,13 @@ var init_reminder = __esm({
11208
12239
  });
11209
12240
 
11210
12241
  // packages/execution/dist/tools/agenda.js
11211
- import { readFile as readFile11, writeFile as writeFile10, mkdir as mkdir6 } from "node:fs/promises";
11212
- import { resolve as resolve23, join as join27 } from "node:path";
12242
+ import { readFile as readFile15, writeFile as writeFile14, mkdir as mkdir10 } from "node:fs/promises";
12243
+ import { resolve as resolve23, join as join31 } from "node:path";
11213
12244
  import { randomBytes as randomBytes5 } from "node:crypto";
11214
12245
  async function loadAttentionStore(workingDir) {
11215
12246
  const storePath = resolve23(workingDir, ".oa", "scheduled", "attention.json");
11216
12247
  try {
11217
- const raw = await readFile11(storePath, "utf-8");
12248
+ const raw = await readFile15(storePath, "utf-8");
11218
12249
  return JSON.parse(raw);
11219
12250
  } catch {
11220
12251
  return { items: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
@@ -11222,9 +12253,9 @@ async function loadAttentionStore(workingDir) {
11222
12253
  }
11223
12254
  async function saveAttentionStore(workingDir, store) {
11224
12255
  const dir = resolve23(workingDir, ".oa", "scheduled");
11225
- await mkdir6(dir, { recursive: true });
12256
+ await mkdir10(dir, { recursive: true });
11226
12257
  store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
11227
- await writeFile10(join27(dir, "attention.json"), JSON.stringify(store, null, 2), "utf-8");
12258
+ await writeFile14(join31(dir, "attention.json"), JSON.stringify(store, null, 2), "utf-8");
11228
12259
  }
11229
12260
  async function getActiveAttentionItems(workingDir) {
11230
12261
  const store = await loadAttentionStore(workingDir);
@@ -11520,7 +12551,7 @@ ${sections.join("\n")}`,
11520
12551
  async loadScheduleStore() {
11521
12552
  try {
11522
12553
  const storePath = resolve23(this.workingDir, ".oa", "scheduled", "tasks.json");
11523
- const raw = await readFile11(storePath, "utf-8");
12554
+ const raw = await readFile15(storePath, "utf-8");
11524
12555
  const store = JSON.parse(raw);
11525
12556
  return store.tasks ?? [];
11526
12557
  } catch {
@@ -11534,7 +12565,7 @@ ${sections.join("\n")}`,
11534
12565
  // packages/execution/dist/tools/opencode.js
11535
12566
  import { execSync as execSync19, spawn as spawn10 } from "node:child_process";
11536
12567
  import { existsSync as existsSync21 } from "node:fs";
11537
- import { join as join28, resolve as resolve24 } from "node:path";
12568
+ import { join as join32, resolve as resolve24 } from "node:path";
11538
12569
  function findOpencode() {
11539
12570
  for (const cmd of ["opencode"]) {
11540
12571
  try {
@@ -11546,8 +12577,8 @@ function findOpencode() {
11546
12577
  }
11547
12578
  const homeDir = process.env.HOME || process.env.USERPROFILE || "";
11548
12579
  const candidates = [
11549
- join28(homeDir, ".opencode", "bin", "opencode"),
11550
- join28(homeDir, "bin", "opencode"),
12580
+ join32(homeDir, ".opencode", "bin", "opencode"),
12581
+ join32(homeDir, "bin", "opencode"),
11551
12582
  "/usr/local/bin/opencode"
11552
12583
  ];
11553
12584
  for (const p of candidates) {
@@ -11808,7 +12839,7 @@ var init_opencode = __esm({
11808
12839
  // packages/execution/dist/tools/factory.js
11809
12840
  import { execSync as execSync20, spawn as spawn11 } from "node:child_process";
11810
12841
  import { existsSync as existsSync22 } from "node:fs";
11811
- import { join as join29 } from "node:path";
12842
+ import { join as join33 } from "node:path";
11812
12843
  function findDroid() {
11813
12844
  for (const cmd of ["droid"]) {
11814
12845
  try {
@@ -11820,8 +12851,8 @@ function findDroid() {
11820
12851
  }
11821
12852
  const homeDir = process.env.HOME || process.env.USERPROFILE || "";
11822
12853
  const candidates = [
11823
- join29(homeDir, ".factory", "bin", "droid"),
11824
- join29(homeDir, "bin", "droid"),
12854
+ join33(homeDir, ".factory", "bin", "droid"),
12855
+ join33(homeDir, "bin", "droid"),
11825
12856
  "/usr/local/bin/droid"
11826
12857
  ];
11827
12858
  for (const p of candidates) {
@@ -12116,8 +13147,8 @@ var init_factory = __esm({
12116
13147
 
12117
13148
  // packages/execution/dist/tools/cron-agent.js
12118
13149
  import { execSync as execSync21 } from "node:child_process";
12119
- import { readFile as readFile12, writeFile as writeFile11, mkdir as mkdir7 } from "node:fs/promises";
12120
- import { resolve as resolve25, join as join30 } from "node:path";
13150
+ import { readFile as readFile16, writeFile as writeFile15, mkdir as mkdir11 } from "node:fs/promises";
13151
+ import { resolve as resolve25, join as join34 } from "node:path";
12121
13152
  import { randomBytes as randomBytes6 } from "node:crypto";
12122
13153
  function isValidCron2(expr) {
12123
13154
  const parts = expr.trim().split(/\s+/);
@@ -12203,7 +13234,7 @@ function installCronAgentJob(job, workingDir) {
12203
13234
  const lines = getCurrentCrontab2();
12204
13235
  const oaBin = findOaBinary2();
12205
13236
  const logDir = resolve25(workingDir, ".oa", "cron-agents", "logs");
12206
- const logFile = join30(logDir, `${job.id}.log`);
13237
+ const logFile = join34(logDir, `${job.id}.log`);
12207
13238
  const storeFile = resolve25(workingDir, ".oa", "cron-agents", "store.json");
12208
13239
  const taskEscaped = job.task.replace(/'/g, "'\\''");
12209
13240
  const jobId = job.id;
@@ -12233,7 +13264,7 @@ function removeCronAgentJob(jobId) {
12233
13264
  async function loadStore2(workingDir) {
12234
13265
  const storePath = resolve25(workingDir, ".oa", "cron-agents", "store.json");
12235
13266
  try {
12236
- const raw = await readFile12(storePath, "utf-8");
13267
+ const raw = await readFile16(storePath, "utf-8");
12237
13268
  return JSON.parse(raw);
12238
13269
  } catch {
12239
13270
  return { jobs: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
@@ -12241,10 +13272,10 @@ async function loadStore2(workingDir) {
12241
13272
  }
12242
13273
  async function saveStore2(workingDir, store) {
12243
13274
  const dir = resolve25(workingDir, ".oa", "cron-agents");
12244
- await mkdir7(dir, { recursive: true });
12245
- await mkdir7(join30(dir, "logs"), { recursive: true });
13275
+ await mkdir11(dir, { recursive: true });
13276
+ await mkdir11(join34(dir, "logs"), { recursive: true });
12246
13277
  store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
12247
- await writeFile11(join30(dir, "store.json"), JSON.stringify(store, null, 2), "utf-8");
13278
+ await writeFile15(join34(dir, "store.json"), JSON.stringify(store, null, 2), "utf-8");
12248
13279
  }
12249
13280
  var LONG_HORIZON_PRESETS, CRON_AGENT_MARKER, CronAgentTool;
12250
13281
  var init_cron_agent = __esm({
@@ -12509,7 +13540,7 @@ var init_cron_agent = __esm({
12509
13540
  return { success: false, output: "", error: "id is required", durationMs: performance.now() - start };
12510
13541
  const logFile = resolve25(this.workingDir, ".oa", "cron-agents", "logs", `${id}.log`);
12511
13542
  try {
12512
- const raw = await readFile12(logFile, "utf-8");
13543
+ const raw = await readFile16(logFile, "utf-8");
12513
13544
  const truncated = raw.length > 2e4 ? "...(truncated)\n" + raw.slice(-2e4) : raw;
12514
13545
  return { success: true, output: `Logs for ${id}:
12515
13546
  ${truncated}`, durationMs: performance.now() - start };
@@ -12580,9 +13611,9 @@ ${truncated}`, durationMs: performance.now() - start };
12580
13611
  });
12581
13612
 
12582
13613
  // packages/execution/dist/tools/nexus.js
12583
- import { readFile as readFile13, writeFile as writeFile12, mkdir as mkdir8, chmod, unlink, readdir as readdir3, open as fsOpen } from "node:fs/promises";
13614
+ import { readFile as readFile17, writeFile as writeFile16, mkdir as mkdir12, chmod, unlink, readdir as readdir3, open as fsOpen } from "node:fs/promises";
12584
13615
  import { existsSync as existsSync23, readFileSync as readFileSync16, watch as fsWatchLocal } from "node:fs";
12585
- import { resolve as resolve26, join as join31 } from "node:path";
13616
+ import { resolve as resolve26, join as join35 } from "node:path";
12586
13617
  import { randomBytes as randomBytes7, createCipheriv, createDecipheriv, scryptSync, createHash } from "node:crypto";
12587
13618
  import { execSync as execSync22, spawn as spawn12 } from "node:child_process";
12588
13619
  import { hostname, userInfo } from "node:os";
@@ -14555,7 +15586,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14555
15586
  }
14556
15587
  async ensureDir() {
14557
15588
  if (!existsSync23(this.nexusDir)) {
14558
- await mkdir8(this.nexusDir, { recursive: true });
15589
+ await mkdir12(this.nexusDir, { recursive: true });
14559
15590
  }
14560
15591
  }
14561
15592
  async execute(args) {
@@ -14675,7 +15706,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14675
15706
  // Daemon management
14676
15707
  // =========================================================================
14677
15708
  getDaemonPid() {
14678
- const pidFile = join31(this.nexusDir, "daemon.pid");
15709
+ const pidFile = join35(this.nexusDir, "daemon.pid");
14679
15710
  if (!existsSync23(pidFile))
14680
15711
  return null;
14681
15712
  try {
@@ -14701,12 +15732,12 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14701
15732
  throw new Error("Nexus daemon not running. Use action 'connect' first.");
14702
15733
  }
14703
15734
  const cmdId = randomBytes7(8).toString("hex");
14704
- const cmdFile = join31(this.nexusDir, "cmd.json");
14705
- const respFile = join31(this.nexusDir, "resp.json");
15735
+ const cmdFile = join35(this.nexusDir, "cmd.json");
15736
+ const respFile = join35(this.nexusDir, "resp.json");
14706
15737
  if (existsSync23(respFile))
14707
15738
  await unlink(respFile).catch(() => {
14708
15739
  });
14709
- await writeFile12(cmdFile, JSON.stringify({ id: cmdId, action, args }, null, 2));
15740
+ await writeFile16(cmdFile, JSON.stringify({ id: cmdId, action, args }, null, 2));
14710
15741
  const pollMs = 50;
14711
15742
  const polls = Math.ceil(timeoutMs / pollMs);
14712
15743
  let resolved = false;
@@ -14738,7 +15769,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14738
15769
  if (!existsSync23(respFile))
14739
15770
  continue;
14740
15771
  try {
14741
- const resp = JSON.parse(await readFile13(respFile, "utf8"));
15772
+ const resp = JSON.parse(await readFile17(respFile, "utf8"));
14742
15773
  if (resp.id === cmdId) {
14743
15774
  resolved = true;
14744
15775
  return resp.output || (resp.ok ? "OK" : "Failed");
@@ -14761,7 +15792,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14761
15792
  }
14762
15793
  if (existsSync23(respFile)) {
14763
15794
  try {
14764
- const resp = JSON.parse(await readFile13(respFile, "utf8"));
15795
+ const resp = JSON.parse(await readFile17(respFile, "utf8"));
14765
15796
  if (resp.id === cmdId) {
14766
15797
  return resp.output || (resp.ok ? "OK" : "Failed");
14767
15798
  }
@@ -14786,7 +15817,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14786
15817
  const currentScriptHash = createHash("sha256").update(DAEMON_SCRIPT).digest("hex").slice(0, 16);
14787
15818
  const existingPid = this.getDaemonPid();
14788
15819
  if (existingPid) {
14789
- const daemonPath2 = join31(this.nexusDir, "nexus-daemon.mjs");
15820
+ const daemonPath2 = join35(this.nexusDir, "nexus-daemon.mjs");
14790
15821
  let needsRestart = true;
14791
15822
  if (existsSync23(daemonPath2)) {
14792
15823
  try {
@@ -14810,16 +15841,16 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14810
15841
  } catch {
14811
15842
  }
14812
15843
  for (const f of ["daemon.pid", "status.json", "cmd.json", "resp.json"]) {
14813
- const p = join31(this.nexusDir, f);
15844
+ const p = join35(this.nexusDir, f);
14814
15845
  if (existsSync23(p))
14815
15846
  await unlink(p).catch(() => {
14816
15847
  });
14817
15848
  }
14818
15849
  } else {
14819
- const statusFile2 = join31(this.nexusDir, "status.json");
15850
+ const statusFile2 = join35(this.nexusDir, "status.json");
14820
15851
  if (existsSync23(statusFile2)) {
14821
15852
  try {
14822
- const status = JSON.parse(await readFile13(statusFile2, "utf8"));
15853
+ const status = JSON.parse(await readFile17(statusFile2, "utf8"));
14823
15854
  if (status.connected && status.peerId) {
14824
15855
  await this.ensureWallet();
14825
15856
  return `Already connected (pid: ${existingPid}, peerId: ${status.peerId})`;
@@ -14835,7 +15866,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14835
15866
  }
14836
15867
  }
14837
15868
  for (const f of ["daemon.pid", "status.json", "cmd.json", "resp.json"]) {
14838
- const p = join31(this.nexusDir, f);
15869
+ const p = join35(this.nexusDir, f);
14839
15870
  if (existsSync23(p))
14840
15871
  await unlink(p).catch(() => {
14841
15872
  });
@@ -14853,7 +15884,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14853
15884
  });
14854
15885
  });
14855
15886
  try {
14856
- const nexusPkg = join31(nodeModulesDir, "open-agents-nexus", "package.json");
15887
+ const nexusPkg = join35(nodeModulesDir, "open-agents-nexus", "package.json");
14857
15888
  if (existsSync23(nexusPkg)) {
14858
15889
  nexusResolved = true;
14859
15890
  try {
@@ -14864,7 +15895,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14864
15895
  } else {
14865
15896
  try {
14866
15897
  const globalDir = await execAsync2("npm root -g", { timeout: 5e3 });
14867
- const globalPkg = join31(globalDir, "open-agents-nexus", "package.json");
15898
+ const globalPkg = join35(globalDir, "open-agents-nexus", "package.json");
14868
15899
  if (existsSync23(globalPkg)) {
14869
15900
  nexusResolved = true;
14870
15901
  try {
@@ -14909,8 +15940,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14909
15940
  }
14910
15941
  }
14911
15942
  await this.ensureWallet();
14912
- const daemonPath = join31(this.nexusDir, "nexus-daemon.mjs");
14913
- await writeFile12(daemonPath, DAEMON_SCRIPT);
15943
+ const daemonPath = join35(this.nexusDir, "nexus-daemon.mjs");
15944
+ await writeFile16(daemonPath, DAEMON_SCRIPT);
14914
15945
  const agentName = args.agent_name || "open-agents-node";
14915
15946
  const agentType = args.agent_type || "general";
14916
15947
  const nodePaths = [nodeModulesDir];
@@ -14920,8 +15951,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14920
15951
  } catch {
14921
15952
  }
14922
15953
  const { openSync: openSync2, closeSync: closeSync2 } = await import("node:fs");
14923
- const daemonLogPath = join31(this.nexusDir, "daemon.log");
14924
- const daemonErrPath = join31(this.nexusDir, "daemon.err");
15954
+ const daemonLogPath = join35(this.nexusDir, "daemon.log");
15955
+ const daemonErrPath = join35(this.nexusDir, "daemon.err");
14925
15956
  const outFd = openSync2(daemonLogPath, "w");
14926
15957
  const errFd = openSync2(daemonErrPath, "w");
14927
15958
  const child = spawn12("node", [daemonPath, this.nexusDir, agentName, agentType], {
@@ -14939,16 +15970,16 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14939
15970
  closeSync2(errFd);
14940
15971
  } catch {
14941
15972
  }
14942
- const statusFile = join31(this.nexusDir, "status.json");
15973
+ const statusFile = join35(this.nexusDir, "status.json");
14943
15974
  for (let i = 0; i < 40; i++) {
14944
15975
  await new Promise((r) => setTimeout(r, 500));
14945
15976
  if (existsSync23(statusFile)) {
14946
15977
  try {
14947
- const status = JSON.parse(await readFile13(statusFile, "utf8"));
15978
+ const status = JSON.parse(await readFile17(statusFile, "utf8"));
14948
15979
  if (status.error) {
14949
15980
  let errTail = "";
14950
15981
  try {
14951
- errTail = (await readFile13(daemonErrPath, "utf8")).slice(-300);
15982
+ errTail = (await readFile17(daemonErrPath, "utf8")).slice(-300);
14952
15983
  } catch {
14953
15984
  }
14954
15985
  return `Nexus daemon failed to connect: ${status.error}${errTail ? "\n" + errTail : ""}`;
@@ -14970,12 +16001,12 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14970
16001
  const pid = this.getDaemonPid();
14971
16002
  let earlyError = "";
14972
16003
  try {
14973
- earlyError = (await readFile13(daemonErrPath, "utf8")).slice(-500);
16004
+ earlyError = (await readFile17(daemonErrPath, "utf8")).slice(-500);
14974
16005
  } catch {
14975
16006
  }
14976
16007
  let earlyOutput = "";
14977
16008
  try {
14978
- earlyOutput = (await readFile13(daemonLogPath, "utf8")).slice(-500);
16009
+ earlyOutput = (await readFile17(daemonLogPath, "utf8")).slice(-500);
14979
16010
  } catch {
14980
16011
  }
14981
16012
  if (pid) {
@@ -14998,7 +16029,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14998
16029
  } catch {
14999
16030
  }
15000
16031
  for (const f of ["daemon.pid", "status.json", "cmd.json", "resp.json"]) {
15001
- const p = join31(this.nexusDir, f);
16032
+ const p = join35(this.nexusDir, f);
15002
16033
  if (existsSync23(p))
15003
16034
  await unlink(p).catch(() => {
15004
16035
  });
@@ -15009,11 +16040,11 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15009
16040
  const pid = this.getDaemonPid();
15010
16041
  if (!pid)
15011
16042
  return "Nexus daemon not running. Use action 'connect' to start.";
15012
- const statusFile = join31(this.nexusDir, "status.json");
16043
+ const statusFile = join35(this.nexusDir, "status.json");
15013
16044
  if (!existsSync23(statusFile))
15014
16045
  return `Daemon running (pid: ${pid}) but no status yet.`;
15015
16046
  try {
15016
- const status = JSON.parse(await readFile13(statusFile, "utf8"));
16047
+ const status = JSON.parse(await readFile17(statusFile, "utf8"));
15017
16048
  const lines = [
15018
16049
  `Nexus Status (v1.5.0)`,
15019
16050
  ` Connected: ${status.connected}`,
@@ -15024,10 +16055,10 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15024
16055
  ` Capabilities: ${(status.capabilities || []).length ? (status.capabilities || []).join(", ") : "none"}`,
15025
16056
  ` Blocked peers: ${(status.blockedPeers || []).length || 0}`
15026
16057
  ];
15027
- const walletPath = join31(this.nexusDir, "wallet.enc");
16058
+ const walletPath = join35(this.nexusDir, "wallet.enc");
15028
16059
  if (existsSync23(walletPath)) {
15029
16060
  try {
15030
- const w = JSON.parse(await readFile13(walletPath, "utf8"));
16061
+ const w = JSON.parse(await readFile17(walletPath, "utf8"));
15031
16062
  lines.push(` Wallet: ${w.address}`);
15032
16063
  } catch {
15033
16064
  lines.push(` Wallet: corrupt`);
@@ -15035,14 +16066,14 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15035
16066
  } else {
15036
16067
  lines.push(` Wallet: not configured`);
15037
16068
  }
15038
- const inboxDir = join31(this.nexusDir, "inbox");
16069
+ const inboxDir = join35(this.nexusDir, "inbox");
15039
16070
  if (existsSync23(inboxDir)) {
15040
16071
  try {
15041
16072
  const roomDirs = await readdir3(inboxDir);
15042
16073
  let totalMsgs = 0;
15043
16074
  for (const rd of roomDirs) {
15044
16075
  try {
15045
- totalMsgs += (await readdir3(join31(inboxDir, rd))).length;
16076
+ totalMsgs += (await readdir3(join35(inboxDir, rd))).length;
15046
16077
  } catch {
15047
16078
  }
15048
16079
  }
@@ -15089,9 +16120,9 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15089
16120
  }
15090
16121
  async doReadMessages(args) {
15091
16122
  const roomId = args.room_id;
15092
- const inboxDir = join31(this.nexusDir, "inbox");
16123
+ const inboxDir = join35(this.nexusDir, "inbox");
15093
16124
  if (roomId) {
15094
- const roomInbox = join31(inboxDir, roomId);
16125
+ const roomInbox = join35(inboxDir, roomId);
15095
16126
  if (!existsSync23(roomInbox))
15096
16127
  return `No messages in room: ${roomId}`;
15097
16128
  const files = (await readdir3(roomInbox)).sort().slice(-20);
@@ -15100,7 +16131,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15100
16131
  const messages = [`Messages in ${roomId} (last ${files.length}):`];
15101
16132
  for (const f of files) {
15102
16133
  try {
15103
- const msg = JSON.parse(await readFile13(join31(roomInbox, f), "utf8"));
16134
+ const msg = JSON.parse(await readFile17(join35(roomInbox, f), "utf8"));
15104
16135
  const sender = (msg.sender || "unknown").slice(0, 12);
15105
16136
  messages.push(` [${new Date(msg.timestamp).toLocaleTimeString()}] ${sender}...: ${msg.content}`);
15106
16137
  } catch {
@@ -15116,7 +16147,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15116
16147
  const lines = ["Inbox:"];
15117
16148
  for (const rd of roomDirs) {
15118
16149
  try {
15119
- const count = (await readdir3(join31(inboxDir, rd))).length;
16150
+ const count = (await readdir3(join35(inboxDir, rd))).length;
15120
16151
  lines.push(` ${rd}: ${count} message(s)`);
15121
16152
  } catch {
15122
16153
  }
@@ -15128,12 +16159,12 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15128
16159
  // ---------------------------------------------------------------------------
15129
16160
  async doWalletStatus() {
15130
16161
  await this.ensureDir();
15131
- const walletPath = join31(this.nexusDir, "wallet.enc");
16162
+ const walletPath = join35(this.nexusDir, "wallet.enc");
15132
16163
  if (!existsSync23(walletPath)) {
15133
16164
  return "No wallet configured. Use wallet_create to set one up.";
15134
16165
  }
15135
16166
  try {
15136
- const w = JSON.parse(await readFile13(walletPath, "utf8"));
16167
+ const w = JSON.parse(await readFile17(walletPath, "utf8"));
15137
16168
  const lines = [
15138
16169
  `Wallet Status:`,
15139
16170
  ` Address: ${w.address}`,
@@ -15167,7 +16198,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15167
16198
  }
15168
16199
  async doWalletCreate(args) {
15169
16200
  await this.ensureDir();
15170
- const walletPath = join31(this.nexusDir, "wallet.enc");
16201
+ const walletPath = join35(this.nexusDir, "wallet.enc");
15171
16202
  if (existsSync23(walletPath))
15172
16203
  return "Wallet already exists. Delete wallet.enc to create a new one.";
15173
16204
  const userAddress = args.wallet_address;
@@ -15213,7 +16244,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15213
16244
  const cipher = createCipheriv("aes-256-gcm", key, iv);
15214
16245
  let enc = cipher.update(privKeyHex, "utf8", "hex");
15215
16246
  enc += cipher.final("hex");
15216
- const x402KeyPath = join31(this.nexusDir, "x402-wallet.key");
16247
+ const x402KeyPath = join35(this.nexusDir, "x402-wallet.key");
15217
16248
  const x402Fh = await fsOpen(x402KeyPath, "w", 384);
15218
16249
  await x402Fh.writeFile("0x" + privKeyHex);
15219
16250
  await x402Fh.close();
@@ -15251,7 +16282,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15251
16282
  * Silent — no user output, just ensures the files exist.
15252
16283
  */
15253
16284
  async ensureWallet() {
15254
- const walletPath = join31(this.nexusDir, "wallet.enc");
16285
+ const walletPath = join35(this.nexusDir, "wallet.enc");
15255
16286
  if (existsSync23(walletPath))
15256
16287
  return;
15257
16288
  let address;
@@ -15275,7 +16306,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15275
16306
  const cipher = createCipheriv("aes-256-gcm", key, iv);
15276
16307
  let enc = cipher.update(privKeyHex, "utf8", "hex");
15277
16308
  enc += cipher.final("hex");
15278
- const x402KeyPath = join31(this.nexusDir, "x402-wallet.key");
16309
+ const x402KeyPath = join35(this.nexusDir, "x402-wallet.key");
15279
16310
  const x402Fh = await fsOpen(x402KeyPath, "w", 384);
15280
16311
  await x402Fh.writeFile("0x" + privKeyHex);
15281
16312
  await x402Fh.close();
@@ -15335,12 +16366,12 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15335
16366
  // ---------------------------------------------------------------------------
15336
16367
  async doLedgerStatus() {
15337
16368
  await this.ensureDir();
15338
- const ledgerPath = join31(this.nexusDir, "ledger.jsonl");
16369
+ const ledgerPath = join35(this.nexusDir, "ledger.jsonl");
15339
16370
  if (!existsSync23(ledgerPath)) {
15340
16371
  return "No ledger entries. Earnings and spending will be tracked here after x402 transactions.";
15341
16372
  }
15342
16373
  try {
15343
- const raw = await readFile13(ledgerPath, "utf8");
16374
+ const raw = await readFile17(ledgerPath, "utf8");
15344
16375
  const entries = raw.trim().split("\n").filter((l) => l.trim()).map((l) => JSON.parse(l));
15345
16376
  if (entries.length === 0) {
15346
16377
  return "Ledger is empty. No transactions recorded.";
@@ -15377,11 +16408,11 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15377
16408
  }
15378
16409
  }
15379
16410
  async getLedgerSummary() {
15380
- const ledgerPath = join31(this.nexusDir, "ledger.jsonl");
16411
+ const ledgerPath = join35(this.nexusDir, "ledger.jsonl");
15381
16412
  if (!existsSync23(ledgerPath))
15382
16413
  return null;
15383
16414
  try {
15384
- const raw = await readFile13(ledgerPath, "utf8");
16415
+ const raw = await readFile17(ledgerPath, "utf8");
15385
16416
  const entries = raw.trim().split("\n").filter((l) => l.trim()).map((l) => JSON.parse(l));
15386
16417
  let totalEarned = 0n, totalSpent = 0n;
15387
16418
  for (const e of entries) {
@@ -15402,25 +16433,25 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15402
16433
  }
15403
16434
  async appendLedger(entry) {
15404
16435
  await this.ensureDir();
15405
- const ledgerPath = join31(this.nexusDir, "ledger.jsonl");
16436
+ const ledgerPath = join35(this.nexusDir, "ledger.jsonl");
15406
16437
  const line = JSON.stringify(entry) + "\n";
15407
- await writeFile12(ledgerPath, existsSync23(ledgerPath) ? await readFile13(ledgerPath, "utf8") + line : line);
16438
+ await writeFile16(ledgerPath, existsSync23(ledgerPath) ? await readFile17(ledgerPath, "utf8") + line : line);
15408
16439
  }
15409
16440
  // ---------------------------------------------------------------------------
15410
16441
  // Step 4: Budget Policy — Spending limits and auto-approve thresholds
15411
16442
  // ---------------------------------------------------------------------------
15412
16443
  async loadBudget() {
15413
- const budgetPath = join31(this.nexusDir, "budget.json");
16444
+ const budgetPath = join35(this.nexusDir, "budget.json");
15414
16445
  if (!existsSync23(budgetPath))
15415
16446
  return null;
15416
16447
  try {
15417
- return JSON.parse(await readFile13(budgetPath, "utf8"));
16448
+ return JSON.parse(await readFile17(budgetPath, "utf8"));
15418
16449
  } catch {
15419
16450
  return null;
15420
16451
  }
15421
16452
  }
15422
16453
  async ensureDefaultBudget() {
15423
- const budgetPath = join31(this.nexusDir, "budget.json");
16454
+ const budgetPath = join35(this.nexusDir, "budget.json");
15424
16455
  if (existsSync23(budgetPath))
15425
16456
  return;
15426
16457
  const defaultBudget = {
@@ -15441,7 +16472,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15441
16472
  deniedPeers: []
15442
16473
  };
15443
16474
  await this.ensureDir();
15444
- await writeFile12(budgetPath, JSON.stringify(defaultBudget, null, 2));
16475
+ await writeFile16(budgetPath, JSON.stringify(defaultBudget, null, 2));
15445
16476
  }
15446
16477
  async doBudgetStatus() {
15447
16478
  await this.ensureDir();
@@ -15490,17 +16521,17 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15490
16521
  if (changes.length === 0) {
15491
16522
  return "No budget parameters provided. Use daily_limit, per_invoke_max, or auto_approve_below.";
15492
16523
  }
15493
- const budgetPath = join31(this.nexusDir, "budget.json");
15494
- await writeFile12(budgetPath, JSON.stringify(budget, null, 2));
16524
+ const budgetPath = join35(this.nexusDir, "budget.json");
16525
+ await writeFile16(budgetPath, JSON.stringify(budget, null, 2));
15495
16526
  return `Budget updated: ${changes.join(", ")}`;
15496
16527
  }
15497
16528
  async getTodaySpending() {
15498
- const ledgerPath = join31(this.nexusDir, "ledger.jsonl");
16529
+ const ledgerPath = join35(this.nexusDir, "ledger.jsonl");
15499
16530
  if (!existsSync23(ledgerPath))
15500
16531
  return 0;
15501
16532
  try {
15502
16533
  const todayPrefix = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
15503
- const raw = await readFile13(ledgerPath, "utf8");
16534
+ const raw = await readFile17(ledgerPath, "utf8");
15504
16535
  let total = 0;
15505
16536
  for (const line of raw.trim().split("\n")) {
15506
16537
  if (!line.trim())
@@ -15539,10 +16570,10 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15539
16570
  if (todaySpent + amountUsdc > budget.dailyLimitUsdc) {
15540
16571
  return { allowed: false, reason: `Would exceed daily limit ($${((todaySpent + amountUsdc) / 1e6).toFixed(6)} > $${(budget.dailyLimitUsdc / 1e6).toFixed(6)})` };
15541
16572
  }
15542
- const walletPath = join31(this.nexusDir, "wallet.enc");
16573
+ const walletPath = join35(this.nexusDir, "wallet.enc");
15543
16574
  if (existsSync23(walletPath)) {
15544
16575
  try {
15545
- const w = JSON.parse(await readFile13(walletPath, "utf8"));
16576
+ const w = JSON.parse(await readFile17(walletPath, "utf8"));
15546
16577
  if (w.version === 2 && w.address) {
15547
16578
  const balance = await this.queryUsdcBalance(w.address, w.chainId || 8453);
15548
16579
  if (balance !== null && Number(balance) < budget.circuitBreakerUsdc) {
@@ -15570,10 +16601,10 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15570
16601
  const budgetResult = await this.checkBudget(amountSmallest, "transfer:direct", targetAddress);
15571
16602
  if (!budgetResult.allowed)
15572
16603
  return `BLOCKED by budget policy: ${budgetResult.reason}`;
15573
- const walletPath = join31(this.nexusDir, "wallet.enc");
16604
+ const walletPath = join35(this.nexusDir, "wallet.enc");
15574
16605
  if (!existsSync23(walletPath))
15575
16606
  throw new Error("No wallet. Use wallet_create first.");
15576
- const w = JSON.parse(await readFile13(walletPath, "utf8"));
16607
+ const w = JSON.parse(await readFile17(walletPath, "utf8"));
15577
16608
  if (!w.encryptedKey)
15578
16609
  throw new Error("User-managed wallet cannot spend (no private key)");
15579
16610
  const salt = Buffer.from(w.salt, "hex");
@@ -15631,7 +16662,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15631
16662
  capability: "transfer:direct",
15632
16663
  note: "signed, awaiting submission"
15633
16664
  });
15634
- const proofFile = join31(this.nexusDir, "pending-transfer.json");
16665
+ const proofFile = join35(this.nexusDir, "pending-transfer.json");
15635
16666
  const proof = {
15636
16667
  from: account.address,
15637
16668
  to: targetAddress,
@@ -15644,7 +16675,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15644
16675
  usdcContract: USDC_ADDRESS,
15645
16676
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
15646
16677
  };
15647
- await writeFile12(proofFile, JSON.stringify(proof, null, 2));
16678
+ await writeFile16(proofFile, JSON.stringify(proof, null, 2));
15648
16679
  return [
15649
16680
  `Transfer signed (EIP-3009 TransferWithAuthorization):`,
15650
16681
  ` From: ${account.address}`,
@@ -15673,10 +16704,10 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15673
16704
  throw new Error("prompt is required");
15674
16705
  const estimatedTokens = Math.ceil(prompt.length / 4) + 1e3;
15675
16706
  let estimatedCostSmallest = 0;
15676
- const pricingPath = join31(this.nexusDir, "pricing.json");
16707
+ const pricingPath = join35(this.nexusDir, "pricing.json");
15677
16708
  if (existsSync23(pricingPath)) {
15678
16709
  try {
15679
- const pricing = JSON.parse(await readFile13(pricingPath, "utf8"));
16710
+ const pricing = JSON.parse(await readFile17(pricingPath, "utf8"));
15680
16711
  const modelPricing = (pricing.models || []).find((m) => m.model === model || m.model.startsWith(model.split(":")[0]));
15681
16712
  if (modelPricing?.pricing?.input_per_1m_tokens > 0) {
15682
16713
  estimatedCostSmallest = Math.ceil(estimatedTokens / 1e6 * modelPricing.pricing.input_per_1m_tokens * 1e6);
@@ -15793,7 +16824,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15793
16824
  const bar = (s) => "\u2588".repeat(Math.round(s / 5)) + "\u2591".repeat(20 - Math.round(s / 5));
15794
16825
  const mem = vramMb > 24e3 ? 95 : vramMb > 16e3 ? 80 : vramMb > 8e3 ? 60 : vramMb > 0 ? 40 : 20;
15795
16826
  await this.ensureDir();
15796
- await writeFile12(join31(this.nexusDir, "inference-proof.json"), JSON.stringify({
16827
+ await writeFile16(join35(this.nexusDir, "inference-proof.json"), JSON.stringify({
15797
16828
  modelName,
15798
16829
  gpuName,
15799
16830
  vramMb,
@@ -16434,6 +17465,7 @@ __export(dist_exports, {
16434
17465
  DesktopClickTool: () => DesktopClickTool,
16435
17466
  DesktopDescribeTool: () => DesktopDescribeTool,
16436
17467
  DiagnosticTool: () => DiagnosticTool,
17468
+ ExplorationCultureTool: () => ExplorationCultureTool,
16437
17469
  ExploreToolsTool: () => ExploreToolsTool,
16438
17470
  FactoryTool: () => FactoryTool,
16439
17471
  FileEditTool: () => FileEditTool,
@@ -16443,9 +17475,11 @@ __export(dist_exports, {
16443
17475
  GitInfoTool: () => GitInfoTool,
16444
17476
  GlobFindTool: () => GlobFindTool,
16445
17477
  GrepSearchTool: () => GrepSearchTool,
17478
+ IdentityKernelTool: () => IdentityKernelTool,
16446
17479
  ImageReadTool: () => ImageReadTool,
16447
17480
  ListDirectoryTool: () => ListDirectoryTool,
16448
17481
  ManageToolsTool: () => ManageToolsTool,
17482
+ MemoryMetabolismTool: () => MemoryMetabolismTool,
16449
17483
  MemoryReadTool: () => MemoryReadTool,
16450
17484
  MemorySearchTool: () => MemorySearchTool,
16451
17485
  MemoryWriteTool: () => MemoryWriteTool,
@@ -16455,6 +17489,7 @@ __export(dist_exports, {
16455
17489
  OcrPdfTool: () => OcrPdfTool,
16456
17490
  OpenCodeTool: () => OpenCodeTool,
16457
17491
  PdfToTextTool: () => PdfToTextTool,
17492
+ ReflectionIntegrityTool: () => ReflectionIntegrityTool,
16458
17493
  ReminderTool: () => ReminderTool,
16459
17494
  ReplTool: () => ReplTool,
16460
17495
  SchedulerTool: () => SchedulerTool,
@@ -16542,6 +17577,10 @@ var init_dist2 = __esm({
16542
17577
  init_structured_file();
16543
17578
  init_code_sandbox();
16544
17579
  init_repl();
17580
+ init_memory_metabolism();
17581
+ init_identity_kernel();
17582
+ init_reflection_integrity();
17583
+ init_exploration_culture();
16545
17584
  init_structured_read();
16546
17585
  init_vision();
16547
17586
  init_desktop_click();
@@ -17242,12 +18281,12 @@ var init_dist3 = __esm({
17242
18281
 
17243
18282
  // packages/orchestrator/dist/promptLoader.js
17244
18283
  import { readFileSync as readFileSync18, existsSync as existsSync25 } from "node:fs";
17245
- import { join as join32, dirname as dirname12 } from "node:path";
18284
+ import { join as join36, dirname as dirname12 } from "node:path";
17246
18285
  import { fileURLToPath as fileURLToPath7 } from "node:url";
17247
18286
  function loadPrompt(promptPath, vars) {
17248
18287
  let content = cache.get(promptPath);
17249
18288
  if (content === void 0) {
17250
- const fullPath = join32(PROMPTS_DIR, promptPath);
18289
+ const fullPath = join36(PROMPTS_DIR, promptPath);
17251
18290
  if (!existsSync25(fullPath)) {
17252
18291
  throw new Error(`Prompt file not found: ${fullPath}`);
17253
18292
  }
@@ -17264,7 +18303,7 @@ var init_promptLoader = __esm({
17264
18303
  "use strict";
17265
18304
  __filename = fileURLToPath7(import.meta.url);
17266
18305
  __dirname4 = dirname12(__filename);
17267
- PROMPTS_DIR = join32(__dirname4, "..", "prompts");
18306
+ PROMPTS_DIR = join36(__dirname4, "..", "prompts");
17268
18307
  cache = /* @__PURE__ */ new Map();
17269
18308
  }
17270
18309
  });
@@ -17627,8 +18666,8 @@ var init_code_retriever = __esm({
17627
18666
  });
17628
18667
  }
17629
18668
  async getFileContent(filePath, startLine, endLine) {
17630
- const { readFile: readFile18 } = await import("node:fs/promises");
17631
- const content = await readFile18(filePath, "utf-8");
18669
+ const { readFile: readFile22 } = await import("node:fs/promises");
18670
+ const content = await readFile22(filePath, "utf-8");
17632
18671
  if (startLine === void 0)
17633
18672
  return content;
17634
18673
  const lines = content.split("\n");
@@ -17643,8 +18682,8 @@ var init_code_retriever = __esm({
17643
18682
  // packages/retrieval/dist/lexicalSearch.js
17644
18683
  import { execFile as execFile5 } from "node:child_process";
17645
18684
  import { promisify as promisify4 } from "node:util";
17646
- import { readFile as readFile14, readdir as readdir4, stat as stat3 } from "node:fs/promises";
17647
- import { join as join33, extname as extname7 } from "node:path";
18685
+ import { readFile as readFile18, readdir as readdir4, stat as stat3 } from "node:fs/promises";
18686
+ import { join as join37, extname as extname7 } from "node:path";
17648
18687
  async function searchByPath(pathPattern, options) {
17649
18688
  const allFiles = await collectFiles(options.rootDir, options.includeGlobs ?? DEFAULT_INCLUDE_GLOBS, options.excludeGlobs ?? DEFAULT_EXCLUDE_GLOBS);
17650
18689
  const pattern = options.caseInsensitive ? pathPattern.toLowerCase() : pathPattern;
@@ -17749,7 +18788,7 @@ async function searchWithNodeFallback(pattern, kind, options) {
17749
18788
  if (results.length >= maxMatches)
17750
18789
  break;
17751
18790
  try {
17752
- const content = await readFile14(filePath, "utf-8");
18791
+ const content = await readFile18(filePath, "utf-8");
17753
18792
  const contentLines = content.split("\n");
17754
18793
  for (let i = 0; i < contentLines.length; i++) {
17755
18794
  if (results.length >= maxMatches)
@@ -17786,7 +18825,7 @@ async function walkForFiles(rootDir, dir, excludeGlobs, results) {
17786
18825
  continue;
17787
18826
  if (excludeGlobs.some((g) => entry.name === g || matchesGlob(entry.name, g)))
17788
18827
  continue;
17789
- const absPath = join33(dir, entry.name);
18828
+ const absPath = join37(dir, entry.name);
17790
18829
  if (entry.isDirectory()) {
17791
18830
  await walkForFiles(rootDir, absPath, excludeGlobs, results);
17792
18831
  } else if (entry.isFile()) {
@@ -18092,8 +19131,8 @@ var init_graphExpand = __esm({
18092
19131
  });
18093
19132
 
18094
19133
  // packages/retrieval/dist/snippetPacker.js
18095
- import { readFile as readFile15 } from "node:fs/promises";
18096
- import { join as join34 } from "node:path";
19134
+ import { readFile as readFile19 } from "node:fs/promises";
19135
+ import { join as join38 } from "node:path";
18097
19136
  async function packSnippets(requests, opts = {}) {
18098
19137
  const maxTokens = opts.maxTokens ?? DEFAULT_MAX_TOKENS;
18099
19138
  const contextLines = opts.contextLines ?? DEFAULT_CONTEXT_LINES;
@@ -18119,10 +19158,10 @@ async function packSnippets(requests, opts = {}) {
18119
19158
  return { packed, dropped, totalTokens };
18120
19159
  }
18121
19160
  async function extractSnippet(req, repoRoot, contextLines = DEFAULT_CONTEXT_LINES) {
18122
- const absPath = req.filePath.startsWith("/") ? req.filePath : join34(repoRoot, req.filePath);
19161
+ const absPath = req.filePath.startsWith("/") ? req.filePath : join38(repoRoot, req.filePath);
18123
19162
  let content;
18124
19163
  try {
18125
- content = await readFile15(absPath, "utf-8");
19164
+ content = await readFile19(absPath, "utf-8");
18126
19165
  } catch {
18127
19166
  return null;
18128
19167
  }
@@ -20713,8 +21752,8 @@ ${marker}` : marker);
20713
21752
  return;
20714
21753
  try {
20715
21754
  const { mkdirSync: mkdirSync21, writeFileSync: writeFileSync20 } = __require("node:fs");
20716
- const { join: join58 } = __require("node:path");
20717
- const sessionDir = join58(this._workingDirectory, ".oa", "session", this._sessionId);
21755
+ const { join: join62 } = __require("node:path");
21756
+ const sessionDir = join62(this._workingDirectory, ".oa", "session", this._sessionId);
20718
21757
  mkdirSync21(sessionDir, { recursive: true });
20719
21758
  const checkpoint = {
20720
21759
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -20727,7 +21766,7 @@ ${marker}` : marker);
20727
21766
  memexEntryCount: this._memexArchive.size,
20728
21767
  fileRegistrySize: this._fileRegistry.size
20729
21768
  };
20730
- writeFileSync20(join58(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
21769
+ writeFileSync20(join62(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
20731
21770
  } catch {
20732
21771
  }
20733
21772
  }
@@ -21995,7 +23034,7 @@ ${transcript}`
21995
23034
  // packages/orchestrator/dist/nexusBackend.js
21996
23035
  import { existsSync as existsSync26, statSync as statSync9, openSync, readSync, closeSync, unlinkSync as unlinkSync4, writeFileSync as writeFileSync8 } from "node:fs";
21997
23036
  import { watch as fsWatch } from "node:fs";
21998
- import { join as join35 } from "node:path";
23037
+ import { join as join39 } from "node:path";
21999
23038
  import { tmpdir as tmpdir7 } from "node:os";
22000
23039
  import { randomBytes as randomBytes8 } from "node:crypto";
22001
23040
  var NexusAgenticBackend;
@@ -22145,7 +23184,7 @@ var init_nexusBackend = __esm({
22145
23184
  * Falls back to unary + word-split if streaming setup fails.
22146
23185
  */
22147
23186
  async *chatCompletionStream(request) {
22148
- const streamFile = join35(tmpdir7(), `nexus-stream-${randomBytes8(6).toString("hex")}.jsonl`);
23187
+ const streamFile = join39(tmpdir7(), `nexus-stream-${randomBytes8(6).toString("hex")}.jsonl`);
22149
23188
  writeFileSync8(streamFile, "", "utf8");
22150
23189
  const daemonArgs = {
22151
23190
  model: this.model,
@@ -23182,7 +24221,7 @@ __export(listen_exports, {
23182
24221
  });
23183
24222
  import { spawn as spawn15, execSync as execSync23 } from "node:child_process";
23184
24223
  import { existsSync as existsSync27, mkdirSync as mkdirSync8, writeFileSync as writeFileSync9, readdirSync as readdirSync6 } from "node:fs";
23185
- import { join as join36, dirname as dirname13 } from "node:path";
24224
+ import { join as join40, dirname as dirname13 } from "node:path";
23186
24225
  import { homedir as homedir8 } from "node:os";
23187
24226
  import { fileURLToPath as fileURLToPath8 } from "node:url";
23188
24227
  import { EventEmitter } from "node:events";
@@ -23268,12 +24307,12 @@ function findMicCaptureCommand() {
23268
24307
  function findLiveWhisperScript() {
23269
24308
  const thisDir = dirname13(fileURLToPath8(import.meta.url));
23270
24309
  const candidates = [
23271
- join36(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
23272
- join36(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
23273
- join36(thisDir, "../../execution/scripts/live-whisper.py"),
24310
+ join40(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
24311
+ join40(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
24312
+ join40(thisDir, "../../execution/scripts/live-whisper.py"),
23274
24313
  // npm install layout — scripts bundled alongside dist
23275
- join36(thisDir, "../scripts/live-whisper.py"),
23276
- join36(thisDir, "../../scripts/live-whisper.py")
24314
+ join40(thisDir, "../scripts/live-whisper.py"),
24315
+ join40(thisDir, "../../scripts/live-whisper.py")
23277
24316
  ];
23278
24317
  for (const p of candidates) {
23279
24318
  if (existsSync27(p))
@@ -23286,8 +24325,8 @@ function findLiveWhisperScript() {
23286
24325
  stdio: ["pipe", "pipe", "pipe"]
23287
24326
  }).trim();
23288
24327
  const candidates2 = [
23289
- join36(globalRoot, "open-agents-ai", "dist", "scripts", "live-whisper.py"),
23290
- join36(globalRoot, "open-agents-ai", "scripts", "live-whisper.py")
24328
+ join40(globalRoot, "open-agents-ai", "dist", "scripts", "live-whisper.py"),
24329
+ join40(globalRoot, "open-agents-ai", "scripts", "live-whisper.py")
23291
24330
  ];
23292
24331
  for (const p of candidates2) {
23293
24332
  if (existsSync27(p))
@@ -23295,11 +24334,11 @@ function findLiveWhisperScript() {
23295
24334
  }
23296
24335
  } catch {
23297
24336
  }
23298
- const nvmBase = join36(homedir8(), ".nvm", "versions", "node");
24337
+ const nvmBase = join40(homedir8(), ".nvm", "versions", "node");
23299
24338
  if (existsSync27(nvmBase)) {
23300
24339
  try {
23301
24340
  for (const ver of readdirSync6(nvmBase)) {
23302
- const p = join36(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
24341
+ const p = join40(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
23303
24342
  if (existsSync27(p))
23304
24343
  return p;
23305
24344
  }
@@ -23318,7 +24357,7 @@ function ensureTranscribeCliBackground() {
23318
24357
  timeout: 5e3,
23319
24358
  stdio: ["pipe", "pipe", "pipe"]
23320
24359
  }).trim();
23321
- if (existsSync27(join36(globalRoot, "transcribe-cli", "dist", "index.js"))) {
24360
+ if (existsSync27(join40(globalRoot, "transcribe-cli", "dist", "index.js"))) {
23322
24361
  return true;
23323
24362
  }
23324
24363
  } catch {
@@ -23541,24 +24580,24 @@ var init_listen = __esm({
23541
24580
  timeout: 5e3,
23542
24581
  stdio: ["pipe", "pipe", "pipe"]
23543
24582
  }).trim();
23544
- const tcPath = join36(globalRoot, "transcribe-cli");
23545
- if (existsSync27(join36(tcPath, "dist", "index.js"))) {
24583
+ const tcPath = join40(globalRoot, "transcribe-cli");
24584
+ if (existsSync27(join40(tcPath, "dist", "index.js"))) {
23546
24585
  const { createRequire: createRequire4 } = await import("node:module");
23547
24586
  const req = createRequire4(import.meta.url);
23548
- return req(join36(tcPath, "dist", "index.js"));
24587
+ return req(join40(tcPath, "dist", "index.js"));
23549
24588
  }
23550
24589
  } catch {
23551
24590
  }
23552
- const nvmBase = join36(homedir8(), ".nvm", "versions", "node");
24591
+ const nvmBase = join40(homedir8(), ".nvm", "versions", "node");
23553
24592
  if (existsSync27(nvmBase)) {
23554
24593
  try {
23555
24594
  const { readdirSync: readdirSync17 } = await import("node:fs");
23556
24595
  for (const ver of readdirSync17(nvmBase)) {
23557
- const tcPath = join36(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
23558
- if (existsSync27(join36(tcPath, "dist", "index.js"))) {
24596
+ const tcPath = join40(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
24597
+ if (existsSync27(join40(tcPath, "dist", "index.js"))) {
23559
24598
  const { createRequire: createRequire4 } = await import("node:module");
23560
24599
  const req = createRequire4(import.meta.url);
23561
- return req(join36(tcPath, "dist", "index.js"));
24600
+ return req(join40(tcPath, "dist", "index.js"));
23562
24601
  }
23563
24602
  }
23564
24603
  } catch {
@@ -23840,9 +24879,9 @@ transcribe-cli error: ${transcribeCliError}` : "";
23840
24879
  });
23841
24880
  if (outputDir) {
23842
24881
  const { basename: basename16 } = await import("node:path");
23843
- const transcriptDir = join36(outputDir, ".oa", "transcripts");
24882
+ const transcriptDir = join40(outputDir, ".oa", "transcripts");
23844
24883
  mkdirSync8(transcriptDir, { recursive: true });
23845
- const outFile = join36(transcriptDir, `${basename16(filePath)}.txt`);
24884
+ const outFile = join40(transcriptDir, `${basename16(filePath)}.txt`);
23846
24885
  writeFileSync9(outFile, result.text, "utf-8");
23847
24886
  }
23848
24887
  return {
@@ -29200,7 +30239,7 @@ import { randomBytes as randomBytes9 } from "node:crypto";
29200
30239
  import { URL as URL2 } from "node:url";
29201
30240
  import { loadavg, cpus, totalmem, freemem } from "node:os";
29202
30241
  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";
29203
- import { join as join37 } from "node:path";
30242
+ import { join as join41 } from "node:path";
29204
30243
  function cleanForwardHeaders(raw, targetHost) {
29205
30244
  const out = {};
29206
30245
  for (const [key, value] of Object.entries(raw)) {
@@ -29228,7 +30267,7 @@ function fmtTokens(n) {
29228
30267
  }
29229
30268
  function readExposeState(stateDir) {
29230
30269
  try {
29231
- const path = join37(stateDir, STATE_FILE_NAME);
30270
+ const path = join41(stateDir, STATE_FILE_NAME);
29232
30271
  if (!existsSync28(path))
29233
30272
  return null;
29234
30273
  const raw = readFileSync19(path, "utf8");
@@ -29243,13 +30282,13 @@ function readExposeState(stateDir) {
29243
30282
  function writeExposeState(stateDir, state) {
29244
30283
  try {
29245
30284
  mkdirSync9(stateDir, { recursive: true });
29246
- writeFileSync10(join37(stateDir, STATE_FILE_NAME), JSON.stringify(state, null, 2));
30285
+ writeFileSync10(join41(stateDir, STATE_FILE_NAME), JSON.stringify(state, null, 2));
29247
30286
  } catch {
29248
30287
  }
29249
30288
  }
29250
30289
  function removeExposeState(stateDir) {
29251
30290
  try {
29252
- unlinkSync5(join37(stateDir, STATE_FILE_NAME));
30291
+ unlinkSync5(join41(stateDir, STATE_FILE_NAME));
29253
30292
  } catch {
29254
30293
  }
29255
30294
  }
@@ -29338,7 +30377,7 @@ async function collectSystemMetricsAsync() {
29338
30377
  }
29339
30378
  function readP2PExposeState(stateDir) {
29340
30379
  try {
29341
- const path = join37(stateDir, P2P_STATE_FILE_NAME);
30380
+ const path = join41(stateDir, P2P_STATE_FILE_NAME);
29342
30381
  if (!existsSync28(path))
29343
30382
  return null;
29344
30383
  const raw = readFileSync19(path, "utf8");
@@ -29353,13 +30392,13 @@ function readP2PExposeState(stateDir) {
29353
30392
  function writeP2PExposeState(stateDir, state) {
29354
30393
  try {
29355
30394
  mkdirSync9(stateDir, { recursive: true });
29356
- writeFileSync10(join37(stateDir, P2P_STATE_FILE_NAME), JSON.stringify(state, null, 2));
30395
+ writeFileSync10(join41(stateDir, P2P_STATE_FILE_NAME), JSON.stringify(state, null, 2));
29357
30396
  } catch {
29358
30397
  }
29359
30398
  }
29360
30399
  function removeP2PExposeState(stateDir) {
29361
30400
  try {
29362
- unlinkSync5(join37(stateDir, P2P_STATE_FILE_NAME));
30401
+ unlinkSync5(join41(stateDir, P2P_STATE_FILE_NAME));
29363
30402
  } catch {
29364
30403
  }
29365
30404
  }
@@ -30189,7 +31228,7 @@ ${this.formatConnectionInfo()}`);
30189
31228
  throw new Error(`Expose failed: ${exposeResult.error}`);
30190
31229
  }
30191
31230
  const nexusDir = this._nexusTool.getNexusDir();
30192
- const statusPath = join37(nexusDir, "status.json");
31231
+ const statusPath = join41(nexusDir, "status.json");
30193
31232
  for (let i = 0; i < 80; i++) {
30194
31233
  try {
30195
31234
  const raw = readFileSync19(statusPath, "utf8");
@@ -30223,7 +31262,7 @@ ${this.formatConnectionInfo()}`);
30223
31262
  });
30224
31263
  }
30225
31264
  try {
30226
- const invocDir = join37(nexusDir, "invocations");
31265
+ const invocDir = join41(nexusDir, "invocations");
30227
31266
  if (existsSync28(invocDir)) {
30228
31267
  this._prevInvocCount = readdirSync7(invocDir).filter((f) => f.endsWith(".json")).length;
30229
31268
  this._stats.totalRequests = this._prevInvocCount;
@@ -30253,7 +31292,7 @@ ${this.formatConnectionInfo()}`);
30253
31292
  if (!state)
30254
31293
  return null;
30255
31294
  const nexusDir = nexusTool.getNexusDir();
30256
- const statusPath = join37(nexusDir, "status.json");
31295
+ const statusPath = join41(nexusDir, "status.json");
30257
31296
  try {
30258
31297
  if (!existsSync28(statusPath)) {
30259
31298
  removeP2PExposeState(stateDir);
@@ -30312,7 +31351,7 @@ ${this.formatConnectionInfo()}`);
30312
31351
  let lastMeteringLineCount = 0;
30313
31352
  this._activityPollTimer = setInterval(() => {
30314
31353
  try {
30315
- const invocDir = join37(nexusDir, "invocations");
31354
+ const invocDir = join41(nexusDir, "invocations");
30316
31355
  if (!existsSync28(invocDir))
30317
31356
  return;
30318
31357
  const files = readdirSync7(invocDir).filter((f) => f.endsWith(".json"));
@@ -30328,13 +31367,13 @@ ${this.formatConnectionInfo()}`);
30328
31367
  let recentActive = 0;
30329
31368
  for (const f of files.slice(-10)) {
30330
31369
  try {
30331
- const st = statSync10(join37(invocDir, f));
31370
+ const st = statSync10(join41(invocDir, f));
30332
31371
  if (now - st.mtimeMs < 1e4)
30333
31372
  recentActive++;
30334
31373
  } catch {
30335
31374
  }
30336
31375
  }
30337
- const meteringFile = join37(nexusDir, "metering.jsonl");
31376
+ const meteringFile = join41(nexusDir, "metering.jsonl");
30338
31377
  let meteringLines = lastMeteringLineCount;
30339
31378
  try {
30340
31379
  if (existsSync28(meteringFile)) {
@@ -30364,7 +31403,7 @@ ${this.formatConnectionInfo()}`);
30364
31403
  this._activityPollTimer.unref();
30365
31404
  this._pollTimer = setInterval(() => {
30366
31405
  try {
30367
- const statusPath = join37(nexusDir, "status.json");
31406
+ const statusPath = join41(nexusDir, "status.json");
30368
31407
  if (existsSync28(statusPath)) {
30369
31408
  const status = JSON.parse(readFileSync19(statusPath, "utf8"));
30370
31409
  if (status.peerId && !this._peerId) {
@@ -30375,7 +31414,7 @@ ${this.formatConnectionInfo()}`);
30375
31414
  } catch {
30376
31415
  }
30377
31416
  try {
30378
- const invocDir = join37(nexusDir, "invocations");
31417
+ const invocDir = join41(nexusDir, "invocations");
30379
31418
  if (existsSync28(invocDir)) {
30380
31419
  const files = readdirSync7(invocDir);
30381
31420
  const invocCount = files.filter((f) => f.endsWith(".json")).length;
@@ -30387,7 +31426,7 @@ ${this.formatConnectionInfo()}`);
30387
31426
  } catch {
30388
31427
  }
30389
31428
  try {
30390
- const meteringFile = join37(nexusDir, "metering.jsonl");
31429
+ const meteringFile = join41(nexusDir, "metering.jsonl");
30391
31430
  if (existsSync28(meteringFile)) {
30392
31431
  const content = readFileSync19(meteringFile, "utf8");
30393
31432
  if (content.length > lastMeteringSize) {
@@ -30599,7 +31638,7 @@ var init_types = __esm({
30599
31638
  // packages/cli/dist/tui/p2p/secret-vault.js
30600
31639
  import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes10, scryptSync as scryptSync2, createHash as createHash2 } from "node:crypto";
30601
31640
  import { readFileSync as readFileSync20, writeFileSync as writeFileSync11, existsSync as existsSync29, mkdirSync as mkdirSync10 } from "node:fs";
30602
- import { join as join38, dirname as dirname14 } from "node:path";
31641
+ import { join as join42, dirname as dirname14 } from "node:path";
30603
31642
  var PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, CIPHER_ALGO, SALT_LEN, IV_LEN, KEY_LEN, SecretVault;
30604
31643
  var init_secret_vault = __esm({
30605
31644
  "packages/cli/dist/tui/p2p/secret-vault.js"() {
@@ -31936,13 +32975,13 @@ async function fetchPeerModels(peerId, authKey) {
31936
32975
  try {
31937
32976
  const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
31938
32977
  const { existsSync: existsSync45, readFileSync: readFileSync33 } = await import("node:fs");
31939
- const { join: join58 } = await import("node:path");
32978
+ const { join: join62 } = await import("node:path");
31940
32979
  const cwd4 = process.cwd();
31941
32980
  const nexusTool = new NexusTool2(cwd4);
31942
32981
  const nexusDir = nexusTool.getNexusDir();
31943
32982
  let isLocalPeer = false;
31944
32983
  try {
31945
- const statusPath = join58(nexusDir, "status.json");
32984
+ const statusPath = join62(nexusDir, "status.json");
31946
32985
  if (existsSync45(statusPath)) {
31947
32986
  const status = JSON.parse(readFileSync33(statusPath, "utf8"));
31948
32987
  if (status.peerId === peerId)
@@ -31951,7 +32990,7 @@ async function fetchPeerModels(peerId, authKey) {
31951
32990
  } catch {
31952
32991
  }
31953
32992
  if (isLocalPeer) {
31954
- const pricingPath = join58(nexusDir, "pricing.json");
32993
+ const pricingPath = join62(nexusDir, "pricing.json");
31955
32994
  if (existsSync45(pricingPath)) {
31956
32995
  try {
31957
32996
  const pricing = JSON.parse(readFileSync33(pricingPath, "utf8"));
@@ -31968,7 +33007,7 @@ async function fetchPeerModels(peerId, authKey) {
31968
33007
  }
31969
33008
  }
31970
33009
  }
31971
- const cachePath = join58(nexusDir, "peer-models-cache.json");
33010
+ const cachePath = join62(nexusDir, "peer-models-cache.json");
31972
33011
  if (existsSync45(cachePath)) {
31973
33012
  try {
31974
33013
  const cache4 = JSON.parse(readFileSync33(cachePath, "utf8"));
@@ -32086,7 +33125,7 @@ async function fetchPeerModels(peerId, authKey) {
32086
33125
  } catch {
32087
33126
  }
32088
33127
  if (isLocalPeer) {
32089
- const pricingPath = join58(nexusDir, "pricing.json");
33128
+ const pricingPath = join62(nexusDir, "pricing.json");
32090
33129
  if (existsSync45(pricingPath)) {
32091
33130
  try {
32092
33131
  const pricing = JSON.parse(readFileSync33(pricingPath, "utf8"));
@@ -32359,12 +33398,12 @@ var init_render2 = __esm({
32359
33398
 
32360
33399
  // packages/prompts/dist/promptLoader.js
32361
33400
  import { readFileSync as readFileSync21, existsSync as existsSync30 } from "node:fs";
32362
- import { join as join39, dirname as dirname15 } from "node:path";
33401
+ import { join as join43, dirname as dirname15 } from "node:path";
32363
33402
  import { fileURLToPath as fileURLToPath9 } from "node:url";
32364
33403
  function loadPrompt2(promptPath, vars) {
32365
33404
  let content = cache2.get(promptPath);
32366
33405
  if (content === void 0) {
32367
- const fullPath = join39(PROMPTS_DIR2, promptPath);
33406
+ const fullPath = join43(PROMPTS_DIR2, promptPath);
32368
33407
  if (!existsSync30(fullPath)) {
32369
33408
  throw new Error(`Prompt file not found: ${fullPath}`);
32370
33409
  }
@@ -32381,8 +33420,8 @@ var init_promptLoader2 = __esm({
32381
33420
  "use strict";
32382
33421
  __filename2 = fileURLToPath9(import.meta.url);
32383
33422
  __dirname5 = dirname15(__filename2);
32384
- devPath = join39(__dirname5, "..", "templates");
32385
- publishedPath = join39(__dirname5, "..", "prompts", "templates");
33423
+ devPath = join43(__dirname5, "..", "templates");
33424
+ publishedPath = join43(__dirname5, "..", "prompts", "templates");
32386
33425
  PROMPTS_DIR2 = existsSync30(devPath) ? devPath : publishedPath;
32387
33426
  cache2 = /* @__PURE__ */ new Map();
32388
33427
  }
@@ -32494,7 +33533,7 @@ var init_task_templates = __esm({
32494
33533
  });
32495
33534
 
32496
33535
  // packages/prompts/dist/index.js
32497
- import { join as join40, dirname as dirname16 } from "node:path";
33536
+ import { join as join44, dirname as dirname16 } from "node:path";
32498
33537
  import { fileURLToPath as fileURLToPath10 } from "node:url";
32499
33538
  var _dir, _packageRoot;
32500
33539
  var init_dist6 = __esm({
@@ -32505,21 +33544,21 @@ var init_dist6 = __esm({
32505
33544
  init_task_templates();
32506
33545
  init_render2();
32507
33546
  _dir = dirname16(fileURLToPath10(import.meta.url));
32508
- _packageRoot = join40(_dir, "..");
33547
+ _packageRoot = join44(_dir, "..");
32509
33548
  }
32510
33549
  });
32511
33550
 
32512
33551
  // packages/cli/dist/tui/oa-directory.js
32513
33552
  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";
32514
- import { join as join41, relative as relative2, basename as basename9, extname as extname8 } from "node:path";
33553
+ import { join as join45, relative as relative2, basename as basename9, extname as extname8 } from "node:path";
32515
33554
  import { homedir as homedir9 } from "node:os";
32516
33555
  function initOaDirectory(repoRoot) {
32517
- const oaPath = join41(repoRoot, OA_DIR);
33556
+ const oaPath = join45(repoRoot, OA_DIR);
32518
33557
  for (const sub of SUBDIRS) {
32519
- mkdirSync11(join41(oaPath, sub), { recursive: true });
33558
+ mkdirSync11(join45(oaPath, sub), { recursive: true });
32520
33559
  }
32521
33560
  try {
32522
- const gitignorePath = join41(repoRoot, ".gitignore");
33561
+ const gitignorePath = join45(repoRoot, ".gitignore");
32523
33562
  const settingsPattern = ".oa/settings.json";
32524
33563
  if (existsSync31(gitignorePath)) {
32525
33564
  const content = readFileSync22(gitignorePath, "utf-8");
@@ -32532,10 +33571,10 @@ function initOaDirectory(repoRoot) {
32532
33571
  return oaPath;
32533
33572
  }
32534
33573
  function hasOaDirectory(repoRoot) {
32535
- return existsSync31(join41(repoRoot, OA_DIR, "index"));
33574
+ return existsSync31(join45(repoRoot, OA_DIR, "index"));
32536
33575
  }
32537
33576
  function loadProjectSettings(repoRoot) {
32538
- const settingsPath = join41(repoRoot, OA_DIR, "settings.json");
33577
+ const settingsPath = join45(repoRoot, OA_DIR, "settings.json");
32539
33578
  try {
32540
33579
  if (existsSync31(settingsPath)) {
32541
33580
  return JSON.parse(readFileSync22(settingsPath, "utf-8"));
@@ -32545,14 +33584,14 @@ function loadProjectSettings(repoRoot) {
32545
33584
  return {};
32546
33585
  }
32547
33586
  function saveProjectSettings(repoRoot, settings) {
32548
- const oaPath = join41(repoRoot, OA_DIR);
33587
+ const oaPath = join45(repoRoot, OA_DIR);
32549
33588
  mkdirSync11(oaPath, { recursive: true });
32550
33589
  const existing = loadProjectSettings(repoRoot);
32551
33590
  const merged = { ...existing, ...settings };
32552
- writeFileSync12(join41(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
33591
+ writeFileSync12(join45(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
32553
33592
  }
32554
33593
  function loadGlobalSettings() {
32555
- const settingsPath = join41(homedir9(), ".open-agents", "settings.json");
33594
+ const settingsPath = join45(homedir9(), ".open-agents", "settings.json");
32556
33595
  try {
32557
33596
  if (existsSync31(settingsPath)) {
32558
33597
  return JSON.parse(readFileSync22(settingsPath, "utf-8"));
@@ -32562,11 +33601,11 @@ function loadGlobalSettings() {
32562
33601
  return {};
32563
33602
  }
32564
33603
  function saveGlobalSettings(settings) {
32565
- const dir = join41(homedir9(), ".open-agents");
33604
+ const dir = join45(homedir9(), ".open-agents");
32566
33605
  mkdirSync11(dir, { recursive: true });
32567
33606
  const existing = loadGlobalSettings();
32568
33607
  const merged = { ...existing, ...settings };
32569
- writeFileSync12(join41(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
33608
+ writeFileSync12(join45(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
32570
33609
  }
32571
33610
  function resolveSettings(repoRoot) {
32572
33611
  const global = loadGlobalSettings();
@@ -32581,7 +33620,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
32581
33620
  while (dir && !visited.has(dir)) {
32582
33621
  visited.add(dir);
32583
33622
  for (const name of CONTEXT_FILES) {
32584
- const filePath = join41(dir, name);
33623
+ const filePath = join45(dir, name);
32585
33624
  const normalizedName = name.toLowerCase();
32586
33625
  if (existsSync31(filePath) && !seen.has(filePath)) {
32587
33626
  seen.add(filePath);
@@ -32600,7 +33639,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
32600
33639
  }
32601
33640
  }
32602
33641
  }
32603
- const projectMap = join41(dir, OA_DIR, "context", "project-map.md");
33642
+ const projectMap = join45(dir, OA_DIR, "context", "project-map.md");
32604
33643
  if (existsSync31(projectMap) && !seen.has(projectMap)) {
32605
33644
  seen.add(projectMap);
32606
33645
  try {
@@ -32616,7 +33655,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
32616
33655
  } catch {
32617
33656
  }
32618
33657
  }
32619
- const parent = join41(dir, "..");
33658
+ const parent = join45(dir, "..");
32620
33659
  if (parent === dir)
32621
33660
  break;
32622
33661
  dir = parent;
@@ -32634,7 +33673,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
32634
33673
  return found;
32635
33674
  }
32636
33675
  function readIndexMeta(repoRoot) {
32637
- const metaPath = join41(repoRoot, OA_DIR, "index", "meta.json");
33676
+ const metaPath = join45(repoRoot, OA_DIR, "index", "meta.json");
32638
33677
  try {
32639
33678
  return JSON.parse(readFileSync22(metaPath, "utf-8"));
32640
33679
  } catch {
@@ -32687,28 +33726,28 @@ ${tree}\`\`\`
32687
33726
  sections.push("");
32688
33727
  }
32689
33728
  const content = sections.join("\n");
32690
- const contextDir = join41(repoRoot, OA_DIR, "context");
33729
+ const contextDir = join45(repoRoot, OA_DIR, "context");
32691
33730
  mkdirSync11(contextDir, { recursive: true });
32692
- writeFileSync12(join41(contextDir, "project-map.md"), content, "utf-8");
33731
+ writeFileSync12(join45(contextDir, "project-map.md"), content, "utf-8");
32693
33732
  return content;
32694
33733
  }
32695
33734
  function saveSession(repoRoot, session) {
32696
- const historyDir = join41(repoRoot, OA_DIR, "history");
33735
+ const historyDir = join45(repoRoot, OA_DIR, "history");
32697
33736
  mkdirSync11(historyDir, { recursive: true });
32698
- writeFileSync12(join41(historyDir, `${session.id}.json`), JSON.stringify(session, null, 2), "utf-8");
33737
+ writeFileSync12(join45(historyDir, `${session.id}.json`), JSON.stringify(session, null, 2), "utf-8");
32699
33738
  }
32700
33739
  function loadRecentSessions(repoRoot, limit = 5) {
32701
- const historyDir = join41(repoRoot, OA_DIR, "history");
33740
+ const historyDir = join45(repoRoot, OA_DIR, "history");
32702
33741
  if (!existsSync31(historyDir))
32703
33742
  return [];
32704
33743
  try {
32705
33744
  const files = readdirSync8(historyDir).filter((f) => f.endsWith(".json") && f !== "pending-task.json").map((f) => {
32706
- const stat5 = statSync11(join41(historyDir, f));
33745
+ const stat5 = statSync11(join45(historyDir, f));
32707
33746
  return { file: f, mtime: stat5.mtimeMs };
32708
33747
  }).sort((a, b) => b.mtime - a.mtime).slice(0, limit);
32709
33748
  return files.map((f) => {
32710
33749
  try {
32711
- return JSON.parse(readFileSync22(join41(historyDir, f.file), "utf-8"));
33750
+ return JSON.parse(readFileSync22(join45(historyDir, f.file), "utf-8"));
32712
33751
  } catch {
32713
33752
  return null;
32714
33753
  }
@@ -32718,12 +33757,12 @@ function loadRecentSessions(repoRoot, limit = 5) {
32718
33757
  }
32719
33758
  }
32720
33759
  function savePendingTask(repoRoot, task) {
32721
- const historyDir = join41(repoRoot, OA_DIR, "history");
33760
+ const historyDir = join45(repoRoot, OA_DIR, "history");
32722
33761
  mkdirSync11(historyDir, { recursive: true });
32723
- writeFileSync12(join41(historyDir, PENDING_TASK_FILE), JSON.stringify(task, null, 2) + "\n", "utf-8");
33762
+ writeFileSync12(join45(historyDir, PENDING_TASK_FILE), JSON.stringify(task, null, 2) + "\n", "utf-8");
32724
33763
  }
32725
33764
  function loadPendingTask(repoRoot) {
32726
- const filePath = join41(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
33765
+ const filePath = join45(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
32727
33766
  try {
32728
33767
  if (!existsSync31(filePath))
32729
33768
  return null;
@@ -32738,9 +33777,9 @@ function loadPendingTask(repoRoot) {
32738
33777
  }
32739
33778
  }
32740
33779
  function saveSessionContext(repoRoot, entry) {
32741
- const contextDir = join41(repoRoot, OA_DIR, "context");
33780
+ const contextDir = join45(repoRoot, OA_DIR, "context");
32742
33781
  mkdirSync11(contextDir, { recursive: true });
32743
- const filePath = join41(contextDir, CONTEXT_SAVE_FILE);
33782
+ const filePath = join45(contextDir, CONTEXT_SAVE_FILE);
32744
33783
  let ctx;
32745
33784
  try {
32746
33785
  if (existsSync31(filePath)) {
@@ -32759,7 +33798,7 @@ function saveSessionContext(repoRoot, entry) {
32759
33798
  writeFileSync12(filePath, JSON.stringify(ctx, null, 2) + "\n", "utf-8");
32760
33799
  }
32761
33800
  function loadSessionContext(repoRoot) {
32762
- const filePath = join41(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
33801
+ const filePath = join45(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
32763
33802
  try {
32764
33803
  if (!existsSync31(filePath))
32765
33804
  return null;
@@ -32810,7 +33849,7 @@ function detectManifests(repoRoot) {
32810
33849
  { file: "docker-compose.yaml", type: "Docker Compose" }
32811
33850
  ];
32812
33851
  for (const check of checks) {
32813
- const filePath = join41(repoRoot, check.file);
33852
+ const filePath = join45(repoRoot, check.file);
32814
33853
  if (existsSync31(filePath)) {
32815
33854
  let name;
32816
33855
  if (check.nameField) {
@@ -32844,7 +33883,7 @@ function findKeyFiles(repoRoot) {
32844
33883
  { pattern: "CLAUDE.md", description: "Claude Code context" }
32845
33884
  ];
32846
33885
  for (const check of checks) {
32847
- if (existsSync31(join41(repoRoot, check.pattern))) {
33886
+ if (existsSync31(join45(repoRoot, check.pattern))) {
32848
33887
  keyFiles.push({ path: check.pattern, description: check.description });
32849
33888
  }
32850
33889
  }
@@ -32870,12 +33909,12 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
32870
33909
  if (entry.isDirectory()) {
32871
33910
  let fileCount = 0;
32872
33911
  try {
32873
- fileCount = readdirSync8(join41(root, entry.name)).filter((f) => !f.startsWith(".")).length;
33912
+ fileCount = readdirSync8(join45(root, entry.name)).filter((f) => !f.startsWith(".")).length;
32874
33913
  } catch {
32875
33914
  }
32876
33915
  result += `${prefix}${connector}${entry.name}/ (${fileCount})
32877
33916
  `;
32878
- result += buildDirTree(join41(root, entry.name), maxDepth, childPrefix, depth + 1);
33917
+ result += buildDirTree(join45(root, entry.name), maxDepth, childPrefix, depth + 1);
32879
33918
  } else if (depth < maxDepth) {
32880
33919
  result += `${prefix}${connector}${entry.name}
32881
33920
  `;
@@ -32895,7 +33934,7 @@ function loadUsageFile(filePath) {
32895
33934
  return { records: [] };
32896
33935
  }
32897
33936
  function saveUsageFile(filePath, data) {
32898
- const dir = join41(filePath, "..");
33937
+ const dir = join45(filePath, "..");
32899
33938
  mkdirSync11(dir, { recursive: true });
32900
33939
  writeFileSync12(filePath, JSON.stringify(data, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
32901
33940
  }
@@ -32925,15 +33964,15 @@ function recordUsage(kind, value, opts) {
32925
33964
  }
32926
33965
  saveUsageFile(filePath, data);
32927
33966
  };
32928
- update(join41(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
33967
+ update(join45(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
32929
33968
  if (opts?.repoRoot) {
32930
- update(join41(opts.repoRoot, OA_DIR, USAGE_HISTORY_FILE));
33969
+ update(join45(opts.repoRoot, OA_DIR, USAGE_HISTORY_FILE));
32931
33970
  }
32932
33971
  }
32933
33972
  function loadUsageHistory(kind, repoRoot) {
32934
- const globalPath = join41(homedir9(), ".open-agents", USAGE_HISTORY_FILE);
33973
+ const globalPath = join45(homedir9(), ".open-agents", USAGE_HISTORY_FILE);
32935
33974
  const globalData = loadUsageFile(globalPath);
32936
- const localData = repoRoot ? loadUsageFile(join41(repoRoot, OA_DIR, USAGE_HISTORY_FILE)) : { records: [] };
33975
+ const localData = repoRoot ? loadUsageFile(join45(repoRoot, OA_DIR, USAGE_HISTORY_FILE)) : { records: [] };
32937
33976
  const map = /* @__PURE__ */ new Map();
32938
33977
  for (const r of globalData.records) {
32939
33978
  if (r.kind !== kind)
@@ -32964,9 +34003,9 @@ function deleteUsageRecord(kind, value, repoRoot) {
32964
34003
  saveUsageFile(filePath, data);
32965
34004
  }
32966
34005
  };
32967
- remove(join41(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
34006
+ remove(join45(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
32968
34007
  if (repoRoot) {
32969
- remove(join41(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
34008
+ remove(join45(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
32970
34009
  }
32971
34010
  }
32972
34011
  var OA_DIR, SUBDIRS, CONTEXT_FILES, PENDING_TASK_FILE, CONTEXT_SAVE_FILE, MAX_CONTEXT_ENTRIES, SKIP_DIRS, USAGE_HISTORY_FILE, MAX_HISTORY_RECORDS;
@@ -33017,7 +34056,7 @@ import * as readline from "node:readline";
33017
34056
  import { execSync as execSync25, spawn as spawn18, exec as exec2 } from "node:child_process";
33018
34057
  import { promisify as promisify5 } from "node:util";
33019
34058
  import { existsSync as existsSync32, writeFileSync as writeFileSync13, readFileSync as readFileSync23, appendFileSync as appendFileSync2, mkdirSync as mkdirSync12 } from "node:fs";
33020
- import { join as join42 } from "node:path";
34059
+ import { join as join46 } from "node:path";
33021
34060
  import { homedir as homedir10, platform } from "node:os";
33022
34061
  function detectSystemSpecs() {
33023
34062
  let totalRamGB = 0;
@@ -34058,9 +35097,9 @@ async function doSetup(config, rl) {
34058
35097
  `PARAMETER num_predict ${numPredict}`,
34059
35098
  `PARAMETER stop "<|endoftext|>"`
34060
35099
  ].join("\n");
34061
- const modelDir2 = join42(homedir10(), ".open-agents", "models");
35100
+ const modelDir2 = join46(homedir10(), ".open-agents", "models");
34062
35101
  mkdirSync12(modelDir2, { recursive: true });
34063
- const modelfilePath = join42(modelDir2, `Modelfile.${customName}`);
35102
+ const modelfilePath = join46(modelDir2, `Modelfile.${customName}`);
34064
35103
  writeFileSync13(modelfilePath, modelfileContent + "\n", "utf8");
34065
35104
  process.stdout.write(` ${c2.dim("Creating model...")} `);
34066
35105
  execSync25(`ollama create ${customName} -f ${modelfilePath}`, {
@@ -34106,7 +35145,7 @@ async function isModelAvailable(config) {
34106
35145
  }
34107
35146
  function isFirstRun() {
34108
35147
  try {
34109
- return !existsSync32(join42(homedir10(), ".open-agents", "config.json"));
35148
+ return !existsSync32(join46(homedir10(), ".open-agents", "config.json"));
34110
35149
  } catch {
34111
35150
  return true;
34112
35151
  }
@@ -34143,7 +35182,7 @@ function detectPkgManager() {
34143
35182
  return null;
34144
35183
  }
34145
35184
  function getVenvDir() {
34146
- return join42(homedir10(), ".open-agents", "venv");
35185
+ return join46(homedir10(), ".open-agents", "venv");
34147
35186
  }
34148
35187
  function hasVenvModule() {
34149
35188
  try {
@@ -34155,7 +35194,7 @@ function hasVenvModule() {
34155
35194
  }
34156
35195
  function ensureVenv(log) {
34157
35196
  const venvDir = getVenvDir();
34158
- const venvPip = join42(venvDir, "bin", "pip");
35197
+ const venvPip = join46(venvDir, "bin", "pip");
34159
35198
  if (existsSync32(venvPip))
34160
35199
  return venvDir;
34161
35200
  log("Creating Python venv for vision deps...");
@@ -34168,9 +35207,9 @@ function ensureVenv(log) {
34168
35207
  return null;
34169
35208
  }
34170
35209
  try {
34171
- mkdirSync12(join42(homedir10(), ".open-agents"), { recursive: true });
35210
+ mkdirSync12(join46(homedir10(), ".open-agents"), { recursive: true });
34172
35211
  execSync25(`python3 -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
34173
- execSync25(`"${join42(venvDir, "bin", "pip")}" install --upgrade pip`, {
35212
+ execSync25(`"${join46(venvDir, "bin", "pip")}" install --upgrade pip`, {
34174
35213
  stdio: "pipe",
34175
35214
  timeout: 6e4
34176
35215
  });
@@ -34361,11 +35400,11 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
34361
35400
  }
34362
35401
  }
34363
35402
  const venvDir = getVenvDir();
34364
- const venvBin = join42(venvDir, "bin");
34365
- const venvMoondream = join42(venvBin, "moondream-station");
35403
+ const venvBin = join46(venvDir, "bin");
35404
+ const venvMoondream = join46(venvBin, "moondream-station");
34366
35405
  const venv = ensureVenv(log);
34367
35406
  if (venv && !hasCmd("moondream-station") && !existsSync32(venvMoondream)) {
34368
- const venvPip = join42(venvBin, "pip");
35407
+ const venvPip = join46(venvBin, "pip");
34369
35408
  log("Installing moondream-station in ~/.open-agents/venv...");
34370
35409
  try {
34371
35410
  execSync25(`"${venvPip}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
@@ -34386,8 +35425,8 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
34386
35425
  }
34387
35426
  }
34388
35427
  if (venv) {
34389
- const venvPython = join42(venvBin, "python");
34390
- const venvPip2 = join42(venvBin, "pip");
35428
+ const venvPython = join46(venvBin, "python");
35429
+ const venvPip2 = join46(venvBin, "pip");
34391
35430
  let ocrStackInstalled = false;
34392
35431
  try {
34393
35432
  execSync25(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
@@ -34531,9 +35570,9 @@ async function createExpandedVariantAsync(baseModel, specs, sizeGB, kvBytesPerTo
34531
35570
  `PARAMETER num_predict ${numPredict}`,
34532
35571
  `PARAMETER stop "<|endoftext|>"`
34533
35572
  ].join("\n");
34534
- const modelDir2 = join42(homedir10(), ".open-agents", "models");
35573
+ const modelDir2 = join46(homedir10(), ".open-agents", "models");
34535
35574
  mkdirSync12(modelDir2, { recursive: true });
34536
- const modelfilePath = join42(modelDir2, `Modelfile.${customName}`);
35575
+ const modelfilePath = join46(modelDir2, `Modelfile.${customName}`);
34537
35576
  writeFileSync13(modelfilePath, modelfileContent + "\n", "utf8");
34538
35577
  await execAsync(`ollama create ${customName} -f ${modelfilePath}`, {
34539
35578
  timeout: 12e4
@@ -34608,8 +35647,8 @@ async function ensureNeovim() {
34608
35647
  const platform5 = process.platform;
34609
35648
  const arch = process.arch;
34610
35649
  if (platform5 === "linux") {
34611
- const binDir = join42(homedir10(), ".local", "bin");
34612
- const nvimDest = join42(binDir, "nvim");
35650
+ const binDir = join46(homedir10(), ".local", "bin");
35651
+ const nvimDest = join46(binDir, "nvim");
34613
35652
  try {
34614
35653
  mkdirSync12(binDir, { recursive: true });
34615
35654
  } catch {
@@ -34680,7 +35719,7 @@ async function ensureNeovim() {
34680
35719
  }
34681
35720
  function ensurePathInShellRc(binDir) {
34682
35721
  const shell = process.env.SHELL ?? "";
34683
- const rcFile = shell.includes("zsh") ? join42(homedir10(), ".zshrc") : join42(homedir10(), ".bashrc");
35722
+ const rcFile = shell.includes("zsh") ? join46(homedir10(), ".zshrc") : join46(homedir10(), ".bashrc");
34684
35723
  try {
34685
35724
  const rcContent = existsSync32(rcFile) ? readFileSync23(rcFile, "utf8") : "";
34686
35725
  if (rcContent.includes(binDir))
@@ -35452,7 +36491,7 @@ var init_drop_panel = __esm({
35452
36491
  // packages/cli/dist/tui/neovim-mode.js
35453
36492
  import { existsSync as existsSync34, unlinkSync as unlinkSync7 } from "node:fs";
35454
36493
  import { tmpdir as tmpdir8 } from "node:os";
35455
- import { join as join43 } from "node:path";
36494
+ import { join as join47 } from "node:path";
35456
36495
  import { execSync as execSync26 } from "node:child_process";
35457
36496
  function isNeovimActive() {
35458
36497
  return _state !== null && !_state.cleanedUp;
@@ -35500,7 +36539,7 @@ async function startNeovimMode(opts) {
35500
36539
  );
35501
36540
  } catch {
35502
36541
  }
35503
- const socketPath = join43(tmpdir8(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
36542
+ const socketPath = join47(tmpdir8(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
35504
36543
  try {
35505
36544
  if (existsSync34(socketPath))
35506
36545
  unlinkSync7(socketPath);
@@ -35852,7 +36891,7 @@ __export(voice_exports, {
35852
36891
  resetNarrationContext: () => resetNarrationContext
35853
36892
  });
35854
36893
  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";
35855
- import { join as join44 } from "node:path";
36894
+ import { join as join48 } from "node:path";
35856
36895
  import { homedir as homedir11, tmpdir as tmpdir9, platform as platform2 } from "node:os";
35857
36896
  import { execSync as execSync27, spawn as nodeSpawn } from "node:child_process";
35858
36897
  import { createRequire } from "node:module";
@@ -35874,34 +36913,34 @@ function listVoiceModels() {
35874
36913
  }));
35875
36914
  }
35876
36915
  function voiceDir() {
35877
- return join44(homedir11(), ".open-agents", "voice");
36916
+ return join48(homedir11(), ".open-agents", "voice");
35878
36917
  }
35879
36918
  function modelsDir() {
35880
- return join44(voiceDir(), "models");
36919
+ return join48(voiceDir(), "models");
35881
36920
  }
35882
36921
  function modelDir(id) {
35883
- return join44(modelsDir(), id);
36922
+ return join48(modelsDir(), id);
35884
36923
  }
35885
36924
  function modelOnnxPath(id) {
35886
- return join44(modelDir(id), "model.onnx");
36925
+ return join48(modelDir(id), "model.onnx");
35887
36926
  }
35888
36927
  function modelConfigPath(id) {
35889
- return join44(modelDir(id), "config.json");
36928
+ return join48(modelDir(id), "config.json");
35890
36929
  }
35891
36930
  function luxttsVenvDir() {
35892
- return join44(voiceDir(), "luxtts-venv");
36931
+ return join48(voiceDir(), "luxtts-venv");
35893
36932
  }
35894
36933
  function luxttsVenvPy() {
35895
- return platform2() === "win32" ? join44(luxttsVenvDir(), "Scripts", "python.exe") : join44(luxttsVenvDir(), "bin", "python3");
36934
+ return platform2() === "win32" ? join48(luxttsVenvDir(), "Scripts", "python.exe") : join48(luxttsVenvDir(), "bin", "python3");
35896
36935
  }
35897
36936
  function luxttsRepoDir() {
35898
- return join44(voiceDir(), "LuxTTS");
36937
+ return join48(voiceDir(), "LuxTTS");
35899
36938
  }
35900
36939
  function luxttsCloneRefsDir() {
35901
- return join44(voiceDir(), "clone-refs");
36940
+ return join48(voiceDir(), "clone-refs");
35902
36941
  }
35903
36942
  function luxttsInferScript() {
35904
- return join44(voiceDir(), "luxtts-infer.py");
36943
+ return join48(voiceDir(), "luxtts-infer.py");
35905
36944
  }
35906
36945
  function emotionToPitchBias(emotion, stark = false, autist = false) {
35907
36946
  if (autist)
@@ -36709,7 +37748,7 @@ var init_voice = __esm({
36709
37748
  const refsDir = luxttsCloneRefsDir();
36710
37749
  const targets = ["glados", "overwatch"];
36711
37750
  for (const modelId of targets) {
36712
- const refFile = join44(refsDir, `${modelId}-ref.wav`);
37751
+ const refFile = join48(refsDir, `${modelId}-ref.wav`);
36713
37752
  if (existsSync35(refFile))
36714
37753
  continue;
36715
37754
  try {
@@ -36789,7 +37828,7 @@ var init_voice = __esm({
36789
37828
  }
36790
37829
  p = p.replace(/\\ /g, " ");
36791
37830
  if (p.startsWith("~/") || p === "~") {
36792
- p = join44(homedir11(), p.slice(1));
37831
+ p = join48(homedir11(), p.slice(1));
36793
37832
  }
36794
37833
  if (!existsSync35(p)) {
36795
37834
  return `File not found: ${p}
@@ -36803,7 +37842,7 @@ var init_voice = __esm({
36803
37842
  const srcName = (audioPath.split("/").pop() ?? "clone").replace(/\.[^.]+$/, "").replace(/[^a-zA-Z0-9_-]/g, "-");
36804
37843
  const ts = Date.now().toString(36);
36805
37844
  const destFilename = `clone-${srcName}-${ts}.${ext}`;
36806
- const destPath = join44(refsDir, destFilename);
37845
+ const destPath = join48(refsDir, destFilename);
36807
37846
  try {
36808
37847
  const data = readFileSync24(audioPath);
36809
37848
  writeFileSync14(destPath, data);
@@ -36848,7 +37887,7 @@ var init_voice = __esm({
36848
37887
  const refsDir = luxttsCloneRefsDir();
36849
37888
  if (!existsSync35(refsDir))
36850
37889
  mkdirSync13(refsDir, { recursive: true });
36851
- const destPath = join44(refsDir, `${sourceModelId}-ref.wav`);
37890
+ const destPath = join48(refsDir, `${sourceModelId}-ref.wav`);
36852
37891
  const sampleRate = this.config?.audio?.sample_rate ?? 22050;
36853
37892
  this.writeWav(audioData, sampleRate, destPath);
36854
37893
  this.luxttsCloneRef = destPath;
@@ -36864,7 +37903,7 @@ var init_voice = __esm({
36864
37903
  // -------------------------------------------------------------------------
36865
37904
  /** Metadata file for friendly names of clone refs */
36866
37905
  static cloneMetaFile() {
36867
- return join44(luxttsCloneRefsDir(), "meta.json");
37906
+ return join48(luxttsCloneRefsDir(), "meta.json");
36868
37907
  }
36869
37908
  loadCloneMeta() {
36870
37909
  const p = _VoiceEngine.cloneMetaFile();
@@ -36898,7 +37937,7 @@ var init_voice = __esm({
36898
37937
  return _VoiceEngine.AUDIO_EXTS.has(ext);
36899
37938
  });
36900
37939
  return files.map((f) => {
36901
- const p = join44(dir, f);
37940
+ const p = join48(dir, f);
36902
37941
  let size = 0;
36903
37942
  try {
36904
37943
  size = statSync12(p).size;
@@ -36915,7 +37954,7 @@ var init_voice = __esm({
36915
37954
  }
36916
37955
  /** Delete a clone reference file by filename. Returns true if deleted. */
36917
37956
  deleteCloneRef(filename) {
36918
- const p = join44(luxttsCloneRefsDir(), filename);
37957
+ const p = join48(luxttsCloneRefsDir(), filename);
36919
37958
  if (!existsSync35(p))
36920
37959
  return false;
36921
37960
  try {
@@ -36940,7 +37979,7 @@ var init_voice = __esm({
36940
37979
  }
36941
37980
  /** Set the active clone reference by filename. */
36942
37981
  setActiveCloneRef(filename) {
36943
- const p = join44(luxttsCloneRefsDir(), filename);
37982
+ const p = join48(luxttsCloneRefsDir(), filename);
36944
37983
  if (!existsSync35(p))
36945
37984
  return `File not found: ${filename}`;
36946
37985
  this.luxttsCloneRef = p;
@@ -37226,7 +38265,7 @@ var init_voice = __esm({
37226
38265
  }
37227
38266
  this.onPCMOutput(Buffer.from(int16.buffer), sampleRate);
37228
38267
  }
37229
- const wavPath = join44(tmpdir9(), `oa-voice-${Date.now()}.wav`);
38268
+ const wavPath = join48(tmpdir9(), `oa-voice-${Date.now()}.wav`);
37230
38269
  this.writeWav(audioData, sampleRate, wavPath);
37231
38270
  await this.playWav(wavPath);
37232
38271
  try {
@@ -37569,7 +38608,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
37569
38608
  const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
37570
38609
  const mlxVoice = model.mlxVoice ?? "af_heart";
37571
38610
  const mlxLangCode = model.mlxLangCode ?? "a";
37572
- const wavPath = join44(tmpdir9(), `oa-mlx-${Date.now()}.wav`);
38611
+ const wavPath = join48(tmpdir9(), `oa-mlx-${Date.now()}.wav`);
37573
38612
  const pyScript = [
37574
38613
  "import sys, json",
37575
38614
  "from mlx_audio.tts import generate as tts_gen",
@@ -37637,7 +38676,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
37637
38676
  const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
37638
38677
  const mlxVoice = model.mlxVoice ?? "af_heart";
37639
38678
  const mlxLangCode = model.mlxLangCode ?? "a";
37640
- const wavPath = join44(tmpdir9(), `oa-mlx-buf-${Date.now()}.wav`);
38679
+ const wavPath = join48(tmpdir9(), `oa-mlx-buf-${Date.now()}.wav`);
37641
38680
  const pyScript = [
37642
38681
  "import sys, json",
37643
38682
  "from mlx_audio.tts import generate as tts_gen",
@@ -37748,7 +38787,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
37748
38787
  }
37749
38788
  }
37750
38789
  const repoDir = luxttsRepoDir();
37751
- if (!existsSync35(join44(repoDir, "zipvoice", "luxvoice.py"))) {
38790
+ if (!existsSync35(join48(repoDir, "zipvoice", "luxvoice.py"))) {
37752
38791
  renderInfo(" Cloning LuxTTS repository...");
37753
38792
  try {
37754
38793
  if (existsSync35(repoDir)) {
@@ -37797,7 +38836,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
37797
38836
  if (!existsSync35(refsDir))
37798
38837
  return;
37799
38838
  for (const name of ["custom-clone.wav", "custom-clone.mp3", "glados-ref.wav", "overwatch-ref.wav"]) {
37800
- const p = join44(refsDir, name);
38839
+ const p = join48(refsDir, name);
37801
38840
  if (existsSync35(p)) {
37802
38841
  this.luxttsCloneRef = p;
37803
38842
  return;
@@ -37994,7 +39033,7 @@ if __name__ == '__main__':
37994
39033
  const ready = await this.ensureLuxttsDaemon();
37995
39034
  if (!ready)
37996
39035
  return;
37997
- const wavPath = join44(tmpdir9(), `oa-luxtts-${Date.now()}.wav`);
39036
+ const wavPath = join48(tmpdir9(), `oa-luxtts-${Date.now()}.wav`);
37998
39037
  try {
37999
39038
  await this.luxttsRequest({
38000
39039
  action: "synthesize",
@@ -38068,7 +39107,7 @@ if __name__ == '__main__':
38068
39107
  const ready = await this.ensureLuxttsDaemon();
38069
39108
  if (!ready)
38070
39109
  return null;
38071
- const wavPath = join44(tmpdir9(), `oa-luxtts-buf-${Date.now()}.wav`);
39110
+ const wavPath = join48(tmpdir9(), `oa-luxtts-buf-${Date.now()}.wav`);
38072
39111
  try {
38073
39112
  await this.luxttsRequest({
38074
39113
  action: "synthesize",
@@ -38098,7 +39137,7 @@ if __name__ == '__main__':
38098
39137
  return;
38099
39138
  const arch = process.arch;
38100
39139
  mkdirSync13(voiceDir(), { recursive: true });
38101
- const pkgPath = join44(voiceDir(), "package.json");
39140
+ const pkgPath = join48(voiceDir(), "package.json");
38102
39141
  const expectedDeps = {
38103
39142
  "onnxruntime-node": "^1.21.0",
38104
39143
  "phonemizer": "^1.2.1"
@@ -38120,17 +39159,17 @@ if __name__ == '__main__':
38120
39159
  dependencies: expectedDeps
38121
39160
  }, null, 2));
38122
39161
  }
38123
- const voiceRequire = createRequire(join44(voiceDir(), "index.js"));
39162
+ const voiceRequire = createRequire(join48(voiceDir(), "index.js"));
38124
39163
  const probeOnnx = () => {
38125
39164
  try {
38126
- 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") } });
39165
+ const result = execSync27(`node -e "try { require('onnxruntime-node'); console.log('OK'); } catch(e) { console.log('FAIL:' + e.message); }"`, { cwd: voiceDir(), stdio: "pipe", timeout: 15e3, env: { ...process.env, NODE_PATH: join48(voiceDir(), "node_modules") } });
38127
39166
  const output = result.toString().trim();
38128
39167
  return output === "OK";
38129
39168
  } catch {
38130
39169
  return false;
38131
39170
  }
38132
39171
  };
38133
- const onnxNodeModules = join44(voiceDir(), "node_modules", "onnxruntime-node");
39172
+ const onnxNodeModules = join48(voiceDir(), "node_modules", "onnxruntime-node");
38134
39173
  const onnxInstalled = existsSync35(onnxNodeModules);
38135
39174
  if (onnxInstalled && !probeOnnx()) {
38136
39175
  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.`);
@@ -40474,8 +41513,8 @@ async function handlePeerEndpoint(peerId, authKey, ctx, local) {
40474
41513
  if (models.length > 0) {
40475
41514
  try {
40476
41515
  const { writeFileSync: writeFileSync20, mkdirSync: mkdirSync21 } = await import("node:fs");
40477
- const { join: join58, dirname: dirname20 } = await import("node:path");
40478
- const cachePath = join58(ctx.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
41516
+ const { join: join62, dirname: dirname20 } = await import("node:path");
41517
+ const cachePath = join62(ctx.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
40479
41518
  mkdirSync21(dirname20(cachePath), { recursive: true });
40480
41519
  writeFileSync20(cachePath, JSON.stringify({
40481
41520
  peerId,
@@ -40676,14 +41715,14 @@ async function handleUpdate(subcommand, ctx) {
40676
41715
  try {
40677
41716
  const { createRequire: createRequire4 } = await import("node:module");
40678
41717
  const { fileURLToPath: fileURLToPath14 } = await import("node:url");
40679
- const { dirname: dirname20, join: join58 } = await import("node:path");
41718
+ const { dirname: dirname20, join: join62 } = await import("node:path");
40680
41719
  const { existsSync: existsSync45 } = await import("node:fs");
40681
41720
  const req = createRequire4(import.meta.url);
40682
41721
  const thisDir = dirname20(fileURLToPath14(import.meta.url));
40683
41722
  const candidates = [
40684
- join58(thisDir, "..", "package.json"),
40685
- join58(thisDir, "..", "..", "package.json"),
40686
- join58(thisDir, "..", "..", "..", "package.json")
41723
+ join62(thisDir, "..", "package.json"),
41724
+ join62(thisDir, "..", "..", "package.json"),
41725
+ join62(thisDir, "..", "..", "..", "package.json")
40687
41726
  ];
40688
41727
  for (const pkgPath of candidates) {
40689
41728
  if (existsSync45(pkgPath)) {
@@ -41401,7 +42440,7 @@ var init_commands = __esm({
41401
42440
 
41402
42441
  // packages/cli/dist/tui/project-context.js
41403
42442
  import { existsSync as existsSync36, readFileSync as readFileSync25, readdirSync as readdirSync10 } from "node:fs";
41404
- import { join as join45, basename as basename10 } from "node:path";
42443
+ import { join as join49, basename as basename10 } from "node:path";
41405
42444
  import { execSync as execSync28 } from "node:child_process";
41406
42445
  import { homedir as homedir12, platform as platform3, release } from "node:os";
41407
42446
  function getModelTier(modelName) {
@@ -41436,7 +42475,7 @@ function loadProjectMap(repoRoot) {
41436
42475
  if (!hasOaDirectory(repoRoot)) {
41437
42476
  initOaDirectory(repoRoot);
41438
42477
  }
41439
- const mapPath = join45(repoRoot, OA_DIR, "context", "project-map.md");
42478
+ const mapPath = join49(repoRoot, OA_DIR, "context", "project-map.md");
41440
42479
  if (existsSync36(mapPath)) {
41441
42480
  try {
41442
42481
  const content = readFileSync25(mapPath, "utf-8");
@@ -41480,17 +42519,17 @@ ${log}`);
41480
42519
  }
41481
42520
  function loadMemoryContext(repoRoot) {
41482
42521
  const sections = [];
41483
- const oaMemDir = join45(repoRoot, OA_DIR, "memory");
42522
+ const oaMemDir = join49(repoRoot, OA_DIR, "memory");
41484
42523
  const oaEntries = loadMemoryDir(oaMemDir, "project");
41485
42524
  if (oaEntries)
41486
42525
  sections.push(oaEntries);
41487
- const legacyMemDir = join45(repoRoot, ".open-agents", "memory");
42526
+ const legacyMemDir = join49(repoRoot, ".open-agents", "memory");
41488
42527
  if (legacyMemDir !== oaMemDir && existsSync36(legacyMemDir)) {
41489
42528
  const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
41490
42529
  if (legacyEntries)
41491
42530
  sections.push(legacyEntries);
41492
42531
  }
41493
- const globalMemDir = join45(homedir12(), ".open-agents", "memory");
42532
+ const globalMemDir = join49(homedir12(), ".open-agents", "memory");
41494
42533
  const globalEntries = loadMemoryDir(globalMemDir, "global");
41495
42534
  if (globalEntries)
41496
42535
  sections.push(globalEntries);
@@ -41504,7 +42543,7 @@ function loadMemoryDir(memDir, scope) {
41504
42543
  const files = readdirSync10(memDir).filter((f) => f.endsWith(".json"));
41505
42544
  for (const file of files.slice(0, 10)) {
41506
42545
  try {
41507
- const raw = readFileSync25(join45(memDir, file), "utf-8");
42546
+ const raw = readFileSync25(join49(memDir, file), "utf-8");
41508
42547
  const entries = JSON.parse(raw);
41509
42548
  const topic = basename10(file, ".json");
41510
42549
  const keys = Object.keys(entries);
@@ -42528,9 +43567,9 @@ var init_carousel = __esm({
42528
43567
 
42529
43568
  // packages/cli/dist/tui/carousel-descriptors.js
42530
43569
  import { existsSync as existsSync37, readFileSync as readFileSync26, writeFileSync as writeFileSync15, mkdirSync as mkdirSync14, readdirSync as readdirSync11 } from "node:fs";
42531
- import { join as join46, basename as basename11 } from "node:path";
43570
+ import { join as join50, basename as basename11 } from "node:path";
42532
43571
  function loadToolProfile(repoRoot) {
42533
- const filePath = join46(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
43572
+ const filePath = join50(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
42534
43573
  try {
42535
43574
  if (!existsSync37(filePath))
42536
43575
  return null;
@@ -42540,9 +43579,9 @@ function loadToolProfile(repoRoot) {
42540
43579
  }
42541
43580
  }
42542
43581
  function saveToolProfile(repoRoot, profile) {
42543
- const contextDir = join46(repoRoot, OA_DIR, "context");
43582
+ const contextDir = join50(repoRoot, OA_DIR, "context");
42544
43583
  mkdirSync14(contextDir, { recursive: true });
42545
- writeFileSync15(join46(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
43584
+ writeFileSync15(join50(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
42546
43585
  }
42547
43586
  function categorizeToolCall(toolName) {
42548
43587
  for (const cat of TOOL_CATEGORIES) {
@@ -42600,7 +43639,7 @@ function weightedColor(profile) {
42600
43639
  return selectedCat.colors[Math.floor(Math.random() * selectedCat.colors.length)];
42601
43640
  }
42602
43641
  function loadCachedDescriptors(repoRoot) {
42603
- const filePath = join46(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
43642
+ const filePath = join50(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
42604
43643
  try {
42605
43644
  if (!existsSync37(filePath))
42606
43645
  return null;
@@ -42611,14 +43650,14 @@ function loadCachedDescriptors(repoRoot) {
42611
43650
  }
42612
43651
  }
42613
43652
  function saveCachedDescriptors(repoRoot, phrases, sourceHash) {
42614
- const contextDir = join46(repoRoot, OA_DIR, "context");
43653
+ const contextDir = join50(repoRoot, OA_DIR, "context");
42615
43654
  mkdirSync14(contextDir, { recursive: true });
42616
43655
  const cached = {
42617
43656
  phrases,
42618
43657
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
42619
43658
  sourceHash
42620
43659
  };
42621
- writeFileSync15(join46(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
43660
+ writeFileSync15(join50(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
42622
43661
  }
42623
43662
  function generateDescriptors(repoRoot) {
42624
43663
  const profile = loadToolProfile(repoRoot);
@@ -42666,7 +43705,7 @@ function generateDescriptors(repoRoot) {
42666
43705
  return phrases;
42667
43706
  }
42668
43707
  function extractFromPackageJson(repoRoot, tags) {
42669
- const pkgPath = join46(repoRoot, "package.json");
43708
+ const pkgPath = join50(repoRoot, "package.json");
42670
43709
  try {
42671
43710
  if (!existsSync37(pkgPath))
42672
43711
  return;
@@ -42714,7 +43753,7 @@ function extractFromManifests(repoRoot, tags) {
42714
43753
  { file: ".github/workflows", tag: "ci/cd" }
42715
43754
  ];
42716
43755
  for (const check of manifestChecks) {
42717
- if (existsSync37(join46(repoRoot, check.file))) {
43756
+ if (existsSync37(join50(repoRoot, check.file))) {
42718
43757
  tags.push(check.tag);
42719
43758
  }
42720
43759
  }
@@ -42736,7 +43775,7 @@ function extractFromSessions(repoRoot, tags) {
42736
43775
  }
42737
43776
  }
42738
43777
  function extractFromMemory(repoRoot, tags) {
42739
- const memoryDir = join46(repoRoot, OA_DIR, "memory");
43778
+ const memoryDir = join50(repoRoot, OA_DIR, "memory");
42740
43779
  try {
42741
43780
  if (!existsSync37(memoryDir))
42742
43781
  return;
@@ -42745,7 +43784,7 @@ function extractFromMemory(repoRoot, tags) {
42745
43784
  const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
42746
43785
  tags.push(topic);
42747
43786
  try {
42748
- const data = JSON.parse(readFileSync26(join46(memoryDir, file), "utf-8"));
43787
+ const data = JSON.parse(readFileSync26(join50(memoryDir, file), "utf-8"));
42749
43788
  if (data && typeof data === "object") {
42750
43789
  const keys = Object.keys(data).slice(0, 3);
42751
43790
  for (const key of keys) {
@@ -43368,10 +44407,10 @@ var init_stream_renderer = __esm({
43368
44407
 
43369
44408
  // packages/cli/dist/tui/edit-history.js
43370
44409
  import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync15 } from "node:fs";
43371
- import { join as join47 } from "node:path";
44410
+ import { join as join51 } from "node:path";
43372
44411
  function createEditHistoryLogger(repoRoot, sessionId) {
43373
- const historyDir = join47(repoRoot, ".oa", "history");
43374
- const logPath = join47(historyDir, "edits.jsonl");
44412
+ const historyDir = join51(repoRoot, ".oa", "history");
44413
+ const logPath = join51(historyDir, "edits.jsonl");
43375
44414
  try {
43376
44415
  mkdirSync15(historyDir, { recursive: true });
43377
44416
  } catch {
@@ -43483,12 +44522,12 @@ var init_edit_history = __esm({
43483
44522
 
43484
44523
  // packages/cli/dist/tui/promptLoader.js
43485
44524
  import { readFileSync as readFileSync27, existsSync as existsSync38 } from "node:fs";
43486
- import { join as join48, dirname as dirname17 } from "node:path";
44525
+ import { join as join52, dirname as dirname17 } from "node:path";
43487
44526
  import { fileURLToPath as fileURLToPath11 } from "node:url";
43488
44527
  function loadPrompt3(promptPath, vars) {
43489
44528
  let content = cache3.get(promptPath);
43490
44529
  if (content === void 0) {
43491
- const fullPath = join48(PROMPTS_DIR3, promptPath);
44530
+ const fullPath = join52(PROMPTS_DIR3, promptPath);
43492
44531
  if (!existsSync38(fullPath)) {
43493
44532
  throw new Error(`Prompt file not found: ${fullPath}`);
43494
44533
  }
@@ -43505,8 +44544,8 @@ var init_promptLoader3 = __esm({
43505
44544
  "use strict";
43506
44545
  __filename3 = fileURLToPath11(import.meta.url);
43507
44546
  __dirname6 = dirname17(__filename3);
43508
- devPath2 = join48(__dirname6, "..", "..", "prompts");
43509
- publishedPath2 = join48(__dirname6, "..", "prompts");
44547
+ devPath2 = join52(__dirname6, "..", "..", "prompts");
44548
+ publishedPath2 = join52(__dirname6, "..", "prompts");
43510
44549
  PROMPTS_DIR3 = existsSync38(devPath2) ? devPath2 : publishedPath2;
43511
44550
  cache3 = /* @__PURE__ */ new Map();
43512
44551
  }
@@ -43514,10 +44553,10 @@ var init_promptLoader3 = __esm({
43514
44553
 
43515
44554
  // packages/cli/dist/tui/dream-engine.js
43516
44555
  import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync16, readFileSync as readFileSync28, existsSync as existsSync39, cpSync, rmSync, readdirSync as readdirSync12 } from "node:fs";
43517
- import { join as join49, basename as basename12 } from "node:path";
44556
+ import { join as join53, basename as basename12 } from "node:path";
43518
44557
  import { execSync as execSync29 } from "node:child_process";
43519
44558
  function loadAutoresearchMemory(repoRoot) {
43520
- const memoryPath = join49(repoRoot, ".oa", "memory", "autoresearch.json");
44559
+ const memoryPath = join53(repoRoot, ".oa", "memory", "autoresearch.json");
43521
44560
  if (!existsSync39(memoryPath))
43522
44561
  return "";
43523
44562
  try {
@@ -43711,12 +44750,12 @@ var init_dream_engine = __esm({
43711
44750
  const content = String(args["content"] ?? "");
43712
44751
  if (!rawPath)
43713
44752
  return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
43714
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join49(this.autoresearchDir, basename12(rawPath)) : join49(this.autoresearchDir, rawPath);
44753
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join53(this.autoresearchDir, basename12(rawPath)) : join53(this.autoresearchDir, rawPath);
43715
44754
  if (!targetPath.startsWith(this.autoresearchDir)) {
43716
44755
  return { success: false, output: "", error: "Autoresearch mode: writes are confined to .oa/autoresearch/", durationMs: Date.now() - start };
43717
44756
  }
43718
44757
  try {
43719
- const dir = join49(targetPath, "..");
44758
+ const dir = join53(targetPath, "..");
43720
44759
  mkdirSync16(dir, { recursive: true });
43721
44760
  writeFileSync16(targetPath, content, "utf-8");
43722
44761
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
@@ -43746,7 +44785,7 @@ var init_dream_engine = __esm({
43746
44785
  const rawPath = String(args["path"] ?? "");
43747
44786
  const oldStr = String(args["old_string"] ?? "");
43748
44787
  const newStr = String(args["new_string"] ?? "");
43749
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join49(this.autoresearchDir, basename12(rawPath)) : join49(this.autoresearchDir, rawPath);
44788
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join53(this.autoresearchDir, basename12(rawPath)) : join53(this.autoresearchDir, rawPath);
43750
44789
  if (!targetPath.startsWith(this.autoresearchDir)) {
43751
44790
  return { success: false, output: "", error: "Autoresearch mode: edits are confined to .oa/autoresearch/", durationMs: Date.now() - start };
43752
44791
  }
@@ -43800,12 +44839,12 @@ var init_dream_engine = __esm({
43800
44839
  const content = String(args["content"] ?? "");
43801
44840
  if (!rawPath)
43802
44841
  return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
43803
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join49(this.dreamsDir, basename12(rawPath)) : join49(this.dreamsDir, rawPath);
44842
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join53(this.dreamsDir, basename12(rawPath)) : join53(this.dreamsDir, rawPath);
43804
44843
  if (!targetPath.startsWith(this.dreamsDir)) {
43805
44844
  return { success: false, output: "", error: "Dream mode: writes are confined to .oa/dreams/", durationMs: Date.now() - start };
43806
44845
  }
43807
44846
  try {
43808
- const dir = join49(targetPath, "..");
44847
+ const dir = join53(targetPath, "..");
43809
44848
  mkdirSync16(dir, { recursive: true });
43810
44849
  writeFileSync16(targetPath, content, "utf-8");
43811
44850
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
@@ -43835,7 +44874,7 @@ var init_dream_engine = __esm({
43835
44874
  const rawPath = String(args["path"] ?? "");
43836
44875
  const oldStr = String(args["old_string"] ?? "");
43837
44876
  const newStr = String(args["new_string"] ?? "");
43838
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join49(this.dreamsDir, basename12(rawPath)) : join49(this.dreamsDir, rawPath);
44877
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join53(this.dreamsDir, basename12(rawPath)) : join53(this.dreamsDir, rawPath);
43839
44878
  if (!targetPath.startsWith(this.dreamsDir)) {
43840
44879
  return { success: false, output: "", error: "Dream mode: edits are confined to .oa/dreams/", durationMs: Date.now() - start };
43841
44880
  }
@@ -43902,7 +44941,7 @@ var init_dream_engine = __esm({
43902
44941
  constructor(config, repoRoot) {
43903
44942
  this.config = config;
43904
44943
  this.repoRoot = repoRoot;
43905
- this.dreamsDir = join49(repoRoot, ".oa", "dreams");
44944
+ this.dreamsDir = join53(repoRoot, ".oa", "dreams");
43906
44945
  this.state = {
43907
44946
  mode: "default",
43908
44947
  active: false,
@@ -43986,7 +45025,7 @@ ${result.summary}`;
43986
45025
  if (mode !== "default" || cycle === totalCycles) {
43987
45026
  renderDreamContraction(cycle);
43988
45027
  const cycleSummary = this.buildCycleSummary(cycle, previousFindings);
43989
- const summaryPath = join49(this.dreamsDir, `cycle-${cycle}-summary.md`);
45028
+ const summaryPath = join53(this.dreamsDir, `cycle-${cycle}-summary.md`);
43990
45029
  writeFileSync16(summaryPath, cycleSummary, "utf-8");
43991
45030
  }
43992
45031
  if (mode === "lucid" && !this.abortController.signal.aborted) {
@@ -44199,7 +45238,7 @@ After synthesis, call task_complete with the final prioritized summary.`, toolMo
44199
45238
  }
44200
45239
  /** Build role-specific tool sets for swarm agents */
44201
45240
  buildSwarmTools(role, _workspace) {
44202
- const autoresearchDir = join49(this.repoRoot, ".oa", "autoresearch");
45241
+ const autoresearchDir = join53(this.repoRoot, ".oa", "autoresearch");
44203
45242
  const taskComplete = this.createSwarmTaskCompleteTool(role);
44204
45243
  switch (role) {
44205
45244
  case "researcher": {
@@ -44563,7 +45602,7 @@ INSTRUCTIONS:
44563
45602
  2. Summarize the key learnings and next steps
44564
45603
 
44565
45604
  Call task_complete with a human-readable summary of the autoresearch session.`, workspace, onEvent);
44566
- const reportPath = join49(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
45605
+ const reportPath = join53(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
44567
45606
  const report = `# Autoresearch Swarm Report \u2014 Cycle ${cycleNum}
44568
45607
 
44569
45608
  **Date**: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
@@ -44652,7 +45691,7 @@ ${summaryResult}
44652
45691
  }
44653
45692
  /** Save workspace backup for lucid mode */
44654
45693
  saveVersionCheckpoint(cycle) {
44655
- const checkpointDir = join49(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
45694
+ const checkpointDir = join53(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
44656
45695
  try {
44657
45696
  mkdirSync16(checkpointDir, { recursive: true });
44658
45697
  try {
@@ -44671,10 +45710,10 @@ ${summaryResult}
44671
45710
  encoding: "utf-8",
44672
45711
  timeout: 5e3
44673
45712
  }).trim();
44674
- writeFileSync16(join49(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
44675
- writeFileSync16(join49(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
44676
- writeFileSync16(join49(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
44677
- writeFileSync16(join49(checkpointDir, "checkpoint.json"), JSON.stringify({
45713
+ writeFileSync16(join53(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
45714
+ writeFileSync16(join53(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
45715
+ writeFileSync16(join53(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
45716
+ writeFileSync16(join53(checkpointDir, "checkpoint.json"), JSON.stringify({
44678
45717
  cycle,
44679
45718
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
44680
45719
  gitHash,
@@ -44682,7 +45721,7 @@ ${summaryResult}
44682
45721
  }, null, 2), "utf-8");
44683
45722
  renderInfo(`Checkpoint saved: cycle ${cycle} (${gitHash.slice(0, 8)})`);
44684
45723
  } catch {
44685
- writeFileSync16(join49(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
45724
+ writeFileSync16(join53(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
44686
45725
  renderInfo(`Checkpoint saved: cycle ${cycle} (no git)`);
44687
45726
  }
44688
45727
  } catch (err) {
@@ -44740,14 +45779,14 @@ ${files.map((f) => `- [\`${f}\`](./${f})`).join("\n")}
44740
45779
  ---
44741
45780
  *Auto-generated by open-agents dream engine*
44742
45781
  `;
44743
- writeFileSync16(join49(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
45782
+ writeFileSync16(join53(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
44744
45783
  } catch {
44745
45784
  }
44746
45785
  }
44747
45786
  /** Save dream state for resume/inspection */
44748
45787
  saveDreamState() {
44749
45788
  try {
44750
- writeFileSync16(join49(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
45789
+ writeFileSync16(join53(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
44751
45790
  } catch {
44752
45791
  }
44753
45792
  }
@@ -45122,7 +46161,7 @@ var init_bless_engine = __esm({
45122
46161
 
45123
46162
  // packages/cli/dist/tui/dmn-engine.js
45124
46163
  import { existsSync as existsSync40, readFileSync as readFileSync29, writeFileSync as writeFileSync17, mkdirSync as mkdirSync17, readdirSync as readdirSync13, unlinkSync as unlinkSync9 } from "node:fs";
45125
- import { join as join50, basename as basename13 } from "node:path";
46164
+ import { join as join54, basename as basename13 } from "node:path";
45126
46165
  function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
45127
46166
  const competenceReport = competence.length > 0 ? competence.map((c3) => {
45128
46167
  const rate = c3.attempts > 0 ? Math.round(c3.successes / c3.attempts * 100) : 0;
@@ -45235,8 +46274,8 @@ var init_dmn_engine = __esm({
45235
46274
  constructor(config, repoRoot) {
45236
46275
  this.config = config;
45237
46276
  this.repoRoot = repoRoot;
45238
- this.stateDir = join50(repoRoot, ".oa", "dmn");
45239
- this.historyDir = join50(repoRoot, ".oa", "dmn", "cycles");
46277
+ this.stateDir = join54(repoRoot, ".oa", "dmn");
46278
+ this.historyDir = join54(repoRoot, ".oa", "dmn", "cycles");
45240
46279
  mkdirSync17(this.historyDir, { recursive: true });
45241
46280
  this.loadState();
45242
46281
  }
@@ -45826,8 +46865,8 @@ OUTPUT: Call task_complete with JSON:
45826
46865
  async gatherMemoryTopics() {
45827
46866
  const topics = [];
45828
46867
  const dirs = [
45829
- join50(this.repoRoot, ".oa", "memory"),
45830
- join50(this.repoRoot, ".open-agents", "memory")
46868
+ join54(this.repoRoot, ".oa", "memory"),
46869
+ join54(this.repoRoot, ".open-agents", "memory")
45831
46870
  ];
45832
46871
  for (const dir of dirs) {
45833
46872
  if (!existsSync40(dir))
@@ -45846,7 +46885,7 @@ OUTPUT: Call task_complete with JSON:
45846
46885
  }
45847
46886
  // ── State persistence ─────────────────────────────────────────────────
45848
46887
  loadState() {
45849
- const path = join50(this.stateDir, "state.json");
46888
+ const path = join54(this.stateDir, "state.json");
45850
46889
  if (existsSync40(path)) {
45851
46890
  try {
45852
46891
  this.state = JSON.parse(readFileSync29(path, "utf-8"));
@@ -45856,19 +46895,19 @@ OUTPUT: Call task_complete with JSON:
45856
46895
  }
45857
46896
  saveState() {
45858
46897
  try {
45859
- writeFileSync17(join50(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
46898
+ writeFileSync17(join54(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
45860
46899
  } catch {
45861
46900
  }
45862
46901
  }
45863
46902
  saveCycleResult(result) {
45864
46903
  try {
45865
46904
  const filename = `cycle-${result.cycleNumber}-${Date.now()}.json`;
45866
- writeFileSync17(join50(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
46905
+ writeFileSync17(join54(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
45867
46906
  const files = readdirSync13(this.historyDir).filter((f) => f.startsWith("cycle-") && f.endsWith(".json")).sort();
45868
46907
  if (files.length > 50) {
45869
46908
  for (const old of files.slice(0, files.length - 50)) {
45870
46909
  try {
45871
- unlinkSync9(join50(this.historyDir, old));
46910
+ unlinkSync9(join54(this.historyDir, old));
45872
46911
  } catch {
45873
46912
  }
45874
46913
  }
@@ -45882,7 +46921,7 @@ OUTPUT: Call task_complete with JSON:
45882
46921
 
45883
46922
  // packages/cli/dist/tui/snr-engine.js
45884
46923
  import { existsSync as existsSync41, readdirSync as readdirSync14, readFileSync as readFileSync30 } from "node:fs";
45885
- import { join as join51, basename as basename14 } from "node:path";
46924
+ import { join as join55, basename as basename14 } from "node:path";
45886
46925
  function computeDPrime(signalScores, noiseScores) {
45887
46926
  if (signalScores.length === 0 || noiseScores.length === 0)
45888
46927
  return 0;
@@ -46122,8 +47161,8 @@ Call task_complete with the JSON array when done.`, onEvent)
46122
47161
  loadMemoryEntries(topics) {
46123
47162
  const entries = [];
46124
47163
  const dirs = [
46125
- join51(this.repoRoot, ".oa", "memory"),
46126
- join51(this.repoRoot, ".open-agents", "memory")
47164
+ join55(this.repoRoot, ".oa", "memory"),
47165
+ join55(this.repoRoot, ".open-agents", "memory")
46127
47166
  ];
46128
47167
  for (const dir of dirs) {
46129
47168
  if (!existsSync41(dir))
@@ -46135,7 +47174,7 @@ Call task_complete with the JSON array when done.`, onEvent)
46135
47174
  if (topics.length > 0 && !topics.includes(topic))
46136
47175
  continue;
46137
47176
  try {
46138
- const data = JSON.parse(readFileSync30(join51(dir, f), "utf-8"));
47177
+ const data = JSON.parse(readFileSync30(join55(dir, f), "utf-8"));
46139
47178
  for (const [key, val] of Object.entries(data)) {
46140
47179
  const value = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
46141
47180
  entries.push({ topic, key, value });
@@ -46703,7 +47742,7 @@ var init_tool_policy = __esm({
46703
47742
 
46704
47743
  // packages/cli/dist/tui/telegram-bridge.js
46705
47744
  import { mkdirSync as mkdirSync18, existsSync as existsSync42, unlinkSync as unlinkSync10, readdirSync as readdirSync15, statSync as statSync13 } from "node:fs";
46706
- import { join as join52, resolve as resolve28 } from "node:path";
47745
+ import { join as join56, resolve as resolve28 } from "node:path";
46707
47746
  import { writeFile as writeFileAsync } from "node:fs/promises";
46708
47747
  function convertMarkdownToTelegramHTML(md) {
46709
47748
  let html = md;
@@ -47468,7 +48507,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
47468
48507
  return null;
47469
48508
  const buffer = Buffer.from(await res.arrayBuffer());
47470
48509
  const fileName = `${Date.now()}-${fileId.slice(0, 8)}${extension}`;
47471
- const localPath = join52(this.mediaCacheDir, fileName);
48510
+ const localPath = join56(this.mediaCacheDir, fileName);
47472
48511
  await writeFileAsync(localPath, buffer);
47473
48512
  return localPath;
47474
48513
  } catch {
@@ -48119,7 +49158,7 @@ var init_braille_spinner = __esm({
48119
49158
  // packages/cli/dist/tui/system-metrics.js
48120
49159
  import { loadavg as loadavg3, cpus as cpus3, totalmem as totalmem4, freemem as freemem3, platform as platform4 } from "node:os";
48121
49160
  import { exec as exec3 } from "node:child_process";
48122
- import { readFile as readFile16 } from "node:fs/promises";
49161
+ import { readFile as readFile20 } from "node:fs/promises";
48123
49162
  function formatRate(bytesPerSec) {
48124
49163
  if (bytesPerSec < 1024)
48125
49164
  return `${Math.round(bytesPerSec)}B`;
@@ -48131,7 +49170,7 @@ function formatRate(bytesPerSec) {
48131
49170
  }
48132
49171
  async function readProcNetDev() {
48133
49172
  try {
48134
- const data = await readFile16("/proc/net/dev", "utf8");
49173
+ const data = await readFile20("/proc/net/dev", "utf8");
48135
49174
  let rxTotal = 0;
48136
49175
  let txTotal = 0;
48137
49176
  for (const line of data.split("\n")) {
@@ -49906,7 +50945,7 @@ var init_status_bar = __esm({
49906
50945
  import * as readline2 from "node:readline";
49907
50946
  import { Writable } from "node:stream";
49908
50947
  import { cwd } from "node:process";
49909
- import { resolve as resolve29, join as join53, dirname as dirname18, extname as extname10 } from "node:path";
50948
+ import { resolve as resolve29, join as join57, dirname as dirname18, extname as extname10 } from "node:path";
49910
50949
  import { createRequire as createRequire2 } from "node:module";
49911
50950
  import { fileURLToPath as fileURLToPath12 } from "node:url";
49912
50951
  import { readFileSync as readFileSync32, writeFileSync as writeFileSync18, appendFileSync as appendFileSync4, rmSync as rmSync2, readdirSync as readdirSync16, mkdirSync as mkdirSync19 } from "node:fs";
@@ -49930,9 +50969,9 @@ function getVersion3() {
49930
50969
  const require2 = createRequire2(import.meta.url);
49931
50970
  const thisDir = dirname18(fileURLToPath12(import.meta.url));
49932
50971
  const candidates = [
49933
- join53(thisDir, "..", "package.json"),
49934
- join53(thisDir, "..", "..", "package.json"),
49935
- join53(thisDir, "..", "..", "..", "package.json")
50972
+ join57(thisDir, "..", "package.json"),
50973
+ join57(thisDir, "..", "..", "package.json"),
50974
+ join57(thisDir, "..", "..", "..", "package.json")
49936
50975
  ];
49937
50976
  for (const pkgPath of candidates) {
49938
50977
  if (existsSync43(pkgPath)) {
@@ -50025,6 +51064,14 @@ function buildTools(repoRoot, config, contextWindowSize) {
50025
51064
  new CodeSandboxTool(repoRoot),
50026
51065
  // Persistent Python REPL — RLM (arxiv:2512.24601)
50027
51066
  new ReplTool(repoRoot),
51067
+ // Memory Metabolism — COHERE Layer 5 (arxiv:2512.13564)
51068
+ new MemoryMetabolismTool(repoRoot),
51069
+ // Identity Kernel — COHERE Layer 6
51070
+ new IdentityKernelTool(repoRoot),
51071
+ // Reflection & Integrity — COHERE Layer 7
51072
+ new ReflectionIntegrityTool(repoRoot),
51073
+ // Exploration & Culture — COHERE Layer 8 (ARCHE)
51074
+ new ExplorationCultureTool(repoRoot),
50028
51075
  // Structured file reading (CSV, JSON, Markdown, binary detection)
50029
51076
  new StructuredReadTool(repoRoot),
50030
51077
  // Vision tools (Moondream — desktop awareness + point-and-click)
@@ -50144,15 +51191,15 @@ Use task_status("${taskId}") or task_output("${taskId}") to check progress.`
50144
51191
  function gatherMemorySnippets(root) {
50145
51192
  const snippets = [];
50146
51193
  const dirs = [
50147
- join53(root, ".oa", "memory"),
50148
- join53(root, ".open-agents", "memory")
51194
+ join57(root, ".oa", "memory"),
51195
+ join57(root, ".open-agents", "memory")
50149
51196
  ];
50150
51197
  for (const dir of dirs) {
50151
51198
  if (!existsSync43(dir))
50152
51199
  continue;
50153
51200
  try {
50154
51201
  for (const f of readdirSync16(dir).filter((f2) => f2.endsWith(".json"))) {
50155
- const data = JSON.parse(readFileSync32(join53(dir, f), "utf-8"));
51202
+ const data = JSON.parse(readFileSync32(join57(dir, f), "utf-8"));
50156
51203
  for (const val of Object.values(data)) {
50157
51204
  const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
50158
51205
  if (v.length > 10)
@@ -51174,7 +52221,7 @@ async function startInteractive(config, repoPath) {
51174
52221
  let p2pGateway = null;
51175
52222
  let peerMesh = null;
51176
52223
  let inferenceRouter = null;
51177
- const secretVault = new SecretVault(join53(repoRoot, ".oa", "vault.enc"));
52224
+ const secretVault = new SecretVault(join57(repoRoot, ".oa", "vault.enc"));
51178
52225
  let adminSessionKey = null;
51179
52226
  const callSubAgents = /* @__PURE__ */ new Map();
51180
52227
  const streamRenderer = new StreamRenderer();
@@ -51383,8 +52430,8 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
51383
52430
  const hits = allCompletions.filter((c3) => c3.toLowerCase().startsWith(lower));
51384
52431
  return [hits, line];
51385
52432
  }
51386
- const HISTORY_DIR = join53(homedir13(), ".open-agents");
51387
- const HISTORY_FILE = join53(HISTORY_DIR, "repl-history");
52433
+ const HISTORY_DIR = join57(homedir13(), ".open-agents");
52434
+ const HISTORY_FILE = join57(HISTORY_DIR, "repl-history");
51388
52435
  const MAX_HISTORY_LINES = 500;
51389
52436
  let savedHistory = [];
51390
52437
  try {
@@ -51594,7 +52641,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
51594
52641
  } catch {
51595
52642
  }
51596
52643
  try {
51597
- const oaDir = join53(repoRoot, ".oa");
52644
+ const oaDir = join57(repoRoot, ".oa");
51598
52645
  const reconnected = await ExposeGateway.checkAndReconnect(oaDir, {
51599
52646
  onInfo: (msg) => writeContent(() => renderInfo(msg)),
51600
52647
  onError: (msg) => writeContent(() => renderWarning(msg))
@@ -51617,7 +52664,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
51617
52664
  } catch {
51618
52665
  }
51619
52666
  try {
51620
- const oaDir = join53(repoRoot, ".oa");
52667
+ const oaDir = join57(repoRoot, ".oa");
51621
52668
  const reconnectedP2P = await ExposeP2PGateway.checkAndReconnect(oaDir, new NexusTool(repoRoot), {
51622
52669
  onInfo: (msg) => writeContent(() => renderInfo(msg)),
51623
52670
  onError: (msg) => writeContent(() => renderWarning(msg))
@@ -52436,7 +53483,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
52436
53483
  kind,
52437
53484
  targetUrl,
52438
53485
  authKey,
52439
- stateDir: join53(repoRoot, ".oa"),
53486
+ stateDir: join57(repoRoot, ".oa"),
52440
53487
  passthrough: passthrough ?? false,
52441
53488
  loadbalance: loadbalance ?? false,
52442
53489
  endpointAuth: passthrough ? currentConfig.apiKey : void 0,
@@ -52484,7 +53531,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
52484
53531
  await tunnelGateway.stop();
52485
53532
  tunnelGateway = null;
52486
53533
  }
52487
- const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join53(repoRoot, ".oa") });
53534
+ const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join57(repoRoot, ".oa") });
52488
53535
  newTunnel.on("stats", (stats) => {
52489
53536
  statusBar.setExposeStatus({
52490
53537
  status: stats.status,
@@ -52746,7 +53793,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
52746
53793
  }
52747
53794
  },
52748
53795
  destroyProject() {
52749
- const oaPath = join53(repoRoot, OA_DIR);
53796
+ const oaPath = join57(repoRoot, OA_DIR);
52750
53797
  if (existsSync43(oaPath)) {
52751
53798
  try {
52752
53799
  rmSync2(oaPath, { recursive: true, force: true });
@@ -53679,9 +54726,9 @@ var init_run = __esm({
53679
54726
  // packages/indexer/dist/codebase-indexer.js
53680
54727
  import { glob } from "glob";
53681
54728
  import ignore from "ignore";
53682
- import { readFile as readFile17, stat as stat4 } from "node:fs/promises";
54729
+ import { readFile as readFile21, stat as stat4 } from "node:fs/promises";
53683
54730
  import { createHash as createHash4 } from "node:crypto";
53684
- import { join as join54, relative as relative3, extname as extname11, basename as basename15 } from "node:path";
54731
+ import { join as join58, relative as relative3, extname as extname11, basename as basename15 } from "node:path";
53685
54732
  var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
53686
54733
  var init_codebase_indexer = __esm({
53687
54734
  "packages/indexer/dist/codebase-indexer.js"() {
@@ -53725,7 +54772,7 @@ var init_codebase_indexer = __esm({
53725
54772
  const ig = ignore.default();
53726
54773
  if (this.config.respectGitignore) {
53727
54774
  try {
53728
- const gitignoreContent = await readFile17(join54(this.config.rootDir, ".gitignore"), "utf-8");
54775
+ const gitignoreContent = await readFile21(join58(this.config.rootDir, ".gitignore"), "utf-8");
53729
54776
  ig.add(gitignoreContent);
53730
54777
  } catch {
53731
54778
  }
@@ -53740,12 +54787,12 @@ var init_codebase_indexer = __esm({
53740
54787
  for (const relativePath of files) {
53741
54788
  if (ig.ignores(relativePath))
53742
54789
  continue;
53743
- const fullPath = join54(this.config.rootDir, relativePath);
54790
+ const fullPath = join58(this.config.rootDir, relativePath);
53744
54791
  try {
53745
54792
  const fileStat = await stat4(fullPath);
53746
54793
  if (fileStat.size > this.config.maxFileSize)
53747
54794
  continue;
53748
- const content = await readFile17(fullPath);
54795
+ const content = await readFile21(fullPath);
53749
54796
  const hash = createHash4("sha256").update(content).digest("hex");
53750
54797
  const ext = extname11(relativePath);
53751
54798
  indexed.push({
@@ -53786,7 +54833,7 @@ var init_codebase_indexer = __esm({
53786
54833
  if (!child) {
53787
54834
  child = {
53788
54835
  name: part,
53789
- path: join54(current.path, part),
54836
+ path: join58(current.path, part),
53790
54837
  type: "directory",
53791
54838
  children: []
53792
54839
  };
@@ -54127,7 +55174,7 @@ var config_exports = {};
54127
55174
  __export(config_exports, {
54128
55175
  configCommand: () => configCommand
54129
55176
  });
54130
- import { join as join55, resolve as resolve31 } from "node:path";
55177
+ import { join as join59, resolve as resolve31 } from "node:path";
54131
55178
  import { homedir as homedir14 } from "node:os";
54132
55179
  import { cwd as cwd3 } from "node:process";
54133
55180
  function redactIfSensitive(key, value) {
@@ -54210,7 +55257,7 @@ function handleShow(opts, config) {
54210
55257
  }
54211
55258
  }
54212
55259
  printSection("Config File");
54213
- printInfo(`~/.open-agents/config.json (${join55(homedir14(), ".open-agents", "config.json")})`);
55260
+ printInfo(`~/.open-agents/config.json (${join59(homedir14(), ".open-agents", "config.json")})`);
54214
55261
  printSection("Priority Chain");
54215
55262
  printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
54216
55263
  printInfo(" 2. Project .oa/settings.json (--local)");
@@ -54249,7 +55296,7 @@ function handleSet(opts, _config) {
54249
55296
  const coerced = coerceForSettings(key, value);
54250
55297
  saveProjectSettings(repoRoot, { [key]: coerced });
54251
55298
  printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value)}`);
54252
- printInfo(`Saved to ${join55(repoRoot, ".oa", "settings.json")}`);
55299
+ printInfo(`Saved to ${join59(repoRoot, ".oa", "settings.json")}`);
54253
55300
  printInfo("This override applies only when running in this workspace.");
54254
55301
  } catch (err) {
54255
55302
  printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
@@ -54508,7 +55555,7 @@ __export(eval_exports, {
54508
55555
  });
54509
55556
  import { tmpdir as tmpdir10 } from "node:os";
54510
55557
  import { mkdirSync as mkdirSync20, writeFileSync as writeFileSync19 } from "node:fs";
54511
- import { join as join56 } from "node:path";
55558
+ import { join as join60 } from "node:path";
54512
55559
  async function evalCommand(opts, config) {
54513
55560
  const suiteName = opts.suite ?? "basic";
54514
55561
  const suite = SUITES[suiteName];
@@ -54633,9 +55680,9 @@ async function evalCommand(opts, config) {
54633
55680
  process.exit(failed > 0 ? 1 : 0);
54634
55681
  }
54635
55682
  function createTempEvalRepo() {
54636
- const dir = join56(tmpdir10(), `open-agents-eval-${Date.now()}`);
55683
+ const dir = join60(tmpdir10(), `open-agents-eval-${Date.now()}`);
54637
55684
  mkdirSync20(dir, { recursive: true });
54638
- writeFileSync19(join56(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
55685
+ writeFileSync19(join60(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
54639
55686
  return dir;
54640
55687
  }
54641
55688
  var BASIC_SUITE, FULL_SUITE, SUITES;
@@ -54695,7 +55742,7 @@ init_updater();
54695
55742
  import { parseArgs as nodeParseArgs2 } from "node:util";
54696
55743
  import { createRequire as createRequire3 } from "node:module";
54697
55744
  import { fileURLToPath as fileURLToPath13 } from "node:url";
54698
- import { dirname as dirname19, join as join57 } from "node:path";
55745
+ import { dirname as dirname19, join as join61 } from "node:path";
54699
55746
 
54700
55747
  // packages/cli/dist/cli.js
54701
55748
  import { createInterface } from "node:readline";
@@ -54802,7 +55849,7 @@ init_output();
54802
55849
  function getVersion4() {
54803
55850
  try {
54804
55851
  const require2 = createRequire3(import.meta.url);
54805
- const pkgPath = join57(dirname19(fileURLToPath13(import.meta.url)), "..", "package.json");
55852
+ const pkgPath = join61(dirname19(fileURLToPath13(import.meta.url)), "..", "package.json");
54806
55853
  const pkg = require2(pkgPath);
54807
55854
  return pkg.version;
54808
55855
  } catch {