open-agents-ai 0.109.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 +1117 -390
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -8232,8 +8232,723 @@ ${lines.join("\n")}`,
8232
8232
  }
8233
8233
  });
8234
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");
8945
+ }
8946
+ };
8947
+ }
8948
+ });
8949
+
8235
8950
  // packages/execution/dist/tools/structured-read.js
8236
- import { readFile as readFile9, stat as stat2 } from "node:fs/promises";
8951
+ import { readFile as readFile12, stat as stat2 } from "node:fs/promises";
8237
8952
  import { resolve as resolve15, extname as extname5 } from "node:path";
8238
8953
  function parseCSV(text, separator = ",") {
8239
8954
  const lines = text.split("\n").filter((l) => l.trim() !== "");
@@ -8428,7 +9143,7 @@ var init_structured_read = __esm({
8428
9143
  }
8429
9144
  }
8430
9145
  if (format === "xlsx" || format === "pdf" || format === "docx" || format === "auto") {
8431
- const buffer = await readFile9(fullPath);
9146
+ const buffer = await readFile12(fullPath);
8432
9147
  const detected = detectBinaryFormat(buffer);
8433
9148
  if (detected === "xlsx") {
8434
9149
  return {
@@ -8473,7 +9188,7 @@ Or install mammoth for programmatic access.`,
8473
9188
  }
8474
9189
  }
8475
9190
  }
8476
- const text = await readFile9(fullPath, "utf-8");
9191
+ const text = await readFile12(fullPath, "utf-8");
8477
9192
  switch (format) {
8478
9193
  case "csv": {
8479
9194
  const rows = parseCSV(text, ",");
@@ -8570,7 +9285,7 @@ ${parts.join("\n\n")}`,
8570
9285
  // packages/execution/dist/tools/vision.js
8571
9286
  import { readFileSync as readFileSync11, existsSync as existsSync14, statSync as statSync5 } from "node:fs";
8572
9287
  import { execSync as execSync11, spawn as spawn7 } from "node:child_process";
8573
- import { resolve as resolve16, extname as extname6, basename as basename5, dirname as dirname6, join as join20 } from "node:path";
9288
+ import { resolve as resolve16, extname as extname6, basename as basename5, dirname as dirname6, join as join23 } from "node:path";
8574
9289
  import { fileURLToPath as fileURLToPath2 } from "node:url";
8575
9290
  async function probeStation(endpoint) {
8576
9291
  try {
@@ -8585,7 +9300,7 @@ async function probeStation(endpoint) {
8585
9300
  }
8586
9301
  }
8587
9302
  function findStationBinary() {
8588
- const oaVenvPython = join20(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "python");
9303
+ const oaVenvPython = join23(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "python");
8589
9304
  if (existsSync14(oaVenvPython)) {
8590
9305
  try {
8591
9306
  execSync11(`${JSON.stringify(oaVenvPython)} -c "import moondream_station"`, { stdio: "pipe", timeout: 5e3 });
@@ -8593,7 +9308,7 @@ function findStationBinary() {
8593
9308
  } catch {
8594
9309
  }
8595
9310
  }
8596
- const oaVenvBin = join20(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "moondream-station");
9311
+ const oaVenvBin = join23(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "moondream-station");
8597
9312
  if (existsSync14(oaVenvBin))
8598
9313
  return oaVenvBin;
8599
9314
  const thisDir = dirname6(fileURLToPath2(import.meta.url));
@@ -8945,7 +9660,7 @@ ${response}`, durationMs: performance.now() - start };
8945
9660
  import { readFileSync as readFileSync12, existsSync as existsSync15 } from "node:fs";
8946
9661
  import { execSync as execSync12 } from "node:child_process";
8947
9662
  import { tmpdir as tmpdir4 } from "node:os";
8948
- import { join as join21, dirname as dirname7 } from "node:path";
9663
+ import { join as join24, dirname as dirname7 } from "node:path";
8949
9664
  import { fileURLToPath as fileURLToPath3 } from "node:url";
8950
9665
  function hasCommand2(cmd) {
8951
9666
  try {
@@ -9069,7 +9784,7 @@ for i in range(${clicks}):
9069
9784
  } catch {
9070
9785
  }
9071
9786
  try {
9072
- const venvPy = join21(__dirname2, "../../../../.moondream-venv/bin/python");
9787
+ const venvPy = join24(__dirname2, "../../../../.moondream-venv/bin/python");
9073
9788
  execSync12(`DISPLAY=:0 ${JSON.stringify(venvPy)} -c "${pyScript}"`, { stdio: "pipe", timeout: 5e3 });
9074
9789
  return;
9075
9790
  } catch {
@@ -9161,7 +9876,7 @@ var init_desktop_click = __esm({
9161
9876
  if (delayMs > 0) {
9162
9877
  await new Promise((r) => setTimeout(r, delayMs));
9163
9878
  }
9164
- const screenshotPath = join21(tmpdir4(), `oa-desktop-click-${Date.now()}.png`);
9879
+ const screenshotPath = join24(tmpdir4(), `oa-desktop-click-${Date.now()}.png`);
9165
9880
  captureScreenshot(screenshotPath);
9166
9881
  const dims = getImageDimensions2(screenshotPath);
9167
9882
  if (!dims) {
@@ -9336,7 +10051,7 @@ Screenshot: ${screenshotPath}`,
9336
10051
  if (delayMs > 0) {
9337
10052
  await new Promise((r) => setTimeout(r, delayMs));
9338
10053
  }
9339
- const screenshotPath = join21(tmpdir4(), `oa-desktop-describe-${Date.now()}.png`);
10054
+ const screenshotPath = join24(tmpdir4(), `oa-desktop-describe-${Date.now()}.png`);
9340
10055
  captureScreenshot(screenshotPath);
9341
10056
  const dims = getImageDimensions2(screenshotPath);
9342
10057
  const imageBuffer = readFileSync12(screenshotPath);
@@ -9575,7 +10290,7 @@ Language: ${language}
9575
10290
 
9576
10291
  // packages/execution/dist/tools/pdf-to-text.js
9577
10292
  import { existsSync as existsSync17, statSync as statSync7, readFileSync as readFileSync13, unlinkSync as unlinkSync3 } from "node:fs";
9578
- import { resolve as resolve18, basename as basename7, join as join22 } from "node:path";
10293
+ import { resolve as resolve18, basename as basename7, join as join25 } from "node:path";
9579
10294
  import { execSync as execSync14 } from "node:child_process";
9580
10295
  import { tmpdir as tmpdir5 } from "node:os";
9581
10296
  var PdfToTextTool;
@@ -9729,7 +10444,7 @@ ${text}`,
9729
10444
  if (!ocrCheck.available || !tesCheck.available || !gsCheck.available) {
9730
10445
  return null;
9731
10446
  }
9732
- const tmpPdf = join22(tmpdir5(), `oa-ocr-${Date.now()}.pdf`);
10447
+ const tmpPdf = join25(tmpdir5(), `oa-ocr-${Date.now()}.pdf`);
9733
10448
  try {
9734
10449
  const ocrCmd = `ocrmypdf -l ${language} --skip-text ${JSON.stringify(inputPath)} ${JSON.stringify(tmpPdf)}`;
9735
10450
  execSync14(ocrCmd, { stdio: "pipe", timeout: 6e5 });
@@ -9760,7 +10475,7 @@ ${text}`,
9760
10475
 
9761
10476
  // packages/execution/dist/tools/ocr-image-advanced.js
9762
10477
  import { existsSync as existsSync18, statSync as statSync8 } from "node:fs";
9763
- import { resolve as resolve19, basename as basename8, dirname as dirname8, join as join23 } from "node:path";
10478
+ import { resolve as resolve19, basename as basename8, dirname as dirname8, join as join26 } from "node:path";
9764
10479
  import { execSync as execSync15 } from "node:child_process";
9765
10480
  import { fileURLToPath as fileURLToPath4 } from "node:url";
9766
10481
  import { homedir as homedir7, tmpdir as tmpdir6 } from "node:os";
@@ -9778,7 +10493,7 @@ function findOcrScript() {
9778
10493
  return null;
9779
10494
  }
9780
10495
  function findPython() {
9781
- const venvPython = join23(homedir7(), ".open-agents", "venv", "bin", "python");
10496
+ const venvPython = join26(homedir7(), ".open-agents", "venv", "bin", "python");
9782
10497
  if (existsSync18(venvPython)) {
9783
10498
  try {
9784
10499
  execSync15(`${JSON.stringify(venvPython)} -c "import cv2, pytesseract, numpy, PIL"`, {
@@ -9924,7 +10639,7 @@ var init_ocr_image_advanced = __esm({
9924
10639
  cmdParts.push("--output-dir", JSON.stringify(resolve19(this.workingDir, outputDir)));
9925
10640
  let debugDir;
9926
10641
  if (debug) {
9927
- debugDir = join23(tmpdir6(), `oa-ocr-debug-${Date.now()}`);
10642
+ debugDir = join26(tmpdir6(), `oa-ocr-debug-${Date.now()}`);
9928
10643
  cmdParts.push("--debug-dir", debugDir);
9929
10644
  }
9930
10645
  try {
@@ -10023,7 +10738,7 @@ var init_ocr_image_advanced = __esm({
10023
10738
  if (region) {
10024
10739
  try {
10025
10740
  const [x, y, w, h] = region.split(",").map(Number);
10026
- const croppedPath = join23(tmpdir6(), `oa-ocr-crop-${Date.now()}.png`);
10741
+ const croppedPath = join26(tmpdir6(), `oa-ocr-crop-${Date.now()}.png`);
10027
10742
  execSync15(`convert ${JSON.stringify(imagePath)} -crop ${w}x${h}+${x}+${y} +repage ${JSON.stringify(croppedPath)}`, { stdio: "pipe", timeout: 1e4 });
10028
10743
  inputPath = croppedPath;
10029
10744
  } catch {
@@ -10064,18 +10779,18 @@ Note: Advanced Python pipeline not available \u2014 install pytesseract, opencv-
10064
10779
  // packages/execution/dist/tools/browser-action.js
10065
10780
  import { execSync as execSync16, spawn as spawn8 } from "node:child_process";
10066
10781
  import { existsSync as existsSync19, readFileSync as readFileSync14 } from "node:fs";
10067
- import { join as join24, dirname as dirname9 } from "node:path";
10782
+ import { join as join27, dirname as dirname9 } from "node:path";
10068
10783
  import { fileURLToPath as fileURLToPath5 } from "node:url";
10069
10784
  function findScrapeScript() {
10070
10785
  const candidates = [
10071
10786
  // Published npm package: dist/scripts/web_scrape.py
10072
- join24(__dirname3, "scripts", "web_scrape.py"),
10787
+ join27(__dirname3, "scripts", "web_scrape.py"),
10073
10788
  // Published npm package (from node_modules): node_modules/open-agents-ai/dist/scripts/
10074
- join24(__dirname3, "..", "node_modules", "open-agents-ai", "dist", "scripts", "web_scrape.py"),
10789
+ join27(__dirname3, "..", "node_modules", "open-agents-ai", "dist", "scripts", "web_scrape.py"),
10075
10790
  // Dev monorepo: packages/execution/src/tools/../../scripts/
10076
- join24(__dirname3, "..", "..", "scripts", "web_scrape.py"),
10791
+ join27(__dirname3, "..", "..", "scripts", "web_scrape.py"),
10077
10792
  // Dev monorepo alt: packages/execution/scripts/
10078
- join24(__dirname3, "..", "scripts", "web_scrape.py")
10793
+ join27(__dirname3, "..", "scripts", "web_scrape.py")
10079
10794
  ];
10080
10795
  return candidates.find((p) => existsSync19(p)) || candidates[0];
10081
10796
  }
@@ -10330,7 +11045,7 @@ var init_browser_action = __esm({
10330
11045
  // packages/execution/dist/tools/autoresearch.js
10331
11046
  import { execSync as execSync17, spawn as spawn9 } from "node:child_process";
10332
11047
  import { existsSync as existsSync20, readFileSync as readFileSync15, writeFileSync as writeFileSync6, mkdirSync as mkdirSync6, appendFileSync, copyFileSync } from "node:fs";
10333
- import { join as join25, resolve as resolve20, dirname as dirname10 } from "node:path";
11048
+ import { join as join28, resolve as resolve20, dirname as dirname10 } from "node:path";
10334
11049
  import { fileURLToPath as fileURLToPath6 } from "node:url";
10335
11050
  function findAutoresearchScript(scriptName) {
10336
11051
  const thisDir = dirname10(fileURLToPath6(import.meta.url));
@@ -10432,7 +11147,7 @@ Requires: NVIDIA GPU, Python 3.10+, uv (astral.sh package manager).`;
10432
11147
  async execute(args) {
10433
11148
  const start = Date.now();
10434
11149
  const action = String(args["action"] ?? "status");
10435
- const workspacePath = String(args["workspace"] ?? join25(this.repoRoot, ".oa", "autoresearch"));
11150
+ const workspacePath = String(args["workspace"] ?? join28(this.repoRoot, ".oa", "autoresearch"));
10436
11151
  try {
10437
11152
  switch (action) {
10438
11153
  case "setup":
@@ -10473,13 +11188,13 @@ Requires: NVIDIA GPU, Python 3.10+, uv (astral.sh package manager).`;
10473
11188
  const prepareScript = findAutoresearchScript("autoresearch-prepare.py");
10474
11189
  const trainScript = findAutoresearchScript("autoresearch-train.py");
10475
11190
  if (prepareScript) {
10476
- copyFileSync(prepareScript, join25(workspace, "prepare.py"));
11191
+ copyFileSync(prepareScript, join28(workspace, "prepare.py"));
10477
11192
  output.push("Copied prepare.py template");
10478
11193
  } else {
10479
11194
  return { success: false, output: output.join("\n"), error: "autoresearch-prepare.py template not found in distribution", durationMs: Date.now() - start };
10480
11195
  }
10481
11196
  if (trainScript) {
10482
- copyFileSync(trainScript, join25(workspace, "train.py"));
11197
+ copyFileSync(trainScript, join28(workspace, "train.py"));
10483
11198
  output.push("Copied train.py template");
10484
11199
  } else {
10485
11200
  return { success: false, output: output.join("\n"), error: "autoresearch-train.py template not found in distribution", durationMs: Date.now() - start };
@@ -10511,7 +11226,7 @@ name = "pytorch-cu128"
10511
11226
  url = "https://download.pytorch.org/whl/cu128"
10512
11227
  explicit = true
10513
11228
  `;
10514
- writeFileSync6(join25(workspace, "pyproject.toml"), pyprojectContent, "utf-8");
11229
+ writeFileSync6(join28(workspace, "pyproject.toml"), pyprojectContent, "utf-8");
10515
11230
  output.push("Created pyproject.toml");
10516
11231
  try {
10517
11232
  execSync17("git rev-parse --git-dir", { cwd: workspace, encoding: "utf-8", timeout: 5e3 });
@@ -10553,7 +11268,7 @@ explicit = true
10553
11268
  const e = err;
10554
11269
  output.push(`Data prep warning: ${(e.stderr ?? e.stdout ?? "failed").slice(0, 500)}`);
10555
11270
  }
10556
- const tsvPath = join25(workspace, "results.tsv");
11271
+ const tsvPath = join28(workspace, "results.tsv");
10557
11272
  if (!existsSync20(tsvPath)) {
10558
11273
  writeFileSync6(tsvPath, "commit val_bpb memory_gb status description\n", "utf-8");
10559
11274
  output.push("Created results.tsv");
@@ -10575,10 +11290,10 @@ Next steps:
10575
11290
  }
10576
11291
  // ── Run experiment ─────────────────────────────────────────────────────
10577
11292
  async run(workspace, args, start) {
10578
- if (!existsSync20(join25(workspace, "train.py"))) {
11293
+ if (!existsSync20(join28(workspace, "train.py"))) {
10579
11294
  return { success: false, output: "", error: `No train.py found in ${workspace}. Run autoresearch(action="setup") first.`, durationMs: Date.now() - start };
10580
11295
  }
10581
- if (!existsSync20(join25(workspace, ".venv")) && existsSync20(join25(workspace, "pyproject.toml"))) {
11296
+ if (!existsSync20(join28(workspace, ".venv")) && existsSync20(join28(workspace, "pyproject.toml"))) {
10582
11297
  try {
10583
11298
  execSync17("uv sync 2>&1", { cwd: workspace, encoding: "utf-8", timeout: 3e5 });
10584
11299
  } catch {
@@ -10586,7 +11301,7 @@ Next steps:
10586
11301
  }
10587
11302
  const timeoutMin = Number(args["timeout_minutes"] ?? 10);
10588
11303
  const timeoutMs = timeoutMin * 60 * 1e3;
10589
- const logPath = join25(workspace, "run.log");
11304
+ const logPath = join28(workspace, "run.log");
10590
11305
  return new Promise((resolveResult) => {
10591
11306
  const proc = spawn9("uv", ["run", "train.py"], {
10592
11307
  cwd: workspace,
@@ -10657,7 +11372,7 @@ ${fullLog.slice(-2e3)}`,
10657
11372
  return;
10658
11373
  }
10659
11374
  try {
10660
- writeFileSync6(join25(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");
10661
11376
  } catch {
10662
11377
  }
10663
11378
  const memGB = (result.peak_vram_mb / 1024).toFixed(1);
@@ -10693,7 +11408,7 @@ ${fullLog.slice(-2e3)}`,
10693
11408
  }
10694
11409
  // ── Results ────────────────────────────────────────────────────────────
10695
11410
  getResults(workspace, start) {
10696
- const tsvPath = join25(workspace, "results.tsv");
11411
+ const tsvPath = join28(workspace, "results.tsv");
10697
11412
  if (!existsSync20(tsvPath)) {
10698
11413
  return { success: false, output: "", error: `No results.tsv found. Run autoresearch(action="setup") first.`, durationMs: Date.now() - start };
10699
11414
  }
@@ -10720,7 +11435,7 @@ ${fullLog.slice(-2e3)}`,
10720
11435
  // ── Status ─────────────────────────────────────────────────────────────
10721
11436
  getStatus(workspace, start) {
10722
11437
  const output = [];
10723
- if (!existsSync20(join25(workspace, "train.py"))) {
11438
+ if (!existsSync20(join28(workspace, "train.py"))) {
10724
11439
  return {
10725
11440
  success: true,
10726
11441
  output: `Autoresearch workspace not initialized at ${workspace}.
@@ -10743,7 +11458,7 @@ Run autoresearch(action="setup") to begin.`,
10743
11458
  } catch {
10744
11459
  output.push("GPU: not detected");
10745
11460
  }
10746
- const lastResultPath = join25(workspace, ".last-result.json");
11461
+ const lastResultPath = join28(workspace, ".last-result.json");
10747
11462
  if (existsSync20(lastResultPath)) {
10748
11463
  try {
10749
11464
  const last = JSON.parse(readFileSync15(lastResultPath, "utf-8"));
@@ -10751,20 +11466,20 @@ Run autoresearch(action="setup") to begin.`,
10751
11466
  } catch {
10752
11467
  }
10753
11468
  }
10754
- const tsvPath = join25(workspace, "results.tsv");
11469
+ const tsvPath = join28(workspace, "results.tsv");
10755
11470
  if (existsSync20(tsvPath)) {
10756
11471
  const lines = readFileSync15(tsvPath, "utf-8").trim().split("\n");
10757
11472
  output.push(`Experiments recorded: ${lines.length - 1}`);
10758
11473
  }
10759
- const cacheDir = join25(process.env["HOME"] ?? "~", ".cache", "autoresearch");
11474
+ const cacheDir = join28(process.env["HOME"] ?? "~", ".cache", "autoresearch");
10760
11475
  output.push(`Data cache: ${existsSync20(cacheDir) ? "present" : "not found"} (${cacheDir})`);
10761
11476
  return { success: true, output: output.join("\n"), durationMs: Date.now() - start };
10762
11477
  }
10763
11478
  // ── Keep / Discard ─────────────────────────────────────────────────────
10764
11479
  keepExperiment(workspace, args, start) {
10765
11480
  const desc = String(args["description"] ?? "experiment");
10766
- const tsvPath = join25(workspace, "results.tsv");
10767
- const lastResultPath = join25(workspace, ".last-result.json");
11481
+ const tsvPath = join28(workspace, "results.tsv");
11482
+ const lastResultPath = join28(workspace, ".last-result.json");
10768
11483
  let valBpb = args["val_bpb"];
10769
11484
  let memGb = args["memory_gb"];
10770
11485
  if ((valBpb === void 0 || memGb === void 0) && existsSync20(lastResultPath)) {
@@ -10802,8 +11517,8 @@ Branch advanced. Ready for next experiment.`,
10802
11517
  }
10803
11518
  discardExperiment(workspace, args, start) {
10804
11519
  const desc = String(args["description"] ?? "experiment");
10805
- const tsvPath = join25(workspace, "results.tsv");
10806
- const lastResultPath = join25(workspace, ".last-result.json");
11520
+ const tsvPath = join28(workspace, "results.tsv");
11521
+ const lastResultPath = join28(workspace, ".last-result.json");
10807
11522
  let valBpb = args["val_bpb"];
10808
11523
  let memGb = args["memory_gb"];
10809
11524
  if ((valBpb === void 0 || memGb === void 0) && existsSync20(lastResultPath)) {
@@ -10849,8 +11564,8 @@ train.py reverted to last kept state. Ready for next experiment.`,
10849
11564
 
10850
11565
  // packages/execution/dist/tools/scheduler.js
10851
11566
  import { execSync as execSync18, exec as execCb } from "node:child_process";
10852
- import { readFile as readFile10, writeFile as writeFile9, mkdir as mkdir5 } from "node:fs/promises";
10853
- import { resolve as resolve21, join as join26 } from "node:path";
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";
10854
11569
  import { randomBytes as randomBytes3 } from "node:crypto";
10855
11570
  function isValidCron(expr) {
10856
11571
  const parts = expr.trim().split(/\s+/);
@@ -10934,7 +11649,7 @@ function installCronJob(task, workingDir) {
10934
11649
  const lines = getCurrentCrontab();
10935
11650
  const oaBin = findOaBinary();
10936
11651
  const logDir = resolve21(workingDir, ".oa", "scheduled", "logs");
10937
- const logFile = join26(logDir, `${task.id}.log`);
11652
+ const logFile = join29(logDir, `${task.id}.log`);
10938
11653
  const storeFile = resolve21(workingDir, ".oa", "scheduled", "tasks.json");
10939
11654
  const taskEscaped = task.task.replace(/'/g, "'\\''");
10940
11655
  const taskId = task.id;
@@ -10967,7 +11682,7 @@ function listCronJobs() {
10967
11682
  async function loadStore(workingDir) {
10968
11683
  const storePath = resolve21(workingDir, ".oa", "scheduled", "tasks.json");
10969
11684
  try {
10970
- const raw = await readFile10(storePath, "utf-8");
11685
+ const raw = await readFile13(storePath, "utf-8");
10971
11686
  return JSON.parse(raw);
10972
11687
  } catch {
10973
11688
  return { tasks: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
@@ -10975,10 +11690,10 @@ async function loadStore(workingDir) {
10975
11690
  }
10976
11691
  async function saveStore(workingDir, store) {
10977
11692
  const dir = resolve21(workingDir, ".oa", "scheduled");
10978
- await mkdir5(dir, { recursive: true });
10979
- await mkdir5(join26(dir, "logs"), { recursive: true });
11693
+ await mkdir8(dir, { recursive: true });
11694
+ await mkdir8(join29(dir, "logs"), { recursive: true });
10980
11695
  store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
10981
- await writeFile9(join26(dir, "tasks.json"), JSON.stringify(store, null, 2), "utf-8");
11696
+ await writeFile12(join29(dir, "tasks.json"), JSON.stringify(store, null, 2), "utf-8");
10982
11697
  }
10983
11698
  var SCHEDULE_PRESETS, CRON_MARKER, SchedulerTool;
10984
11699
  var init_scheduler = __esm({
@@ -11198,7 +11913,7 @@ var init_scheduler = __esm({
11198
11913
  return { success: false, output: "", error: "id is required for logs action", durationMs: performance.now() - start };
11199
11914
  const logFile = resolve21(this.workingDir, ".oa", "scheduled", "logs", `${id}.log`);
11200
11915
  try {
11201
- const raw = await readFile10(logFile, "utf-8");
11916
+ const raw = await readFile13(logFile, "utf-8");
11202
11917
  const truncated = raw.length > 1e4 ? "...(truncated)\n" + raw.slice(-1e4) : raw;
11203
11918
  return { success: true, output: `Logs for ${id}:
11204
11919
  ${truncated}`, durationMs: performance.now() - start };
@@ -11211,8 +11926,8 @@ ${truncated}`, durationMs: performance.now() - start };
11211
11926
  });
11212
11927
 
11213
11928
  // packages/execution/dist/tools/reminder.js
11214
- import { readFile as readFile11, writeFile as writeFile10, mkdir as mkdir6 } from "node:fs/promises";
11215
- import { resolve as resolve22, join as join27 } from "node:path";
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";
11216
11931
  import { randomBytes as randomBytes4 } from "node:crypto";
11217
11932
  function parseDueTime(due) {
11218
11933
  const lower = due.toLowerCase().trim();
@@ -11263,13 +11978,13 @@ function parseDueTime(due) {
11263
11978
  }
11264
11979
  async function getStorePath(workingDir) {
11265
11980
  const dir = resolve22(workingDir, ".oa", "scheduled");
11266
- await mkdir6(dir, { recursive: true });
11267
- return join27(dir, STORE_FILE);
11981
+ await mkdir9(dir, { recursive: true });
11982
+ return join30(dir, STORE_FILE);
11268
11983
  }
11269
11984
  async function loadReminderStore(workingDir) {
11270
11985
  const storePath = await getStorePath(workingDir);
11271
11986
  try {
11272
- const raw = await readFile11(storePath, "utf-8");
11987
+ const raw = await readFile14(storePath, "utf-8");
11273
11988
  return JSON.parse(raw);
11274
11989
  } catch {
11275
11990
  return { reminders: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
@@ -11278,7 +11993,7 @@ async function loadReminderStore(workingDir) {
11278
11993
  async function saveReminderStore(workingDir, store) {
11279
11994
  const storePath = await getStorePath(workingDir);
11280
11995
  store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
11281
- await writeFile10(storePath, JSON.stringify(store, null, 2), "utf-8");
11996
+ await writeFile13(storePath, JSON.stringify(store, null, 2), "utf-8");
11282
11997
  }
11283
11998
  async function getDueReminders(workingDir) {
11284
11999
  const store = await loadReminderStore(workingDir);
@@ -11524,13 +12239,13 @@ var init_reminder = __esm({
11524
12239
  });
11525
12240
 
11526
12241
  // packages/execution/dist/tools/agenda.js
11527
- import { readFile as readFile12, writeFile as writeFile11, mkdir as mkdir7 } from "node:fs/promises";
11528
- import { resolve as resolve23, join as join28 } from "node:path";
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";
11529
12244
  import { randomBytes as randomBytes5 } from "node:crypto";
11530
12245
  async function loadAttentionStore(workingDir) {
11531
12246
  const storePath = resolve23(workingDir, ".oa", "scheduled", "attention.json");
11532
12247
  try {
11533
- const raw = await readFile12(storePath, "utf-8");
12248
+ const raw = await readFile15(storePath, "utf-8");
11534
12249
  return JSON.parse(raw);
11535
12250
  } catch {
11536
12251
  return { items: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
@@ -11538,9 +12253,9 @@ async function loadAttentionStore(workingDir) {
11538
12253
  }
11539
12254
  async function saveAttentionStore(workingDir, store) {
11540
12255
  const dir = resolve23(workingDir, ".oa", "scheduled");
11541
- await mkdir7(dir, { recursive: true });
12256
+ await mkdir10(dir, { recursive: true });
11542
12257
  store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
11543
- await writeFile11(join28(dir, "attention.json"), JSON.stringify(store, null, 2), "utf-8");
12258
+ await writeFile14(join31(dir, "attention.json"), JSON.stringify(store, null, 2), "utf-8");
11544
12259
  }
11545
12260
  async function getActiveAttentionItems(workingDir) {
11546
12261
  const store = await loadAttentionStore(workingDir);
@@ -11836,7 +12551,7 @@ ${sections.join("\n")}`,
11836
12551
  async loadScheduleStore() {
11837
12552
  try {
11838
12553
  const storePath = resolve23(this.workingDir, ".oa", "scheduled", "tasks.json");
11839
- const raw = await readFile12(storePath, "utf-8");
12554
+ const raw = await readFile15(storePath, "utf-8");
11840
12555
  const store = JSON.parse(raw);
11841
12556
  return store.tasks ?? [];
11842
12557
  } catch {
@@ -11850,7 +12565,7 @@ ${sections.join("\n")}`,
11850
12565
  // packages/execution/dist/tools/opencode.js
11851
12566
  import { execSync as execSync19, spawn as spawn10 } from "node:child_process";
11852
12567
  import { existsSync as existsSync21 } from "node:fs";
11853
- import { join as join29, resolve as resolve24 } from "node:path";
12568
+ import { join as join32, resolve as resolve24 } from "node:path";
11854
12569
  function findOpencode() {
11855
12570
  for (const cmd of ["opencode"]) {
11856
12571
  try {
@@ -11862,8 +12577,8 @@ function findOpencode() {
11862
12577
  }
11863
12578
  const homeDir = process.env.HOME || process.env.USERPROFILE || "";
11864
12579
  const candidates = [
11865
- join29(homeDir, ".opencode", "bin", "opencode"),
11866
- join29(homeDir, "bin", "opencode"),
12580
+ join32(homeDir, ".opencode", "bin", "opencode"),
12581
+ join32(homeDir, "bin", "opencode"),
11867
12582
  "/usr/local/bin/opencode"
11868
12583
  ];
11869
12584
  for (const p of candidates) {
@@ -12124,7 +12839,7 @@ var init_opencode = __esm({
12124
12839
  // packages/execution/dist/tools/factory.js
12125
12840
  import { execSync as execSync20, spawn as spawn11 } from "node:child_process";
12126
12841
  import { existsSync as existsSync22 } from "node:fs";
12127
- import { join as join30 } from "node:path";
12842
+ import { join as join33 } from "node:path";
12128
12843
  function findDroid() {
12129
12844
  for (const cmd of ["droid"]) {
12130
12845
  try {
@@ -12136,8 +12851,8 @@ function findDroid() {
12136
12851
  }
12137
12852
  const homeDir = process.env.HOME || process.env.USERPROFILE || "";
12138
12853
  const candidates = [
12139
- join30(homeDir, ".factory", "bin", "droid"),
12140
- join30(homeDir, "bin", "droid"),
12854
+ join33(homeDir, ".factory", "bin", "droid"),
12855
+ join33(homeDir, "bin", "droid"),
12141
12856
  "/usr/local/bin/droid"
12142
12857
  ];
12143
12858
  for (const p of candidates) {
@@ -12432,8 +13147,8 @@ var init_factory = __esm({
12432
13147
 
12433
13148
  // packages/execution/dist/tools/cron-agent.js
12434
13149
  import { execSync as execSync21 } from "node:child_process";
12435
- import { readFile as readFile13, writeFile as writeFile12, mkdir as mkdir8 } from "node:fs/promises";
12436
- import { resolve as resolve25, join as join31 } from "node:path";
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";
12437
13152
  import { randomBytes as randomBytes6 } from "node:crypto";
12438
13153
  function isValidCron2(expr) {
12439
13154
  const parts = expr.trim().split(/\s+/);
@@ -12519,7 +13234,7 @@ function installCronAgentJob(job, workingDir) {
12519
13234
  const lines = getCurrentCrontab2();
12520
13235
  const oaBin = findOaBinary2();
12521
13236
  const logDir = resolve25(workingDir, ".oa", "cron-agents", "logs");
12522
- const logFile = join31(logDir, `${job.id}.log`);
13237
+ const logFile = join34(logDir, `${job.id}.log`);
12523
13238
  const storeFile = resolve25(workingDir, ".oa", "cron-agents", "store.json");
12524
13239
  const taskEscaped = job.task.replace(/'/g, "'\\''");
12525
13240
  const jobId = job.id;
@@ -12549,7 +13264,7 @@ function removeCronAgentJob(jobId) {
12549
13264
  async function loadStore2(workingDir) {
12550
13265
  const storePath = resolve25(workingDir, ".oa", "cron-agents", "store.json");
12551
13266
  try {
12552
- const raw = await readFile13(storePath, "utf-8");
13267
+ const raw = await readFile16(storePath, "utf-8");
12553
13268
  return JSON.parse(raw);
12554
13269
  } catch {
12555
13270
  return { jobs: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
@@ -12557,10 +13272,10 @@ async function loadStore2(workingDir) {
12557
13272
  }
12558
13273
  async function saveStore2(workingDir, store) {
12559
13274
  const dir = resolve25(workingDir, ".oa", "cron-agents");
12560
- await mkdir8(dir, { recursive: true });
12561
- await mkdir8(join31(dir, "logs"), { recursive: true });
13275
+ await mkdir11(dir, { recursive: true });
13276
+ await mkdir11(join34(dir, "logs"), { recursive: true });
12562
13277
  store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
12563
- await writeFile12(join31(dir, "store.json"), JSON.stringify(store, null, 2), "utf-8");
13278
+ await writeFile15(join34(dir, "store.json"), JSON.stringify(store, null, 2), "utf-8");
12564
13279
  }
12565
13280
  var LONG_HORIZON_PRESETS, CRON_AGENT_MARKER, CronAgentTool;
12566
13281
  var init_cron_agent = __esm({
@@ -12825,7 +13540,7 @@ var init_cron_agent = __esm({
12825
13540
  return { success: false, output: "", error: "id is required", durationMs: performance.now() - start };
12826
13541
  const logFile = resolve25(this.workingDir, ".oa", "cron-agents", "logs", `${id}.log`);
12827
13542
  try {
12828
- const raw = await readFile13(logFile, "utf-8");
13543
+ const raw = await readFile16(logFile, "utf-8");
12829
13544
  const truncated = raw.length > 2e4 ? "...(truncated)\n" + raw.slice(-2e4) : raw;
12830
13545
  return { success: true, output: `Logs for ${id}:
12831
13546
  ${truncated}`, durationMs: performance.now() - start };
@@ -12896,9 +13611,9 @@ ${truncated}`, durationMs: performance.now() - start };
12896
13611
  });
12897
13612
 
12898
13613
  // packages/execution/dist/tools/nexus.js
12899
- import { readFile as readFile14, writeFile as writeFile13, mkdir as mkdir9, 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";
12900
13615
  import { existsSync as existsSync23, readFileSync as readFileSync16, watch as fsWatchLocal } from "node:fs";
12901
- import { resolve as resolve26, join as join32 } from "node:path";
13616
+ import { resolve as resolve26, join as join35 } from "node:path";
12902
13617
  import { randomBytes as randomBytes7, createCipheriv, createDecipheriv, scryptSync, createHash } from "node:crypto";
12903
13618
  import { execSync as execSync22, spawn as spawn12 } from "node:child_process";
12904
13619
  import { hostname, userInfo } from "node:os";
@@ -14871,7 +15586,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14871
15586
  }
14872
15587
  async ensureDir() {
14873
15588
  if (!existsSync23(this.nexusDir)) {
14874
- await mkdir9(this.nexusDir, { recursive: true });
15589
+ await mkdir12(this.nexusDir, { recursive: true });
14875
15590
  }
14876
15591
  }
14877
15592
  async execute(args) {
@@ -14991,7 +15706,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14991
15706
  // Daemon management
14992
15707
  // =========================================================================
14993
15708
  getDaemonPid() {
14994
- const pidFile = join32(this.nexusDir, "daemon.pid");
15709
+ const pidFile = join35(this.nexusDir, "daemon.pid");
14995
15710
  if (!existsSync23(pidFile))
14996
15711
  return null;
14997
15712
  try {
@@ -15017,12 +15732,12 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15017
15732
  throw new Error("Nexus daemon not running. Use action 'connect' first.");
15018
15733
  }
15019
15734
  const cmdId = randomBytes7(8).toString("hex");
15020
- const cmdFile = join32(this.nexusDir, "cmd.json");
15021
- const respFile = join32(this.nexusDir, "resp.json");
15735
+ const cmdFile = join35(this.nexusDir, "cmd.json");
15736
+ const respFile = join35(this.nexusDir, "resp.json");
15022
15737
  if (existsSync23(respFile))
15023
15738
  await unlink(respFile).catch(() => {
15024
15739
  });
15025
- await writeFile13(cmdFile, JSON.stringify({ id: cmdId, action, args }, null, 2));
15740
+ await writeFile16(cmdFile, JSON.stringify({ id: cmdId, action, args }, null, 2));
15026
15741
  const pollMs = 50;
15027
15742
  const polls = Math.ceil(timeoutMs / pollMs);
15028
15743
  let resolved = false;
@@ -15054,7 +15769,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15054
15769
  if (!existsSync23(respFile))
15055
15770
  continue;
15056
15771
  try {
15057
- const resp = JSON.parse(await readFile14(respFile, "utf8"));
15772
+ const resp = JSON.parse(await readFile17(respFile, "utf8"));
15058
15773
  if (resp.id === cmdId) {
15059
15774
  resolved = true;
15060
15775
  return resp.output || (resp.ok ? "OK" : "Failed");
@@ -15077,7 +15792,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15077
15792
  }
15078
15793
  if (existsSync23(respFile)) {
15079
15794
  try {
15080
- const resp = JSON.parse(await readFile14(respFile, "utf8"));
15795
+ const resp = JSON.parse(await readFile17(respFile, "utf8"));
15081
15796
  if (resp.id === cmdId) {
15082
15797
  return resp.output || (resp.ok ? "OK" : "Failed");
15083
15798
  }
@@ -15102,7 +15817,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15102
15817
  const currentScriptHash = createHash("sha256").update(DAEMON_SCRIPT).digest("hex").slice(0, 16);
15103
15818
  const existingPid = this.getDaemonPid();
15104
15819
  if (existingPid) {
15105
- const daemonPath2 = join32(this.nexusDir, "nexus-daemon.mjs");
15820
+ const daemonPath2 = join35(this.nexusDir, "nexus-daemon.mjs");
15106
15821
  let needsRestart = true;
15107
15822
  if (existsSync23(daemonPath2)) {
15108
15823
  try {
@@ -15126,16 +15841,16 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15126
15841
  } catch {
15127
15842
  }
15128
15843
  for (const f of ["daemon.pid", "status.json", "cmd.json", "resp.json"]) {
15129
- const p = join32(this.nexusDir, f);
15844
+ const p = join35(this.nexusDir, f);
15130
15845
  if (existsSync23(p))
15131
15846
  await unlink(p).catch(() => {
15132
15847
  });
15133
15848
  }
15134
15849
  } else {
15135
- const statusFile2 = join32(this.nexusDir, "status.json");
15850
+ const statusFile2 = join35(this.nexusDir, "status.json");
15136
15851
  if (existsSync23(statusFile2)) {
15137
15852
  try {
15138
- const status = JSON.parse(await readFile14(statusFile2, "utf8"));
15853
+ const status = JSON.parse(await readFile17(statusFile2, "utf8"));
15139
15854
  if (status.connected && status.peerId) {
15140
15855
  await this.ensureWallet();
15141
15856
  return `Already connected (pid: ${existingPid}, peerId: ${status.peerId})`;
@@ -15151,7 +15866,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15151
15866
  }
15152
15867
  }
15153
15868
  for (const f of ["daemon.pid", "status.json", "cmd.json", "resp.json"]) {
15154
- const p = join32(this.nexusDir, f);
15869
+ const p = join35(this.nexusDir, f);
15155
15870
  if (existsSync23(p))
15156
15871
  await unlink(p).catch(() => {
15157
15872
  });
@@ -15169,7 +15884,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15169
15884
  });
15170
15885
  });
15171
15886
  try {
15172
- const nexusPkg = join32(nodeModulesDir, "open-agents-nexus", "package.json");
15887
+ const nexusPkg = join35(nodeModulesDir, "open-agents-nexus", "package.json");
15173
15888
  if (existsSync23(nexusPkg)) {
15174
15889
  nexusResolved = true;
15175
15890
  try {
@@ -15180,7 +15895,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15180
15895
  } else {
15181
15896
  try {
15182
15897
  const globalDir = await execAsync2("npm root -g", { timeout: 5e3 });
15183
- const globalPkg = join32(globalDir, "open-agents-nexus", "package.json");
15898
+ const globalPkg = join35(globalDir, "open-agents-nexus", "package.json");
15184
15899
  if (existsSync23(globalPkg)) {
15185
15900
  nexusResolved = true;
15186
15901
  try {
@@ -15225,8 +15940,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15225
15940
  }
15226
15941
  }
15227
15942
  await this.ensureWallet();
15228
- const daemonPath = join32(this.nexusDir, "nexus-daemon.mjs");
15229
- await writeFile13(daemonPath, DAEMON_SCRIPT);
15943
+ const daemonPath = join35(this.nexusDir, "nexus-daemon.mjs");
15944
+ await writeFile16(daemonPath, DAEMON_SCRIPT);
15230
15945
  const agentName = args.agent_name || "open-agents-node";
15231
15946
  const agentType = args.agent_type || "general";
15232
15947
  const nodePaths = [nodeModulesDir];
@@ -15236,8 +15951,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15236
15951
  } catch {
15237
15952
  }
15238
15953
  const { openSync: openSync2, closeSync: closeSync2 } = await import("node:fs");
15239
- const daemonLogPath = join32(this.nexusDir, "daemon.log");
15240
- const daemonErrPath = join32(this.nexusDir, "daemon.err");
15954
+ const daemonLogPath = join35(this.nexusDir, "daemon.log");
15955
+ const daemonErrPath = join35(this.nexusDir, "daemon.err");
15241
15956
  const outFd = openSync2(daemonLogPath, "w");
15242
15957
  const errFd = openSync2(daemonErrPath, "w");
15243
15958
  const child = spawn12("node", [daemonPath, this.nexusDir, agentName, agentType], {
@@ -15255,16 +15970,16 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15255
15970
  closeSync2(errFd);
15256
15971
  } catch {
15257
15972
  }
15258
- const statusFile = join32(this.nexusDir, "status.json");
15973
+ const statusFile = join35(this.nexusDir, "status.json");
15259
15974
  for (let i = 0; i < 40; i++) {
15260
15975
  await new Promise((r) => setTimeout(r, 500));
15261
15976
  if (existsSync23(statusFile)) {
15262
15977
  try {
15263
- const status = JSON.parse(await readFile14(statusFile, "utf8"));
15978
+ const status = JSON.parse(await readFile17(statusFile, "utf8"));
15264
15979
  if (status.error) {
15265
15980
  let errTail = "";
15266
15981
  try {
15267
- errTail = (await readFile14(daemonErrPath, "utf8")).slice(-300);
15982
+ errTail = (await readFile17(daemonErrPath, "utf8")).slice(-300);
15268
15983
  } catch {
15269
15984
  }
15270
15985
  return `Nexus daemon failed to connect: ${status.error}${errTail ? "\n" + errTail : ""}`;
@@ -15286,12 +16001,12 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15286
16001
  const pid = this.getDaemonPid();
15287
16002
  let earlyError = "";
15288
16003
  try {
15289
- earlyError = (await readFile14(daemonErrPath, "utf8")).slice(-500);
16004
+ earlyError = (await readFile17(daemonErrPath, "utf8")).slice(-500);
15290
16005
  } catch {
15291
16006
  }
15292
16007
  let earlyOutput = "";
15293
16008
  try {
15294
- earlyOutput = (await readFile14(daemonLogPath, "utf8")).slice(-500);
16009
+ earlyOutput = (await readFile17(daemonLogPath, "utf8")).slice(-500);
15295
16010
  } catch {
15296
16011
  }
15297
16012
  if (pid) {
@@ -15314,7 +16029,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15314
16029
  } catch {
15315
16030
  }
15316
16031
  for (const f of ["daemon.pid", "status.json", "cmd.json", "resp.json"]) {
15317
- const p = join32(this.nexusDir, f);
16032
+ const p = join35(this.nexusDir, f);
15318
16033
  if (existsSync23(p))
15319
16034
  await unlink(p).catch(() => {
15320
16035
  });
@@ -15325,11 +16040,11 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15325
16040
  const pid = this.getDaemonPid();
15326
16041
  if (!pid)
15327
16042
  return "Nexus daemon not running. Use action 'connect' to start.";
15328
- const statusFile = join32(this.nexusDir, "status.json");
16043
+ const statusFile = join35(this.nexusDir, "status.json");
15329
16044
  if (!existsSync23(statusFile))
15330
16045
  return `Daemon running (pid: ${pid}) but no status yet.`;
15331
16046
  try {
15332
- const status = JSON.parse(await readFile14(statusFile, "utf8"));
16047
+ const status = JSON.parse(await readFile17(statusFile, "utf8"));
15333
16048
  const lines = [
15334
16049
  `Nexus Status (v1.5.0)`,
15335
16050
  ` Connected: ${status.connected}`,
@@ -15340,10 +16055,10 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15340
16055
  ` Capabilities: ${(status.capabilities || []).length ? (status.capabilities || []).join(", ") : "none"}`,
15341
16056
  ` Blocked peers: ${(status.blockedPeers || []).length || 0}`
15342
16057
  ];
15343
- const walletPath = join32(this.nexusDir, "wallet.enc");
16058
+ const walletPath = join35(this.nexusDir, "wallet.enc");
15344
16059
  if (existsSync23(walletPath)) {
15345
16060
  try {
15346
- const w = JSON.parse(await readFile14(walletPath, "utf8"));
16061
+ const w = JSON.parse(await readFile17(walletPath, "utf8"));
15347
16062
  lines.push(` Wallet: ${w.address}`);
15348
16063
  } catch {
15349
16064
  lines.push(` Wallet: corrupt`);
@@ -15351,14 +16066,14 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15351
16066
  } else {
15352
16067
  lines.push(` Wallet: not configured`);
15353
16068
  }
15354
- const inboxDir = join32(this.nexusDir, "inbox");
16069
+ const inboxDir = join35(this.nexusDir, "inbox");
15355
16070
  if (existsSync23(inboxDir)) {
15356
16071
  try {
15357
16072
  const roomDirs = await readdir3(inboxDir);
15358
16073
  let totalMsgs = 0;
15359
16074
  for (const rd of roomDirs) {
15360
16075
  try {
15361
- totalMsgs += (await readdir3(join32(inboxDir, rd))).length;
16076
+ totalMsgs += (await readdir3(join35(inboxDir, rd))).length;
15362
16077
  } catch {
15363
16078
  }
15364
16079
  }
@@ -15405,9 +16120,9 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15405
16120
  }
15406
16121
  async doReadMessages(args) {
15407
16122
  const roomId = args.room_id;
15408
- const inboxDir = join32(this.nexusDir, "inbox");
16123
+ const inboxDir = join35(this.nexusDir, "inbox");
15409
16124
  if (roomId) {
15410
- const roomInbox = join32(inboxDir, roomId);
16125
+ const roomInbox = join35(inboxDir, roomId);
15411
16126
  if (!existsSync23(roomInbox))
15412
16127
  return `No messages in room: ${roomId}`;
15413
16128
  const files = (await readdir3(roomInbox)).sort().slice(-20);
@@ -15416,7 +16131,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15416
16131
  const messages = [`Messages in ${roomId} (last ${files.length}):`];
15417
16132
  for (const f of files) {
15418
16133
  try {
15419
- const msg = JSON.parse(await readFile14(join32(roomInbox, f), "utf8"));
16134
+ const msg = JSON.parse(await readFile17(join35(roomInbox, f), "utf8"));
15420
16135
  const sender = (msg.sender || "unknown").slice(0, 12);
15421
16136
  messages.push(` [${new Date(msg.timestamp).toLocaleTimeString()}] ${sender}...: ${msg.content}`);
15422
16137
  } catch {
@@ -15432,7 +16147,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15432
16147
  const lines = ["Inbox:"];
15433
16148
  for (const rd of roomDirs) {
15434
16149
  try {
15435
- const count = (await readdir3(join32(inboxDir, rd))).length;
16150
+ const count = (await readdir3(join35(inboxDir, rd))).length;
15436
16151
  lines.push(` ${rd}: ${count} message(s)`);
15437
16152
  } catch {
15438
16153
  }
@@ -15444,12 +16159,12 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15444
16159
  // ---------------------------------------------------------------------------
15445
16160
  async doWalletStatus() {
15446
16161
  await this.ensureDir();
15447
- const walletPath = join32(this.nexusDir, "wallet.enc");
16162
+ const walletPath = join35(this.nexusDir, "wallet.enc");
15448
16163
  if (!existsSync23(walletPath)) {
15449
16164
  return "No wallet configured. Use wallet_create to set one up.";
15450
16165
  }
15451
16166
  try {
15452
- const w = JSON.parse(await readFile14(walletPath, "utf8"));
16167
+ const w = JSON.parse(await readFile17(walletPath, "utf8"));
15453
16168
  const lines = [
15454
16169
  `Wallet Status:`,
15455
16170
  ` Address: ${w.address}`,
@@ -15483,7 +16198,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15483
16198
  }
15484
16199
  async doWalletCreate(args) {
15485
16200
  await this.ensureDir();
15486
- const walletPath = join32(this.nexusDir, "wallet.enc");
16201
+ const walletPath = join35(this.nexusDir, "wallet.enc");
15487
16202
  if (existsSync23(walletPath))
15488
16203
  return "Wallet already exists. Delete wallet.enc to create a new one.";
15489
16204
  const userAddress = args.wallet_address;
@@ -15529,7 +16244,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15529
16244
  const cipher = createCipheriv("aes-256-gcm", key, iv);
15530
16245
  let enc = cipher.update(privKeyHex, "utf8", "hex");
15531
16246
  enc += cipher.final("hex");
15532
- const x402KeyPath = join32(this.nexusDir, "x402-wallet.key");
16247
+ const x402KeyPath = join35(this.nexusDir, "x402-wallet.key");
15533
16248
  const x402Fh = await fsOpen(x402KeyPath, "w", 384);
15534
16249
  await x402Fh.writeFile("0x" + privKeyHex);
15535
16250
  await x402Fh.close();
@@ -15567,7 +16282,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15567
16282
  * Silent — no user output, just ensures the files exist.
15568
16283
  */
15569
16284
  async ensureWallet() {
15570
- const walletPath = join32(this.nexusDir, "wallet.enc");
16285
+ const walletPath = join35(this.nexusDir, "wallet.enc");
15571
16286
  if (existsSync23(walletPath))
15572
16287
  return;
15573
16288
  let address;
@@ -15591,7 +16306,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15591
16306
  const cipher = createCipheriv("aes-256-gcm", key, iv);
15592
16307
  let enc = cipher.update(privKeyHex, "utf8", "hex");
15593
16308
  enc += cipher.final("hex");
15594
- const x402KeyPath = join32(this.nexusDir, "x402-wallet.key");
16309
+ const x402KeyPath = join35(this.nexusDir, "x402-wallet.key");
15595
16310
  const x402Fh = await fsOpen(x402KeyPath, "w", 384);
15596
16311
  await x402Fh.writeFile("0x" + privKeyHex);
15597
16312
  await x402Fh.close();
@@ -15651,12 +16366,12 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15651
16366
  // ---------------------------------------------------------------------------
15652
16367
  async doLedgerStatus() {
15653
16368
  await this.ensureDir();
15654
- const ledgerPath = join32(this.nexusDir, "ledger.jsonl");
16369
+ const ledgerPath = join35(this.nexusDir, "ledger.jsonl");
15655
16370
  if (!existsSync23(ledgerPath)) {
15656
16371
  return "No ledger entries. Earnings and spending will be tracked here after x402 transactions.";
15657
16372
  }
15658
16373
  try {
15659
- const raw = await readFile14(ledgerPath, "utf8");
16374
+ const raw = await readFile17(ledgerPath, "utf8");
15660
16375
  const entries = raw.trim().split("\n").filter((l) => l.trim()).map((l) => JSON.parse(l));
15661
16376
  if (entries.length === 0) {
15662
16377
  return "Ledger is empty. No transactions recorded.";
@@ -15693,11 +16408,11 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15693
16408
  }
15694
16409
  }
15695
16410
  async getLedgerSummary() {
15696
- const ledgerPath = join32(this.nexusDir, "ledger.jsonl");
16411
+ const ledgerPath = join35(this.nexusDir, "ledger.jsonl");
15697
16412
  if (!existsSync23(ledgerPath))
15698
16413
  return null;
15699
16414
  try {
15700
- const raw = await readFile14(ledgerPath, "utf8");
16415
+ const raw = await readFile17(ledgerPath, "utf8");
15701
16416
  const entries = raw.trim().split("\n").filter((l) => l.trim()).map((l) => JSON.parse(l));
15702
16417
  let totalEarned = 0n, totalSpent = 0n;
15703
16418
  for (const e of entries) {
@@ -15718,25 +16433,25 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15718
16433
  }
15719
16434
  async appendLedger(entry) {
15720
16435
  await this.ensureDir();
15721
- const ledgerPath = join32(this.nexusDir, "ledger.jsonl");
16436
+ const ledgerPath = join35(this.nexusDir, "ledger.jsonl");
15722
16437
  const line = JSON.stringify(entry) + "\n";
15723
- await writeFile13(ledgerPath, existsSync23(ledgerPath) ? await readFile14(ledgerPath, "utf8") + line : line);
16438
+ await writeFile16(ledgerPath, existsSync23(ledgerPath) ? await readFile17(ledgerPath, "utf8") + line : line);
15724
16439
  }
15725
16440
  // ---------------------------------------------------------------------------
15726
16441
  // Step 4: Budget Policy — Spending limits and auto-approve thresholds
15727
16442
  // ---------------------------------------------------------------------------
15728
16443
  async loadBudget() {
15729
- const budgetPath = join32(this.nexusDir, "budget.json");
16444
+ const budgetPath = join35(this.nexusDir, "budget.json");
15730
16445
  if (!existsSync23(budgetPath))
15731
16446
  return null;
15732
16447
  try {
15733
- return JSON.parse(await readFile14(budgetPath, "utf8"));
16448
+ return JSON.parse(await readFile17(budgetPath, "utf8"));
15734
16449
  } catch {
15735
16450
  return null;
15736
16451
  }
15737
16452
  }
15738
16453
  async ensureDefaultBudget() {
15739
- const budgetPath = join32(this.nexusDir, "budget.json");
16454
+ const budgetPath = join35(this.nexusDir, "budget.json");
15740
16455
  if (existsSync23(budgetPath))
15741
16456
  return;
15742
16457
  const defaultBudget = {
@@ -15757,7 +16472,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15757
16472
  deniedPeers: []
15758
16473
  };
15759
16474
  await this.ensureDir();
15760
- await writeFile13(budgetPath, JSON.stringify(defaultBudget, null, 2));
16475
+ await writeFile16(budgetPath, JSON.stringify(defaultBudget, null, 2));
15761
16476
  }
15762
16477
  async doBudgetStatus() {
15763
16478
  await this.ensureDir();
@@ -15806,17 +16521,17 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15806
16521
  if (changes.length === 0) {
15807
16522
  return "No budget parameters provided. Use daily_limit, per_invoke_max, or auto_approve_below.";
15808
16523
  }
15809
- const budgetPath = join32(this.nexusDir, "budget.json");
15810
- await writeFile13(budgetPath, JSON.stringify(budget, null, 2));
16524
+ const budgetPath = join35(this.nexusDir, "budget.json");
16525
+ await writeFile16(budgetPath, JSON.stringify(budget, null, 2));
15811
16526
  return `Budget updated: ${changes.join(", ")}`;
15812
16527
  }
15813
16528
  async getTodaySpending() {
15814
- const ledgerPath = join32(this.nexusDir, "ledger.jsonl");
16529
+ const ledgerPath = join35(this.nexusDir, "ledger.jsonl");
15815
16530
  if (!existsSync23(ledgerPath))
15816
16531
  return 0;
15817
16532
  try {
15818
16533
  const todayPrefix = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
15819
- const raw = await readFile14(ledgerPath, "utf8");
16534
+ const raw = await readFile17(ledgerPath, "utf8");
15820
16535
  let total = 0;
15821
16536
  for (const line of raw.trim().split("\n")) {
15822
16537
  if (!line.trim())
@@ -15855,10 +16570,10 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15855
16570
  if (todaySpent + amountUsdc > budget.dailyLimitUsdc) {
15856
16571
  return { allowed: false, reason: `Would exceed daily limit ($${((todaySpent + amountUsdc) / 1e6).toFixed(6)} > $${(budget.dailyLimitUsdc / 1e6).toFixed(6)})` };
15857
16572
  }
15858
- const walletPath = join32(this.nexusDir, "wallet.enc");
16573
+ const walletPath = join35(this.nexusDir, "wallet.enc");
15859
16574
  if (existsSync23(walletPath)) {
15860
16575
  try {
15861
- const w = JSON.parse(await readFile14(walletPath, "utf8"));
16576
+ const w = JSON.parse(await readFile17(walletPath, "utf8"));
15862
16577
  if (w.version === 2 && w.address) {
15863
16578
  const balance = await this.queryUsdcBalance(w.address, w.chainId || 8453);
15864
16579
  if (balance !== null && Number(balance) < budget.circuitBreakerUsdc) {
@@ -15886,10 +16601,10 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15886
16601
  const budgetResult = await this.checkBudget(amountSmallest, "transfer:direct", targetAddress);
15887
16602
  if (!budgetResult.allowed)
15888
16603
  return `BLOCKED by budget policy: ${budgetResult.reason}`;
15889
- const walletPath = join32(this.nexusDir, "wallet.enc");
16604
+ const walletPath = join35(this.nexusDir, "wallet.enc");
15890
16605
  if (!existsSync23(walletPath))
15891
16606
  throw new Error("No wallet. Use wallet_create first.");
15892
- const w = JSON.parse(await readFile14(walletPath, "utf8"));
16607
+ const w = JSON.parse(await readFile17(walletPath, "utf8"));
15893
16608
  if (!w.encryptedKey)
15894
16609
  throw new Error("User-managed wallet cannot spend (no private key)");
15895
16610
  const salt = Buffer.from(w.salt, "hex");
@@ -15947,7 +16662,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15947
16662
  capability: "transfer:direct",
15948
16663
  note: "signed, awaiting submission"
15949
16664
  });
15950
- const proofFile = join32(this.nexusDir, "pending-transfer.json");
16665
+ const proofFile = join35(this.nexusDir, "pending-transfer.json");
15951
16666
  const proof = {
15952
16667
  from: account.address,
15953
16668
  to: targetAddress,
@@ -15960,7 +16675,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15960
16675
  usdcContract: USDC_ADDRESS,
15961
16676
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
15962
16677
  };
15963
- await writeFile13(proofFile, JSON.stringify(proof, null, 2));
16678
+ await writeFile16(proofFile, JSON.stringify(proof, null, 2));
15964
16679
  return [
15965
16680
  `Transfer signed (EIP-3009 TransferWithAuthorization):`,
15966
16681
  ` From: ${account.address}`,
@@ -15989,10 +16704,10 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
15989
16704
  throw new Error("prompt is required");
15990
16705
  const estimatedTokens = Math.ceil(prompt.length / 4) + 1e3;
15991
16706
  let estimatedCostSmallest = 0;
15992
- const pricingPath = join32(this.nexusDir, "pricing.json");
16707
+ const pricingPath = join35(this.nexusDir, "pricing.json");
15993
16708
  if (existsSync23(pricingPath)) {
15994
16709
  try {
15995
- const pricing = JSON.parse(await readFile14(pricingPath, "utf8"));
16710
+ const pricing = JSON.parse(await readFile17(pricingPath, "utf8"));
15996
16711
  const modelPricing = (pricing.models || []).find((m) => m.model === model || m.model.startsWith(model.split(":")[0]));
15997
16712
  if (modelPricing?.pricing?.input_per_1m_tokens > 0) {
15998
16713
  estimatedCostSmallest = Math.ceil(estimatedTokens / 1e6 * modelPricing.pricing.input_per_1m_tokens * 1e6);
@@ -16109,7 +16824,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16109
16824
  const bar = (s) => "\u2588".repeat(Math.round(s / 5)) + "\u2591".repeat(20 - Math.round(s / 5));
16110
16825
  const mem = vramMb > 24e3 ? 95 : vramMb > 16e3 ? 80 : vramMb > 8e3 ? 60 : vramMb > 0 ? 40 : 20;
16111
16826
  await this.ensureDir();
16112
- await writeFile13(join32(this.nexusDir, "inference-proof.json"), JSON.stringify({
16827
+ await writeFile16(join35(this.nexusDir, "inference-proof.json"), JSON.stringify({
16113
16828
  modelName,
16114
16829
  gpuName,
16115
16830
  vramMb,
@@ -16750,6 +17465,7 @@ __export(dist_exports, {
16750
17465
  DesktopClickTool: () => DesktopClickTool,
16751
17466
  DesktopDescribeTool: () => DesktopDescribeTool,
16752
17467
  DiagnosticTool: () => DiagnosticTool,
17468
+ ExplorationCultureTool: () => ExplorationCultureTool,
16753
17469
  ExploreToolsTool: () => ExploreToolsTool,
16754
17470
  FactoryTool: () => FactoryTool,
16755
17471
  FileEditTool: () => FileEditTool,
@@ -16759,6 +17475,7 @@ __export(dist_exports, {
16759
17475
  GitInfoTool: () => GitInfoTool,
16760
17476
  GlobFindTool: () => GlobFindTool,
16761
17477
  GrepSearchTool: () => GrepSearchTool,
17478
+ IdentityKernelTool: () => IdentityKernelTool,
16762
17479
  ImageReadTool: () => ImageReadTool,
16763
17480
  ListDirectoryTool: () => ListDirectoryTool,
16764
17481
  ManageToolsTool: () => ManageToolsTool,
@@ -16772,6 +17489,7 @@ __export(dist_exports, {
16772
17489
  OcrPdfTool: () => OcrPdfTool,
16773
17490
  OpenCodeTool: () => OpenCodeTool,
16774
17491
  PdfToTextTool: () => PdfToTextTool,
17492
+ ReflectionIntegrityTool: () => ReflectionIntegrityTool,
16775
17493
  ReminderTool: () => ReminderTool,
16776
17494
  ReplTool: () => ReplTool,
16777
17495
  SchedulerTool: () => SchedulerTool,
@@ -16860,6 +17578,9 @@ var init_dist2 = __esm({
16860
17578
  init_code_sandbox();
16861
17579
  init_repl();
16862
17580
  init_memory_metabolism();
17581
+ init_identity_kernel();
17582
+ init_reflection_integrity();
17583
+ init_exploration_culture();
16863
17584
  init_structured_read();
16864
17585
  init_vision();
16865
17586
  init_desktop_click();
@@ -17560,12 +18281,12 @@ var init_dist3 = __esm({
17560
18281
 
17561
18282
  // packages/orchestrator/dist/promptLoader.js
17562
18283
  import { readFileSync as readFileSync18, existsSync as existsSync25 } from "node:fs";
17563
- import { join as join33, dirname as dirname12 } from "node:path";
18284
+ import { join as join36, dirname as dirname12 } from "node:path";
17564
18285
  import { fileURLToPath as fileURLToPath7 } from "node:url";
17565
18286
  function loadPrompt(promptPath, vars) {
17566
18287
  let content = cache.get(promptPath);
17567
18288
  if (content === void 0) {
17568
- const fullPath = join33(PROMPTS_DIR, promptPath);
18289
+ const fullPath = join36(PROMPTS_DIR, promptPath);
17569
18290
  if (!existsSync25(fullPath)) {
17570
18291
  throw new Error(`Prompt file not found: ${fullPath}`);
17571
18292
  }
@@ -17582,7 +18303,7 @@ var init_promptLoader = __esm({
17582
18303
  "use strict";
17583
18304
  __filename = fileURLToPath7(import.meta.url);
17584
18305
  __dirname4 = dirname12(__filename);
17585
- PROMPTS_DIR = join33(__dirname4, "..", "prompts");
18306
+ PROMPTS_DIR = join36(__dirname4, "..", "prompts");
17586
18307
  cache = /* @__PURE__ */ new Map();
17587
18308
  }
17588
18309
  });
@@ -17945,8 +18666,8 @@ var init_code_retriever = __esm({
17945
18666
  });
17946
18667
  }
17947
18668
  async getFileContent(filePath, startLine, endLine) {
17948
- const { readFile: readFile19 } = await import("node:fs/promises");
17949
- const content = await readFile19(filePath, "utf-8");
18669
+ const { readFile: readFile22 } = await import("node:fs/promises");
18670
+ const content = await readFile22(filePath, "utf-8");
17950
18671
  if (startLine === void 0)
17951
18672
  return content;
17952
18673
  const lines = content.split("\n");
@@ -17961,8 +18682,8 @@ var init_code_retriever = __esm({
17961
18682
  // packages/retrieval/dist/lexicalSearch.js
17962
18683
  import { execFile as execFile5 } from "node:child_process";
17963
18684
  import { promisify as promisify4 } from "node:util";
17964
- import { readFile as readFile15, readdir as readdir4, stat as stat3 } from "node:fs/promises";
17965
- import { join as join34, extname as extname7 } from "node:path";
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";
17966
18687
  async function searchByPath(pathPattern, options) {
17967
18688
  const allFiles = await collectFiles(options.rootDir, options.includeGlobs ?? DEFAULT_INCLUDE_GLOBS, options.excludeGlobs ?? DEFAULT_EXCLUDE_GLOBS);
17968
18689
  const pattern = options.caseInsensitive ? pathPattern.toLowerCase() : pathPattern;
@@ -18067,7 +18788,7 @@ async function searchWithNodeFallback(pattern, kind, options) {
18067
18788
  if (results.length >= maxMatches)
18068
18789
  break;
18069
18790
  try {
18070
- const content = await readFile15(filePath, "utf-8");
18791
+ const content = await readFile18(filePath, "utf-8");
18071
18792
  const contentLines = content.split("\n");
18072
18793
  for (let i = 0; i < contentLines.length; i++) {
18073
18794
  if (results.length >= maxMatches)
@@ -18104,7 +18825,7 @@ async function walkForFiles(rootDir, dir, excludeGlobs, results) {
18104
18825
  continue;
18105
18826
  if (excludeGlobs.some((g) => entry.name === g || matchesGlob(entry.name, g)))
18106
18827
  continue;
18107
- const absPath = join34(dir, entry.name);
18828
+ const absPath = join37(dir, entry.name);
18108
18829
  if (entry.isDirectory()) {
18109
18830
  await walkForFiles(rootDir, absPath, excludeGlobs, results);
18110
18831
  } else if (entry.isFile()) {
@@ -18410,8 +19131,8 @@ var init_graphExpand = __esm({
18410
19131
  });
18411
19132
 
18412
19133
  // packages/retrieval/dist/snippetPacker.js
18413
- import { readFile as readFile16 } from "node:fs/promises";
18414
- import { join as join35 } from "node:path";
19134
+ import { readFile as readFile19 } from "node:fs/promises";
19135
+ import { join as join38 } from "node:path";
18415
19136
  async function packSnippets(requests, opts = {}) {
18416
19137
  const maxTokens = opts.maxTokens ?? DEFAULT_MAX_TOKENS;
18417
19138
  const contextLines = opts.contextLines ?? DEFAULT_CONTEXT_LINES;
@@ -18437,10 +19158,10 @@ async function packSnippets(requests, opts = {}) {
18437
19158
  return { packed, dropped, totalTokens };
18438
19159
  }
18439
19160
  async function extractSnippet(req, repoRoot, contextLines = DEFAULT_CONTEXT_LINES) {
18440
- const absPath = req.filePath.startsWith("/") ? req.filePath : join35(repoRoot, req.filePath);
19161
+ const absPath = req.filePath.startsWith("/") ? req.filePath : join38(repoRoot, req.filePath);
18441
19162
  let content;
18442
19163
  try {
18443
- content = await readFile16(absPath, "utf-8");
19164
+ content = await readFile19(absPath, "utf-8");
18444
19165
  } catch {
18445
19166
  return null;
18446
19167
  }
@@ -21031,8 +21752,8 @@ ${marker}` : marker);
21031
21752
  return;
21032
21753
  try {
21033
21754
  const { mkdirSync: mkdirSync21, writeFileSync: writeFileSync20 } = __require("node:fs");
21034
- const { join: join59 } = __require("node:path");
21035
- const sessionDir = join59(this._workingDirectory, ".oa", "session", this._sessionId);
21755
+ const { join: join62 } = __require("node:path");
21756
+ const sessionDir = join62(this._workingDirectory, ".oa", "session", this._sessionId);
21036
21757
  mkdirSync21(sessionDir, { recursive: true });
21037
21758
  const checkpoint = {
21038
21759
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -21045,7 +21766,7 @@ ${marker}` : marker);
21045
21766
  memexEntryCount: this._memexArchive.size,
21046
21767
  fileRegistrySize: this._fileRegistry.size
21047
21768
  };
21048
- writeFileSync20(join59(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
21769
+ writeFileSync20(join62(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
21049
21770
  } catch {
21050
21771
  }
21051
21772
  }
@@ -22313,7 +23034,7 @@ ${transcript}`
22313
23034
  // packages/orchestrator/dist/nexusBackend.js
22314
23035
  import { existsSync as existsSync26, statSync as statSync9, openSync, readSync, closeSync, unlinkSync as unlinkSync4, writeFileSync as writeFileSync8 } from "node:fs";
22315
23036
  import { watch as fsWatch } from "node:fs";
22316
- import { join as join36 } from "node:path";
23037
+ import { join as join39 } from "node:path";
22317
23038
  import { tmpdir as tmpdir7 } from "node:os";
22318
23039
  import { randomBytes as randomBytes8 } from "node:crypto";
22319
23040
  var NexusAgenticBackend;
@@ -22463,7 +23184,7 @@ var init_nexusBackend = __esm({
22463
23184
  * Falls back to unary + word-split if streaming setup fails.
22464
23185
  */
22465
23186
  async *chatCompletionStream(request) {
22466
- const streamFile = join36(tmpdir7(), `nexus-stream-${randomBytes8(6).toString("hex")}.jsonl`);
23187
+ const streamFile = join39(tmpdir7(), `nexus-stream-${randomBytes8(6).toString("hex")}.jsonl`);
22467
23188
  writeFileSync8(streamFile, "", "utf8");
22468
23189
  const daemonArgs = {
22469
23190
  model: this.model,
@@ -23500,7 +24221,7 @@ __export(listen_exports, {
23500
24221
  });
23501
24222
  import { spawn as spawn15, execSync as execSync23 } from "node:child_process";
23502
24223
  import { existsSync as existsSync27, mkdirSync as mkdirSync8, writeFileSync as writeFileSync9, readdirSync as readdirSync6 } from "node:fs";
23503
- import { join as join37, dirname as dirname13 } from "node:path";
24224
+ import { join as join40, dirname as dirname13 } from "node:path";
23504
24225
  import { homedir as homedir8 } from "node:os";
23505
24226
  import { fileURLToPath as fileURLToPath8 } from "node:url";
23506
24227
  import { EventEmitter } from "node:events";
@@ -23586,12 +24307,12 @@ function findMicCaptureCommand() {
23586
24307
  function findLiveWhisperScript() {
23587
24308
  const thisDir = dirname13(fileURLToPath8(import.meta.url));
23588
24309
  const candidates = [
23589
- join37(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
23590
- join37(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
23591
- join37(thisDir, "../../execution/scripts/live-whisper.py"),
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"),
23592
24313
  // npm install layout — scripts bundled alongside dist
23593
- join37(thisDir, "../scripts/live-whisper.py"),
23594
- join37(thisDir, "../../scripts/live-whisper.py")
24314
+ join40(thisDir, "../scripts/live-whisper.py"),
24315
+ join40(thisDir, "../../scripts/live-whisper.py")
23595
24316
  ];
23596
24317
  for (const p of candidates) {
23597
24318
  if (existsSync27(p))
@@ -23604,8 +24325,8 @@ function findLiveWhisperScript() {
23604
24325
  stdio: ["pipe", "pipe", "pipe"]
23605
24326
  }).trim();
23606
24327
  const candidates2 = [
23607
- join37(globalRoot, "open-agents-ai", "dist", "scripts", "live-whisper.py"),
23608
- join37(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")
23609
24330
  ];
23610
24331
  for (const p of candidates2) {
23611
24332
  if (existsSync27(p))
@@ -23613,11 +24334,11 @@ function findLiveWhisperScript() {
23613
24334
  }
23614
24335
  } catch {
23615
24336
  }
23616
- const nvmBase = join37(homedir8(), ".nvm", "versions", "node");
24337
+ const nvmBase = join40(homedir8(), ".nvm", "versions", "node");
23617
24338
  if (existsSync27(nvmBase)) {
23618
24339
  try {
23619
24340
  for (const ver of readdirSync6(nvmBase)) {
23620
- const p = join37(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");
23621
24342
  if (existsSync27(p))
23622
24343
  return p;
23623
24344
  }
@@ -23636,7 +24357,7 @@ function ensureTranscribeCliBackground() {
23636
24357
  timeout: 5e3,
23637
24358
  stdio: ["pipe", "pipe", "pipe"]
23638
24359
  }).trim();
23639
- if (existsSync27(join37(globalRoot, "transcribe-cli", "dist", "index.js"))) {
24360
+ if (existsSync27(join40(globalRoot, "transcribe-cli", "dist", "index.js"))) {
23640
24361
  return true;
23641
24362
  }
23642
24363
  } catch {
@@ -23859,24 +24580,24 @@ var init_listen = __esm({
23859
24580
  timeout: 5e3,
23860
24581
  stdio: ["pipe", "pipe", "pipe"]
23861
24582
  }).trim();
23862
- const tcPath = join37(globalRoot, "transcribe-cli");
23863
- if (existsSync27(join37(tcPath, "dist", "index.js"))) {
24583
+ const tcPath = join40(globalRoot, "transcribe-cli");
24584
+ if (existsSync27(join40(tcPath, "dist", "index.js"))) {
23864
24585
  const { createRequire: createRequire4 } = await import("node:module");
23865
24586
  const req = createRequire4(import.meta.url);
23866
- return req(join37(tcPath, "dist", "index.js"));
24587
+ return req(join40(tcPath, "dist", "index.js"));
23867
24588
  }
23868
24589
  } catch {
23869
24590
  }
23870
- const nvmBase = join37(homedir8(), ".nvm", "versions", "node");
24591
+ const nvmBase = join40(homedir8(), ".nvm", "versions", "node");
23871
24592
  if (existsSync27(nvmBase)) {
23872
24593
  try {
23873
24594
  const { readdirSync: readdirSync17 } = await import("node:fs");
23874
24595
  for (const ver of readdirSync17(nvmBase)) {
23875
- const tcPath = join37(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
23876
- if (existsSync27(join37(tcPath, "dist", "index.js"))) {
24596
+ const tcPath = join40(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
24597
+ if (existsSync27(join40(tcPath, "dist", "index.js"))) {
23877
24598
  const { createRequire: createRequire4 } = await import("node:module");
23878
24599
  const req = createRequire4(import.meta.url);
23879
- return req(join37(tcPath, "dist", "index.js"));
24600
+ return req(join40(tcPath, "dist", "index.js"));
23880
24601
  }
23881
24602
  }
23882
24603
  } catch {
@@ -24158,9 +24879,9 @@ transcribe-cli error: ${transcribeCliError}` : "";
24158
24879
  });
24159
24880
  if (outputDir) {
24160
24881
  const { basename: basename16 } = await import("node:path");
24161
- const transcriptDir = join37(outputDir, ".oa", "transcripts");
24882
+ const transcriptDir = join40(outputDir, ".oa", "transcripts");
24162
24883
  mkdirSync8(transcriptDir, { recursive: true });
24163
- const outFile = join37(transcriptDir, `${basename16(filePath)}.txt`);
24884
+ const outFile = join40(transcriptDir, `${basename16(filePath)}.txt`);
24164
24885
  writeFileSync9(outFile, result.text, "utf-8");
24165
24886
  }
24166
24887
  return {
@@ -29518,7 +30239,7 @@ import { randomBytes as randomBytes9 } from "node:crypto";
29518
30239
  import { URL as URL2 } from "node:url";
29519
30240
  import { loadavg, cpus, totalmem, freemem } from "node:os";
29520
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";
29521
- import { join as join38 } from "node:path";
30242
+ import { join as join41 } from "node:path";
29522
30243
  function cleanForwardHeaders(raw, targetHost) {
29523
30244
  const out = {};
29524
30245
  for (const [key, value] of Object.entries(raw)) {
@@ -29546,7 +30267,7 @@ function fmtTokens(n) {
29546
30267
  }
29547
30268
  function readExposeState(stateDir) {
29548
30269
  try {
29549
- const path = join38(stateDir, STATE_FILE_NAME);
30270
+ const path = join41(stateDir, STATE_FILE_NAME);
29550
30271
  if (!existsSync28(path))
29551
30272
  return null;
29552
30273
  const raw = readFileSync19(path, "utf8");
@@ -29561,13 +30282,13 @@ function readExposeState(stateDir) {
29561
30282
  function writeExposeState(stateDir, state) {
29562
30283
  try {
29563
30284
  mkdirSync9(stateDir, { recursive: true });
29564
- writeFileSync10(join38(stateDir, STATE_FILE_NAME), JSON.stringify(state, null, 2));
30285
+ writeFileSync10(join41(stateDir, STATE_FILE_NAME), JSON.stringify(state, null, 2));
29565
30286
  } catch {
29566
30287
  }
29567
30288
  }
29568
30289
  function removeExposeState(stateDir) {
29569
30290
  try {
29570
- unlinkSync5(join38(stateDir, STATE_FILE_NAME));
30291
+ unlinkSync5(join41(stateDir, STATE_FILE_NAME));
29571
30292
  } catch {
29572
30293
  }
29573
30294
  }
@@ -29656,7 +30377,7 @@ async function collectSystemMetricsAsync() {
29656
30377
  }
29657
30378
  function readP2PExposeState(stateDir) {
29658
30379
  try {
29659
- const path = join38(stateDir, P2P_STATE_FILE_NAME);
30380
+ const path = join41(stateDir, P2P_STATE_FILE_NAME);
29660
30381
  if (!existsSync28(path))
29661
30382
  return null;
29662
30383
  const raw = readFileSync19(path, "utf8");
@@ -29671,13 +30392,13 @@ function readP2PExposeState(stateDir) {
29671
30392
  function writeP2PExposeState(stateDir, state) {
29672
30393
  try {
29673
30394
  mkdirSync9(stateDir, { recursive: true });
29674
- writeFileSync10(join38(stateDir, P2P_STATE_FILE_NAME), JSON.stringify(state, null, 2));
30395
+ writeFileSync10(join41(stateDir, P2P_STATE_FILE_NAME), JSON.stringify(state, null, 2));
29675
30396
  } catch {
29676
30397
  }
29677
30398
  }
29678
30399
  function removeP2PExposeState(stateDir) {
29679
30400
  try {
29680
- unlinkSync5(join38(stateDir, P2P_STATE_FILE_NAME));
30401
+ unlinkSync5(join41(stateDir, P2P_STATE_FILE_NAME));
29681
30402
  } catch {
29682
30403
  }
29683
30404
  }
@@ -30507,7 +31228,7 @@ ${this.formatConnectionInfo()}`);
30507
31228
  throw new Error(`Expose failed: ${exposeResult.error}`);
30508
31229
  }
30509
31230
  const nexusDir = this._nexusTool.getNexusDir();
30510
- const statusPath = join38(nexusDir, "status.json");
31231
+ const statusPath = join41(nexusDir, "status.json");
30511
31232
  for (let i = 0; i < 80; i++) {
30512
31233
  try {
30513
31234
  const raw = readFileSync19(statusPath, "utf8");
@@ -30541,7 +31262,7 @@ ${this.formatConnectionInfo()}`);
30541
31262
  });
30542
31263
  }
30543
31264
  try {
30544
- const invocDir = join38(nexusDir, "invocations");
31265
+ const invocDir = join41(nexusDir, "invocations");
30545
31266
  if (existsSync28(invocDir)) {
30546
31267
  this._prevInvocCount = readdirSync7(invocDir).filter((f) => f.endsWith(".json")).length;
30547
31268
  this._stats.totalRequests = this._prevInvocCount;
@@ -30571,7 +31292,7 @@ ${this.formatConnectionInfo()}`);
30571
31292
  if (!state)
30572
31293
  return null;
30573
31294
  const nexusDir = nexusTool.getNexusDir();
30574
- const statusPath = join38(nexusDir, "status.json");
31295
+ const statusPath = join41(nexusDir, "status.json");
30575
31296
  try {
30576
31297
  if (!existsSync28(statusPath)) {
30577
31298
  removeP2PExposeState(stateDir);
@@ -30630,7 +31351,7 @@ ${this.formatConnectionInfo()}`);
30630
31351
  let lastMeteringLineCount = 0;
30631
31352
  this._activityPollTimer = setInterval(() => {
30632
31353
  try {
30633
- const invocDir = join38(nexusDir, "invocations");
31354
+ const invocDir = join41(nexusDir, "invocations");
30634
31355
  if (!existsSync28(invocDir))
30635
31356
  return;
30636
31357
  const files = readdirSync7(invocDir).filter((f) => f.endsWith(".json"));
@@ -30646,13 +31367,13 @@ ${this.formatConnectionInfo()}`);
30646
31367
  let recentActive = 0;
30647
31368
  for (const f of files.slice(-10)) {
30648
31369
  try {
30649
- const st = statSync10(join38(invocDir, f));
31370
+ const st = statSync10(join41(invocDir, f));
30650
31371
  if (now - st.mtimeMs < 1e4)
30651
31372
  recentActive++;
30652
31373
  } catch {
30653
31374
  }
30654
31375
  }
30655
- const meteringFile = join38(nexusDir, "metering.jsonl");
31376
+ const meteringFile = join41(nexusDir, "metering.jsonl");
30656
31377
  let meteringLines = lastMeteringLineCount;
30657
31378
  try {
30658
31379
  if (existsSync28(meteringFile)) {
@@ -30682,7 +31403,7 @@ ${this.formatConnectionInfo()}`);
30682
31403
  this._activityPollTimer.unref();
30683
31404
  this._pollTimer = setInterval(() => {
30684
31405
  try {
30685
- const statusPath = join38(nexusDir, "status.json");
31406
+ const statusPath = join41(nexusDir, "status.json");
30686
31407
  if (existsSync28(statusPath)) {
30687
31408
  const status = JSON.parse(readFileSync19(statusPath, "utf8"));
30688
31409
  if (status.peerId && !this._peerId) {
@@ -30693,7 +31414,7 @@ ${this.formatConnectionInfo()}`);
30693
31414
  } catch {
30694
31415
  }
30695
31416
  try {
30696
- const invocDir = join38(nexusDir, "invocations");
31417
+ const invocDir = join41(nexusDir, "invocations");
30697
31418
  if (existsSync28(invocDir)) {
30698
31419
  const files = readdirSync7(invocDir);
30699
31420
  const invocCount = files.filter((f) => f.endsWith(".json")).length;
@@ -30705,7 +31426,7 @@ ${this.formatConnectionInfo()}`);
30705
31426
  } catch {
30706
31427
  }
30707
31428
  try {
30708
- const meteringFile = join38(nexusDir, "metering.jsonl");
31429
+ const meteringFile = join41(nexusDir, "metering.jsonl");
30709
31430
  if (existsSync28(meteringFile)) {
30710
31431
  const content = readFileSync19(meteringFile, "utf8");
30711
31432
  if (content.length > lastMeteringSize) {
@@ -30917,7 +31638,7 @@ var init_types = __esm({
30917
31638
  // packages/cli/dist/tui/p2p/secret-vault.js
30918
31639
  import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes10, scryptSync as scryptSync2, createHash as createHash2 } from "node:crypto";
30919
31640
  import { readFileSync as readFileSync20, writeFileSync as writeFileSync11, existsSync as existsSync29, mkdirSync as mkdirSync10 } from "node:fs";
30920
- import { join as join39, dirname as dirname14 } from "node:path";
31641
+ import { join as join42, dirname as dirname14 } from "node:path";
30921
31642
  var PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, CIPHER_ALGO, SALT_LEN, IV_LEN, KEY_LEN, SecretVault;
30922
31643
  var init_secret_vault = __esm({
30923
31644
  "packages/cli/dist/tui/p2p/secret-vault.js"() {
@@ -32254,13 +32975,13 @@ async function fetchPeerModels(peerId, authKey) {
32254
32975
  try {
32255
32976
  const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
32256
32977
  const { existsSync: existsSync45, readFileSync: readFileSync33 } = await import("node:fs");
32257
- const { join: join59 } = await import("node:path");
32978
+ const { join: join62 } = await import("node:path");
32258
32979
  const cwd4 = process.cwd();
32259
32980
  const nexusTool = new NexusTool2(cwd4);
32260
32981
  const nexusDir = nexusTool.getNexusDir();
32261
32982
  let isLocalPeer = false;
32262
32983
  try {
32263
- const statusPath = join59(nexusDir, "status.json");
32984
+ const statusPath = join62(nexusDir, "status.json");
32264
32985
  if (existsSync45(statusPath)) {
32265
32986
  const status = JSON.parse(readFileSync33(statusPath, "utf8"));
32266
32987
  if (status.peerId === peerId)
@@ -32269,7 +32990,7 @@ async function fetchPeerModels(peerId, authKey) {
32269
32990
  } catch {
32270
32991
  }
32271
32992
  if (isLocalPeer) {
32272
- const pricingPath = join59(nexusDir, "pricing.json");
32993
+ const pricingPath = join62(nexusDir, "pricing.json");
32273
32994
  if (existsSync45(pricingPath)) {
32274
32995
  try {
32275
32996
  const pricing = JSON.parse(readFileSync33(pricingPath, "utf8"));
@@ -32286,7 +33007,7 @@ async function fetchPeerModels(peerId, authKey) {
32286
33007
  }
32287
33008
  }
32288
33009
  }
32289
- const cachePath = join59(nexusDir, "peer-models-cache.json");
33010
+ const cachePath = join62(nexusDir, "peer-models-cache.json");
32290
33011
  if (existsSync45(cachePath)) {
32291
33012
  try {
32292
33013
  const cache4 = JSON.parse(readFileSync33(cachePath, "utf8"));
@@ -32404,7 +33125,7 @@ async function fetchPeerModels(peerId, authKey) {
32404
33125
  } catch {
32405
33126
  }
32406
33127
  if (isLocalPeer) {
32407
- const pricingPath = join59(nexusDir, "pricing.json");
33128
+ const pricingPath = join62(nexusDir, "pricing.json");
32408
33129
  if (existsSync45(pricingPath)) {
32409
33130
  try {
32410
33131
  const pricing = JSON.parse(readFileSync33(pricingPath, "utf8"));
@@ -32677,12 +33398,12 @@ var init_render2 = __esm({
32677
33398
 
32678
33399
  // packages/prompts/dist/promptLoader.js
32679
33400
  import { readFileSync as readFileSync21, existsSync as existsSync30 } from "node:fs";
32680
- import { join as join40, dirname as dirname15 } from "node:path";
33401
+ import { join as join43, dirname as dirname15 } from "node:path";
32681
33402
  import { fileURLToPath as fileURLToPath9 } from "node:url";
32682
33403
  function loadPrompt2(promptPath, vars) {
32683
33404
  let content = cache2.get(promptPath);
32684
33405
  if (content === void 0) {
32685
- const fullPath = join40(PROMPTS_DIR2, promptPath);
33406
+ const fullPath = join43(PROMPTS_DIR2, promptPath);
32686
33407
  if (!existsSync30(fullPath)) {
32687
33408
  throw new Error(`Prompt file not found: ${fullPath}`);
32688
33409
  }
@@ -32699,8 +33420,8 @@ var init_promptLoader2 = __esm({
32699
33420
  "use strict";
32700
33421
  __filename2 = fileURLToPath9(import.meta.url);
32701
33422
  __dirname5 = dirname15(__filename2);
32702
- devPath = join40(__dirname5, "..", "templates");
32703
- publishedPath = join40(__dirname5, "..", "prompts", "templates");
33423
+ devPath = join43(__dirname5, "..", "templates");
33424
+ publishedPath = join43(__dirname5, "..", "prompts", "templates");
32704
33425
  PROMPTS_DIR2 = existsSync30(devPath) ? devPath : publishedPath;
32705
33426
  cache2 = /* @__PURE__ */ new Map();
32706
33427
  }
@@ -32812,7 +33533,7 @@ var init_task_templates = __esm({
32812
33533
  });
32813
33534
 
32814
33535
  // packages/prompts/dist/index.js
32815
- import { join as join41, dirname as dirname16 } from "node:path";
33536
+ import { join as join44, dirname as dirname16 } from "node:path";
32816
33537
  import { fileURLToPath as fileURLToPath10 } from "node:url";
32817
33538
  var _dir, _packageRoot;
32818
33539
  var init_dist6 = __esm({
@@ -32823,21 +33544,21 @@ var init_dist6 = __esm({
32823
33544
  init_task_templates();
32824
33545
  init_render2();
32825
33546
  _dir = dirname16(fileURLToPath10(import.meta.url));
32826
- _packageRoot = join41(_dir, "..");
33547
+ _packageRoot = join44(_dir, "..");
32827
33548
  }
32828
33549
  });
32829
33550
 
32830
33551
  // packages/cli/dist/tui/oa-directory.js
32831
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";
32832
- import { join as join42, 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";
32833
33554
  import { homedir as homedir9 } from "node:os";
32834
33555
  function initOaDirectory(repoRoot) {
32835
- const oaPath = join42(repoRoot, OA_DIR);
33556
+ const oaPath = join45(repoRoot, OA_DIR);
32836
33557
  for (const sub of SUBDIRS) {
32837
- mkdirSync11(join42(oaPath, sub), { recursive: true });
33558
+ mkdirSync11(join45(oaPath, sub), { recursive: true });
32838
33559
  }
32839
33560
  try {
32840
- const gitignorePath = join42(repoRoot, ".gitignore");
33561
+ const gitignorePath = join45(repoRoot, ".gitignore");
32841
33562
  const settingsPattern = ".oa/settings.json";
32842
33563
  if (existsSync31(gitignorePath)) {
32843
33564
  const content = readFileSync22(gitignorePath, "utf-8");
@@ -32850,10 +33571,10 @@ function initOaDirectory(repoRoot) {
32850
33571
  return oaPath;
32851
33572
  }
32852
33573
  function hasOaDirectory(repoRoot) {
32853
- return existsSync31(join42(repoRoot, OA_DIR, "index"));
33574
+ return existsSync31(join45(repoRoot, OA_DIR, "index"));
32854
33575
  }
32855
33576
  function loadProjectSettings(repoRoot) {
32856
- const settingsPath = join42(repoRoot, OA_DIR, "settings.json");
33577
+ const settingsPath = join45(repoRoot, OA_DIR, "settings.json");
32857
33578
  try {
32858
33579
  if (existsSync31(settingsPath)) {
32859
33580
  return JSON.parse(readFileSync22(settingsPath, "utf-8"));
@@ -32863,14 +33584,14 @@ function loadProjectSettings(repoRoot) {
32863
33584
  return {};
32864
33585
  }
32865
33586
  function saveProjectSettings(repoRoot, settings) {
32866
- const oaPath = join42(repoRoot, OA_DIR);
33587
+ const oaPath = join45(repoRoot, OA_DIR);
32867
33588
  mkdirSync11(oaPath, { recursive: true });
32868
33589
  const existing = loadProjectSettings(repoRoot);
32869
33590
  const merged = { ...existing, ...settings };
32870
- writeFileSync12(join42(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 });
32871
33592
  }
32872
33593
  function loadGlobalSettings() {
32873
- const settingsPath = join42(homedir9(), ".open-agents", "settings.json");
33594
+ const settingsPath = join45(homedir9(), ".open-agents", "settings.json");
32874
33595
  try {
32875
33596
  if (existsSync31(settingsPath)) {
32876
33597
  return JSON.parse(readFileSync22(settingsPath, "utf-8"));
@@ -32880,11 +33601,11 @@ function loadGlobalSettings() {
32880
33601
  return {};
32881
33602
  }
32882
33603
  function saveGlobalSettings(settings) {
32883
- const dir = join42(homedir9(), ".open-agents");
33604
+ const dir = join45(homedir9(), ".open-agents");
32884
33605
  mkdirSync11(dir, { recursive: true });
32885
33606
  const existing = loadGlobalSettings();
32886
33607
  const merged = { ...existing, ...settings };
32887
- writeFileSync12(join42(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 });
32888
33609
  }
32889
33610
  function resolveSettings(repoRoot) {
32890
33611
  const global = loadGlobalSettings();
@@ -32899,7 +33620,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
32899
33620
  while (dir && !visited.has(dir)) {
32900
33621
  visited.add(dir);
32901
33622
  for (const name of CONTEXT_FILES) {
32902
- const filePath = join42(dir, name);
33623
+ const filePath = join45(dir, name);
32903
33624
  const normalizedName = name.toLowerCase();
32904
33625
  if (existsSync31(filePath) && !seen.has(filePath)) {
32905
33626
  seen.add(filePath);
@@ -32918,7 +33639,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
32918
33639
  }
32919
33640
  }
32920
33641
  }
32921
- const projectMap = join42(dir, OA_DIR, "context", "project-map.md");
33642
+ const projectMap = join45(dir, OA_DIR, "context", "project-map.md");
32922
33643
  if (existsSync31(projectMap) && !seen.has(projectMap)) {
32923
33644
  seen.add(projectMap);
32924
33645
  try {
@@ -32934,7 +33655,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
32934
33655
  } catch {
32935
33656
  }
32936
33657
  }
32937
- const parent = join42(dir, "..");
33658
+ const parent = join45(dir, "..");
32938
33659
  if (parent === dir)
32939
33660
  break;
32940
33661
  dir = parent;
@@ -32952,7 +33673,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
32952
33673
  return found;
32953
33674
  }
32954
33675
  function readIndexMeta(repoRoot) {
32955
- const metaPath = join42(repoRoot, OA_DIR, "index", "meta.json");
33676
+ const metaPath = join45(repoRoot, OA_DIR, "index", "meta.json");
32956
33677
  try {
32957
33678
  return JSON.parse(readFileSync22(metaPath, "utf-8"));
32958
33679
  } catch {
@@ -33005,28 +33726,28 @@ ${tree}\`\`\`
33005
33726
  sections.push("");
33006
33727
  }
33007
33728
  const content = sections.join("\n");
33008
- const contextDir = join42(repoRoot, OA_DIR, "context");
33729
+ const contextDir = join45(repoRoot, OA_DIR, "context");
33009
33730
  mkdirSync11(contextDir, { recursive: true });
33010
- writeFileSync12(join42(contextDir, "project-map.md"), content, "utf-8");
33731
+ writeFileSync12(join45(contextDir, "project-map.md"), content, "utf-8");
33011
33732
  return content;
33012
33733
  }
33013
33734
  function saveSession(repoRoot, session) {
33014
- const historyDir = join42(repoRoot, OA_DIR, "history");
33735
+ const historyDir = join45(repoRoot, OA_DIR, "history");
33015
33736
  mkdirSync11(historyDir, { recursive: true });
33016
- writeFileSync12(join42(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");
33017
33738
  }
33018
33739
  function loadRecentSessions(repoRoot, limit = 5) {
33019
- const historyDir = join42(repoRoot, OA_DIR, "history");
33740
+ const historyDir = join45(repoRoot, OA_DIR, "history");
33020
33741
  if (!existsSync31(historyDir))
33021
33742
  return [];
33022
33743
  try {
33023
33744
  const files = readdirSync8(historyDir).filter((f) => f.endsWith(".json") && f !== "pending-task.json").map((f) => {
33024
- const stat5 = statSync11(join42(historyDir, f));
33745
+ const stat5 = statSync11(join45(historyDir, f));
33025
33746
  return { file: f, mtime: stat5.mtimeMs };
33026
33747
  }).sort((a, b) => b.mtime - a.mtime).slice(0, limit);
33027
33748
  return files.map((f) => {
33028
33749
  try {
33029
- return JSON.parse(readFileSync22(join42(historyDir, f.file), "utf-8"));
33750
+ return JSON.parse(readFileSync22(join45(historyDir, f.file), "utf-8"));
33030
33751
  } catch {
33031
33752
  return null;
33032
33753
  }
@@ -33036,12 +33757,12 @@ function loadRecentSessions(repoRoot, limit = 5) {
33036
33757
  }
33037
33758
  }
33038
33759
  function savePendingTask(repoRoot, task) {
33039
- const historyDir = join42(repoRoot, OA_DIR, "history");
33760
+ const historyDir = join45(repoRoot, OA_DIR, "history");
33040
33761
  mkdirSync11(historyDir, { recursive: true });
33041
- writeFileSync12(join42(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");
33042
33763
  }
33043
33764
  function loadPendingTask(repoRoot) {
33044
- const filePath = join42(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
33765
+ const filePath = join45(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
33045
33766
  try {
33046
33767
  if (!existsSync31(filePath))
33047
33768
  return null;
@@ -33056,9 +33777,9 @@ function loadPendingTask(repoRoot) {
33056
33777
  }
33057
33778
  }
33058
33779
  function saveSessionContext(repoRoot, entry) {
33059
- const contextDir = join42(repoRoot, OA_DIR, "context");
33780
+ const contextDir = join45(repoRoot, OA_DIR, "context");
33060
33781
  mkdirSync11(contextDir, { recursive: true });
33061
- const filePath = join42(contextDir, CONTEXT_SAVE_FILE);
33782
+ const filePath = join45(contextDir, CONTEXT_SAVE_FILE);
33062
33783
  let ctx;
33063
33784
  try {
33064
33785
  if (existsSync31(filePath)) {
@@ -33077,7 +33798,7 @@ function saveSessionContext(repoRoot, entry) {
33077
33798
  writeFileSync12(filePath, JSON.stringify(ctx, null, 2) + "\n", "utf-8");
33078
33799
  }
33079
33800
  function loadSessionContext(repoRoot) {
33080
- const filePath = join42(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
33801
+ const filePath = join45(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
33081
33802
  try {
33082
33803
  if (!existsSync31(filePath))
33083
33804
  return null;
@@ -33128,7 +33849,7 @@ function detectManifests(repoRoot) {
33128
33849
  { file: "docker-compose.yaml", type: "Docker Compose" }
33129
33850
  ];
33130
33851
  for (const check of checks) {
33131
- const filePath = join42(repoRoot, check.file);
33852
+ const filePath = join45(repoRoot, check.file);
33132
33853
  if (existsSync31(filePath)) {
33133
33854
  let name;
33134
33855
  if (check.nameField) {
@@ -33162,7 +33883,7 @@ function findKeyFiles(repoRoot) {
33162
33883
  { pattern: "CLAUDE.md", description: "Claude Code context" }
33163
33884
  ];
33164
33885
  for (const check of checks) {
33165
- if (existsSync31(join42(repoRoot, check.pattern))) {
33886
+ if (existsSync31(join45(repoRoot, check.pattern))) {
33166
33887
  keyFiles.push({ path: check.pattern, description: check.description });
33167
33888
  }
33168
33889
  }
@@ -33188,12 +33909,12 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
33188
33909
  if (entry.isDirectory()) {
33189
33910
  let fileCount = 0;
33190
33911
  try {
33191
- fileCount = readdirSync8(join42(root, entry.name)).filter((f) => !f.startsWith(".")).length;
33912
+ fileCount = readdirSync8(join45(root, entry.name)).filter((f) => !f.startsWith(".")).length;
33192
33913
  } catch {
33193
33914
  }
33194
33915
  result += `${prefix}${connector}${entry.name}/ (${fileCount})
33195
33916
  `;
33196
- result += buildDirTree(join42(root, entry.name), maxDepth, childPrefix, depth + 1);
33917
+ result += buildDirTree(join45(root, entry.name), maxDepth, childPrefix, depth + 1);
33197
33918
  } else if (depth < maxDepth) {
33198
33919
  result += `${prefix}${connector}${entry.name}
33199
33920
  `;
@@ -33213,7 +33934,7 @@ function loadUsageFile(filePath) {
33213
33934
  return { records: [] };
33214
33935
  }
33215
33936
  function saveUsageFile(filePath, data) {
33216
- const dir = join42(filePath, "..");
33937
+ const dir = join45(filePath, "..");
33217
33938
  mkdirSync11(dir, { recursive: true });
33218
33939
  writeFileSync12(filePath, JSON.stringify(data, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
33219
33940
  }
@@ -33243,15 +33964,15 @@ function recordUsage(kind, value, opts) {
33243
33964
  }
33244
33965
  saveUsageFile(filePath, data);
33245
33966
  };
33246
- update(join42(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
33967
+ update(join45(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
33247
33968
  if (opts?.repoRoot) {
33248
- update(join42(opts.repoRoot, OA_DIR, USAGE_HISTORY_FILE));
33969
+ update(join45(opts.repoRoot, OA_DIR, USAGE_HISTORY_FILE));
33249
33970
  }
33250
33971
  }
33251
33972
  function loadUsageHistory(kind, repoRoot) {
33252
- const globalPath = join42(homedir9(), ".open-agents", USAGE_HISTORY_FILE);
33973
+ const globalPath = join45(homedir9(), ".open-agents", USAGE_HISTORY_FILE);
33253
33974
  const globalData = loadUsageFile(globalPath);
33254
- const localData = repoRoot ? loadUsageFile(join42(repoRoot, OA_DIR, USAGE_HISTORY_FILE)) : { records: [] };
33975
+ const localData = repoRoot ? loadUsageFile(join45(repoRoot, OA_DIR, USAGE_HISTORY_FILE)) : { records: [] };
33255
33976
  const map = /* @__PURE__ */ new Map();
33256
33977
  for (const r of globalData.records) {
33257
33978
  if (r.kind !== kind)
@@ -33282,9 +34003,9 @@ function deleteUsageRecord(kind, value, repoRoot) {
33282
34003
  saveUsageFile(filePath, data);
33283
34004
  }
33284
34005
  };
33285
- remove(join42(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
34006
+ remove(join45(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
33286
34007
  if (repoRoot) {
33287
- remove(join42(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
34008
+ remove(join45(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
33288
34009
  }
33289
34010
  }
33290
34011
  var OA_DIR, SUBDIRS, CONTEXT_FILES, PENDING_TASK_FILE, CONTEXT_SAVE_FILE, MAX_CONTEXT_ENTRIES, SKIP_DIRS, USAGE_HISTORY_FILE, MAX_HISTORY_RECORDS;
@@ -33335,7 +34056,7 @@ import * as readline from "node:readline";
33335
34056
  import { execSync as execSync25, spawn as spawn18, exec as exec2 } from "node:child_process";
33336
34057
  import { promisify as promisify5 } from "node:util";
33337
34058
  import { existsSync as existsSync32, writeFileSync as writeFileSync13, readFileSync as readFileSync23, appendFileSync as appendFileSync2, mkdirSync as mkdirSync12 } from "node:fs";
33338
- import { join as join43 } from "node:path";
34059
+ import { join as join46 } from "node:path";
33339
34060
  import { homedir as homedir10, platform } from "node:os";
33340
34061
  function detectSystemSpecs() {
33341
34062
  let totalRamGB = 0;
@@ -34376,9 +35097,9 @@ async function doSetup(config, rl) {
34376
35097
  `PARAMETER num_predict ${numPredict}`,
34377
35098
  `PARAMETER stop "<|endoftext|>"`
34378
35099
  ].join("\n");
34379
- const modelDir2 = join43(homedir10(), ".open-agents", "models");
35100
+ const modelDir2 = join46(homedir10(), ".open-agents", "models");
34380
35101
  mkdirSync12(modelDir2, { recursive: true });
34381
- const modelfilePath = join43(modelDir2, `Modelfile.${customName}`);
35102
+ const modelfilePath = join46(modelDir2, `Modelfile.${customName}`);
34382
35103
  writeFileSync13(modelfilePath, modelfileContent + "\n", "utf8");
34383
35104
  process.stdout.write(` ${c2.dim("Creating model...")} `);
34384
35105
  execSync25(`ollama create ${customName} -f ${modelfilePath}`, {
@@ -34424,7 +35145,7 @@ async function isModelAvailable(config) {
34424
35145
  }
34425
35146
  function isFirstRun() {
34426
35147
  try {
34427
- return !existsSync32(join43(homedir10(), ".open-agents", "config.json"));
35148
+ return !existsSync32(join46(homedir10(), ".open-agents", "config.json"));
34428
35149
  } catch {
34429
35150
  return true;
34430
35151
  }
@@ -34461,7 +35182,7 @@ function detectPkgManager() {
34461
35182
  return null;
34462
35183
  }
34463
35184
  function getVenvDir() {
34464
- return join43(homedir10(), ".open-agents", "venv");
35185
+ return join46(homedir10(), ".open-agents", "venv");
34465
35186
  }
34466
35187
  function hasVenvModule() {
34467
35188
  try {
@@ -34473,7 +35194,7 @@ function hasVenvModule() {
34473
35194
  }
34474
35195
  function ensureVenv(log) {
34475
35196
  const venvDir = getVenvDir();
34476
- const venvPip = join43(venvDir, "bin", "pip");
35197
+ const venvPip = join46(venvDir, "bin", "pip");
34477
35198
  if (existsSync32(venvPip))
34478
35199
  return venvDir;
34479
35200
  log("Creating Python venv for vision deps...");
@@ -34486,9 +35207,9 @@ function ensureVenv(log) {
34486
35207
  return null;
34487
35208
  }
34488
35209
  try {
34489
- mkdirSync12(join43(homedir10(), ".open-agents"), { recursive: true });
35210
+ mkdirSync12(join46(homedir10(), ".open-agents"), { recursive: true });
34490
35211
  execSync25(`python3 -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
34491
- execSync25(`"${join43(venvDir, "bin", "pip")}" install --upgrade pip`, {
35212
+ execSync25(`"${join46(venvDir, "bin", "pip")}" install --upgrade pip`, {
34492
35213
  stdio: "pipe",
34493
35214
  timeout: 6e4
34494
35215
  });
@@ -34679,11 +35400,11 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
34679
35400
  }
34680
35401
  }
34681
35402
  const venvDir = getVenvDir();
34682
- const venvBin = join43(venvDir, "bin");
34683
- const venvMoondream = join43(venvBin, "moondream-station");
35403
+ const venvBin = join46(venvDir, "bin");
35404
+ const venvMoondream = join46(venvBin, "moondream-station");
34684
35405
  const venv = ensureVenv(log);
34685
35406
  if (venv && !hasCmd("moondream-station") && !existsSync32(venvMoondream)) {
34686
- const venvPip = join43(venvBin, "pip");
35407
+ const venvPip = join46(venvBin, "pip");
34687
35408
  log("Installing moondream-station in ~/.open-agents/venv...");
34688
35409
  try {
34689
35410
  execSync25(`"${venvPip}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
@@ -34704,8 +35425,8 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
34704
35425
  }
34705
35426
  }
34706
35427
  if (venv) {
34707
- const venvPython = join43(venvBin, "python");
34708
- const venvPip2 = join43(venvBin, "pip");
35428
+ const venvPython = join46(venvBin, "python");
35429
+ const venvPip2 = join46(venvBin, "pip");
34709
35430
  let ocrStackInstalled = false;
34710
35431
  try {
34711
35432
  execSync25(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
@@ -34849,9 +35570,9 @@ async function createExpandedVariantAsync(baseModel, specs, sizeGB, kvBytesPerTo
34849
35570
  `PARAMETER num_predict ${numPredict}`,
34850
35571
  `PARAMETER stop "<|endoftext|>"`
34851
35572
  ].join("\n");
34852
- const modelDir2 = join43(homedir10(), ".open-agents", "models");
35573
+ const modelDir2 = join46(homedir10(), ".open-agents", "models");
34853
35574
  mkdirSync12(modelDir2, { recursive: true });
34854
- const modelfilePath = join43(modelDir2, `Modelfile.${customName}`);
35575
+ const modelfilePath = join46(modelDir2, `Modelfile.${customName}`);
34855
35576
  writeFileSync13(modelfilePath, modelfileContent + "\n", "utf8");
34856
35577
  await execAsync(`ollama create ${customName} -f ${modelfilePath}`, {
34857
35578
  timeout: 12e4
@@ -34926,8 +35647,8 @@ async function ensureNeovim() {
34926
35647
  const platform5 = process.platform;
34927
35648
  const arch = process.arch;
34928
35649
  if (platform5 === "linux") {
34929
- const binDir = join43(homedir10(), ".local", "bin");
34930
- const nvimDest = join43(binDir, "nvim");
35650
+ const binDir = join46(homedir10(), ".local", "bin");
35651
+ const nvimDest = join46(binDir, "nvim");
34931
35652
  try {
34932
35653
  mkdirSync12(binDir, { recursive: true });
34933
35654
  } catch {
@@ -34998,7 +35719,7 @@ async function ensureNeovim() {
34998
35719
  }
34999
35720
  function ensurePathInShellRc(binDir) {
35000
35721
  const shell = process.env.SHELL ?? "";
35001
- const rcFile = shell.includes("zsh") ? join43(homedir10(), ".zshrc") : join43(homedir10(), ".bashrc");
35722
+ const rcFile = shell.includes("zsh") ? join46(homedir10(), ".zshrc") : join46(homedir10(), ".bashrc");
35002
35723
  try {
35003
35724
  const rcContent = existsSync32(rcFile) ? readFileSync23(rcFile, "utf8") : "";
35004
35725
  if (rcContent.includes(binDir))
@@ -35770,7 +36491,7 @@ var init_drop_panel = __esm({
35770
36491
  // packages/cli/dist/tui/neovim-mode.js
35771
36492
  import { existsSync as existsSync34, unlinkSync as unlinkSync7 } from "node:fs";
35772
36493
  import { tmpdir as tmpdir8 } from "node:os";
35773
- import { join as join44 } from "node:path";
36494
+ import { join as join47 } from "node:path";
35774
36495
  import { execSync as execSync26 } from "node:child_process";
35775
36496
  function isNeovimActive() {
35776
36497
  return _state !== null && !_state.cleanedUp;
@@ -35818,7 +36539,7 @@ async function startNeovimMode(opts) {
35818
36539
  );
35819
36540
  } catch {
35820
36541
  }
35821
- const socketPath = join44(tmpdir8(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
36542
+ const socketPath = join47(tmpdir8(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
35822
36543
  try {
35823
36544
  if (existsSync34(socketPath))
35824
36545
  unlinkSync7(socketPath);
@@ -36170,7 +36891,7 @@ __export(voice_exports, {
36170
36891
  resetNarrationContext: () => resetNarrationContext
36171
36892
  });
36172
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";
36173
- import { join as join45 } from "node:path";
36894
+ import { join as join48 } from "node:path";
36174
36895
  import { homedir as homedir11, tmpdir as tmpdir9, platform as platform2 } from "node:os";
36175
36896
  import { execSync as execSync27, spawn as nodeSpawn } from "node:child_process";
36176
36897
  import { createRequire } from "node:module";
@@ -36192,34 +36913,34 @@ function listVoiceModels() {
36192
36913
  }));
36193
36914
  }
36194
36915
  function voiceDir() {
36195
- return join45(homedir11(), ".open-agents", "voice");
36916
+ return join48(homedir11(), ".open-agents", "voice");
36196
36917
  }
36197
36918
  function modelsDir() {
36198
- return join45(voiceDir(), "models");
36919
+ return join48(voiceDir(), "models");
36199
36920
  }
36200
36921
  function modelDir(id) {
36201
- return join45(modelsDir(), id);
36922
+ return join48(modelsDir(), id);
36202
36923
  }
36203
36924
  function modelOnnxPath(id) {
36204
- return join45(modelDir(id), "model.onnx");
36925
+ return join48(modelDir(id), "model.onnx");
36205
36926
  }
36206
36927
  function modelConfigPath(id) {
36207
- return join45(modelDir(id), "config.json");
36928
+ return join48(modelDir(id), "config.json");
36208
36929
  }
36209
36930
  function luxttsVenvDir() {
36210
- return join45(voiceDir(), "luxtts-venv");
36931
+ return join48(voiceDir(), "luxtts-venv");
36211
36932
  }
36212
36933
  function luxttsVenvPy() {
36213
- return platform2() === "win32" ? join45(luxttsVenvDir(), "Scripts", "python.exe") : join45(luxttsVenvDir(), "bin", "python3");
36934
+ return platform2() === "win32" ? join48(luxttsVenvDir(), "Scripts", "python.exe") : join48(luxttsVenvDir(), "bin", "python3");
36214
36935
  }
36215
36936
  function luxttsRepoDir() {
36216
- return join45(voiceDir(), "LuxTTS");
36937
+ return join48(voiceDir(), "LuxTTS");
36217
36938
  }
36218
36939
  function luxttsCloneRefsDir() {
36219
- return join45(voiceDir(), "clone-refs");
36940
+ return join48(voiceDir(), "clone-refs");
36220
36941
  }
36221
36942
  function luxttsInferScript() {
36222
- return join45(voiceDir(), "luxtts-infer.py");
36943
+ return join48(voiceDir(), "luxtts-infer.py");
36223
36944
  }
36224
36945
  function emotionToPitchBias(emotion, stark = false, autist = false) {
36225
36946
  if (autist)
@@ -37027,7 +37748,7 @@ var init_voice = __esm({
37027
37748
  const refsDir = luxttsCloneRefsDir();
37028
37749
  const targets = ["glados", "overwatch"];
37029
37750
  for (const modelId of targets) {
37030
- const refFile = join45(refsDir, `${modelId}-ref.wav`);
37751
+ const refFile = join48(refsDir, `${modelId}-ref.wav`);
37031
37752
  if (existsSync35(refFile))
37032
37753
  continue;
37033
37754
  try {
@@ -37107,7 +37828,7 @@ var init_voice = __esm({
37107
37828
  }
37108
37829
  p = p.replace(/\\ /g, " ");
37109
37830
  if (p.startsWith("~/") || p === "~") {
37110
- p = join45(homedir11(), p.slice(1));
37831
+ p = join48(homedir11(), p.slice(1));
37111
37832
  }
37112
37833
  if (!existsSync35(p)) {
37113
37834
  return `File not found: ${p}
@@ -37121,7 +37842,7 @@ var init_voice = __esm({
37121
37842
  const srcName = (audioPath.split("/").pop() ?? "clone").replace(/\.[^.]+$/, "").replace(/[^a-zA-Z0-9_-]/g, "-");
37122
37843
  const ts = Date.now().toString(36);
37123
37844
  const destFilename = `clone-${srcName}-${ts}.${ext}`;
37124
- const destPath = join45(refsDir, destFilename);
37845
+ const destPath = join48(refsDir, destFilename);
37125
37846
  try {
37126
37847
  const data = readFileSync24(audioPath);
37127
37848
  writeFileSync14(destPath, data);
@@ -37166,7 +37887,7 @@ var init_voice = __esm({
37166
37887
  const refsDir = luxttsCloneRefsDir();
37167
37888
  if (!existsSync35(refsDir))
37168
37889
  mkdirSync13(refsDir, { recursive: true });
37169
- const destPath = join45(refsDir, `${sourceModelId}-ref.wav`);
37890
+ const destPath = join48(refsDir, `${sourceModelId}-ref.wav`);
37170
37891
  const sampleRate = this.config?.audio?.sample_rate ?? 22050;
37171
37892
  this.writeWav(audioData, sampleRate, destPath);
37172
37893
  this.luxttsCloneRef = destPath;
@@ -37182,7 +37903,7 @@ var init_voice = __esm({
37182
37903
  // -------------------------------------------------------------------------
37183
37904
  /** Metadata file for friendly names of clone refs */
37184
37905
  static cloneMetaFile() {
37185
- return join45(luxttsCloneRefsDir(), "meta.json");
37906
+ return join48(luxttsCloneRefsDir(), "meta.json");
37186
37907
  }
37187
37908
  loadCloneMeta() {
37188
37909
  const p = _VoiceEngine.cloneMetaFile();
@@ -37216,7 +37937,7 @@ var init_voice = __esm({
37216
37937
  return _VoiceEngine.AUDIO_EXTS.has(ext);
37217
37938
  });
37218
37939
  return files.map((f) => {
37219
- const p = join45(dir, f);
37940
+ const p = join48(dir, f);
37220
37941
  let size = 0;
37221
37942
  try {
37222
37943
  size = statSync12(p).size;
@@ -37233,7 +37954,7 @@ var init_voice = __esm({
37233
37954
  }
37234
37955
  /** Delete a clone reference file by filename. Returns true if deleted. */
37235
37956
  deleteCloneRef(filename) {
37236
- const p = join45(luxttsCloneRefsDir(), filename);
37957
+ const p = join48(luxttsCloneRefsDir(), filename);
37237
37958
  if (!existsSync35(p))
37238
37959
  return false;
37239
37960
  try {
@@ -37258,7 +37979,7 @@ var init_voice = __esm({
37258
37979
  }
37259
37980
  /** Set the active clone reference by filename. */
37260
37981
  setActiveCloneRef(filename) {
37261
- const p = join45(luxttsCloneRefsDir(), filename);
37982
+ const p = join48(luxttsCloneRefsDir(), filename);
37262
37983
  if (!existsSync35(p))
37263
37984
  return `File not found: ${filename}`;
37264
37985
  this.luxttsCloneRef = p;
@@ -37544,7 +38265,7 @@ var init_voice = __esm({
37544
38265
  }
37545
38266
  this.onPCMOutput(Buffer.from(int16.buffer), sampleRate);
37546
38267
  }
37547
- const wavPath = join45(tmpdir9(), `oa-voice-${Date.now()}.wav`);
38268
+ const wavPath = join48(tmpdir9(), `oa-voice-${Date.now()}.wav`);
37548
38269
  this.writeWav(audioData, sampleRate, wavPath);
37549
38270
  await this.playWav(wavPath);
37550
38271
  try {
@@ -37887,7 +38608,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
37887
38608
  const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
37888
38609
  const mlxVoice = model.mlxVoice ?? "af_heart";
37889
38610
  const mlxLangCode = model.mlxLangCode ?? "a";
37890
- const wavPath = join45(tmpdir9(), `oa-mlx-${Date.now()}.wav`);
38611
+ const wavPath = join48(tmpdir9(), `oa-mlx-${Date.now()}.wav`);
37891
38612
  const pyScript = [
37892
38613
  "import sys, json",
37893
38614
  "from mlx_audio.tts import generate as tts_gen",
@@ -37955,7 +38676,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
37955
38676
  const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
37956
38677
  const mlxVoice = model.mlxVoice ?? "af_heart";
37957
38678
  const mlxLangCode = model.mlxLangCode ?? "a";
37958
- const wavPath = join45(tmpdir9(), `oa-mlx-buf-${Date.now()}.wav`);
38679
+ const wavPath = join48(tmpdir9(), `oa-mlx-buf-${Date.now()}.wav`);
37959
38680
  const pyScript = [
37960
38681
  "import sys, json",
37961
38682
  "from mlx_audio.tts import generate as tts_gen",
@@ -38066,7 +38787,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
38066
38787
  }
38067
38788
  }
38068
38789
  const repoDir = luxttsRepoDir();
38069
- if (!existsSync35(join45(repoDir, "zipvoice", "luxvoice.py"))) {
38790
+ if (!existsSync35(join48(repoDir, "zipvoice", "luxvoice.py"))) {
38070
38791
  renderInfo(" Cloning LuxTTS repository...");
38071
38792
  try {
38072
38793
  if (existsSync35(repoDir)) {
@@ -38115,7 +38836,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
38115
38836
  if (!existsSync35(refsDir))
38116
38837
  return;
38117
38838
  for (const name of ["custom-clone.wav", "custom-clone.mp3", "glados-ref.wav", "overwatch-ref.wav"]) {
38118
- const p = join45(refsDir, name);
38839
+ const p = join48(refsDir, name);
38119
38840
  if (existsSync35(p)) {
38120
38841
  this.luxttsCloneRef = p;
38121
38842
  return;
@@ -38312,7 +39033,7 @@ if __name__ == '__main__':
38312
39033
  const ready = await this.ensureLuxttsDaemon();
38313
39034
  if (!ready)
38314
39035
  return;
38315
- const wavPath = join45(tmpdir9(), `oa-luxtts-${Date.now()}.wav`);
39036
+ const wavPath = join48(tmpdir9(), `oa-luxtts-${Date.now()}.wav`);
38316
39037
  try {
38317
39038
  await this.luxttsRequest({
38318
39039
  action: "synthesize",
@@ -38386,7 +39107,7 @@ if __name__ == '__main__':
38386
39107
  const ready = await this.ensureLuxttsDaemon();
38387
39108
  if (!ready)
38388
39109
  return null;
38389
- const wavPath = join45(tmpdir9(), `oa-luxtts-buf-${Date.now()}.wav`);
39110
+ const wavPath = join48(tmpdir9(), `oa-luxtts-buf-${Date.now()}.wav`);
38390
39111
  try {
38391
39112
  await this.luxttsRequest({
38392
39113
  action: "synthesize",
@@ -38416,7 +39137,7 @@ if __name__ == '__main__':
38416
39137
  return;
38417
39138
  const arch = process.arch;
38418
39139
  mkdirSync13(voiceDir(), { recursive: true });
38419
- const pkgPath = join45(voiceDir(), "package.json");
39140
+ const pkgPath = join48(voiceDir(), "package.json");
38420
39141
  const expectedDeps = {
38421
39142
  "onnxruntime-node": "^1.21.0",
38422
39143
  "phonemizer": "^1.2.1"
@@ -38438,17 +39159,17 @@ if __name__ == '__main__':
38438
39159
  dependencies: expectedDeps
38439
39160
  }, null, 2));
38440
39161
  }
38441
- const voiceRequire = createRequire(join45(voiceDir(), "index.js"));
39162
+ const voiceRequire = createRequire(join48(voiceDir(), "index.js"));
38442
39163
  const probeOnnx = () => {
38443
39164
  try {
38444
- const result = execSync27(`node -e "try { require('onnxruntime-node'); console.log('OK'); } catch(e) { console.log('FAIL:' + e.message); }"`, { cwd: voiceDir(), stdio: "pipe", timeout: 15e3, env: { ...process.env, NODE_PATH: join45(voiceDir(), "node_modules") } });
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") } });
38445
39166
  const output = result.toString().trim();
38446
39167
  return output === "OK";
38447
39168
  } catch {
38448
39169
  return false;
38449
39170
  }
38450
39171
  };
38451
- const onnxNodeModules = join45(voiceDir(), "node_modules", "onnxruntime-node");
39172
+ const onnxNodeModules = join48(voiceDir(), "node_modules", "onnxruntime-node");
38452
39173
  const onnxInstalled = existsSync35(onnxNodeModules);
38453
39174
  if (onnxInstalled && !probeOnnx()) {
38454
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.`);
@@ -40792,8 +41513,8 @@ async function handlePeerEndpoint(peerId, authKey, ctx, local) {
40792
41513
  if (models.length > 0) {
40793
41514
  try {
40794
41515
  const { writeFileSync: writeFileSync20, mkdirSync: mkdirSync21 } = await import("node:fs");
40795
- const { join: join59, dirname: dirname20 } = await import("node:path");
40796
- const cachePath = join59(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");
40797
41518
  mkdirSync21(dirname20(cachePath), { recursive: true });
40798
41519
  writeFileSync20(cachePath, JSON.stringify({
40799
41520
  peerId,
@@ -40994,14 +41715,14 @@ async function handleUpdate(subcommand, ctx) {
40994
41715
  try {
40995
41716
  const { createRequire: createRequire4 } = await import("node:module");
40996
41717
  const { fileURLToPath: fileURLToPath14 } = await import("node:url");
40997
- const { dirname: dirname20, join: join59 } = await import("node:path");
41718
+ const { dirname: dirname20, join: join62 } = await import("node:path");
40998
41719
  const { existsSync: existsSync45 } = await import("node:fs");
40999
41720
  const req = createRequire4(import.meta.url);
41000
41721
  const thisDir = dirname20(fileURLToPath14(import.meta.url));
41001
41722
  const candidates = [
41002
- join59(thisDir, "..", "package.json"),
41003
- join59(thisDir, "..", "..", "package.json"),
41004
- join59(thisDir, "..", "..", "..", "package.json")
41723
+ join62(thisDir, "..", "package.json"),
41724
+ join62(thisDir, "..", "..", "package.json"),
41725
+ join62(thisDir, "..", "..", "..", "package.json")
41005
41726
  ];
41006
41727
  for (const pkgPath of candidates) {
41007
41728
  if (existsSync45(pkgPath)) {
@@ -41719,7 +42440,7 @@ var init_commands = __esm({
41719
42440
 
41720
42441
  // packages/cli/dist/tui/project-context.js
41721
42442
  import { existsSync as existsSync36, readFileSync as readFileSync25, readdirSync as readdirSync10 } from "node:fs";
41722
- import { join as join46, basename as basename10 } from "node:path";
42443
+ import { join as join49, basename as basename10 } from "node:path";
41723
42444
  import { execSync as execSync28 } from "node:child_process";
41724
42445
  import { homedir as homedir12, platform as platform3, release } from "node:os";
41725
42446
  function getModelTier(modelName) {
@@ -41754,7 +42475,7 @@ function loadProjectMap(repoRoot) {
41754
42475
  if (!hasOaDirectory(repoRoot)) {
41755
42476
  initOaDirectory(repoRoot);
41756
42477
  }
41757
- const mapPath = join46(repoRoot, OA_DIR, "context", "project-map.md");
42478
+ const mapPath = join49(repoRoot, OA_DIR, "context", "project-map.md");
41758
42479
  if (existsSync36(mapPath)) {
41759
42480
  try {
41760
42481
  const content = readFileSync25(mapPath, "utf-8");
@@ -41798,17 +42519,17 @@ ${log}`);
41798
42519
  }
41799
42520
  function loadMemoryContext(repoRoot) {
41800
42521
  const sections = [];
41801
- const oaMemDir = join46(repoRoot, OA_DIR, "memory");
42522
+ const oaMemDir = join49(repoRoot, OA_DIR, "memory");
41802
42523
  const oaEntries = loadMemoryDir(oaMemDir, "project");
41803
42524
  if (oaEntries)
41804
42525
  sections.push(oaEntries);
41805
- const legacyMemDir = join46(repoRoot, ".open-agents", "memory");
42526
+ const legacyMemDir = join49(repoRoot, ".open-agents", "memory");
41806
42527
  if (legacyMemDir !== oaMemDir && existsSync36(legacyMemDir)) {
41807
42528
  const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
41808
42529
  if (legacyEntries)
41809
42530
  sections.push(legacyEntries);
41810
42531
  }
41811
- const globalMemDir = join46(homedir12(), ".open-agents", "memory");
42532
+ const globalMemDir = join49(homedir12(), ".open-agents", "memory");
41812
42533
  const globalEntries = loadMemoryDir(globalMemDir, "global");
41813
42534
  if (globalEntries)
41814
42535
  sections.push(globalEntries);
@@ -41822,7 +42543,7 @@ function loadMemoryDir(memDir, scope) {
41822
42543
  const files = readdirSync10(memDir).filter((f) => f.endsWith(".json"));
41823
42544
  for (const file of files.slice(0, 10)) {
41824
42545
  try {
41825
- const raw = readFileSync25(join46(memDir, file), "utf-8");
42546
+ const raw = readFileSync25(join49(memDir, file), "utf-8");
41826
42547
  const entries = JSON.parse(raw);
41827
42548
  const topic = basename10(file, ".json");
41828
42549
  const keys = Object.keys(entries);
@@ -42846,9 +43567,9 @@ var init_carousel = __esm({
42846
43567
 
42847
43568
  // packages/cli/dist/tui/carousel-descriptors.js
42848
43569
  import { existsSync as existsSync37, readFileSync as readFileSync26, writeFileSync as writeFileSync15, mkdirSync as mkdirSync14, readdirSync as readdirSync11 } from "node:fs";
42849
- import { join as join47, basename as basename11 } from "node:path";
43570
+ import { join as join50, basename as basename11 } from "node:path";
42850
43571
  function loadToolProfile(repoRoot) {
42851
- const filePath = join47(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
43572
+ const filePath = join50(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
42852
43573
  try {
42853
43574
  if (!existsSync37(filePath))
42854
43575
  return null;
@@ -42858,9 +43579,9 @@ function loadToolProfile(repoRoot) {
42858
43579
  }
42859
43580
  }
42860
43581
  function saveToolProfile(repoRoot, profile) {
42861
- const contextDir = join47(repoRoot, OA_DIR, "context");
43582
+ const contextDir = join50(repoRoot, OA_DIR, "context");
42862
43583
  mkdirSync14(contextDir, { recursive: true });
42863
- writeFileSync15(join47(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");
42864
43585
  }
42865
43586
  function categorizeToolCall(toolName) {
42866
43587
  for (const cat of TOOL_CATEGORIES) {
@@ -42918,7 +43639,7 @@ function weightedColor(profile) {
42918
43639
  return selectedCat.colors[Math.floor(Math.random() * selectedCat.colors.length)];
42919
43640
  }
42920
43641
  function loadCachedDescriptors(repoRoot) {
42921
- const filePath = join47(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
43642
+ const filePath = join50(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
42922
43643
  try {
42923
43644
  if (!existsSync37(filePath))
42924
43645
  return null;
@@ -42929,14 +43650,14 @@ function loadCachedDescriptors(repoRoot) {
42929
43650
  }
42930
43651
  }
42931
43652
  function saveCachedDescriptors(repoRoot, phrases, sourceHash) {
42932
- const contextDir = join47(repoRoot, OA_DIR, "context");
43653
+ const contextDir = join50(repoRoot, OA_DIR, "context");
42933
43654
  mkdirSync14(contextDir, { recursive: true });
42934
43655
  const cached = {
42935
43656
  phrases,
42936
43657
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
42937
43658
  sourceHash
42938
43659
  };
42939
- writeFileSync15(join47(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
43660
+ writeFileSync15(join50(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
42940
43661
  }
42941
43662
  function generateDescriptors(repoRoot) {
42942
43663
  const profile = loadToolProfile(repoRoot);
@@ -42984,7 +43705,7 @@ function generateDescriptors(repoRoot) {
42984
43705
  return phrases;
42985
43706
  }
42986
43707
  function extractFromPackageJson(repoRoot, tags) {
42987
- const pkgPath = join47(repoRoot, "package.json");
43708
+ const pkgPath = join50(repoRoot, "package.json");
42988
43709
  try {
42989
43710
  if (!existsSync37(pkgPath))
42990
43711
  return;
@@ -43032,7 +43753,7 @@ function extractFromManifests(repoRoot, tags) {
43032
43753
  { file: ".github/workflows", tag: "ci/cd" }
43033
43754
  ];
43034
43755
  for (const check of manifestChecks) {
43035
- if (existsSync37(join47(repoRoot, check.file))) {
43756
+ if (existsSync37(join50(repoRoot, check.file))) {
43036
43757
  tags.push(check.tag);
43037
43758
  }
43038
43759
  }
@@ -43054,7 +43775,7 @@ function extractFromSessions(repoRoot, tags) {
43054
43775
  }
43055
43776
  }
43056
43777
  function extractFromMemory(repoRoot, tags) {
43057
- const memoryDir = join47(repoRoot, OA_DIR, "memory");
43778
+ const memoryDir = join50(repoRoot, OA_DIR, "memory");
43058
43779
  try {
43059
43780
  if (!existsSync37(memoryDir))
43060
43781
  return;
@@ -43063,7 +43784,7 @@ function extractFromMemory(repoRoot, tags) {
43063
43784
  const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
43064
43785
  tags.push(topic);
43065
43786
  try {
43066
- const data = JSON.parse(readFileSync26(join47(memoryDir, file), "utf-8"));
43787
+ const data = JSON.parse(readFileSync26(join50(memoryDir, file), "utf-8"));
43067
43788
  if (data && typeof data === "object") {
43068
43789
  const keys = Object.keys(data).slice(0, 3);
43069
43790
  for (const key of keys) {
@@ -43686,10 +44407,10 @@ var init_stream_renderer = __esm({
43686
44407
 
43687
44408
  // packages/cli/dist/tui/edit-history.js
43688
44409
  import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync15 } from "node:fs";
43689
- import { join as join48 } from "node:path";
44410
+ import { join as join51 } from "node:path";
43690
44411
  function createEditHistoryLogger(repoRoot, sessionId) {
43691
- const historyDir = join48(repoRoot, ".oa", "history");
43692
- const logPath = join48(historyDir, "edits.jsonl");
44412
+ const historyDir = join51(repoRoot, ".oa", "history");
44413
+ const logPath = join51(historyDir, "edits.jsonl");
43693
44414
  try {
43694
44415
  mkdirSync15(historyDir, { recursive: true });
43695
44416
  } catch {
@@ -43801,12 +44522,12 @@ var init_edit_history = __esm({
43801
44522
 
43802
44523
  // packages/cli/dist/tui/promptLoader.js
43803
44524
  import { readFileSync as readFileSync27, existsSync as existsSync38 } from "node:fs";
43804
- import { join as join49, dirname as dirname17 } from "node:path";
44525
+ import { join as join52, dirname as dirname17 } from "node:path";
43805
44526
  import { fileURLToPath as fileURLToPath11 } from "node:url";
43806
44527
  function loadPrompt3(promptPath, vars) {
43807
44528
  let content = cache3.get(promptPath);
43808
44529
  if (content === void 0) {
43809
- const fullPath = join49(PROMPTS_DIR3, promptPath);
44530
+ const fullPath = join52(PROMPTS_DIR3, promptPath);
43810
44531
  if (!existsSync38(fullPath)) {
43811
44532
  throw new Error(`Prompt file not found: ${fullPath}`);
43812
44533
  }
@@ -43823,8 +44544,8 @@ var init_promptLoader3 = __esm({
43823
44544
  "use strict";
43824
44545
  __filename3 = fileURLToPath11(import.meta.url);
43825
44546
  __dirname6 = dirname17(__filename3);
43826
- devPath2 = join49(__dirname6, "..", "..", "prompts");
43827
- publishedPath2 = join49(__dirname6, "..", "prompts");
44547
+ devPath2 = join52(__dirname6, "..", "..", "prompts");
44548
+ publishedPath2 = join52(__dirname6, "..", "prompts");
43828
44549
  PROMPTS_DIR3 = existsSync38(devPath2) ? devPath2 : publishedPath2;
43829
44550
  cache3 = /* @__PURE__ */ new Map();
43830
44551
  }
@@ -43832,10 +44553,10 @@ var init_promptLoader3 = __esm({
43832
44553
 
43833
44554
  // packages/cli/dist/tui/dream-engine.js
43834
44555
  import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync16, readFileSync as readFileSync28, existsSync as existsSync39, cpSync, rmSync, readdirSync as readdirSync12 } from "node:fs";
43835
- import { join as join50, basename as basename12 } from "node:path";
44556
+ import { join as join53, basename as basename12 } from "node:path";
43836
44557
  import { execSync as execSync29 } from "node:child_process";
43837
44558
  function loadAutoresearchMemory(repoRoot) {
43838
- const memoryPath = join50(repoRoot, ".oa", "memory", "autoresearch.json");
44559
+ const memoryPath = join53(repoRoot, ".oa", "memory", "autoresearch.json");
43839
44560
  if (!existsSync39(memoryPath))
43840
44561
  return "";
43841
44562
  try {
@@ -44029,12 +44750,12 @@ var init_dream_engine = __esm({
44029
44750
  const content = String(args["content"] ?? "");
44030
44751
  if (!rawPath)
44031
44752
  return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
44032
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join50(this.autoresearchDir, basename12(rawPath)) : join50(this.autoresearchDir, rawPath);
44753
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join53(this.autoresearchDir, basename12(rawPath)) : join53(this.autoresearchDir, rawPath);
44033
44754
  if (!targetPath.startsWith(this.autoresearchDir)) {
44034
44755
  return { success: false, output: "", error: "Autoresearch mode: writes are confined to .oa/autoresearch/", durationMs: Date.now() - start };
44035
44756
  }
44036
44757
  try {
44037
- const dir = join50(targetPath, "..");
44758
+ const dir = join53(targetPath, "..");
44038
44759
  mkdirSync16(dir, { recursive: true });
44039
44760
  writeFileSync16(targetPath, content, "utf-8");
44040
44761
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
@@ -44064,7 +44785,7 @@ var init_dream_engine = __esm({
44064
44785
  const rawPath = String(args["path"] ?? "");
44065
44786
  const oldStr = String(args["old_string"] ?? "");
44066
44787
  const newStr = String(args["new_string"] ?? "");
44067
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join50(this.autoresearchDir, basename12(rawPath)) : join50(this.autoresearchDir, rawPath);
44788
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join53(this.autoresearchDir, basename12(rawPath)) : join53(this.autoresearchDir, rawPath);
44068
44789
  if (!targetPath.startsWith(this.autoresearchDir)) {
44069
44790
  return { success: false, output: "", error: "Autoresearch mode: edits are confined to .oa/autoresearch/", durationMs: Date.now() - start };
44070
44791
  }
@@ -44118,12 +44839,12 @@ var init_dream_engine = __esm({
44118
44839
  const content = String(args["content"] ?? "");
44119
44840
  if (!rawPath)
44120
44841
  return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
44121
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join50(this.dreamsDir, basename12(rawPath)) : join50(this.dreamsDir, rawPath);
44842
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join53(this.dreamsDir, basename12(rawPath)) : join53(this.dreamsDir, rawPath);
44122
44843
  if (!targetPath.startsWith(this.dreamsDir)) {
44123
44844
  return { success: false, output: "", error: "Dream mode: writes are confined to .oa/dreams/", durationMs: Date.now() - start };
44124
44845
  }
44125
44846
  try {
44126
- const dir = join50(targetPath, "..");
44847
+ const dir = join53(targetPath, "..");
44127
44848
  mkdirSync16(dir, { recursive: true });
44128
44849
  writeFileSync16(targetPath, content, "utf-8");
44129
44850
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
@@ -44153,7 +44874,7 @@ var init_dream_engine = __esm({
44153
44874
  const rawPath = String(args["path"] ?? "");
44154
44875
  const oldStr = String(args["old_string"] ?? "");
44155
44876
  const newStr = String(args["new_string"] ?? "");
44156
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join50(this.dreamsDir, basename12(rawPath)) : join50(this.dreamsDir, rawPath);
44877
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join53(this.dreamsDir, basename12(rawPath)) : join53(this.dreamsDir, rawPath);
44157
44878
  if (!targetPath.startsWith(this.dreamsDir)) {
44158
44879
  return { success: false, output: "", error: "Dream mode: edits are confined to .oa/dreams/", durationMs: Date.now() - start };
44159
44880
  }
@@ -44220,7 +44941,7 @@ var init_dream_engine = __esm({
44220
44941
  constructor(config, repoRoot) {
44221
44942
  this.config = config;
44222
44943
  this.repoRoot = repoRoot;
44223
- this.dreamsDir = join50(repoRoot, ".oa", "dreams");
44944
+ this.dreamsDir = join53(repoRoot, ".oa", "dreams");
44224
44945
  this.state = {
44225
44946
  mode: "default",
44226
44947
  active: false,
@@ -44304,7 +45025,7 @@ ${result.summary}`;
44304
45025
  if (mode !== "default" || cycle === totalCycles) {
44305
45026
  renderDreamContraction(cycle);
44306
45027
  const cycleSummary = this.buildCycleSummary(cycle, previousFindings);
44307
- const summaryPath = join50(this.dreamsDir, `cycle-${cycle}-summary.md`);
45028
+ const summaryPath = join53(this.dreamsDir, `cycle-${cycle}-summary.md`);
44308
45029
  writeFileSync16(summaryPath, cycleSummary, "utf-8");
44309
45030
  }
44310
45031
  if (mode === "lucid" && !this.abortController.signal.aborted) {
@@ -44517,7 +45238,7 @@ After synthesis, call task_complete with the final prioritized summary.`, toolMo
44517
45238
  }
44518
45239
  /** Build role-specific tool sets for swarm agents */
44519
45240
  buildSwarmTools(role, _workspace) {
44520
- const autoresearchDir = join50(this.repoRoot, ".oa", "autoresearch");
45241
+ const autoresearchDir = join53(this.repoRoot, ".oa", "autoresearch");
44521
45242
  const taskComplete = this.createSwarmTaskCompleteTool(role);
44522
45243
  switch (role) {
44523
45244
  case "researcher": {
@@ -44881,7 +45602,7 @@ INSTRUCTIONS:
44881
45602
  2. Summarize the key learnings and next steps
44882
45603
 
44883
45604
  Call task_complete with a human-readable summary of the autoresearch session.`, workspace, onEvent);
44884
- const reportPath = join50(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
45605
+ const reportPath = join53(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
44885
45606
  const report = `# Autoresearch Swarm Report \u2014 Cycle ${cycleNum}
44886
45607
 
44887
45608
  **Date**: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
@@ -44970,7 +45691,7 @@ ${summaryResult}
44970
45691
  }
44971
45692
  /** Save workspace backup for lucid mode */
44972
45693
  saveVersionCheckpoint(cycle) {
44973
- const checkpointDir = join50(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
45694
+ const checkpointDir = join53(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
44974
45695
  try {
44975
45696
  mkdirSync16(checkpointDir, { recursive: true });
44976
45697
  try {
@@ -44989,10 +45710,10 @@ ${summaryResult}
44989
45710
  encoding: "utf-8",
44990
45711
  timeout: 5e3
44991
45712
  }).trim();
44992
- writeFileSync16(join50(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
44993
- writeFileSync16(join50(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
44994
- writeFileSync16(join50(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
44995
- writeFileSync16(join50(checkpointDir, "checkpoint.json"), JSON.stringify({
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({
44996
45717
  cycle,
44997
45718
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
44998
45719
  gitHash,
@@ -45000,7 +45721,7 @@ ${summaryResult}
45000
45721
  }, null, 2), "utf-8");
45001
45722
  renderInfo(`Checkpoint saved: cycle ${cycle} (${gitHash.slice(0, 8)})`);
45002
45723
  } catch {
45003
- writeFileSync16(join50(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");
45004
45725
  renderInfo(`Checkpoint saved: cycle ${cycle} (no git)`);
45005
45726
  }
45006
45727
  } catch (err) {
@@ -45058,14 +45779,14 @@ ${files.map((f) => `- [\`${f}\`](./${f})`).join("\n")}
45058
45779
  ---
45059
45780
  *Auto-generated by open-agents dream engine*
45060
45781
  `;
45061
- writeFileSync16(join50(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
45782
+ writeFileSync16(join53(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
45062
45783
  } catch {
45063
45784
  }
45064
45785
  }
45065
45786
  /** Save dream state for resume/inspection */
45066
45787
  saveDreamState() {
45067
45788
  try {
45068
- writeFileSync16(join50(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");
45069
45790
  } catch {
45070
45791
  }
45071
45792
  }
@@ -45440,7 +46161,7 @@ var init_bless_engine = __esm({
45440
46161
 
45441
46162
  // packages/cli/dist/tui/dmn-engine.js
45442
46163
  import { existsSync as existsSync40, readFileSync as readFileSync29, writeFileSync as writeFileSync17, mkdirSync as mkdirSync17, readdirSync as readdirSync13, unlinkSync as unlinkSync9 } from "node:fs";
45443
- import { join as join51, basename as basename13 } from "node:path";
46164
+ import { join as join54, basename as basename13 } from "node:path";
45444
46165
  function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
45445
46166
  const competenceReport = competence.length > 0 ? competence.map((c3) => {
45446
46167
  const rate = c3.attempts > 0 ? Math.round(c3.successes / c3.attempts * 100) : 0;
@@ -45553,8 +46274,8 @@ var init_dmn_engine = __esm({
45553
46274
  constructor(config, repoRoot) {
45554
46275
  this.config = config;
45555
46276
  this.repoRoot = repoRoot;
45556
- this.stateDir = join51(repoRoot, ".oa", "dmn");
45557
- this.historyDir = join51(repoRoot, ".oa", "dmn", "cycles");
46277
+ this.stateDir = join54(repoRoot, ".oa", "dmn");
46278
+ this.historyDir = join54(repoRoot, ".oa", "dmn", "cycles");
45558
46279
  mkdirSync17(this.historyDir, { recursive: true });
45559
46280
  this.loadState();
45560
46281
  }
@@ -46144,8 +46865,8 @@ OUTPUT: Call task_complete with JSON:
46144
46865
  async gatherMemoryTopics() {
46145
46866
  const topics = [];
46146
46867
  const dirs = [
46147
- join51(this.repoRoot, ".oa", "memory"),
46148
- join51(this.repoRoot, ".open-agents", "memory")
46868
+ join54(this.repoRoot, ".oa", "memory"),
46869
+ join54(this.repoRoot, ".open-agents", "memory")
46149
46870
  ];
46150
46871
  for (const dir of dirs) {
46151
46872
  if (!existsSync40(dir))
@@ -46164,7 +46885,7 @@ OUTPUT: Call task_complete with JSON:
46164
46885
  }
46165
46886
  // ── State persistence ─────────────────────────────────────────────────
46166
46887
  loadState() {
46167
- const path = join51(this.stateDir, "state.json");
46888
+ const path = join54(this.stateDir, "state.json");
46168
46889
  if (existsSync40(path)) {
46169
46890
  try {
46170
46891
  this.state = JSON.parse(readFileSync29(path, "utf-8"));
@@ -46174,19 +46895,19 @@ OUTPUT: Call task_complete with JSON:
46174
46895
  }
46175
46896
  saveState() {
46176
46897
  try {
46177
- writeFileSync17(join51(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");
46178
46899
  } catch {
46179
46900
  }
46180
46901
  }
46181
46902
  saveCycleResult(result) {
46182
46903
  try {
46183
46904
  const filename = `cycle-${result.cycleNumber}-${Date.now()}.json`;
46184
- writeFileSync17(join51(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");
46185
46906
  const files = readdirSync13(this.historyDir).filter((f) => f.startsWith("cycle-") && f.endsWith(".json")).sort();
46186
46907
  if (files.length > 50) {
46187
46908
  for (const old of files.slice(0, files.length - 50)) {
46188
46909
  try {
46189
- unlinkSync9(join51(this.historyDir, old));
46910
+ unlinkSync9(join54(this.historyDir, old));
46190
46911
  } catch {
46191
46912
  }
46192
46913
  }
@@ -46200,7 +46921,7 @@ OUTPUT: Call task_complete with JSON:
46200
46921
 
46201
46922
  // packages/cli/dist/tui/snr-engine.js
46202
46923
  import { existsSync as existsSync41, readdirSync as readdirSync14, readFileSync as readFileSync30 } from "node:fs";
46203
- import { join as join52, basename as basename14 } from "node:path";
46924
+ import { join as join55, basename as basename14 } from "node:path";
46204
46925
  function computeDPrime(signalScores, noiseScores) {
46205
46926
  if (signalScores.length === 0 || noiseScores.length === 0)
46206
46927
  return 0;
@@ -46440,8 +47161,8 @@ Call task_complete with the JSON array when done.`, onEvent)
46440
47161
  loadMemoryEntries(topics) {
46441
47162
  const entries = [];
46442
47163
  const dirs = [
46443
- join52(this.repoRoot, ".oa", "memory"),
46444
- join52(this.repoRoot, ".open-agents", "memory")
47164
+ join55(this.repoRoot, ".oa", "memory"),
47165
+ join55(this.repoRoot, ".open-agents", "memory")
46445
47166
  ];
46446
47167
  for (const dir of dirs) {
46447
47168
  if (!existsSync41(dir))
@@ -46453,7 +47174,7 @@ Call task_complete with the JSON array when done.`, onEvent)
46453
47174
  if (topics.length > 0 && !topics.includes(topic))
46454
47175
  continue;
46455
47176
  try {
46456
- const data = JSON.parse(readFileSync30(join52(dir, f), "utf-8"));
47177
+ const data = JSON.parse(readFileSync30(join55(dir, f), "utf-8"));
46457
47178
  for (const [key, val] of Object.entries(data)) {
46458
47179
  const value = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
46459
47180
  entries.push({ topic, key, value });
@@ -47021,7 +47742,7 @@ var init_tool_policy = __esm({
47021
47742
 
47022
47743
  // packages/cli/dist/tui/telegram-bridge.js
47023
47744
  import { mkdirSync as mkdirSync18, existsSync as existsSync42, unlinkSync as unlinkSync10, readdirSync as readdirSync15, statSync as statSync13 } from "node:fs";
47024
- import { join as join53, resolve as resolve28 } from "node:path";
47745
+ import { join as join56, resolve as resolve28 } from "node:path";
47025
47746
  import { writeFile as writeFileAsync } from "node:fs/promises";
47026
47747
  function convertMarkdownToTelegramHTML(md) {
47027
47748
  let html = md;
@@ -47786,7 +48507,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
47786
48507
  return null;
47787
48508
  const buffer = Buffer.from(await res.arrayBuffer());
47788
48509
  const fileName = `${Date.now()}-${fileId.slice(0, 8)}${extension}`;
47789
- const localPath = join53(this.mediaCacheDir, fileName);
48510
+ const localPath = join56(this.mediaCacheDir, fileName);
47790
48511
  await writeFileAsync(localPath, buffer);
47791
48512
  return localPath;
47792
48513
  } catch {
@@ -48437,7 +49158,7 @@ var init_braille_spinner = __esm({
48437
49158
  // packages/cli/dist/tui/system-metrics.js
48438
49159
  import { loadavg as loadavg3, cpus as cpus3, totalmem as totalmem4, freemem as freemem3, platform as platform4 } from "node:os";
48439
49160
  import { exec as exec3 } from "node:child_process";
48440
- import { readFile as readFile17 } from "node:fs/promises";
49161
+ import { readFile as readFile20 } from "node:fs/promises";
48441
49162
  function formatRate(bytesPerSec) {
48442
49163
  if (bytesPerSec < 1024)
48443
49164
  return `${Math.round(bytesPerSec)}B`;
@@ -48449,7 +49170,7 @@ function formatRate(bytesPerSec) {
48449
49170
  }
48450
49171
  async function readProcNetDev() {
48451
49172
  try {
48452
- const data = await readFile17("/proc/net/dev", "utf8");
49173
+ const data = await readFile20("/proc/net/dev", "utf8");
48453
49174
  let rxTotal = 0;
48454
49175
  let txTotal = 0;
48455
49176
  for (const line of data.split("\n")) {
@@ -50224,7 +50945,7 @@ var init_status_bar = __esm({
50224
50945
  import * as readline2 from "node:readline";
50225
50946
  import { Writable } from "node:stream";
50226
50947
  import { cwd } from "node:process";
50227
- import { resolve as resolve29, join as join54, 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";
50228
50949
  import { createRequire as createRequire2 } from "node:module";
50229
50950
  import { fileURLToPath as fileURLToPath12 } from "node:url";
50230
50951
  import { readFileSync as readFileSync32, writeFileSync as writeFileSync18, appendFileSync as appendFileSync4, rmSync as rmSync2, readdirSync as readdirSync16, mkdirSync as mkdirSync19 } from "node:fs";
@@ -50248,9 +50969,9 @@ function getVersion3() {
50248
50969
  const require2 = createRequire2(import.meta.url);
50249
50970
  const thisDir = dirname18(fileURLToPath12(import.meta.url));
50250
50971
  const candidates = [
50251
- join54(thisDir, "..", "package.json"),
50252
- join54(thisDir, "..", "..", "package.json"),
50253
- join54(thisDir, "..", "..", "..", "package.json")
50972
+ join57(thisDir, "..", "package.json"),
50973
+ join57(thisDir, "..", "..", "package.json"),
50974
+ join57(thisDir, "..", "..", "..", "package.json")
50254
50975
  ];
50255
50976
  for (const pkgPath of candidates) {
50256
50977
  if (existsSync43(pkgPath)) {
@@ -50345,6 +51066,12 @@ function buildTools(repoRoot, config, contextWindowSize) {
50345
51066
  new ReplTool(repoRoot),
50346
51067
  // Memory Metabolism — COHERE Layer 5 (arxiv:2512.13564)
50347
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),
50348
51075
  // Structured file reading (CSV, JSON, Markdown, binary detection)
50349
51076
  new StructuredReadTool(repoRoot),
50350
51077
  // Vision tools (Moondream — desktop awareness + point-and-click)
@@ -50464,15 +51191,15 @@ Use task_status("${taskId}") or task_output("${taskId}") to check progress.`
50464
51191
  function gatherMemorySnippets(root) {
50465
51192
  const snippets = [];
50466
51193
  const dirs = [
50467
- join54(root, ".oa", "memory"),
50468
- join54(root, ".open-agents", "memory")
51194
+ join57(root, ".oa", "memory"),
51195
+ join57(root, ".open-agents", "memory")
50469
51196
  ];
50470
51197
  for (const dir of dirs) {
50471
51198
  if (!existsSync43(dir))
50472
51199
  continue;
50473
51200
  try {
50474
51201
  for (const f of readdirSync16(dir).filter((f2) => f2.endsWith(".json"))) {
50475
- const data = JSON.parse(readFileSync32(join54(dir, f), "utf-8"));
51202
+ const data = JSON.parse(readFileSync32(join57(dir, f), "utf-8"));
50476
51203
  for (const val of Object.values(data)) {
50477
51204
  const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
50478
51205
  if (v.length > 10)
@@ -51494,7 +52221,7 @@ async function startInteractive(config, repoPath) {
51494
52221
  let p2pGateway = null;
51495
52222
  let peerMesh = null;
51496
52223
  let inferenceRouter = null;
51497
- const secretVault = new SecretVault(join54(repoRoot, ".oa", "vault.enc"));
52224
+ const secretVault = new SecretVault(join57(repoRoot, ".oa", "vault.enc"));
51498
52225
  let adminSessionKey = null;
51499
52226
  const callSubAgents = /* @__PURE__ */ new Map();
51500
52227
  const streamRenderer = new StreamRenderer();
@@ -51703,8 +52430,8 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
51703
52430
  const hits = allCompletions.filter((c3) => c3.toLowerCase().startsWith(lower));
51704
52431
  return [hits, line];
51705
52432
  }
51706
- const HISTORY_DIR = join54(homedir13(), ".open-agents");
51707
- const HISTORY_FILE = join54(HISTORY_DIR, "repl-history");
52433
+ const HISTORY_DIR = join57(homedir13(), ".open-agents");
52434
+ const HISTORY_FILE = join57(HISTORY_DIR, "repl-history");
51708
52435
  const MAX_HISTORY_LINES = 500;
51709
52436
  let savedHistory = [];
51710
52437
  try {
@@ -51914,7 +52641,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
51914
52641
  } catch {
51915
52642
  }
51916
52643
  try {
51917
- const oaDir = join54(repoRoot, ".oa");
52644
+ const oaDir = join57(repoRoot, ".oa");
51918
52645
  const reconnected = await ExposeGateway.checkAndReconnect(oaDir, {
51919
52646
  onInfo: (msg) => writeContent(() => renderInfo(msg)),
51920
52647
  onError: (msg) => writeContent(() => renderWarning(msg))
@@ -51937,7 +52664,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
51937
52664
  } catch {
51938
52665
  }
51939
52666
  try {
51940
- const oaDir = join54(repoRoot, ".oa");
52667
+ const oaDir = join57(repoRoot, ".oa");
51941
52668
  const reconnectedP2P = await ExposeP2PGateway.checkAndReconnect(oaDir, new NexusTool(repoRoot), {
51942
52669
  onInfo: (msg) => writeContent(() => renderInfo(msg)),
51943
52670
  onError: (msg) => writeContent(() => renderWarning(msg))
@@ -52756,7 +53483,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
52756
53483
  kind,
52757
53484
  targetUrl,
52758
53485
  authKey,
52759
- stateDir: join54(repoRoot, ".oa"),
53486
+ stateDir: join57(repoRoot, ".oa"),
52760
53487
  passthrough: passthrough ?? false,
52761
53488
  loadbalance: loadbalance ?? false,
52762
53489
  endpointAuth: passthrough ? currentConfig.apiKey : void 0,
@@ -52804,7 +53531,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
52804
53531
  await tunnelGateway.stop();
52805
53532
  tunnelGateway = null;
52806
53533
  }
52807
- const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join54(repoRoot, ".oa") });
53534
+ const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join57(repoRoot, ".oa") });
52808
53535
  newTunnel.on("stats", (stats) => {
52809
53536
  statusBar.setExposeStatus({
52810
53537
  status: stats.status,
@@ -53066,7 +53793,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
53066
53793
  }
53067
53794
  },
53068
53795
  destroyProject() {
53069
- const oaPath = join54(repoRoot, OA_DIR);
53796
+ const oaPath = join57(repoRoot, OA_DIR);
53070
53797
  if (existsSync43(oaPath)) {
53071
53798
  try {
53072
53799
  rmSync2(oaPath, { recursive: true, force: true });
@@ -53999,9 +54726,9 @@ var init_run = __esm({
53999
54726
  // packages/indexer/dist/codebase-indexer.js
54000
54727
  import { glob } from "glob";
54001
54728
  import ignore from "ignore";
54002
- import { readFile as readFile18, stat as stat4 } from "node:fs/promises";
54729
+ import { readFile as readFile21, stat as stat4 } from "node:fs/promises";
54003
54730
  import { createHash as createHash4 } from "node:crypto";
54004
- import { join as join55, 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";
54005
54732
  var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
54006
54733
  var init_codebase_indexer = __esm({
54007
54734
  "packages/indexer/dist/codebase-indexer.js"() {
@@ -54045,7 +54772,7 @@ var init_codebase_indexer = __esm({
54045
54772
  const ig = ignore.default();
54046
54773
  if (this.config.respectGitignore) {
54047
54774
  try {
54048
- const gitignoreContent = await readFile18(join55(this.config.rootDir, ".gitignore"), "utf-8");
54775
+ const gitignoreContent = await readFile21(join58(this.config.rootDir, ".gitignore"), "utf-8");
54049
54776
  ig.add(gitignoreContent);
54050
54777
  } catch {
54051
54778
  }
@@ -54060,12 +54787,12 @@ var init_codebase_indexer = __esm({
54060
54787
  for (const relativePath of files) {
54061
54788
  if (ig.ignores(relativePath))
54062
54789
  continue;
54063
- const fullPath = join55(this.config.rootDir, relativePath);
54790
+ const fullPath = join58(this.config.rootDir, relativePath);
54064
54791
  try {
54065
54792
  const fileStat = await stat4(fullPath);
54066
54793
  if (fileStat.size > this.config.maxFileSize)
54067
54794
  continue;
54068
- const content = await readFile18(fullPath);
54795
+ const content = await readFile21(fullPath);
54069
54796
  const hash = createHash4("sha256").update(content).digest("hex");
54070
54797
  const ext = extname11(relativePath);
54071
54798
  indexed.push({
@@ -54106,7 +54833,7 @@ var init_codebase_indexer = __esm({
54106
54833
  if (!child) {
54107
54834
  child = {
54108
54835
  name: part,
54109
- path: join55(current.path, part),
54836
+ path: join58(current.path, part),
54110
54837
  type: "directory",
54111
54838
  children: []
54112
54839
  };
@@ -54447,7 +55174,7 @@ var config_exports = {};
54447
55174
  __export(config_exports, {
54448
55175
  configCommand: () => configCommand
54449
55176
  });
54450
- import { join as join56, resolve as resolve31 } from "node:path";
55177
+ import { join as join59, resolve as resolve31 } from "node:path";
54451
55178
  import { homedir as homedir14 } from "node:os";
54452
55179
  import { cwd as cwd3 } from "node:process";
54453
55180
  function redactIfSensitive(key, value) {
@@ -54530,7 +55257,7 @@ function handleShow(opts, config) {
54530
55257
  }
54531
55258
  }
54532
55259
  printSection("Config File");
54533
- printInfo(`~/.open-agents/config.json (${join56(homedir14(), ".open-agents", "config.json")})`);
55260
+ printInfo(`~/.open-agents/config.json (${join59(homedir14(), ".open-agents", "config.json")})`);
54534
55261
  printSection("Priority Chain");
54535
55262
  printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
54536
55263
  printInfo(" 2. Project .oa/settings.json (--local)");
@@ -54569,7 +55296,7 @@ function handleSet(opts, _config) {
54569
55296
  const coerced = coerceForSettings(key, value);
54570
55297
  saveProjectSettings(repoRoot, { [key]: coerced });
54571
55298
  printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value)}`);
54572
- printInfo(`Saved to ${join56(repoRoot, ".oa", "settings.json")}`);
55299
+ printInfo(`Saved to ${join59(repoRoot, ".oa", "settings.json")}`);
54573
55300
  printInfo("This override applies only when running in this workspace.");
54574
55301
  } catch (err) {
54575
55302
  printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
@@ -54828,7 +55555,7 @@ __export(eval_exports, {
54828
55555
  });
54829
55556
  import { tmpdir as tmpdir10 } from "node:os";
54830
55557
  import { mkdirSync as mkdirSync20, writeFileSync as writeFileSync19 } from "node:fs";
54831
- import { join as join57 } from "node:path";
55558
+ import { join as join60 } from "node:path";
54832
55559
  async function evalCommand(opts, config) {
54833
55560
  const suiteName = opts.suite ?? "basic";
54834
55561
  const suite = SUITES[suiteName];
@@ -54953,9 +55680,9 @@ async function evalCommand(opts, config) {
54953
55680
  process.exit(failed > 0 ? 1 : 0);
54954
55681
  }
54955
55682
  function createTempEvalRepo() {
54956
- const dir = join57(tmpdir10(), `open-agents-eval-${Date.now()}`);
55683
+ const dir = join60(tmpdir10(), `open-agents-eval-${Date.now()}`);
54957
55684
  mkdirSync20(dir, { recursive: true });
54958
- writeFileSync19(join57(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");
54959
55686
  return dir;
54960
55687
  }
54961
55688
  var BASIC_SUITE, FULL_SUITE, SUITES;
@@ -55015,7 +55742,7 @@ init_updater();
55015
55742
  import { parseArgs as nodeParseArgs2 } from "node:util";
55016
55743
  import { createRequire as createRequire3 } from "node:module";
55017
55744
  import { fileURLToPath as fileURLToPath13 } from "node:url";
55018
- import { dirname as dirname19, join as join58 } from "node:path";
55745
+ import { dirname as dirname19, join as join61 } from "node:path";
55019
55746
 
55020
55747
  // packages/cli/dist/cli.js
55021
55748
  import { createInterface } from "node:readline";
@@ -55122,7 +55849,7 @@ init_output();
55122
55849
  function getVersion4() {
55123
55850
  try {
55124
55851
  const require2 = createRequire3(import.meta.url);
55125
- const pkgPath = join58(dirname19(fileURLToPath13(import.meta.url)), "..", "package.json");
55852
+ const pkgPath = join61(dirname19(fileURLToPath13(import.meta.url)), "..", "package.json");
55126
55853
  const pkg = require2(pkgPath);
55127
55854
  return pkg.version;
55128
55855
  } catch {