open-agents-ai 0.32.2 → 0.33.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 +864 -450
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1285,7 +1285,7 @@ ${stdinInput ?? ""}`);
1285
1285
  }
1286
1286
  runCommand(command, timeout, stdinInput) {
1287
1287
  const start = performance.now();
1288
- return new Promise((resolve22) => {
1288
+ return new Promise((resolve23) => {
1289
1289
  const child = spawn("bash", ["-c", command], {
1290
1290
  cwd: this.workingDir,
1291
1291
  env: {
@@ -1313,7 +1313,7 @@ ${stdinInput ?? ""}`);
1313
1313
  clearTimeout(timer);
1314
1314
  if (exitFlushTimer)
1315
1315
  clearTimeout(exitFlushTimer);
1316
- resolve22(result);
1316
+ resolve23(result);
1317
1317
  };
1318
1318
  const timer = setTimeout(() => {
1319
1319
  killed = true;
@@ -2317,7 +2317,7 @@ Meta: ${metaKeys.map((k) => `${k}="${meta[k]?.slice(0, 80)}"`).join(", ")}`);
2317
2317
  return null;
2318
2318
  }
2319
2319
  runProcess(cmd, args, timeoutMs) {
2320
- return new Promise((resolve22, reject) => {
2320
+ return new Promise((resolve23, reject) => {
2321
2321
  const proc = execFile3(cmd, args, {
2322
2322
  timeout: timeoutMs,
2323
2323
  maxBuffer: 10 * 1024 * 1024,
@@ -2327,7 +2327,7 @@ Meta: ${metaKeys.map((k) => `${k}="${meta[k]?.slice(0, 80)}"`).join(", ")}`);
2327
2327
  reject(new Error(`Process timeout after ${timeoutMs}ms`));
2328
2328
  return;
2329
2329
  }
2330
- resolve22({
2330
+ resolve23({
2331
2331
  stdout: String(stdout),
2332
2332
  stderr: String(stderr),
2333
2333
  exitCode: error ? error.code ?? 1 : 0
@@ -2639,9 +2639,402 @@ var init_memory_write = __esm({
2639
2639
  }
2640
2640
  });
2641
2641
 
2642
+ // packages/execution/dist/tools/memory-search.js
2643
+ import { readFile as readFile5, readdir } from "node:fs/promises";
2644
+ import { resolve as resolve8, join as join6, basename } from "node:path";
2645
+ import { existsSync as existsSync4 } from "node:fs";
2646
+ import { homedir as homedir3 } from "node:os";
2647
+ function termMatchScore(query, document) {
2648
+ const queryTerms = tokenize(query);
2649
+ const docTerms = tokenize(document);
2650
+ if (queryTerms.length === 0 || docTerms.length === 0)
2651
+ return 0;
2652
+ const docSet = new Set(docTerms);
2653
+ const docBigrams = /* @__PURE__ */ new Set();
2654
+ for (let i = 0; i < docTerms.length - 1; i++) {
2655
+ docBigrams.add(`${docTerms[i]} ${docTerms[i + 1]}`);
2656
+ }
2657
+ let matchedTerms = 0;
2658
+ let matchedBigrams = 0;
2659
+ let totalWeight = 0;
2660
+ for (const term of queryTerms) {
2661
+ totalWeight += 1;
2662
+ if (docSet.has(term)) {
2663
+ matchedTerms += 1;
2664
+ } else if ([...docSet].some((d) => d.startsWith(term) || term.startsWith(d))) {
2665
+ matchedTerms += 0.5;
2666
+ }
2667
+ }
2668
+ for (let i = 0; i < queryTerms.length - 1; i++) {
2669
+ const bigram = `${queryTerms[i]} ${queryTerms[i + 1]}`;
2670
+ totalWeight += 1;
2671
+ if (docBigrams.has(bigram)) {
2672
+ matchedBigrams += 1;
2673
+ }
2674
+ }
2675
+ return totalWeight > 0 ? (matchedTerms + matchedBigrams * 2) / (totalWeight * 2) : 0;
2676
+ }
2677
+ function tokenize(text) {
2678
+ const STOP_WORDS2 = /* @__PURE__ */ new Set([
2679
+ "a",
2680
+ "an",
2681
+ "the",
2682
+ "is",
2683
+ "are",
2684
+ "was",
2685
+ "were",
2686
+ "be",
2687
+ "been",
2688
+ "being",
2689
+ "have",
2690
+ "has",
2691
+ "had",
2692
+ "do",
2693
+ "does",
2694
+ "did",
2695
+ "will",
2696
+ "would",
2697
+ "could",
2698
+ "should",
2699
+ "may",
2700
+ "might",
2701
+ "can",
2702
+ "shall",
2703
+ "to",
2704
+ "of",
2705
+ "in",
2706
+ "for",
2707
+ "on",
2708
+ "with",
2709
+ "at",
2710
+ "by",
2711
+ "from",
2712
+ "as",
2713
+ "into",
2714
+ "through",
2715
+ "during",
2716
+ "before",
2717
+ "after",
2718
+ "above",
2719
+ "below",
2720
+ "and",
2721
+ "but",
2722
+ "or",
2723
+ "not",
2724
+ "no",
2725
+ "if",
2726
+ "then",
2727
+ "else",
2728
+ "when",
2729
+ "up",
2730
+ "out",
2731
+ "so",
2732
+ "than",
2733
+ "too",
2734
+ "very",
2735
+ "just",
2736
+ "about",
2737
+ "this",
2738
+ "that",
2739
+ "these",
2740
+ "those",
2741
+ "it",
2742
+ "its"
2743
+ ]);
2744
+ return text.toLowerCase().replace(/[^a-z0-9_\-\.]+/g, " ").split(/\s+/).filter((t) => t.length > 1 && !STOP_WORDS2.has(t));
2745
+ }
2746
+ var MemorySearchTool;
2747
+ var init_memory_search = __esm({
2748
+ "packages/execution/dist/tools/memory-search.js"() {
2749
+ "use strict";
2750
+ MemorySearchTool = class {
2751
+ name = "memory_search";
2752
+ description = "Search across all memory entries by relevance. Unlike memory_read (exact topic+key), this finds relevant memories using text matching. Use when you don't know the exact topic or key, or want to find all memories related to a concept.";
2753
+ parameters = {
2754
+ type: "object",
2755
+ properties: {
2756
+ query: {
2757
+ type: "string",
2758
+ description: "Natural language search query (e.g. 'authentication bug fix', 'React patterns')"
2759
+ },
2760
+ max_results: {
2761
+ type: "number",
2762
+ description: "Maximum number of results to return (default: 10)"
2763
+ }
2764
+ },
2765
+ required: ["query"]
2766
+ };
2767
+ workingDir;
2768
+ constructor(workingDir) {
2769
+ this.workingDir = workingDir;
2770
+ }
2771
+ async execute(args) {
2772
+ const query = args["query"];
2773
+ const maxResults = args["max_results"] ?? 10;
2774
+ const start = performance.now();
2775
+ try {
2776
+ const allEntries = await this.loadAllMemories();
2777
+ if (allEntries.length === 0) {
2778
+ return {
2779
+ success: true,
2780
+ output: "No memory entries found. Use memory_write to store insights.",
2781
+ durationMs: performance.now() - start
2782
+ };
2783
+ }
2784
+ const scored = allEntries.map((entry) => ({
2785
+ ...entry,
2786
+ score: termMatchScore(query, `${entry.topic} ${entry.key} ${entry.value}`)
2787
+ }));
2788
+ const results = scored.filter((e) => e.score > 0).sort((a, b) => b.score - a.score).slice(0, maxResults);
2789
+ if (results.length === 0) {
2790
+ return {
2791
+ success: true,
2792
+ output: `No memories matched query: "${query}"
2793
+
2794
+ Try broader terms or use memory_read with a specific topic.`,
2795
+ durationMs: performance.now() - start
2796
+ };
2797
+ }
2798
+ const lines = [
2799
+ `Found ${results.length} relevant memories for: "${query}"
2800
+ `
2801
+ ];
2802
+ for (const r of results) {
2803
+ const score = Math.round(r.score * 100);
2804
+ lines.push(`[${r.topic}/${r.key}] (relevance: ${score}%)`);
2805
+ lines.push(` ${r.value.slice(0, 300)}${r.value.length > 300 ? "..." : ""}`);
2806
+ if (r.timestamp)
2807
+ lines.push(` (saved: ${r.timestamp.split("T")[0]})`);
2808
+ lines.push("");
2809
+ }
2810
+ return {
2811
+ success: true,
2812
+ output: lines.join("\n"),
2813
+ durationMs: performance.now() - start
2814
+ };
2815
+ } catch (error) {
2816
+ return {
2817
+ success: false,
2818
+ output: "",
2819
+ error: error instanceof Error ? error.message : String(error),
2820
+ durationMs: performance.now() - start
2821
+ };
2822
+ }
2823
+ }
2824
+ /**
2825
+ * Load all memory entries from all memory directories.
2826
+ */
2827
+ async loadAllMemories() {
2828
+ const entries = [];
2829
+ const dirs = [
2830
+ resolve8(this.workingDir, ".oa", "memory"),
2831
+ resolve8(this.workingDir, ".open-agents", "memory"),
2832
+ resolve8(homedir3(), ".open-agents", "memory")
2833
+ ];
2834
+ const seen = /* @__PURE__ */ new Set();
2835
+ for (const dir of dirs) {
2836
+ if (!existsSync4(dir))
2837
+ continue;
2838
+ try {
2839
+ const files = await readdir(dir);
2840
+ for (const file of files.filter((f) => f.endsWith(".json"))) {
2841
+ try {
2842
+ const raw = await readFile5(join6(dir, file), "utf-8");
2843
+ const data = JSON.parse(raw);
2844
+ const topic = basename(file, ".json");
2845
+ for (const [key, entry] of Object.entries(data)) {
2846
+ const dedup = `${topic}:${key}`;
2847
+ if (seen.has(dedup))
2848
+ continue;
2849
+ seen.add(dedup);
2850
+ if (entry?.value) {
2851
+ entries.push({
2852
+ topic,
2853
+ key,
2854
+ value: String(entry.value),
2855
+ timestamp: entry.timestamp,
2856
+ score: 0
2857
+ });
2858
+ }
2859
+ }
2860
+ } catch {
2861
+ }
2862
+ }
2863
+ } catch {
2864
+ }
2865
+ }
2866
+ return entries;
2867
+ }
2868
+ };
2869
+ }
2870
+ });
2871
+
2872
+ // packages/execution/dist/tools/explore-tools.js
2873
+ var TOOL_CATALOG, ExploreToolsTool;
2874
+ var init_explore_tools = __esm({
2875
+ "packages/execution/dist/tools/explore-tools.js"() {
2876
+ "use strict";
2877
+ TOOL_CATALOG = {
2878
+ grep_search: "Search file contents with regex patterns",
2879
+ find_files: "Find files by glob pattern (e.g. **/*.ts)",
2880
+ list_directory: "List contents of a directory",
2881
+ web_search: "Search the web via DuckDuckGo",
2882
+ web_fetch: "Fetch and read a web page URL",
2883
+ web_crawl: "Crawl a website following links",
2884
+ memory_read: "Read from persistent memory (exact topic+key)",
2885
+ memory_write: "Store a fact in persistent memory",
2886
+ memory_search: "Search all memories by relevance",
2887
+ batch_edit: "Apply multiple file edits atomically",
2888
+ file_patch: "Apply unified diff patches to files",
2889
+ git_info: "Get git status, branch, recent commits",
2890
+ codebase_map: "Generate overview of project structure",
2891
+ diagnostic: "Run project diagnostics (build, test, lint)",
2892
+ image_read: "Read and describe image contents",
2893
+ screenshot: "Capture a screenshot of the desktop",
2894
+ ocr_image: "Extract text from images via OCR",
2895
+ ocr_pdf: "Extract text from PDF pages via OCR",
2896
+ pdf_to_text: "Convert PDF to plain text",
2897
+ vision: "Describe what's on screen using Moondream",
2898
+ desktop_click: "Click at coordinates on the desktop",
2899
+ desktop_describe: "Describe a region of the desktop",
2900
+ transcribe_file: "Transcribe audio/video files to text",
2901
+ create_tool: "Create a new custom tool from a workflow",
2902
+ manage_tools: "List, inspect, or remove custom tools",
2903
+ skill_list: "List available AIWG skills",
2904
+ skill_execute: "Execute an AIWG skill",
2905
+ structured_file: "Generate structured files (CSV, JSON, MD)",
2906
+ code_sandbox: "Run code in an isolated sandbox",
2907
+ structured_read: "Read structured data files (CSV, JSON)",
2908
+ sub_agent: "Delegate a subtask to a new agent instance",
2909
+ background_run: "Run a shell command in the background",
2910
+ task_status: "Check status of background tasks",
2911
+ task_output: "Read output from a background task",
2912
+ task_stop: "Stop a running background task"
2913
+ };
2914
+ ExploreToolsTool = class {
2915
+ name = "explore_tools";
2916
+ description = "Discover and enable additional tools. Call with no arguments to see all available tools. Call with enable='tool_name' to unlock a tool for this session. Call with search='query' to find tools matching your need.";
2917
+ parameters = {
2918
+ type: "object",
2919
+ properties: {
2920
+ enable: {
2921
+ type: "string",
2922
+ description: "Tool name to unlock for this session (omit to list available)"
2923
+ },
2924
+ search: {
2925
+ type: "string",
2926
+ description: "Search query to find relevant tools (e.g. 'search files', 'web')"
2927
+ }
2928
+ },
2929
+ required: []
2930
+ };
2931
+ /** Set of currently unlocked tool names (managed by the runner) */
2932
+ unlockedTools = /* @__PURE__ */ new Set();
2933
+ /** Callback to signal tool unlock to the runner */
2934
+ onUnlock;
2935
+ /**
2936
+ * Set the unlock callback. The runner calls this to wire up the unlock mechanism.
2937
+ * The callback should return true if the tool was successfully unlocked.
2938
+ */
2939
+ setUnlockCallback(cb) {
2940
+ this.onUnlock = cb;
2941
+ }
2942
+ /** Mark a tool as already unlocked (called by runner during init) */
2943
+ markUnlocked(name) {
2944
+ this.unlockedTools.add(name);
2945
+ }
2946
+ async execute(args) {
2947
+ const start = performance.now();
2948
+ const enableName = args["enable"]?.trim();
2949
+ const searchQuery = args["search"]?.trim();
2950
+ if (enableName) {
2951
+ if (!(enableName in TOOL_CATALOG)) {
2952
+ return {
2953
+ success: false,
2954
+ output: "",
2955
+ error: `Unknown tool '${enableName}'. Call explore_tools() to see available tools.`,
2956
+ durationMs: performance.now() - start
2957
+ };
2958
+ }
2959
+ if (this.unlockedTools.has(enableName)) {
2960
+ return {
2961
+ success: true,
2962
+ output: `Tool '${enableName}' is already unlocked. You can use it now.`,
2963
+ durationMs: performance.now() - start
2964
+ };
2965
+ }
2966
+ if (this.onUnlock) {
2967
+ const success = this.onUnlock(enableName);
2968
+ if (success) {
2969
+ this.unlockedTools.add(enableName);
2970
+ return {
2971
+ success: true,
2972
+ output: `Tool '${enableName}' is now unlocked and available. You can use it in your next response.`,
2973
+ durationMs: performance.now() - start
2974
+ };
2975
+ }
2976
+ }
2977
+ return {
2978
+ success: true,
2979
+ output: `UNLOCK_TOOL:${enableName}`,
2980
+ durationMs: performance.now() - start
2981
+ };
2982
+ }
2983
+ if (searchQuery) {
2984
+ const terms = searchQuery.toLowerCase().split(/\s+/);
2985
+ const matches = [];
2986
+ for (const [name, desc] of Object.entries(TOOL_CATALOG)) {
2987
+ const text = `${name} ${desc}`.toLowerCase();
2988
+ const score = terms.reduce((s, t) => s + (text.includes(t) ? 1 : 0), 0);
2989
+ if (score > 0)
2990
+ matches.push([name, desc, score]);
2991
+ }
2992
+ matches.sort((a, b) => b[2] - a[2]);
2993
+ if (matches.length === 0) {
2994
+ return {
2995
+ success: true,
2996
+ output: `No tools match "${searchQuery}". Try broader terms or call explore_tools() to list all.`,
2997
+ durationMs: performance.now() - start
2998
+ };
2999
+ }
3000
+ const lines2 = [`Tools matching "${searchQuery}":
3001
+ `];
3002
+ for (const [name, desc] of matches.slice(0, 8)) {
3003
+ const status = this.unlockedTools.has(name) ? " [unlocked]" : "";
3004
+ lines2.push(` ${name}: ${desc}${status}`);
3005
+ }
3006
+ lines2.push(`
3007
+ Use explore_tools(enable='name') to unlock a tool.`);
3008
+ return {
3009
+ success: true,
3010
+ output: lines2.join("\n"),
3011
+ durationMs: performance.now() - start
3012
+ };
3013
+ }
3014
+ const lines = ["Available tools (call explore_tools with enable='name' to unlock):\n"];
3015
+ for (const [name, desc] of Object.entries(TOOL_CATALOG)) {
3016
+ const status = this.unlockedTools.has(name) ? " [unlocked]" : "";
3017
+ lines.push(` ${name}: ${desc}${status}`);
3018
+ }
3019
+ lines.push(`
3020
+ ${this.unlockedTools.size} of ${Object.keys(TOOL_CATALOG).length} tools currently unlocked.`);
3021
+ lines.push(`
3022
+ Examples:`);
3023
+ lines.push(` explore_tools({enable: 'grep_search'})`);
3024
+ lines.push(` explore_tools({search: 'search files'})`);
3025
+ return {
3026
+ success: true,
3027
+ output: lines.join("\n"),
3028
+ durationMs: performance.now() - start
3029
+ };
3030
+ }
3031
+ };
3032
+ }
3033
+ });
3034
+
2642
3035
  // packages/execution/dist/tools/list-directory.js
2643
3036
  import { readdirSync, statSync } from "node:fs";
2644
- import { resolve as resolve8, join as join6 } from "node:path";
3037
+ import { resolve as resolve9, join as join7 } from "node:path";
2645
3038
  var EXCLUDED, MAX_ENTRIES, ListDirectoryTool;
2646
3039
  var init_list_directory = __esm({
2647
3040
  "packages/execution/dist/tools/list-directory.js"() {
@@ -2669,7 +3062,7 @@ var init_list_directory = __esm({
2669
3062
  const dirPath = args["path"] ?? ".";
2670
3063
  const start = performance.now();
2671
3064
  try {
2672
- const fullPath = resolve8(this.workingDir, dirPath);
3065
+ const fullPath = resolve9(this.workingDir, dirPath);
2673
3066
  const entries = readdirSync(fullPath, { withFileTypes: true });
2674
3067
  const visible = entries.filter((e) => !EXCLUDED.has(e.name));
2675
3068
  const limited = visible.slice(0, MAX_ENTRIES);
@@ -2680,7 +3073,7 @@ var init_list_directory = __esm({
2680
3073
  }
2681
3074
  let size = 0;
2682
3075
  try {
2683
- size = statSync(join6(fullPath, entry.name)).size;
3076
+ size = statSync(join7(fullPath, entry.name)).size;
2684
3077
  } catch {
2685
3078
  }
2686
3079
  return `${prefix} ${entry.name} ${size}`;
@@ -2783,8 +3176,8 @@ ${output}`,
2783
3176
 
2784
3177
  // packages/execution/dist/tools/aiwg-health.js
2785
3178
  import { execSync as execSync2 } from "node:child_process";
2786
- import { existsSync as existsSync4, readdirSync as readdirSync2, readFileSync as readFileSync3, statSync as statSync2 } from "node:fs";
2787
- import { join as join7 } from "node:path";
3179
+ import { existsSync as existsSync5, readdirSync as readdirSync2, readFileSync as readFileSync3, statSync as statSync2 } from "node:fs";
3180
+ import { join as join8 } from "node:path";
2788
3181
  var AiwgHealthTool;
2789
3182
  var init_aiwg_health = __esm({
2790
3183
  "packages/execution/dist/tools/aiwg-health.js"() {
@@ -2816,8 +3209,8 @@ var init_aiwg_health = __esm({
2816
3209
  const detailed = args["detailed"] ?? false;
2817
3210
  const report = [];
2818
3211
  report.push("# SDLC Health Report\n");
2819
- const aiwgDir = join7(projectDir, ".aiwg");
2820
- const hasAiwg = existsSync4(aiwgDir);
3212
+ const aiwgDir = join8(projectDir, ".aiwg");
3213
+ const hasAiwg = existsSync5(aiwgDir);
2821
3214
  report.push(`## AIWG Framework: ${hasAiwg ? "DEPLOYED" : "NOT DEPLOYED"}`);
2822
3215
  if (hasAiwg) {
2823
3216
  const aiwgArtifacts = this.scanAiwgArtifacts(aiwgDir);
@@ -2885,7 +3278,7 @@ var init_aiwg_health = __esm({
2885
3278
  const entries = readdirSync2(aiwgDir, { withFileTypes: true });
2886
3279
  for (const entry of entries) {
2887
3280
  if (entry.isDirectory()) {
2888
- const subDir = join7(aiwgDir, entry.name);
3281
+ const subDir = join8(aiwgDir, entry.name);
2889
3282
  try {
2890
3283
  const files = readdirSync2(subDir).filter((f) => !f.startsWith("."));
2891
3284
  categories[entry.name] = files.length;
@@ -2899,7 +3292,7 @@ var init_aiwg_health = __esm({
2899
3292
  return { total, categories };
2900
3293
  }
2901
3294
  analyzeStructure(dir) {
2902
- const has = (p) => existsSync4(join7(dir, p));
3295
+ const has = (p) => existsSync5(join8(dir, p));
2903
3296
  return {
2904
3297
  packageManager: has("pnpm-lock.yaml") ? "pnpm" : has("yarn.lock") ? "yarn" : has("package-lock.json") ? "npm" : has("Cargo.toml") ? "cargo" : has("go.mod") ? "go" : "unknown",
2905
3298
  language: has("tsconfig.json") ? "TypeScript" : has("package.json") ? "JavaScript" : has("Cargo.toml") ? "Rust" : has("go.mod") ? "Go" : has("pyproject.toml") || has("setup.py") ? "Python" : "unknown",
@@ -2912,8 +3305,8 @@ var init_aiwg_health = __esm({
2912
3305
  }
2913
3306
  analyzeDocumentation(dir) {
2914
3307
  let readmeQuality = "missing";
2915
- const readmePath = join7(dir, "README.md");
2916
- if (existsSync4(readmePath)) {
3308
+ const readmePath = join8(dir, "README.md");
3309
+ if (existsSync5(readmePath)) {
2917
3310
  try {
2918
3311
  const content = readFileSync3(readmePath, "utf8");
2919
3312
  const len = content.length;
@@ -2922,12 +3315,12 @@ var init_aiwg_health = __esm({
2922
3315
  readmeQuality = "unreadable";
2923
3316
  }
2924
3317
  }
2925
- const has = (p) => existsSync4(join7(dir, p));
3318
+ const has = (p) => existsSync5(join8(dir, p));
2926
3319
  const hasApiDocs = has("docs/api") || has("api-docs") || has("swagger.json") || has("openapi.yaml");
2927
3320
  const hasArchDocs = has("docs/architecture") || has(".aiwg/architecture") || has("ARCHITECTURE.md");
2928
3321
  let docFileCount = 0;
2929
- const docsDir = join7(dir, "docs");
2930
- if (existsSync4(docsDir)) {
3322
+ const docsDir = join8(dir, "docs");
3323
+ if (existsSync5(docsDir)) {
2931
3324
  try {
2932
3325
  docFileCount = this.countFiles(docsDir);
2933
3326
  } catch {
@@ -2943,7 +3336,7 @@ var init_aiwg_health = __esm({
2943
3336
  if (entry.isFile())
2944
3337
  count++;
2945
3338
  else if (entry.isDirectory() && entry.name !== "node_modules") {
2946
- count += this.countFiles(join7(dir, entry.name));
3339
+ count += this.countFiles(join8(dir, entry.name));
2947
3340
  }
2948
3341
  }
2949
3342
  } catch {
@@ -3079,8 +3472,8 @@ var init_aiwg_workflow = __esm({
3079
3472
  });
3080
3473
 
3081
3474
  // packages/execution/dist/tools/batch-edit.js
3082
- import { readFile as readFile5, writeFile as writeFile4 } from "node:fs/promises";
3083
- import { resolve as resolve9 } from "node:path";
3475
+ import { readFile as readFile6, writeFile as writeFile4 } from "node:fs/promises";
3476
+ import { resolve as resolve10 } from "node:path";
3084
3477
  function countOccurrences2(haystack, needle) {
3085
3478
  let count = 0;
3086
3479
  let pos = 0;
@@ -3146,7 +3539,7 @@ var init_batch_edit = __esm({
3146
3539
  }
3147
3540
  const byFile = /* @__PURE__ */ new Map();
3148
3541
  for (const edit of edits) {
3149
- const fullPath = resolve9(this.workingDir, edit.path);
3542
+ const fullPath = resolve10(this.workingDir, edit.path);
3150
3543
  if (!byFile.has(fullPath))
3151
3544
  byFile.set(fullPath, []);
3152
3545
  byFile.get(fullPath).push({
@@ -3161,7 +3554,7 @@ var init_batch_edit = __esm({
3161
3554
  let failCount = 0;
3162
3555
  for (const [fullPath, fileEdits] of byFile) {
3163
3556
  try {
3164
- let content = await readFile5(fullPath, "utf-8");
3557
+ let content = await readFile6(fullPath, "utf-8");
3165
3558
  for (const edit of fileEdits) {
3166
3559
  const occurrences = countOccurrences2(content, edit.old_string);
3167
3560
  if (occurrences === 0) {
@@ -3205,8 +3598,8 @@ ${results.join("\n")}`,
3205
3598
  });
3206
3599
 
3207
3600
  // packages/execution/dist/tools/file-patch.js
3208
- import { readFile as readFile6, writeFile as writeFile5, copyFile } from "node:fs/promises";
3209
- import { resolve as resolve10 } from "node:path";
3601
+ import { readFile as readFile7, writeFile as writeFile5, copyFile } from "node:fs/promises";
3602
+ import { resolve as resolve11 } from "node:path";
3210
3603
  var FilePatchTool;
3211
3604
  var init_file_patch = __esm({
3212
3605
  "packages/execution/dist/tools/file-patch.js"() {
@@ -3274,8 +3667,8 @@ var init_file_patch = __esm({
3274
3667
  durationMs: performance.now() - start
3275
3668
  };
3276
3669
  }
3277
- const fullPath = resolve10(this.workingDir, filePath);
3278
- const content = await readFile6(fullPath, "utf-8");
3670
+ const fullPath = resolve11(this.workingDir, filePath);
3671
+ const content = await readFile7(fullPath, "utf-8");
3279
3672
  const lines = content.split("\n");
3280
3673
  const totalLines = lines.length;
3281
3674
  if (startLine > totalLines) {
@@ -3377,8 +3770,8 @@ ${diff}`,
3377
3770
  });
3378
3771
 
3379
3772
  // packages/execution/dist/tools/codebase-map.js
3380
- import { readdirSync as readdirSync3, statSync as statSync3, readFileSync as readFileSync4, existsSync as existsSync5 } from "node:fs";
3381
- import { join as join8, relative, extname } from "node:path";
3773
+ import { readdirSync as readdirSync3, statSync as statSync3, readFileSync as readFileSync4, existsSync as existsSync6 } from "node:fs";
3774
+ import { join as join9, relative, extname } from "node:path";
3382
3775
  var CodebaseMapTool;
3383
3776
  var init_codebase_map = __esm({
3384
3777
  "packages/execution/dist/tools/codebase-map.js"() {
@@ -3462,8 +3855,8 @@ var init_codebase_map = __esm({
3462
3855
  }
3463
3856
  detectProjectInfo(dir) {
3464
3857
  const info = {};
3465
- const pkgPath = join8(dir, "package.json");
3466
- if (existsSync5(pkgPath)) {
3858
+ const pkgPath = join9(dir, "package.json");
3859
+ if (existsSync6(pkgPath)) {
3467
3860
  try {
3468
3861
  const pkg = JSON.parse(readFileSync4(pkgPath, "utf8"));
3469
3862
  info.name = pkg.name;
@@ -3471,15 +3864,15 @@ var init_codebase_map = __esm({
3471
3864
  } catch {
3472
3865
  }
3473
3866
  }
3474
- if (existsSync5(join8(dir, "tsconfig.json")))
3867
+ if (existsSync6(join9(dir, "tsconfig.json")))
3475
3868
  info.language = "TypeScript";
3476
- else if (existsSync5(join8(dir, "package.json")))
3869
+ else if (existsSync6(join9(dir, "package.json")))
3477
3870
  info.language = "JavaScript";
3478
- else if (existsSync5(join8(dir, "Cargo.toml")))
3871
+ else if (existsSync6(join9(dir, "Cargo.toml")))
3479
3872
  info.language = "Rust";
3480
- else if (existsSync5(join8(dir, "go.mod")))
3873
+ else if (existsSync6(join9(dir, "go.mod")))
3481
3874
  info.language = "Go";
3482
- else if (existsSync5(join8(dir, "pyproject.toml")))
3875
+ else if (existsSync6(join9(dir, "pyproject.toml")))
3483
3876
  info.language = "Python";
3484
3877
  return info;
3485
3878
  }
@@ -3507,7 +3900,7 @@ var init_codebase_map = __esm({
3507
3900
  ];
3508
3901
  const found = [];
3509
3902
  for (const kf of KEY_FILES) {
3510
- if (existsSync5(join8(dir, kf))) {
3903
+ if (existsSync6(join9(dir, kf))) {
3511
3904
  found.push(kf);
3512
3905
  }
3513
3906
  }
@@ -3545,7 +3938,7 @@ var init_codebase_map = __esm({
3545
3938
  const dirs = entries.filter((e) => e.isDirectory() && !this.SKIP_DIRS.has(e.name));
3546
3939
  const files = entries.filter((e) => e.isFile());
3547
3940
  for (const d of dirs) {
3548
- const subPath = join8(dir, d.name);
3941
+ const subPath = join9(dir, d.name);
3549
3942
  const fileCount = this.countFilesShallow(subPath);
3550
3943
  lines.push(`${indent}${d.name}/ (${fileCount} files)`);
3551
3944
  const subtree = this.buildTree(subPath, rootDir, depth + 1, maxDepth, showFiles);
@@ -3586,7 +3979,7 @@ var init_codebase_map = __esm({
3586
3979
  if (lang)
3587
3980
  counts.set(lang, (counts.get(lang) ?? 0) + 1);
3588
3981
  } else if (entry.isDirectory() && !this.SKIP_DIRS.has(entry.name) && !entry.name.startsWith(".")) {
3589
- const sub = this.countLanguages(join8(dir, entry.name), depth + 1, maxDepth);
3982
+ const sub = this.countLanguages(join9(dir, entry.name), depth + 1, maxDepth);
3590
3983
  for (const [lang, count] of sub) {
3591
3984
  counts.set(lang, (counts.get(lang) ?? 0) + count);
3592
3985
  }
@@ -3644,13 +4037,13 @@ var init_codebase_map = __esm({
3644
4037
  if (entry.isFile()) {
3645
4038
  files++;
3646
4039
  try {
3647
- const size = statSync3(join8(dir, entry.name)).size;
4040
+ const size = statSync3(join9(dir, entry.name)).size;
3648
4041
  estimatedLines += Math.ceil(size / 40);
3649
4042
  } catch {
3650
4043
  }
3651
4044
  } else if (entry.isDirectory() && !this.SKIP_DIRS.has(entry.name)) {
3652
4045
  dirs++;
3653
- const sub = this.countStats(join8(dir, entry.name), depth + 1, maxDepth);
4046
+ const sub = this.countStats(join9(dir, entry.name), depth + 1, maxDepth);
3654
4047
  files += sub.files;
3655
4048
  dirs += sub.dirs;
3656
4049
  estimatedLines += sub.estimatedLines;
@@ -3666,8 +4059,8 @@ var init_codebase_map = __esm({
3666
4059
 
3667
4060
  // packages/execution/dist/tools/diagnostic.js
3668
4061
  import { execSync as execSync4 } from "node:child_process";
3669
- import { existsSync as existsSync6, readFileSync as readFileSync5 } from "node:fs";
3670
- import { join as join9 } from "node:path";
4062
+ import { existsSync as existsSync7, readFileSync as readFileSync5 } from "node:fs";
4063
+ import { join as join10 } from "node:path";
3671
4064
  var DiagnosticTool;
3672
4065
  var init_diagnostic = __esm({
3673
4066
  "packages/execution/dist/tools/diagnostic.js"() {
@@ -3746,7 +4139,7 @@ var init_diagnostic = __esm({
3746
4139
  }
3747
4140
  detectSteps(dir) {
3748
4141
  const steps = /* @__PURE__ */ new Map();
3749
- const has = (p) => existsSync6(join9(dir, p));
4142
+ const has = (p) => existsSync7(join10(dir, p));
3750
4143
  if (has(".eslintrc.json") || has(".eslintrc.js") || has(".eslintrc.yml") || has("eslint.config.js") || has("eslint.config.mjs")) {
3751
4144
  steps.set("lint", "npx eslint . --max-warnings 0");
3752
4145
  } else if (has("biome.json") || has("biome.jsonc")) {
@@ -3761,7 +4154,7 @@ var init_diagnostic = __esm({
3761
4154
  steps.set("test", "npx jest --passWithNoTests");
3762
4155
  } else {
3763
4156
  try {
3764
- const pkg = JSON.parse(readFileSync5(join9(dir, "package.json"), "utf8"));
4157
+ const pkg = JSON.parse(readFileSync5(join10(dir, "package.json"), "utf8"));
3765
4158
  if (pkg.scripts?.test && pkg.scripts.test !== 'echo "Error: no test specified" && exit 1') {
3766
4159
  steps.set("test", "npm test");
3767
4160
  }
@@ -3769,7 +4162,7 @@ var init_diagnostic = __esm({
3769
4162
  }
3770
4163
  }
3771
4164
  try {
3772
- const pkg = JSON.parse(readFileSync5(join9(dir, "package.json"), "utf8"));
4165
+ const pkg = JSON.parse(readFileSync5(join10(dir, "package.json"), "utf8"));
3773
4166
  if (pkg.scripts?.build) {
3774
4167
  steps.set("build", "npm run build");
3775
4168
  }
@@ -3811,8 +4204,8 @@ ${err.stderr ?? ""}`.trim(),
3811
4204
 
3812
4205
  // packages/execution/dist/tools/git-info.js
3813
4206
  import { execSync as execSync5 } from "node:child_process";
3814
- import { existsSync as existsSync7 } from "node:fs";
3815
- import { join as join10 } from "node:path";
4207
+ import { existsSync as existsSync8 } from "node:fs";
4208
+ import { join as join11 } from "node:path";
3816
4209
  var GitInfoTool;
3817
4210
  var init_git_info = __esm({
3818
4211
  "packages/execution/dist/tools/git-info.js"() {
@@ -3847,7 +4240,7 @@ var init_git_info = __esm({
3847
4240
  const repoDir = args["path"] || this.workingDir;
3848
4241
  const showDiff = args["show_diff"] ?? false;
3849
4242
  const logCount = args["log_count"] ?? 5;
3850
- if (!existsSync7(join10(repoDir, ".git"))) {
4243
+ if (!existsSync8(join11(repoDir, ".git"))) {
3851
4244
  return {
3852
4245
  success: false,
3853
4246
  output: "",
@@ -4421,11 +4814,11 @@ var init_system_deps = __esm({
4421
4814
  });
4422
4815
 
4423
4816
  // packages/execution/dist/tools/image.js
4424
- import { existsSync as existsSync8, readFileSync as readFileSync6, statSync as statSync4 } from "node:fs";
4425
- import { resolve as resolve11, extname as extname2, basename } from "node:path";
4817
+ import { existsSync as existsSync9, readFileSync as readFileSync6, statSync as statSync4 } from "node:fs";
4818
+ import { resolve as resolve12, extname as extname2, basename as basename2 } from "node:path";
4426
4819
  import { execSync as execSync7 } from "node:child_process";
4427
4820
  import { tmpdir } from "node:os";
4428
- import { join as join11 } from "node:path";
4821
+ import { join as join12 } from "node:path";
4429
4822
  function isImagePath(path) {
4430
4823
  return IMAGE_EXTENSIONS.has(extname2(path).toLowerCase());
4431
4824
  }
@@ -4547,8 +4940,8 @@ var init_image = __esm({
4547
4940
  if (!rawPath) {
4548
4941
  return { success: false, output: "", error: "path is required", durationMs: 0 };
4549
4942
  }
4550
- const fullPath = resolve11(this.workingDir, rawPath);
4551
- if (!existsSync8(fullPath)) {
4943
+ const fullPath = resolve12(this.workingDir, rawPath);
4944
+ if (!existsSync9(fullPath)) {
4552
4945
  return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
4553
4946
  }
4554
4947
  const stat5 = statSync4(fullPath);
@@ -4568,7 +4961,7 @@ var init_image = __esm({
4568
4961
  const dims = getImageDimensions(fullPath);
4569
4962
  const sizeKb = (stat5.size / 1024).toFixed(1);
4570
4963
  const parts = [
4571
- `File: ${basename(fullPath)}`,
4964
+ `File: ${basename2(fullPath)}`,
4572
4965
  `Size: ${sizeKb}KB`,
4573
4966
  `Format: ${mime}`
4574
4967
  ];
@@ -4616,7 +5009,7 @@ ${ocrText}`);
4616
5009
  }
4617
5010
  async execute(args) {
4618
5011
  const start = Date.now();
4619
- const outputPath = args["output_path"] ? resolve11(this.workingDir, String(args["output_path"])) : join11(tmpdir(), `oa-screenshot-${Date.now()}.png`);
5012
+ const outputPath = args["output_path"] ? resolve12(this.workingDir, String(args["output_path"])) : join12(tmpdir(), `oa-screenshot-${Date.now()}.png`);
4620
5013
  const delayMs = typeof args["delay_ms"] === "number" ? args["delay_ms"] : 0;
4621
5014
  const region = String(args["region"] ?? "full");
4622
5015
  if (delayMs > 0) {
@@ -4641,7 +5034,7 @@ ${ocrText}`);
4641
5034
  durationMs: Date.now() - start
4642
5035
  };
4643
5036
  }
4644
- if (!existsSync8(outputPath)) {
5037
+ if (!existsSync9(outputPath)) {
4645
5038
  return { success: false, output: "", error: "Screenshot file not created", durationMs: Date.now() - start };
4646
5039
  }
4647
5040
  const stat5 = statSync4(outputPath);
@@ -4749,8 +5142,8 @@ ${ocrText}`);
4749
5142
  if (!rawPath) {
4750
5143
  return { success: false, output: "", error: "path is required", durationMs: 0 };
4751
5144
  }
4752
- const fullPath = resolve11(this.workingDir, rawPath);
4753
- if (!existsSync8(fullPath)) {
5145
+ const fullPath = resolve12(this.workingDir, rawPath);
5146
+ if (!existsSync9(fullPath)) {
4754
5147
  return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
4755
5148
  }
4756
5149
  if (!hasTesseract()) {
@@ -4765,7 +5158,7 @@ ${ocrText}`);
4765
5158
  if (region) {
4766
5159
  const [x, y, w, h] = region.split(",").map(Number);
4767
5160
  if (x != null && y != null && w != null && h != null) {
4768
- const croppedPath = join11(tmpdir(), `oa-ocr-crop-${Date.now()}.png`);
5161
+ const croppedPath = join12(tmpdir(), `oa-ocr-crop-${Date.now()}.png`);
4769
5162
  try {
4770
5163
  execSync7(`convert ${JSON.stringify(fullPath)} -crop ${w}x${h}+${x}+${y} +repage ${JSON.stringify(croppedPath)}`, { stdio: "pipe", timeout: 1e4 });
4771
5164
  inputPath = croppedPath;
@@ -4781,7 +5174,7 @@ ${ocrText}`);
4781
5174
  const lineCount = text.split("\n").length;
4782
5175
  return {
4783
5176
  success: true,
4784
- output: `OCR extracted ${lineCount} lines from ${basename(fullPath)}${region ? ` (region: ${region})` : ""}:
5177
+ output: `OCR extracted ${lineCount} lines from ${basename2(fullPath)}${region ? ` (region: ${region})` : ""}:
4785
5178
 
4786
5179
  ${text}`,
4787
5180
  durationMs: Date.now() - start
@@ -4809,15 +5202,15 @@ __export(custom_tool_exports, {
4809
5202
  loadCustomTools: () => loadCustomTools,
4810
5203
  saveCustomToolDefinition: () => saveCustomToolDefinition
4811
5204
  });
4812
- import { existsSync as existsSync9, readdirSync as readdirSync4, readFileSync as readFileSync7, mkdirSync as mkdirSync3, writeFileSync as writeFileSync3 } from "node:fs";
4813
- import { join as join12 } from "node:path";
4814
- import { homedir as homedir3 } from "node:os";
5205
+ import { existsSync as existsSync10, readdirSync as readdirSync4, readFileSync as readFileSync7, mkdirSync as mkdirSync3, writeFileSync as writeFileSync3 } from "node:fs";
5206
+ import { join as join13 } from "node:path";
5207
+ import { homedir as homedir4 } from "node:os";
4815
5208
  import { spawn as spawn3 } from "node:child_process";
4816
5209
  function globalToolsDir() {
4817
- return join12(homedir3(), ".open-agents", "tools");
5210
+ return join13(homedir4(), ".open-agents", "tools");
4818
5211
  }
4819
5212
  function projectToolsDir(repoRoot) {
4820
- return join12(repoRoot, ".oa", "tools");
5213
+ return join13(repoRoot, ".oa", "tools");
4821
5214
  }
4822
5215
  function loadCustomTools(repoRoot) {
4823
5216
  const definitions = /* @__PURE__ */ new Map();
@@ -4837,14 +5230,14 @@ function buildCustomTools(repoRoot) {
4837
5230
  function saveCustomToolDefinition(definition, scope, repoRoot) {
4838
5231
  const dir = scope === "project" && repoRoot ? projectToolsDir(repoRoot) : globalToolsDir();
4839
5232
  mkdirSync3(dir, { recursive: true });
4840
- const filePath = join12(dir, `${definition.name}.json`);
5233
+ const filePath = join13(dir, `${definition.name}.json`);
4841
5234
  writeFileSync3(filePath, JSON.stringify(definition, null, 2), "utf-8");
4842
5235
  return filePath;
4843
5236
  }
4844
5237
  function deleteCustomToolDefinition(name, scope, repoRoot) {
4845
5238
  const dir = scope === "project" && repoRoot ? projectToolsDir(repoRoot) : globalToolsDir();
4846
- const filePath = join12(dir, `${name}.json`);
4847
- if (existsSync9(filePath)) {
5239
+ const filePath = join13(dir, `${name}.json`);
5240
+ if (existsSync10(filePath)) {
4848
5241
  const { unlinkSync: unlinkSync5 } = __require("node:fs");
4849
5242
  unlinkSync5(filePath);
4850
5243
  return true;
@@ -4878,14 +5271,14 @@ function listCustomToolFiles(repoRoot) {
4878
5271
  return result;
4879
5272
  }
4880
5273
  function loadFromDirectory(dir) {
4881
- if (!existsSync9(dir))
5274
+ if (!existsSync10(dir))
4882
5275
  return [];
4883
5276
  const definitions = [];
4884
5277
  try {
4885
5278
  const files = readdirSync4(dir).filter((f) => f.endsWith(".json"));
4886
5279
  for (const file of files) {
4887
5280
  try {
4888
- const content = readFileSync7(join12(dir, file), "utf-8");
5281
+ const content = readFileSync7(join13(dir, file), "utf-8");
4889
5282
  const def = JSON.parse(content);
4890
5283
  if (def.name && def.description && Array.isArray(def.steps) && def.steps.length > 0) {
4891
5284
  if (!def.parameters || typeof def.parameters !== "object") {
@@ -4964,7 +5357,7 @@ var init_custom_tool = __esm({
4964
5357
  }
4965
5358
  /** Execute a single shell command and return output */
4966
5359
  runCommand(command) {
4967
- return new Promise((resolve22) => {
5360
+ return new Promise((resolve23) => {
4968
5361
  const child = spawn3("bash", ["-c", command], {
4969
5362
  cwd: this.workingDir,
4970
5363
  env: { ...process.env, CI: "true", NO_COLOR: "1" },
@@ -4989,11 +5382,11 @@ var init_custom_tool = __esm({
4989
5382
  child.kill("SIGTERM");
4990
5383
  } catch {
4991
5384
  }
4992
- resolve22({ success: false, output: stdout, error: "Command timed out after 60s" });
5385
+ resolve23({ success: false, output: stdout, error: "Command timed out after 60s" });
4993
5386
  }, 6e4);
4994
5387
  child.on("close", (code) => {
4995
5388
  clearTimeout(timer);
4996
- resolve22({
5389
+ resolve23({
4997
5390
  success: code === 0,
4998
5391
  output: stdout + (stderr && code === 0 ? `
4999
5392
  STDERR:
@@ -5003,7 +5396,7 @@ ${stderr}` : ""),
5003
5396
  });
5004
5397
  child.on("error", (err) => {
5005
5398
  clearTimeout(timer);
5006
- resolve22({ success: false, output: stdout, error: err.message });
5399
+ resolve23({ success: false, output: stdout, error: err.message });
5007
5400
  });
5008
5401
  });
5009
5402
  }
@@ -5306,16 +5699,16 @@ var init_tool_creator = __esm({
5306
5699
  });
5307
5700
 
5308
5701
  // packages/execution/dist/tools/skill-tools.js
5309
- import { existsSync as existsSync10, readdirSync as readdirSync5, readFileSync as readFileSync8 } from "node:fs";
5310
- import { join as join13, basename as basename2, dirname as dirname3 } from "node:path";
5311
- import { homedir as homedir4 } from "node:os";
5702
+ import { existsSync as existsSync11, readdirSync as readdirSync5, readFileSync as readFileSync8 } from "node:fs";
5703
+ import { join as join14, basename as basename3, dirname as dirname3 } from "node:path";
5704
+ import { homedir as homedir5 } from "node:os";
5312
5705
  import { execSync as execSync8 } from "node:child_process";
5313
5706
  function getAiwgPaths() {
5314
- const dataDir = join13(homedir4(), ".local", "share", "ai-writing-guide");
5707
+ const dataDir = join14(homedir5(), ".local", "share", "ai-writing-guide");
5315
5708
  return {
5316
- frameworksDir: join13(dataDir, "agentic", "code", "frameworks"),
5317
- addonsDir: join13(dataDir, "agentic", "code", "addons"),
5318
- pluginsDir: join13(dataDir, "plugins")
5709
+ frameworksDir: join14(dataDir, "agentic", "code", "frameworks"),
5710
+ addonsDir: join14(dataDir, "agentic", "code", "addons"),
5711
+ pluginsDir: join14(dataDir, "plugins")
5319
5712
  };
5320
5713
  }
5321
5714
  function findAiwgPackageRoot() {
@@ -5327,8 +5720,8 @@ function findAiwgPackageRoot() {
5327
5720
  timeout: 5e3,
5328
5721
  stdio: ["pipe", "pipe", "pipe"]
5329
5722
  }).trim();
5330
- const candidate = join13(globalRoot, "aiwg");
5331
- if (existsSync10(join13(candidate, "package.json"))) {
5723
+ const candidate = join14(globalRoot, "aiwg");
5724
+ if (existsSync11(join14(candidate, "package.json"))) {
5332
5725
  _cachedAiwgPkgRoot = candidate;
5333
5726
  return candidate;
5334
5727
  }
@@ -5337,18 +5730,18 @@ function findAiwgPackageRoot() {
5337
5730
  const candidates = [
5338
5731
  "/usr/local/lib/node_modules/aiwg",
5339
5732
  "/usr/lib/node_modules/aiwg",
5340
- join13(homedir4(), ".nvm", "versions")
5733
+ join14(homedir5(), ".nvm", "versions")
5341
5734
  // nvm — need to search deeper
5342
5735
  ];
5343
5736
  for (const c3 of candidates) {
5344
5737
  if (c3.includes(".nvm")) {
5345
- if (existsSync10(c3)) {
5738
+ if (existsSync11(c3)) {
5346
5739
  try {
5347
- for (const ver of readdirSync5(join13(c3, "node"), { withFileTypes: true })) {
5740
+ for (const ver of readdirSync5(join14(c3, "node"), { withFileTypes: true })) {
5348
5741
  if (!ver.isDirectory())
5349
5742
  continue;
5350
- const nvmPath = join13(c3, "node", ver.name, "lib", "node_modules", "aiwg");
5351
- if (existsSync10(join13(nvmPath, "package.json"))) {
5743
+ const nvmPath = join14(c3, "node", ver.name, "lib", "node_modules", "aiwg");
5744
+ if (existsSync11(join14(nvmPath, "package.json"))) {
5352
5745
  _cachedAiwgPkgRoot = nvmPath;
5353
5746
  return nvmPath;
5354
5747
  }
@@ -5356,7 +5749,7 @@ function findAiwgPackageRoot() {
5356
5749
  } catch {
5357
5750
  }
5358
5751
  }
5359
- } else if (existsSync10(join13(c3, "package.json"))) {
5752
+ } else if (existsSync11(join14(c3, "package.json"))) {
5360
5753
  _cachedAiwgPkgRoot = c3;
5361
5754
  return c3;
5362
5755
  }
@@ -5368,49 +5761,49 @@ function discoverSkills(repoRoot) {
5368
5761
  const skills = /* @__PURE__ */ new Map();
5369
5762
  const { frameworksDir, addonsDir, pluginsDir } = getAiwgPaths();
5370
5763
  const loadComponent = (componentDir, source) => {
5371
- loadSkillsFromDir(join13(componentDir, "skills"), source, skills);
5372
- loadCommandsFromDir(join13(componentDir, "commands"), source, skills);
5764
+ loadSkillsFromDir(join14(componentDir, "skills"), source, skills);
5765
+ loadCommandsFromDir(join14(componentDir, "commands"), source, skills);
5373
5766
  };
5374
5767
  const pkgRoot = findAiwgPackageRoot();
5375
5768
  if (pkgRoot) {
5376
- const pkgFrameworks = join13(pkgRoot, "agentic", "code", "frameworks");
5377
- if (existsSync10(pkgFrameworks)) {
5769
+ const pkgFrameworks = join14(pkgRoot, "agentic", "code", "frameworks");
5770
+ if (existsSync11(pkgFrameworks)) {
5378
5771
  for (const fw of safeReaddir(pkgFrameworks)) {
5379
- loadComponent(join13(pkgFrameworks, fw), `framework:${fw}`);
5772
+ loadComponent(join14(pkgFrameworks, fw), `framework:${fw}`);
5380
5773
  }
5381
5774
  }
5382
- const pkgAddons = join13(pkgRoot, "agentic", "code", "addons");
5383
- if (existsSync10(pkgAddons)) {
5775
+ const pkgAddons = join14(pkgRoot, "agentic", "code", "addons");
5776
+ if (existsSync11(pkgAddons)) {
5384
5777
  for (const addon of safeReaddir(pkgAddons)) {
5385
- loadComponent(join13(pkgAddons, addon), `addon:${addon}`);
5778
+ loadComponent(join14(pkgAddons, addon), `addon:${addon}`);
5386
5779
  }
5387
5780
  }
5388
- const pkgPlugins = join13(pkgRoot, "plugins");
5389
- if (existsSync10(pkgPlugins)) {
5781
+ const pkgPlugins = join14(pkgRoot, "plugins");
5782
+ if (existsSync11(pkgPlugins)) {
5390
5783
  for (const plugin of safeReaddir(pkgPlugins)) {
5391
- loadComponent(join13(pkgPlugins, plugin), `plugin:${plugin}`);
5784
+ loadComponent(join14(pkgPlugins, plugin), `plugin:${plugin}`);
5392
5785
  }
5393
5786
  }
5394
5787
  }
5395
- if (existsSync10(frameworksDir)) {
5788
+ if (existsSync11(frameworksDir)) {
5396
5789
  for (const framework of safeReaddir(frameworksDir)) {
5397
- loadComponent(join13(frameworksDir, framework), `framework:${framework}`);
5790
+ loadComponent(join14(frameworksDir, framework), `framework:${framework}`);
5398
5791
  }
5399
5792
  }
5400
- if (existsSync10(addonsDir)) {
5793
+ if (existsSync11(addonsDir)) {
5401
5794
  for (const addon of safeReaddir(addonsDir)) {
5402
- loadComponent(join13(addonsDir, addon), `addon:${addon}`);
5795
+ loadComponent(join14(addonsDir, addon), `addon:${addon}`);
5403
5796
  }
5404
5797
  }
5405
- if (existsSync10(pluginsDir)) {
5798
+ if (existsSync11(pluginsDir)) {
5406
5799
  for (const plugin of safeReaddir(pluginsDir)) {
5407
- loadComponent(join13(pluginsDir, plugin), `plugin:${plugin}`);
5800
+ loadComponent(join14(pluginsDir, plugin), `plugin:${plugin}`);
5408
5801
  }
5409
5802
  }
5410
- const projectAiwg = join13(repoRoot, ".aiwg");
5411
- loadSkillsFromDir(join13(projectAiwg, "skills"), "project", skills);
5412
- loadCommandsFromDir(join13(projectAiwg, "commands"), "project", skills);
5413
- const projectOaSkills = join13(repoRoot, ".oa", "skills");
5803
+ const projectAiwg = join14(repoRoot, ".aiwg");
5804
+ loadSkillsFromDir(join14(projectAiwg, "skills"), "project", skills);
5805
+ loadCommandsFromDir(join14(projectAiwg, "commands"), "project", skills);
5806
+ const projectOaSkills = join14(repoRoot, ".oa", "skills");
5414
5807
  loadSkillsFromDir(projectOaSkills, "local", skills);
5415
5808
  return Array.from(skills.values());
5416
5809
  }
@@ -5456,13 +5849,13 @@ function safeReaddir(dir) {
5456
5849
  }
5457
5850
  }
5458
5851
  function loadSkillsFromDir(dir, source, out) {
5459
- if (!existsSync10(dir))
5852
+ if (!existsSync11(dir))
5460
5853
  return;
5461
5854
  const manifest = loadManifest(dir);
5462
5855
  const entries = safeReaddir(dir);
5463
5856
  for (const entry of entries) {
5464
- const skillMd = join13(dir, entry, "SKILL.md");
5465
- if (!existsSync10(skillMd))
5857
+ const skillMd = join14(dir, entry, "SKILL.md");
5858
+ if (!existsSync11(skillMd))
5466
5859
  continue;
5467
5860
  const manifestEntry = manifest.get(entry);
5468
5861
  const info = {
@@ -5476,7 +5869,7 @@ function loadSkillsFromDir(dir, source, out) {
5476
5869
  }
5477
5870
  }
5478
5871
  function loadCommandsFromDir(dir, source, out) {
5479
- if (!existsSync10(dir))
5872
+ if (!existsSync11(dir))
5480
5873
  return;
5481
5874
  let entries;
5482
5875
  try {
@@ -5486,7 +5879,7 @@ function loadCommandsFromDir(dir, source, out) {
5486
5879
  }
5487
5880
  for (const file of entries) {
5488
5881
  const name = file.replace(/\.md$/, "");
5489
- const filePath = join13(dir, file);
5882
+ const filePath = join14(dir, file);
5490
5883
  if (out.has(name))
5491
5884
  continue;
5492
5885
  const info = {
@@ -5522,8 +5915,8 @@ function parseCommandTriggers(name) {
5522
5915
  }
5523
5916
  function loadManifest(dir) {
5524
5917
  const result = /* @__PURE__ */ new Map();
5525
- const manifestPath = join13(dir, "manifest.json");
5526
- if (!existsSync10(manifestPath))
5918
+ const manifestPath = join14(dir, "manifest.json");
5919
+ if (!existsSync11(manifestPath))
5527
5920
  return result;
5528
5921
  try {
5529
5922
  const content = readFileSync8(manifestPath, "utf-8");
@@ -5706,9 +6099,9 @@ ${content}`,
5706
6099
  });
5707
6100
 
5708
6101
  // packages/execution/dist/tools/transcribe-tool.js
5709
- import { existsSync as existsSync11, mkdirSync as mkdirSync4, writeFileSync as writeFileSync4, readFileSync as readFileSync9, unlinkSync } from "node:fs";
5710
- import { join as join14, basename as basename3, extname as extname3, resolve as resolve12 } from "node:path";
5711
- import { homedir as homedir5 } from "node:os";
6102
+ import { existsSync as existsSync12, mkdirSync as mkdirSync4, writeFileSync as writeFileSync4, readFileSync as readFileSync9, unlinkSync } from "node:fs";
6103
+ import { join as join15, basename as basename4, extname as extname3, resolve as resolve13 } from "node:path";
6104
+ import { homedir as homedir6 } from "node:os";
5712
6105
  import { execSync as execSync9, spawn as spawn4 } from "node:child_process";
5713
6106
  function isTranscribable(path) {
5714
6107
  const ext = extname3(path).toLowerCase();
@@ -5724,25 +6117,25 @@ async function loadTranscribeCli() {
5724
6117
  timeout: 5e3,
5725
6118
  stdio: ["pipe", "pipe", "pipe"]
5726
6119
  }).trim();
5727
- const tcPath = join14(globalRoot, "transcribe-cli");
5728
- if (existsSync11(join14(tcPath, "dist", "index.js"))) {
6120
+ const tcPath = join15(globalRoot, "transcribe-cli");
6121
+ if (existsSync12(join15(tcPath, "dist", "index.js"))) {
5729
6122
  const { createRequire: createRequire4 } = await import("node:module");
5730
6123
  const req = createRequire4(import.meta.url);
5731
- _tcModule = req(join14(tcPath, "dist", "index.js"));
6124
+ _tcModule = req(join15(tcPath, "dist", "index.js"));
5732
6125
  return _tcModule;
5733
6126
  }
5734
6127
  } catch {
5735
6128
  }
5736
- const nvmBase = join14(homedir5(), ".nvm", "versions", "node");
5737
- if (existsSync11(nvmBase)) {
6129
+ const nvmBase = join15(homedir6(), ".nvm", "versions", "node");
6130
+ if (existsSync12(nvmBase)) {
5738
6131
  try {
5739
6132
  const { readdirSync: readdirSync11 } = await import("node:fs");
5740
6133
  for (const ver of readdirSync11(nvmBase)) {
5741
- const tcPath = join14(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
5742
- if (existsSync11(join14(tcPath, "dist", "index.js"))) {
6134
+ const tcPath = join15(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
6135
+ if (existsSync12(join15(tcPath, "dist", "index.js"))) {
5743
6136
  const { createRequire: createRequire4 } = await import("node:module");
5744
6137
  const req = createRequire4(import.meta.url);
5745
- _tcModule = req(join14(tcPath, "dist", "index.js"));
6138
+ _tcModule = req(join15(tcPath, "dist", "index.js"));
5746
6139
  return _tcModule;
5747
6140
  }
5748
6141
  }
@@ -5811,10 +6204,10 @@ var init_transcribe_tool = __esm({
5811
6204
  }
5812
6205
  async execute(args) {
5813
6206
  const start = performance.now();
5814
- const filePath = resolve12(this.workingDir, String(args["path"] ?? ""));
6207
+ const filePath = resolve13(this.workingDir, String(args["path"] ?? ""));
5815
6208
  const model = String(args["model"] ?? "base");
5816
6209
  const diarize = Boolean(args["diarize"] ?? false);
5817
- if (!existsSync11(filePath)) {
6210
+ if (!existsSync12(filePath)) {
5818
6211
  return {
5819
6212
  success: false,
5820
6213
  output: "",
@@ -5841,12 +6234,12 @@ var init_transcribe_tool = __esm({
5841
6234
  diarize,
5842
6235
  wordTimestamps: false
5843
6236
  });
5844
- const transcriptDir = join14(this.workingDir, ".oa", "transcripts");
6237
+ const transcriptDir = join15(this.workingDir, ".oa", "transcripts");
5845
6238
  mkdirSync4(transcriptDir, { recursive: true });
5846
- const outFile = join14(transcriptDir, `${basename3(filePath)}.txt`);
6239
+ const outFile = join15(transcriptDir, `${basename4(filePath)}.txt`);
5847
6240
  writeFileSync4(outFile, result.text, "utf-8");
5848
6241
  const lines = [
5849
- `Transcription of: ${basename3(filePath)}`,
6242
+ `Transcription of: ${basename4(filePath)}`,
5850
6243
  `Model: ${model} | Language: ${result.language} | Duration: ${result.duration ? `${result.duration.toFixed(1)}s` : "unknown"}`,
5851
6244
  `Words: ${result.wordCount} | Saved to: ${outFile}`,
5852
6245
  ""
@@ -5941,14 +6334,14 @@ var init_transcribe_tool = __esm({
5941
6334
  durationMs: performance.now() - start
5942
6335
  };
5943
6336
  }
5944
- const tmpDir = join14(this.workingDir, ".oa", "tmp");
6337
+ const tmpDir = join15(this.workingDir, ".oa", "tmp");
5945
6338
  mkdirSync4(tmpDir, { recursive: true });
5946
6339
  const urlPath = new URL(url).pathname;
5947
6340
  let ext = extname3(urlPath).toLowerCase();
5948
6341
  if (!ext || !AUDIO_EXTS.has(ext) && !VIDEO_EXTS.has(ext)) {
5949
6342
  ext = ".mp3";
5950
6343
  }
5951
- const tmpFile = join14(tmpDir, `download-${Date.now()}${ext}`);
6344
+ const tmpFile = join15(tmpDir, `download-${Date.now()}${ext}`);
5952
6345
  try {
5953
6346
  try {
5954
6347
  execSync9(`curl -sL -o "${tmpFile}" "${url}"`, {
@@ -5961,7 +6354,7 @@ var init_transcribe_tool = __esm({
5961
6354
  stdio: ["pipe", "pipe", "pipe"]
5962
6355
  });
5963
6356
  }
5964
- if (!existsSync11(tmpFile)) {
6357
+ if (!existsSync12(tmpFile)) {
5965
6358
  return {
5966
6359
  success: false,
5967
6360
  output: "",
@@ -6001,7 +6394,7 @@ ${result.output}`,
6001
6394
 
6002
6395
  // packages/execution/dist/tools/structured-file.js
6003
6396
  import { writeFile as writeFile6, mkdir as mkdir3 } from "node:fs/promises";
6004
- import { resolve as resolve13, dirname as dirname4, extname as extname4 } from "node:path";
6397
+ import { resolve as resolve14, dirname as dirname4, extname as extname4 } from "node:path";
6005
6398
  function jsonToCSV(data, separator = ",") {
6006
6399
  if (!Array.isArray(data) || data.length === 0)
6007
6400
  return "";
@@ -6115,7 +6508,7 @@ var init_structured_file = __esm({
6115
6508
  }
6116
6509
  }
6117
6510
  try {
6118
- const fullPath = resolve13(this.workingDir, filePath);
6511
+ const fullPath = resolve14(this.workingDir, filePath);
6119
6512
  await mkdir3(dirname4(fullPath), { recursive: true });
6120
6513
  let content;
6121
6514
  let byteInfo = "";
@@ -6181,11 +6574,11 @@ var init_structured_file = __esm({
6181
6574
 
6182
6575
  // packages/execution/dist/tools/code-sandbox.js
6183
6576
  import { spawn as spawn5 } from "node:child_process";
6184
- import { writeFile as writeFile7, mkdtemp, rm, readdir, stat } from "node:fs/promises";
6185
- import { join as join15 } from "node:path";
6577
+ import { writeFile as writeFile7, mkdtemp, rm, readdir as readdir2, stat } from "node:fs/promises";
6578
+ import { join as join16 } from "node:path";
6186
6579
  import { tmpdir as tmpdir2 } from "node:os";
6187
6580
  function runProcess(cmd, args, options) {
6188
- return new Promise((resolve22) => {
6581
+ return new Promise((resolve23) => {
6189
6582
  const proc = spawn5(cmd, args, {
6190
6583
  cwd: options.cwd,
6191
6584
  timeout: options.timeout,
@@ -6215,7 +6608,7 @@ function runProcess(cmd, args, options) {
6215
6608
  }
6216
6609
  });
6217
6610
  proc.on("error", (err) => {
6218
- resolve22({
6611
+ resolve23({
6219
6612
  stdout,
6220
6613
  stderr: stderr || err.message,
6221
6614
  exitCode: 1,
@@ -6227,7 +6620,7 @@ function runProcess(cmd, args, options) {
6227
6620
  if (signal === "SIGTERM" || signal === "SIGKILL") {
6228
6621
  timedOut = true;
6229
6622
  }
6230
- resolve22({
6623
+ resolve23({
6231
6624
  stdout,
6232
6625
  stderr,
6233
6626
  exitCode: code ?? (timedOut ? 124 : 1),
@@ -6244,11 +6637,11 @@ function runProcess(cmd, args, options) {
6244
6637
  async function listCreatedFiles(dir) {
6245
6638
  const files = [];
6246
6639
  try {
6247
- const entries = await readdir(dir);
6640
+ const entries = await readdir2(dir);
6248
6641
  for (const entry of entries) {
6249
6642
  if (entry.startsWith("_sandbox_script"))
6250
6643
  continue;
6251
- const fullPath = join15(dir, entry);
6644
+ const fullPath = join16(dir, entry);
6252
6645
  const s = await stat(fullPath);
6253
6646
  if (s.isFile()) {
6254
6647
  files.push(entry);
@@ -6368,9 +6761,9 @@ ${result.filesCreated.join("\n")}`);
6368
6761
  // Subprocess mode — temp directory + separate process
6369
6762
  // -------------------------------------------------------------------------
6370
6763
  async #runSubprocess(code, langConfig, timeoutMs, stdin) {
6371
- const sandboxDir = await mkdtemp(join15(tmpdir2(), "oa-sandbox-"));
6764
+ const sandboxDir = await mkdtemp(join16(tmpdir2(), "oa-sandbox-"));
6372
6765
  try {
6373
- const scriptFile = join15(sandboxDir, `_sandbox_script${langConfig.ext}`);
6766
+ const scriptFile = join16(sandboxDir, `_sandbox_script${langConfig.ext}`);
6374
6767
  await writeFile7(scriptFile, code, "utf-8");
6375
6768
  const result = await runProcess(langConfig.cmd, langConfig.args(scriptFile), {
6376
6769
  cwd: sandboxDir,
@@ -6395,10 +6788,10 @@ ${result.filesCreated.join("\n")}`);
6395
6788
  bash: "bash:5"
6396
6789
  };
6397
6790
  const image = images[language] ?? "node:22-slim";
6398
- const sandboxDir = await mkdtemp(join15(tmpdir2(), "oa-docker-sandbox-"));
6791
+ const sandboxDir = await mkdtemp(join16(tmpdir2(), "oa-docker-sandbox-"));
6399
6792
  try {
6400
6793
  const scriptFile = `_sandbox_script${langConfig.ext}`;
6401
- await writeFile7(join15(sandboxDir, scriptFile), code, "utf-8");
6794
+ await writeFile7(join16(sandboxDir, scriptFile), code, "utf-8");
6402
6795
  const dockerArgs = [
6403
6796
  "run",
6404
6797
  "--rm",
@@ -6433,8 +6826,8 @@ ${result.filesCreated.join("\n")}`);
6433
6826
  });
6434
6827
 
6435
6828
  // packages/execution/dist/tools/structured-read.js
6436
- import { readFile as readFile7, stat as stat2 } from "node:fs/promises";
6437
- import { resolve as resolve14, extname as extname5 } from "node:path";
6829
+ import { readFile as readFile8, stat as stat2 } from "node:fs/promises";
6830
+ import { resolve as resolve15, extname as extname5 } from "node:path";
6438
6831
  function parseCSV(text, separator = ",") {
6439
6832
  const lines = text.split("\n").filter((l) => l.trim() !== "");
6440
6833
  if (lines.length < 2)
@@ -6575,7 +6968,7 @@ var init_structured_read = __esm({
6575
6968
  if (!filePath) {
6576
6969
  return { success: false, output: "", error: "path is required", durationMs: 0 };
6577
6970
  }
6578
- const fullPath = resolve14(this.workingDir, filePath);
6971
+ const fullPath = resolve15(this.workingDir, filePath);
6579
6972
  try {
6580
6973
  const fileStat = await stat2(fullPath);
6581
6974
  if (!fileStat.isFile()) {
@@ -6628,7 +7021,7 @@ var init_structured_read = __esm({
6628
7021
  }
6629
7022
  }
6630
7023
  if (format === "xlsx" || format === "pdf" || format === "docx" || format === "auto") {
6631
- const buffer = await readFile7(fullPath);
7024
+ const buffer = await readFile8(fullPath);
6632
7025
  const detected = detectBinaryFormat(buffer);
6633
7026
  if (detected === "xlsx") {
6634
7027
  return {
@@ -6673,7 +7066,7 @@ Or install mammoth for programmatic access.`,
6673
7066
  }
6674
7067
  }
6675
7068
  }
6676
- const text = await readFile7(fullPath, "utf-8");
7069
+ const text = await readFile8(fullPath, "utf-8");
6677
7070
  switch (format) {
6678
7071
  case "csv": {
6679
7072
  const rows = parseCSV(text, ",");
@@ -6768,9 +7161,9 @@ ${parts.join("\n\n")}`,
6768
7161
  });
6769
7162
 
6770
7163
  // packages/execution/dist/tools/vision.js
6771
- import { readFileSync as readFileSync10, existsSync as existsSync12, statSync as statSync5 } from "node:fs";
7164
+ import { readFileSync as readFileSync10, existsSync as existsSync13, statSync as statSync5 } from "node:fs";
6772
7165
  import { execSync as execSync10, spawn as spawn6 } from "node:child_process";
6773
- import { resolve as resolve15, extname as extname6, basename as basename4, dirname as dirname5, join as join16 } from "node:path";
7166
+ import { resolve as resolve16, extname as extname6, basename as basename5, dirname as dirname5, join as join17 } from "node:path";
6774
7167
  import { fileURLToPath as fileURLToPath2 } from "node:url";
6775
7168
  async function probeStation(endpoint) {
6776
7169
  try {
@@ -6785,24 +7178,24 @@ async function probeStation(endpoint) {
6785
7178
  }
6786
7179
  }
6787
7180
  function findStationBinary() {
6788
- const oaVenvPython = join16(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "python");
6789
- if (existsSync12(oaVenvPython)) {
7181
+ const oaVenvPython = join17(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "python");
7182
+ if (existsSync13(oaVenvPython)) {
6790
7183
  try {
6791
7184
  execSync10(`${JSON.stringify(oaVenvPython)} -c "import moondream_station"`, { stdio: "pipe", timeout: 5e3 });
6792
7185
  return oaVenvPython;
6793
7186
  } catch {
6794
7187
  }
6795
7188
  }
6796
- const oaVenvBin = join16(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "moondream-station");
6797
- if (existsSync12(oaVenvBin))
7189
+ const oaVenvBin = join17(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "moondream-station");
7190
+ if (existsSync13(oaVenvBin))
6798
7191
  return oaVenvBin;
6799
7192
  const thisDir = dirname5(fileURLToPath2(import.meta.url));
6800
7193
  const localVenvPaths = [
6801
- resolve15(thisDir, "../../../../.moondream-venv/bin/python"),
6802
- resolve15(thisDir, "../../../.moondream-venv/bin/python")
7194
+ resolve16(thisDir, "../../../../.moondream-venv/bin/python"),
7195
+ resolve16(thisDir, "../../../.moondream-venv/bin/python")
6803
7196
  ];
6804
7197
  for (const p of localVenvPaths) {
6805
- if (existsSync12(p)) {
7198
+ if (existsSync13(p)) {
6806
7199
  try {
6807
7200
  execSync10(`${JSON.stringify(p)} -c "import moondream_station"`, { stdio: "pipe", timeout: 5e3 });
6808
7201
  return p;
@@ -6823,8 +7216,8 @@ async function autoLaunchStation(port = 2020) {
6823
7216
  if (!pythonBin)
6824
7217
  return false;
6825
7218
  const thisDir = dirname5(fileURLToPath2(import.meta.url));
6826
- const launcherScript = resolve15(thisDir, "../../scripts/start-moondream.py");
6827
- if (!existsSync12(launcherScript))
7219
+ const launcherScript = resolve16(thisDir, "../../scripts/start-moondream.py");
7220
+ if (!existsSync13(launcherScript))
6828
7221
  return false;
6829
7222
  return new Promise((resolvePromise) => {
6830
7223
  const child = spawn6(pythonBin, [launcherScript, "--port", String(port)], {
@@ -6898,8 +7291,8 @@ Details: ${err.message}` : "");
6898
7291
  }
6899
7292
  }
6900
7293
  function loadImageBuffer(workingDir, rawPath) {
6901
- const fullPath = resolve15(workingDir, rawPath);
6902
- if (!existsSync12(fullPath)) {
7294
+ const fullPath = resolve16(workingDir, rawPath);
7295
+ if (!existsSync13(fullPath)) {
6903
7296
  throw new Error(`File not found: ${rawPath}`);
6904
7297
  }
6905
7298
  const stat5 = statSync5(fullPath);
@@ -6988,7 +7381,7 @@ var init_vision = __esm({
6988
7381
  }
6989
7382
  try {
6990
7383
  const { buffer, fullPath } = loadImageBuffer(this.workingDir, rawPath);
6991
- const filename = basename4(fullPath);
7384
+ const filename = basename5(fullPath);
6992
7385
  let client = null;
6993
7386
  try {
6994
7387
  client = await getMoondreamClient();
@@ -7138,10 +7531,10 @@ ${response}`, durationMs: performance.now() - start };
7138
7531
  });
7139
7532
 
7140
7533
  // packages/execution/dist/tools/desktop-click.js
7141
- import { readFileSync as readFileSync11, existsSync as existsSync13 } from "node:fs";
7534
+ import { readFileSync as readFileSync11, existsSync as existsSync14 } from "node:fs";
7142
7535
  import { execSync as execSync11 } from "node:child_process";
7143
7536
  import { tmpdir as tmpdir3 } from "node:os";
7144
- import { join as join17, dirname as dirname6 } from "node:path";
7537
+ import { join as join18, dirname as dirname6 } from "node:path";
7145
7538
  import { fileURLToPath as fileURLToPath3 } from "node:url";
7146
7539
  function hasCommand2(cmd) {
7147
7540
  try {
@@ -7203,7 +7596,7 @@ function captureScreenshot(outputPath) {
7203
7596
  } else {
7204
7597
  try {
7205
7598
  execSync11(`DISPLAY=:0 python3 -c "from PIL import ImageGrab; ImageGrab.grab().save(${JSON.stringify(outputPath)})"`, { stdio: "pipe", timeout: 1e4 });
7206
- if (existsSync13(outputPath))
7599
+ if (existsSync14(outputPath))
7207
7600
  return;
7208
7601
  } catch {
7209
7602
  }
@@ -7214,7 +7607,7 @@ function captureScreenshot(outputPath) {
7214
7607
  throw new Error("No screenshot tool found. Auto-install failed. Try manually: sudo apt install scrot");
7215
7608
  }
7216
7609
  execSync11(cmd, { stdio: "pipe", timeout: 1e4 });
7217
- if (!existsSync13(outputPath)) {
7610
+ if (!existsSync14(outputPath)) {
7218
7611
  throw new Error("Screenshot file was not created");
7219
7612
  }
7220
7613
  }
@@ -7265,7 +7658,7 @@ for i in range(${clicks}):
7265
7658
  } catch {
7266
7659
  }
7267
7660
  try {
7268
- const venvPy = join17(__dirname, "../../../../.moondream-venv/bin/python");
7661
+ const venvPy = join18(__dirname, "../../../../.moondream-venv/bin/python");
7269
7662
  execSync11(`DISPLAY=:0 ${JSON.stringify(venvPy)} -c "${pyScript}"`, { stdio: "pipe", timeout: 5e3 });
7270
7663
  return;
7271
7664
  } catch {
@@ -7357,7 +7750,7 @@ var init_desktop_click = __esm({
7357
7750
  if (delayMs > 0) {
7358
7751
  await new Promise((r) => setTimeout(r, delayMs));
7359
7752
  }
7360
- const screenshotPath = join17(tmpdir3(), `oa-desktop-click-${Date.now()}.png`);
7753
+ const screenshotPath = join18(tmpdir3(), `oa-desktop-click-${Date.now()}.png`);
7361
7754
  captureScreenshot(screenshotPath);
7362
7755
  const dims = getImageDimensions2(screenshotPath);
7363
7756
  if (!dims) {
@@ -7532,7 +7925,7 @@ Screenshot: ${screenshotPath}`,
7532
7925
  if (delayMs > 0) {
7533
7926
  await new Promise((r) => setTimeout(r, delayMs));
7534
7927
  }
7535
- const screenshotPath = join17(tmpdir3(), `oa-desktop-describe-${Date.now()}.png`);
7928
+ const screenshotPath = join18(tmpdir3(), `oa-desktop-describe-${Date.now()}.png`);
7536
7929
  captureScreenshot(screenshotPath);
7537
7930
  const dims = getImageDimensions2(screenshotPath);
7538
7931
  const imageBuffer = readFileSync11(screenshotPath);
@@ -7647,8 +8040,8 @@ Screen: ${dims.width}x${dims.height}`);
7647
8040
  });
7648
8041
 
7649
8042
  // packages/execution/dist/tools/ocr-pdf.js
7650
- import { existsSync as existsSync14, statSync as statSync6 } from "node:fs";
7651
- import { resolve as resolve16, basename as basename5 } from "node:path";
8043
+ import { existsSync as existsSync15, statSync as statSync6 } from "node:fs";
8044
+ import { resolve as resolve17, basename as basename6 } from "node:path";
7652
8045
  import { execSync as execSync12 } from "node:child_process";
7653
8046
  var OcrPdfTool;
7654
8047
  var init_ocr_pdf = __esm({
@@ -7698,8 +8091,8 @@ var init_ocr_pdf = __esm({
7698
8091
  if (!rawInput) {
7699
8092
  return { success: false, output: "", error: "input path is required", durationMs: 0 };
7700
8093
  }
7701
- const inputPath = resolve16(this.workingDir, rawInput);
7702
- if (!existsSync14(inputPath)) {
8094
+ const inputPath = resolve17(this.workingDir, rawInput);
8095
+ if (!existsSync15(inputPath)) {
7703
8096
  return { success: false, output: "", error: `File not found: ${rawInput}`, durationMs: performance.now() - start };
7704
8097
  }
7705
8098
  const stat5 = statSync6(inputPath);
@@ -7722,7 +8115,7 @@ var init_ocr_pdf = __esm({
7722
8115
  durationMs: performance.now() - start
7723
8116
  };
7724
8117
  }
7725
- const outputPath = rawOutput ? resolve16(this.workingDir, rawOutput) : inputPath;
8118
+ const outputPath = rawOutput ? resolve17(this.workingDir, rawOutput) : inputPath;
7726
8119
  const cmdParts = ["ocrmypdf"];
7727
8120
  cmdParts.push("-l", language);
7728
8121
  if (deskew)
@@ -7747,7 +8140,7 @@ var init_ocr_pdf = __esm({
7747
8140
  const sizeMB = (outputStat.size / 1024 / 1024).toFixed(1);
7748
8141
  return {
7749
8142
  success: true,
7750
- output: `OCR completed for ${basename5(inputPath)}
8143
+ output: `OCR completed for ${basename6(inputPath)}
7751
8144
  Output: ${outputPath === inputPath ? "(in-place)" : outputPath}
7752
8145
  Size: ${sizeMB}MB
7753
8146
  Language: ${language}
@@ -7770,8 +8163,8 @@ Language: ${language}
7770
8163
  });
7771
8164
 
7772
8165
  // packages/execution/dist/tools/pdf-to-text.js
7773
- import { existsSync as existsSync15, statSync as statSync7, readFileSync as readFileSync12, unlinkSync as unlinkSync2 } from "node:fs";
7774
- import { resolve as resolve17, basename as basename6, join as join18 } from "node:path";
8166
+ import { existsSync as existsSync16, statSync as statSync7, readFileSync as readFileSync12, unlinkSync as unlinkSync2 } from "node:fs";
8167
+ import { resolve as resolve18, basename as basename7, join as join19 } from "node:path";
7775
8168
  import { execSync as execSync13 } from "node:child_process";
7776
8169
  import { tmpdir as tmpdir4 } from "node:os";
7777
8170
  var PdfToTextTool;
@@ -7822,8 +8215,8 @@ var init_pdf_to_text = __esm({
7822
8215
  if (!rawPath) {
7823
8216
  return { success: false, output: "", error: "path is required", durationMs: 0 };
7824
8217
  }
7825
- const fullPath = resolve17(this.workingDir, rawPath);
7826
- if (!existsSync15(fullPath)) {
8218
+ const fullPath = resolve18(this.workingDir, rawPath);
8219
+ if (!existsSync16(fullPath)) {
7827
8220
  return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: performance.now() - start };
7828
8221
  }
7829
8222
  const fileStat = statSync7(fullPath);
@@ -7881,7 +8274,7 @@ var init_pdf_to_text = __esm({
7881
8274
  const pageInfo2 = pages ? ` (pages: ${pages})` : "";
7882
8275
  return {
7883
8276
  success: true,
7884
- output: `Extracted ${lineCount2} lines from ${basename6(fullPath)}${pageInfo2} (via OCR):
8277
+ output: `Extracted ${lineCount2} lines from ${basename7(fullPath)}${pageInfo2} (via OCR):
7885
8278
 
7886
8279
  ${text}`,
7887
8280
  durationMs: performance.now() - start
@@ -7889,14 +8282,14 @@ ${text}`,
7889
8282
  }
7890
8283
  return {
7891
8284
  success: true,
7892
- output: `No text found in ${basename6(fullPath)} \u2014 appears to be a scanned/image PDF with no extractable text. OCR also returned no results.`,
8285
+ output: `No text found in ${basename7(fullPath)} \u2014 appears to be a scanned/image PDF with no extractable text. OCR also returned no results.`,
7893
8286
  durationMs: performance.now() - start
7894
8287
  };
7895
8288
  }
7896
8289
  if (!text) {
7897
8290
  return {
7898
8291
  success: true,
7899
- output: `No text found in ${basename6(fullPath)} \u2014 may be a scanned/image PDF. Use ocr_pdf tool to add a text layer first.`,
8292
+ output: `No text found in ${basename7(fullPath)} \u2014 may be a scanned/image PDF. Use ocr_pdf tool to add a text layer first.`,
7900
8293
  durationMs: performance.now() - start
7901
8294
  };
7902
8295
  }
@@ -7904,7 +8297,7 @@ ${text}`,
7904
8297
  const pageInfo = pages ? ` (pages: ${pages})` : "";
7905
8298
  return {
7906
8299
  success: true,
7907
- output: `Extracted ${lineCount} lines from ${basename6(fullPath)}${pageInfo}:
8300
+ output: `Extracted ${lineCount} lines from ${basename7(fullPath)}${pageInfo}:
7908
8301
 
7909
8302
  ${text}`,
7910
8303
  durationMs: performance.now() - start
@@ -7925,7 +8318,7 @@ ${text}`,
7925
8318
  if (!ocrCheck.available || !tesCheck.available || !gsCheck.available) {
7926
8319
  return null;
7927
8320
  }
7928
- const tmpPdf = join18(tmpdir4(), `oa-ocr-${Date.now()}.pdf`);
8321
+ const tmpPdf = join19(tmpdir4(), `oa-ocr-${Date.now()}.pdf`);
7929
8322
  try {
7930
8323
  const ocrCmd = `ocrmypdf -l ${language} --skip-text ${JSON.stringify(inputPath)} ${JSON.stringify(tmpPdf)}`;
7931
8324
  execSync13(ocrCmd, { stdio: "pipe", timeout: 6e5 });
@@ -7955,27 +8348,27 @@ ${text}`,
7955
8348
  });
7956
8349
 
7957
8350
  // packages/execution/dist/tools/ocr-image-advanced.js
7958
- import { existsSync as existsSync16, statSync as statSync8 } from "node:fs";
7959
- import { resolve as resolve18, basename as basename7, dirname as dirname7, join as join19 } from "node:path";
8351
+ import { existsSync as existsSync17, statSync as statSync8 } from "node:fs";
8352
+ import { resolve as resolve19, basename as basename8, dirname as dirname7, join as join20 } from "node:path";
7960
8353
  import { execSync as execSync14 } from "node:child_process";
7961
8354
  import { fileURLToPath as fileURLToPath4 } from "node:url";
7962
- import { homedir as homedir6, tmpdir as tmpdir5 } from "node:os";
8355
+ import { homedir as homedir7, tmpdir as tmpdir5 } from "node:os";
7963
8356
  function findOcrScript() {
7964
8357
  const thisDir = dirname7(fileURLToPath4(import.meta.url));
7965
- const devPath = resolve18(thisDir, "../../scripts/ocr-advanced.py");
7966
- if (existsSync16(devPath))
8358
+ const devPath = resolve19(thisDir, "../../scripts/ocr-advanced.py");
8359
+ if (existsSync17(devPath))
7967
8360
  return devPath;
7968
- const bundledPath = resolve18(thisDir, "../scripts/ocr-advanced.py");
7969
- if (existsSync16(bundledPath))
8361
+ const bundledPath = resolve19(thisDir, "../scripts/ocr-advanced.py");
8362
+ if (existsSync17(bundledPath))
7970
8363
  return bundledPath;
7971
- const sameDirPath = resolve18(thisDir, "ocr-advanced.py");
7972
- if (existsSync16(sameDirPath))
8364
+ const sameDirPath = resolve19(thisDir, "ocr-advanced.py");
8365
+ if (existsSync17(sameDirPath))
7973
8366
  return sameDirPath;
7974
8367
  return null;
7975
8368
  }
7976
8369
  function findPython() {
7977
- const venvPython = join19(homedir6(), ".open-agents", "venv", "bin", "python");
7978
- if (existsSync16(venvPython)) {
8370
+ const venvPython = join20(homedir7(), ".open-agents", "venv", "bin", "python");
8371
+ if (existsSync17(venvPython)) {
7979
8372
  try {
7980
8373
  execSync14(`${JSON.stringify(venvPython)} -c "import cv2, pytesseract, numpy, PIL"`, {
7981
8374
  stdio: "pipe",
@@ -8058,8 +8451,8 @@ var init_ocr_image_advanced = __esm({
8058
8451
  if (!rawPath) {
8059
8452
  return { success: false, output: "", error: "image path is required", durationMs: 0 };
8060
8453
  }
8061
- const fullPath = resolve18(this.workingDir, rawPath);
8062
- if (!existsSync16(fullPath)) {
8454
+ const fullPath = resolve19(this.workingDir, rawPath);
8455
+ if (!existsSync17(fullPath)) {
8063
8456
  return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: performance.now() - start };
8064
8457
  }
8065
8458
  if (!batch) {
@@ -8117,10 +8510,10 @@ var init_ocr_image_advanced = __esm({
8117
8510
  if (batch)
8118
8511
  cmdParts.push("--batch");
8119
8512
  if (outputDir)
8120
- cmdParts.push("--output-dir", JSON.stringify(resolve18(this.workingDir, outputDir)));
8513
+ cmdParts.push("--output-dir", JSON.stringify(resolve19(this.workingDir, outputDir)));
8121
8514
  let debugDir;
8122
8515
  if (debug) {
8123
- debugDir = join19(tmpdir5(), `oa-ocr-debug-${Date.now()}`);
8516
+ debugDir = join20(tmpdir5(), `oa-ocr-debug-${Date.now()}`);
8124
8517
  cmdParts.push("--debug-dir", debugDir);
8125
8518
  }
8126
8519
  try {
@@ -8160,7 +8553,7 @@ var init_ocr_image_advanced = __esm({
8160
8553
  };
8161
8554
  }
8162
8555
  const parts = [];
8163
- parts.push(`OCR extracted from ${basename7(imagePath)} (${result.image_size})`);
8556
+ parts.push(`OCR extracted from ${basename8(imagePath)} (${result.image_size})`);
8164
8557
  parts.push(`Best variant: ${result.variant} (confidence: ${result.confidence}%, ${result.chars} chars, ${result.lines} lines, score: ${result.score})`);
8165
8558
  parts.push(`Variants tested: ${result.variants_tested}`);
8166
8559
  if (result.output_files) {
@@ -8219,7 +8612,7 @@ var init_ocr_image_advanced = __esm({
8219
8612
  if (region) {
8220
8613
  try {
8221
8614
  const [x, y, w, h] = region.split(",").map(Number);
8222
- const croppedPath = join19(tmpdir5(), `oa-ocr-crop-${Date.now()}.png`);
8615
+ const croppedPath = join20(tmpdir5(), `oa-ocr-crop-${Date.now()}.png`);
8223
8616
  execSync14(`convert ${JSON.stringify(imagePath)} -crop ${w}x${h}+${x}+${y} +repage ${JSON.stringify(croppedPath)}`, { stdio: "pipe", timeout: 1e4 });
8224
8617
  inputPath = croppedPath;
8225
8618
  } catch {
@@ -8231,14 +8624,14 @@ var init_ocr_image_advanced = __esm({
8231
8624
  if (!text) {
8232
8625
  return {
8233
8626
  success: true,
8234
- output: `(no text detected in ${basename7(imagePath)} \u2014 try the advanced Python OCR pipeline for better results)`,
8627
+ output: `(no text detected in ${basename8(imagePath)} \u2014 try the advanced Python OCR pipeline for better results)`,
8235
8628
  durationMs: performance.now() - start
8236
8629
  };
8237
8630
  }
8238
8631
  const lineCount = text.split("\n").length;
8239
8632
  return {
8240
8633
  success: true,
8241
- output: `OCR extracted ${lineCount} lines from ${basename7(imagePath)} (basic tesseract, PSM ${psmArg}):
8634
+ output: `OCR extracted ${lineCount} lines from ${basename8(imagePath)} (basic tesseract, PSM ${psmArg}):
8242
8635
  Note: Advanced Python pipeline not available \u2014 install pytesseract, opencv-python-headless, Pillow, numpy for better results.
8243
8636
 
8244
8637
  ` + text,
@@ -8347,6 +8740,8 @@ var init_dist2 = __esm({
8347
8740
  init_file_edit();
8348
8741
  init_memory_read();
8349
8742
  init_memory_write();
8743
+ init_memory_search();
8744
+ init_explore_tools();
8350
8745
  init_list_directory();
8351
8746
  init_aiwg_setup();
8352
8747
  init_aiwg_health();
@@ -9485,8 +9880,8 @@ var init_code_retriever = __esm({
9485
9880
  });
9486
9881
  }
9487
9882
  async getFileContent(filePath, startLine, endLine) {
9488
- const { readFile: readFile11 } = await import("node:fs/promises");
9489
- const content = await readFile11(filePath, "utf-8");
9883
+ const { readFile: readFile12 } = await import("node:fs/promises");
9884
+ const content = await readFile12(filePath, "utf-8");
9490
9885
  if (startLine === void 0)
9491
9886
  return content;
9492
9887
  const lines = content.split("\n");
@@ -9501,8 +9896,8 @@ var init_code_retriever = __esm({
9501
9896
  // packages/retrieval/dist/lexicalSearch.js
9502
9897
  import { execFile as execFile5 } from "node:child_process";
9503
9898
  import { promisify as promisify4 } from "node:util";
9504
- import { readFile as readFile8, readdir as readdir2, stat as stat3 } from "node:fs/promises";
9505
- import { join as join20, extname as extname7 } from "node:path";
9899
+ import { readFile as readFile9, readdir as readdir3, stat as stat3 } from "node:fs/promises";
9900
+ import { join as join21, extname as extname7 } from "node:path";
9506
9901
  async function searchByPath(pathPattern, options) {
9507
9902
  const allFiles = await collectFiles(options.rootDir, options.includeGlobs ?? DEFAULT_INCLUDE_GLOBS, options.excludeGlobs ?? DEFAULT_EXCLUDE_GLOBS);
9508
9903
  const pattern = options.caseInsensitive ? pathPattern.toLowerCase() : pathPattern;
@@ -9607,7 +10002,7 @@ async function searchWithNodeFallback(pattern, kind, options) {
9607
10002
  if (results.length >= maxMatches)
9608
10003
  break;
9609
10004
  try {
9610
- const content = await readFile8(filePath, "utf-8");
10005
+ const content = await readFile9(filePath, "utf-8");
9611
10006
  const contentLines = content.split("\n");
9612
10007
  for (let i = 0; i < contentLines.length; i++) {
9613
10008
  if (results.length >= maxMatches)
@@ -9635,7 +10030,7 @@ async function collectFiles(rootDir, includeGlobs, excludeGlobs) {
9635
10030
  async function walkForFiles(rootDir, dir, excludeGlobs, results) {
9636
10031
  let entries;
9637
10032
  try {
9638
- entries = await readdir2(dir, { withFileTypes: true, encoding: "utf-8" });
10033
+ entries = await readdir3(dir, { withFileTypes: true, encoding: "utf-8" });
9639
10034
  } catch {
9640
10035
  return;
9641
10036
  }
@@ -9644,7 +10039,7 @@ async function walkForFiles(rootDir, dir, excludeGlobs, results) {
9644
10039
  continue;
9645
10040
  if (excludeGlobs.some((g) => entry.name === g || matchesGlob(entry.name, g)))
9646
10041
  continue;
9647
- const absPath = join20(dir, entry.name);
10042
+ const absPath = join21(dir, entry.name);
9648
10043
  if (entry.isDirectory()) {
9649
10044
  await walkForFiles(rootDir, absPath, excludeGlobs, results);
9650
10045
  } else if (entry.isFile()) {
@@ -9818,8 +10213,8 @@ var init_graphExpand = __esm({
9818
10213
  });
9819
10214
 
9820
10215
  // packages/retrieval/dist/snippetPacker.js
9821
- import { readFile as readFile9 } from "node:fs/promises";
9822
- import { join as join21 } from "node:path";
10216
+ import { readFile as readFile10 } from "node:fs/promises";
10217
+ import { join as join22 } from "node:path";
9823
10218
  async function packSnippets(requests, opts = {}) {
9824
10219
  const maxTokens = opts.maxTokens ?? DEFAULT_MAX_TOKENS;
9825
10220
  const contextLines = opts.contextLines ?? DEFAULT_CONTEXT_LINES;
@@ -9845,10 +10240,10 @@ async function packSnippets(requests, opts = {}) {
9845
10240
  return { packed, dropped, totalTokens };
9846
10241
  }
9847
10242
  async function extractSnippet(req, repoRoot, contextLines = DEFAULT_CONTEXT_LINES) {
9848
- const absPath = req.filePath.startsWith("/") ? req.filePath : join21(repoRoot, req.filePath);
10243
+ const absPath = req.filePath.startsWith("/") ? req.filePath : join22(repoRoot, req.filePath);
9849
10244
  let content;
9850
10245
  try {
9851
- content = await readFile9(absPath, "utf-8");
10246
+ content = await readFile10(absPath, "utf-8");
9852
10247
  } catch {
9853
10248
  return null;
9854
10249
  }
@@ -11451,8 +11846,8 @@ Rules:
11451
11846
  async waitIfPaused() {
11452
11847
  if (!this._paused)
11453
11848
  return true;
11454
- await new Promise((resolve22) => {
11455
- this._pauseResolve = resolve22;
11849
+ await new Promise((resolve23) => {
11850
+ this._pauseResolve = resolve23;
11456
11851
  });
11457
11852
  return !this.aborted;
11458
11853
  }
@@ -11709,6 +12104,15 @@ Integrate this guidance into your current approach. Continue working on the task
11709
12104
  }
11710
12105
  }
11711
12106
  }
12107
+ if (tc.name === "explore_tools" && result.success && result.output.startsWith("UNLOCK_TOOL:")) {
12108
+ const unlockName = result.output.slice("UNLOCK_TOOL:".length).trim();
12109
+ const existingTool = this.tools.get(unlockName);
12110
+ if (existingTool) {
12111
+ result = { success: true, output: `Tool '${unlockName}' is now unlocked and available. You can use it in your next response.` };
12112
+ } else {
12113
+ result = { success: false, output: "", error: `Unknown tool '${unlockName}'. Call explore_tools() with no args to see available tools.` };
12114
+ }
12115
+ }
11712
12116
  const { toolOutputMaxChars: maxLen } = this.contextLimits();
11713
12117
  const output = result.success ? result.output.length > maxLen ? this.foldOutput(result.output, maxLen) : result.output : `Error: ${result.error || "unknown error"}
11714
12118
  ${result.output.length > maxLen ? this.foldOutput(result.output, maxLen) : result.output}`;
@@ -12020,14 +12424,14 @@ ${result.output}`;
12020
12424
  waitForSudoPassword(timeoutMs = 12e4) {
12021
12425
  if (this._sudoPassword)
12022
12426
  return Promise.resolve(this._sudoPassword);
12023
- return new Promise((resolve22) => {
12427
+ return new Promise((resolve23) => {
12024
12428
  const timer = setTimeout(() => {
12025
12429
  this._sudoResolve = null;
12026
- resolve22(null);
12430
+ resolve23(null);
12027
12431
  }, timeoutMs);
12028
12432
  this._sudoResolve = (pw) => {
12029
12433
  clearTimeout(timer);
12030
- resolve22(pw);
12434
+ resolve23(pw);
12031
12435
  };
12032
12436
  });
12033
12437
  }
@@ -12150,8 +12554,8 @@ ${marker}` : marker);
12150
12554
  return;
12151
12555
  try {
12152
12556
  const { mkdirSync: mkdirSync13, writeFileSync: writeFileSync12 } = __require("node:fs");
12153
- const { join: join36 } = __require("node:path");
12154
- const sessionDir = join36(this._workingDirectory, ".oa", "session", this._sessionId);
12557
+ const { join: join37 } = __require("node:path");
12558
+ const sessionDir = join37(this._workingDirectory, ".oa", "session", this._sessionId);
12155
12559
  mkdirSync13(sessionDir, { recursive: true });
12156
12560
  const checkpoint = {
12157
12561
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -12164,7 +12568,7 @@ ${marker}` : marker);
12164
12568
  memexEntryCount: this._memexArchive.size,
12165
12569
  fileRegistrySize: this._fileRegistry.size
12166
12570
  };
12167
- writeFileSync12(join36(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
12571
+ writeFileSync12(join37(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
12168
12572
  } catch {
12169
12573
  }
12170
12574
  }
@@ -13697,9 +14101,9 @@ var init_dist5 = __esm({
13697
14101
 
13698
14102
  // packages/cli/dist/tui/listen.js
13699
14103
  import { spawn as spawn7, execSync as execSync15 } from "node:child_process";
13700
- import { existsSync as existsSync17, mkdirSync as mkdirSync5, writeFileSync as writeFileSync5, readdirSync as readdirSync6 } from "node:fs";
13701
- import { join as join22, dirname as dirname8 } from "node:path";
13702
- import { homedir as homedir7 } from "node:os";
14104
+ import { existsSync as existsSync18, mkdirSync as mkdirSync5, writeFileSync as writeFileSync5, readdirSync as readdirSync6 } from "node:fs";
14105
+ import { join as join23, dirname as dirname8 } from "node:path";
14106
+ import { homedir as homedir8 } from "node:os";
13703
14107
  import { fileURLToPath as fileURLToPath5 } from "node:url";
13704
14108
  import { EventEmitter } from "node:events";
13705
14109
  import { createInterface as createInterface2 } from "node:readline";
@@ -13784,15 +14188,15 @@ function findMicCaptureCommand() {
13784
14188
  function findLiveWhisperScript() {
13785
14189
  const thisDir = dirname8(fileURLToPath5(import.meta.url));
13786
14190
  const candidates = [
13787
- join22(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
13788
- join22(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
13789
- join22(thisDir, "../../execution/scripts/live-whisper.py"),
14191
+ join23(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
14192
+ join23(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
14193
+ join23(thisDir, "../../execution/scripts/live-whisper.py"),
13790
14194
  // npm install layout — scripts bundled alongside dist
13791
- join22(thisDir, "../scripts/live-whisper.py"),
13792
- join22(thisDir, "../../scripts/live-whisper.py")
14195
+ join23(thisDir, "../scripts/live-whisper.py"),
14196
+ join23(thisDir, "../../scripts/live-whisper.py")
13793
14197
  ];
13794
14198
  for (const p of candidates) {
13795
- if (existsSync17(p))
14199
+ if (existsSync18(p))
13796
14200
  return p;
13797
14201
  }
13798
14202
  try {
@@ -13802,21 +14206,21 @@ function findLiveWhisperScript() {
13802
14206
  stdio: ["pipe", "pipe", "pipe"]
13803
14207
  }).trim();
13804
14208
  const candidates2 = [
13805
- join22(globalRoot, "open-agents-ai", "dist", "scripts", "live-whisper.py"),
13806
- join22(globalRoot, "open-agents-ai", "scripts", "live-whisper.py")
14209
+ join23(globalRoot, "open-agents-ai", "dist", "scripts", "live-whisper.py"),
14210
+ join23(globalRoot, "open-agents-ai", "scripts", "live-whisper.py")
13807
14211
  ];
13808
14212
  for (const p of candidates2) {
13809
- if (existsSync17(p))
14213
+ if (existsSync18(p))
13810
14214
  return p;
13811
14215
  }
13812
14216
  } catch {
13813
14217
  }
13814
- const nvmBase = join22(homedir7(), ".nvm", "versions", "node");
13815
- if (existsSync17(nvmBase)) {
14218
+ const nvmBase = join23(homedir8(), ".nvm", "versions", "node");
14219
+ if (existsSync18(nvmBase)) {
13816
14220
  try {
13817
14221
  for (const ver of readdirSync6(nvmBase)) {
13818
- const p = join22(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
13819
- if (existsSync17(p))
14222
+ const p = join23(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
14223
+ if (existsSync18(p))
13820
14224
  return p;
13821
14225
  }
13822
14226
  } catch {
@@ -13834,16 +14238,16 @@ function ensureTranscribeCliBackground() {
13834
14238
  timeout: 5e3,
13835
14239
  stdio: ["pipe", "pipe", "pipe"]
13836
14240
  }).trim();
13837
- if (existsSync17(join22(globalRoot, "transcribe-cli", "dist", "index.js"))) {
14241
+ if (existsSync18(join23(globalRoot, "transcribe-cli", "dist", "index.js"))) {
13838
14242
  return true;
13839
14243
  }
13840
14244
  } catch {
13841
14245
  }
13842
14246
  try {
13843
14247
  const { exec } = await import("node:child_process");
13844
- return new Promise((resolve22) => {
14248
+ return new Promise((resolve23) => {
13845
14249
  exec("npm i -g transcribe-cli", { timeout: 18e4 }, (err) => {
13846
- resolve22(!err);
14250
+ resolve23(!err);
13847
14251
  });
13848
14252
  });
13849
14253
  } catch {
@@ -13896,7 +14300,7 @@ var init_listen = __esm({
13896
14300
  return this._ready;
13897
14301
  }
13898
14302
  async start() {
13899
- return new Promise((resolve22, reject) => {
14303
+ return new Promise((resolve23, reject) => {
13900
14304
  const timeout = setTimeout(() => {
13901
14305
  reject(new Error("Whisper fallback: model load timeout (5 min). First run downloads the model."));
13902
14306
  }, 3e5);
@@ -13924,7 +14328,7 @@ var init_listen = __esm({
13924
14328
  this._ready = true;
13925
14329
  clearTimeout(timeout);
13926
14330
  this.emit("ready");
13927
- resolve22();
14331
+ resolve23();
13928
14332
  break;
13929
14333
  case "transcript":
13930
14334
  this.emit("transcript", {
@@ -14051,24 +14455,24 @@ var init_listen = __esm({
14051
14455
  timeout: 5e3,
14052
14456
  stdio: ["pipe", "pipe", "pipe"]
14053
14457
  }).trim();
14054
- const tcPath = join22(globalRoot, "transcribe-cli");
14055
- if (existsSync17(join22(tcPath, "dist", "index.js"))) {
14458
+ const tcPath = join23(globalRoot, "transcribe-cli");
14459
+ if (existsSync18(join23(tcPath, "dist", "index.js"))) {
14056
14460
  const { createRequire: createRequire4 } = await import("node:module");
14057
14461
  const req = createRequire4(import.meta.url);
14058
- return req(join22(tcPath, "dist", "index.js"));
14462
+ return req(join23(tcPath, "dist", "index.js"));
14059
14463
  }
14060
14464
  } catch {
14061
14465
  }
14062
- const nvmBase = join22(homedir7(), ".nvm", "versions", "node");
14063
- if (existsSync17(nvmBase)) {
14466
+ const nvmBase = join23(homedir8(), ".nvm", "versions", "node");
14467
+ if (existsSync18(nvmBase)) {
14064
14468
  try {
14065
14469
  const { readdirSync: readdirSync11 } = await import("node:fs");
14066
14470
  for (const ver of readdirSync11(nvmBase)) {
14067
- const tcPath = join22(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
14068
- if (existsSync17(join22(tcPath, "dist", "index.js"))) {
14471
+ const tcPath = join23(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
14472
+ if (existsSync18(join23(tcPath, "dist", "index.js"))) {
14069
14473
  const { createRequire: createRequire4 } = await import("node:module");
14070
14474
  const req = createRequire4(import.meta.url);
14071
- return req(join22(tcPath, "dist", "index.js"));
14475
+ return req(join23(tcPath, "dist", "index.js"));
14072
14476
  }
14073
14477
  }
14074
14478
  } catch {
@@ -14128,11 +14532,11 @@ var init_listen = __esm({
14128
14532
  this.liveTranscriber.on("error", (err) => {
14129
14533
  this.emit("error", err);
14130
14534
  });
14131
- await new Promise((resolve22, reject) => {
14535
+ await new Promise((resolve23, reject) => {
14132
14536
  const timeout = setTimeout(() => reject(new Error("Model load timeout (60s)")), 6e4);
14133
14537
  this.liveTranscriber.on("ready", () => {
14134
14538
  clearTimeout(timeout);
14135
- resolve22();
14539
+ resolve23();
14136
14540
  });
14137
14541
  this.liveTranscriber.on("error", (err) => {
14138
14542
  clearTimeout(timeout);
@@ -14293,10 +14697,10 @@ transcribe-cli error: ${transcribeCliError}` : "";
14293
14697
  wordTimestamps: false
14294
14698
  });
14295
14699
  if (outputDir) {
14296
- const { basename: basename13 } = await import("node:path");
14297
- const transcriptDir = join22(outputDir, ".oa", "transcripts");
14700
+ const { basename: basename14 } = await import("node:path");
14701
+ const transcriptDir = join23(outputDir, ".oa", "transcripts");
14298
14702
  mkdirSync5(transcriptDir, { recursive: true });
14299
- const outFile = join22(transcriptDir, `${basename13(filePath)}.txt`);
14703
+ const outFile = join23(transcriptDir, `${basename14(filePath)}.txt`);
14300
14704
  writeFileSync5(outFile, result.text, "utf-8");
14301
14705
  }
14302
14706
  return {
@@ -15568,7 +15972,7 @@ Approach this task thoughtfully:
15568
15972
  });
15569
15973
 
15570
15974
  // packages/prompts/dist/index.js
15571
- import { join as join23, dirname as dirname9 } from "node:path";
15975
+ import { join as join24, dirname as dirname9 } from "node:path";
15572
15976
  import { fileURLToPath as fileURLToPath6 } from "node:url";
15573
15977
  var _dir, _packageRoot;
15574
15978
  var init_dist6 = __esm({
@@ -15579,28 +15983,28 @@ var init_dist6 = __esm({
15579
15983
  init_task_templates();
15580
15984
  init_render2();
15581
15985
  _dir = dirname9(fileURLToPath6(import.meta.url));
15582
- _packageRoot = join23(_dir, "..");
15986
+ _packageRoot = join24(_dir, "..");
15583
15987
  }
15584
15988
  });
15585
15989
 
15586
15990
  // packages/cli/dist/tui/oa-directory.js
15587
- import { existsSync as existsSync18, mkdirSync as mkdirSync6, readFileSync as readFileSync13, writeFileSync as writeFileSync6, readdirSync as readdirSync7, statSync as statSync9, unlinkSync as unlinkSync3 } from "node:fs";
15588
- import { join as join24, relative as relative2, basename as basename8, extname as extname8 } from "node:path";
15589
- import { homedir as homedir8 } from "node:os";
15991
+ import { existsSync as existsSync19, mkdirSync as mkdirSync6, readFileSync as readFileSync13, writeFileSync as writeFileSync6, readdirSync as readdirSync7, statSync as statSync9, unlinkSync as unlinkSync3 } from "node:fs";
15992
+ import { join as join25, relative as relative2, basename as basename9, extname as extname8 } from "node:path";
15993
+ import { homedir as homedir9 } from "node:os";
15590
15994
  function initOaDirectory(repoRoot) {
15591
- const oaPath = join24(repoRoot, OA_DIR);
15995
+ const oaPath = join25(repoRoot, OA_DIR);
15592
15996
  for (const sub of SUBDIRS) {
15593
- mkdirSync6(join24(oaPath, sub), { recursive: true });
15997
+ mkdirSync6(join25(oaPath, sub), { recursive: true });
15594
15998
  }
15595
15999
  return oaPath;
15596
16000
  }
15597
16001
  function hasOaDirectory(repoRoot) {
15598
- return existsSync18(join24(repoRoot, OA_DIR, "index"));
16002
+ return existsSync19(join25(repoRoot, OA_DIR, "index"));
15599
16003
  }
15600
16004
  function loadProjectSettings(repoRoot) {
15601
- const settingsPath = join24(repoRoot, OA_DIR, "settings.json");
16005
+ const settingsPath = join25(repoRoot, OA_DIR, "settings.json");
15602
16006
  try {
15603
- if (existsSync18(settingsPath)) {
16007
+ if (existsSync19(settingsPath)) {
15604
16008
  return JSON.parse(readFileSync13(settingsPath, "utf-8"));
15605
16009
  }
15606
16010
  } catch {
@@ -15608,16 +16012,16 @@ function loadProjectSettings(repoRoot) {
15608
16012
  return {};
15609
16013
  }
15610
16014
  function saveProjectSettings(repoRoot, settings) {
15611
- const oaPath = join24(repoRoot, OA_DIR);
16015
+ const oaPath = join25(repoRoot, OA_DIR);
15612
16016
  mkdirSync6(oaPath, { recursive: true });
15613
16017
  const existing = loadProjectSettings(repoRoot);
15614
16018
  const merged = { ...existing, ...settings };
15615
- writeFileSync6(join24(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", "utf-8");
16019
+ writeFileSync6(join25(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", "utf-8");
15616
16020
  }
15617
16021
  function loadGlobalSettings() {
15618
- const settingsPath = join24(homedir8(), ".open-agents", "settings.json");
16022
+ const settingsPath = join25(homedir9(), ".open-agents", "settings.json");
15619
16023
  try {
15620
- if (existsSync18(settingsPath)) {
16024
+ if (existsSync19(settingsPath)) {
15621
16025
  return JSON.parse(readFileSync13(settingsPath, "utf-8"));
15622
16026
  }
15623
16027
  } catch {
@@ -15625,11 +16029,11 @@ function loadGlobalSettings() {
15625
16029
  return {};
15626
16030
  }
15627
16031
  function saveGlobalSettings(settings) {
15628
- const dir = join24(homedir8(), ".open-agents");
16032
+ const dir = join25(homedir9(), ".open-agents");
15629
16033
  mkdirSync6(dir, { recursive: true });
15630
16034
  const existing = loadGlobalSettings();
15631
16035
  const merged = { ...existing, ...settings };
15632
- writeFileSync6(join24(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", "utf-8");
16036
+ writeFileSync6(join25(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", "utf-8");
15633
16037
  }
15634
16038
  function resolveSettings(repoRoot) {
15635
16039
  const global = loadGlobalSettings();
@@ -15644,9 +16048,9 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
15644
16048
  while (dir && !visited.has(dir)) {
15645
16049
  visited.add(dir);
15646
16050
  for (const name of CONTEXT_FILES) {
15647
- const filePath = join24(dir, name);
16051
+ const filePath = join25(dir, name);
15648
16052
  const normalizedName = name.toLowerCase();
15649
- if (existsSync18(filePath) && !seen.has(filePath)) {
16053
+ if (existsSync19(filePath) && !seen.has(filePath)) {
15650
16054
  seen.add(filePath);
15651
16055
  try {
15652
16056
  let content = readFileSync13(filePath, "utf-8");
@@ -15663,8 +16067,8 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
15663
16067
  }
15664
16068
  }
15665
16069
  }
15666
- const projectMap = join24(dir, OA_DIR, "context", "project-map.md");
15667
- if (existsSync18(projectMap) && !seen.has(projectMap)) {
16070
+ const projectMap = join25(dir, OA_DIR, "context", "project-map.md");
16071
+ if (existsSync19(projectMap) && !seen.has(projectMap)) {
15668
16072
  seen.add(projectMap);
15669
16073
  try {
15670
16074
  let content = readFileSync13(projectMap, "utf-8");
@@ -15679,7 +16083,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
15679
16083
  } catch {
15680
16084
  }
15681
16085
  }
15682
- const parent = join24(dir, "..");
16086
+ const parent = join25(dir, "..");
15683
16087
  if (parent === dir)
15684
16088
  break;
15685
16089
  dir = parent;
@@ -15697,7 +16101,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
15697
16101
  return found;
15698
16102
  }
15699
16103
  function readIndexMeta(repoRoot) {
15700
- const metaPath = join24(repoRoot, OA_DIR, "index", "meta.json");
16104
+ const metaPath = join25(repoRoot, OA_DIR, "index", "meta.json");
15701
16105
  try {
15702
16106
  return JSON.parse(readFileSync13(metaPath, "utf-8"));
15703
16107
  } catch {
@@ -15706,7 +16110,7 @@ function readIndexMeta(repoRoot) {
15706
16110
  }
15707
16111
  function generateProjectMap(repoRoot) {
15708
16112
  const sections = [];
15709
- const repoName2 = basename8(repoRoot);
16113
+ const repoName2 = basename9(repoRoot);
15710
16114
  sections.push(`# Project Map: ${repoName2}
15711
16115
  `);
15712
16116
  sections.push(`> Auto-generated by open-agents. Updated: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
@@ -15750,28 +16154,28 @@ ${tree}\`\`\`
15750
16154
  sections.push("");
15751
16155
  }
15752
16156
  const content = sections.join("\n");
15753
- const contextDir = join24(repoRoot, OA_DIR, "context");
16157
+ const contextDir = join25(repoRoot, OA_DIR, "context");
15754
16158
  mkdirSync6(contextDir, { recursive: true });
15755
- writeFileSync6(join24(contextDir, "project-map.md"), content, "utf-8");
16159
+ writeFileSync6(join25(contextDir, "project-map.md"), content, "utf-8");
15756
16160
  return content;
15757
16161
  }
15758
16162
  function saveSession(repoRoot, session) {
15759
- const historyDir = join24(repoRoot, OA_DIR, "history");
16163
+ const historyDir = join25(repoRoot, OA_DIR, "history");
15760
16164
  mkdirSync6(historyDir, { recursive: true });
15761
- writeFileSync6(join24(historyDir, `${session.id}.json`), JSON.stringify(session, null, 2), "utf-8");
16165
+ writeFileSync6(join25(historyDir, `${session.id}.json`), JSON.stringify(session, null, 2), "utf-8");
15762
16166
  }
15763
16167
  function loadRecentSessions(repoRoot, limit = 5) {
15764
- const historyDir = join24(repoRoot, OA_DIR, "history");
15765
- if (!existsSync18(historyDir))
16168
+ const historyDir = join25(repoRoot, OA_DIR, "history");
16169
+ if (!existsSync19(historyDir))
15766
16170
  return [];
15767
16171
  try {
15768
16172
  const files = readdirSync7(historyDir).filter((f) => f.endsWith(".json") && f !== "pending-task.json").map((f) => {
15769
- const stat5 = statSync9(join24(historyDir, f));
16173
+ const stat5 = statSync9(join25(historyDir, f));
15770
16174
  return { file: f, mtime: stat5.mtimeMs };
15771
16175
  }).sort((a, b) => b.mtime - a.mtime).slice(0, limit);
15772
16176
  return files.map((f) => {
15773
16177
  try {
15774
- return JSON.parse(readFileSync13(join24(historyDir, f.file), "utf-8"));
16178
+ return JSON.parse(readFileSync13(join25(historyDir, f.file), "utf-8"));
15775
16179
  } catch {
15776
16180
  return null;
15777
16181
  }
@@ -15781,14 +16185,14 @@ function loadRecentSessions(repoRoot, limit = 5) {
15781
16185
  }
15782
16186
  }
15783
16187
  function savePendingTask(repoRoot, task) {
15784
- const historyDir = join24(repoRoot, OA_DIR, "history");
16188
+ const historyDir = join25(repoRoot, OA_DIR, "history");
15785
16189
  mkdirSync6(historyDir, { recursive: true });
15786
- writeFileSync6(join24(historyDir, PENDING_TASK_FILE), JSON.stringify(task, null, 2) + "\n", "utf-8");
16190
+ writeFileSync6(join25(historyDir, PENDING_TASK_FILE), JSON.stringify(task, null, 2) + "\n", "utf-8");
15787
16191
  }
15788
16192
  function loadPendingTask(repoRoot) {
15789
- const filePath = join24(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
16193
+ const filePath = join25(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
15790
16194
  try {
15791
- if (!existsSync18(filePath))
16195
+ if (!existsSync19(filePath))
15792
16196
  return null;
15793
16197
  const data = JSON.parse(readFileSync13(filePath, "utf-8"));
15794
16198
  try {
@@ -15801,12 +16205,12 @@ function loadPendingTask(repoRoot) {
15801
16205
  }
15802
16206
  }
15803
16207
  function saveSessionContext(repoRoot, entry) {
15804
- const contextDir = join24(repoRoot, OA_DIR, "context");
16208
+ const contextDir = join25(repoRoot, OA_DIR, "context");
15805
16209
  mkdirSync6(contextDir, { recursive: true });
15806
- const filePath = join24(contextDir, CONTEXT_SAVE_FILE);
16210
+ const filePath = join25(contextDir, CONTEXT_SAVE_FILE);
15807
16211
  let ctx;
15808
16212
  try {
15809
- if (existsSync18(filePath)) {
16213
+ if (existsSync19(filePath)) {
15810
16214
  ctx = JSON.parse(readFileSync13(filePath, "utf-8"));
15811
16215
  } else {
15812
16216
  ctx = { entries: [], maxEntries: MAX_CONTEXT_ENTRIES, updatedAt: "" };
@@ -15822,9 +16226,9 @@ function saveSessionContext(repoRoot, entry) {
15822
16226
  writeFileSync6(filePath, JSON.stringify(ctx, null, 2) + "\n", "utf-8");
15823
16227
  }
15824
16228
  function loadSessionContext(repoRoot) {
15825
- const filePath = join24(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
16229
+ const filePath = join25(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
15826
16230
  try {
15827
- if (!existsSync18(filePath))
16231
+ if (!existsSync19(filePath))
15828
16232
  return null;
15829
16233
  return JSON.parse(readFileSync13(filePath, "utf-8"));
15830
16234
  } catch {
@@ -15873,8 +16277,8 @@ function detectManifests(repoRoot) {
15873
16277
  { file: "docker-compose.yaml", type: "Docker Compose" }
15874
16278
  ];
15875
16279
  for (const check of checks) {
15876
- const filePath = join24(repoRoot, check.file);
15877
- if (existsSync18(filePath)) {
16280
+ const filePath = join25(repoRoot, check.file);
16281
+ if (existsSync19(filePath)) {
15878
16282
  let name;
15879
16283
  if (check.nameField) {
15880
16284
  try {
@@ -15907,7 +16311,7 @@ function findKeyFiles(repoRoot) {
15907
16311
  { pattern: "CLAUDE.md", description: "Claude Code context" }
15908
16312
  ];
15909
16313
  for (const check of checks) {
15910
- if (existsSync18(join24(repoRoot, check.pattern))) {
16314
+ if (existsSync19(join25(repoRoot, check.pattern))) {
15911
16315
  keyFiles.push({ path: check.pattern, description: check.description });
15912
16316
  }
15913
16317
  }
@@ -15933,12 +16337,12 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
15933
16337
  if (entry.isDirectory()) {
15934
16338
  let fileCount = 0;
15935
16339
  try {
15936
- fileCount = readdirSync7(join24(root, entry.name)).filter((f) => !f.startsWith(".")).length;
16340
+ fileCount = readdirSync7(join25(root, entry.name)).filter((f) => !f.startsWith(".")).length;
15937
16341
  } catch {
15938
16342
  }
15939
16343
  result += `${prefix}${connector}${entry.name}/ (${fileCount})
15940
16344
  `;
15941
- result += buildDirTree(join24(root, entry.name), maxDepth, childPrefix, depth + 1);
16345
+ result += buildDirTree(join25(root, entry.name), maxDepth, childPrefix, depth + 1);
15942
16346
  } else if (depth < maxDepth) {
15943
16347
  result += `${prefix}${connector}${entry.name}
15944
16348
  `;
@@ -15992,9 +16396,9 @@ var init_oa_directory = __esm({
15992
16396
  // packages/cli/dist/tui/setup.js
15993
16397
  import * as readline from "node:readline";
15994
16398
  import { execSync as execSync16, spawn as spawn8 } from "node:child_process";
15995
- import { existsSync as existsSync19, writeFileSync as writeFileSync7, mkdirSync as mkdirSync7 } from "node:fs";
15996
- import { join as join25 } from "node:path";
15997
- import { homedir as homedir9, platform } from "node:os";
16399
+ import { existsSync as existsSync20, writeFileSync as writeFileSync7, mkdirSync as mkdirSync7 } from "node:fs";
16400
+ import { join as join26 } from "node:path";
16401
+ import { homedir as homedir10, platform } from "node:os";
15998
16402
  function detectSystemSpecs() {
15999
16403
  let totalRamGB = 0;
16000
16404
  let availableRamGB = 0;
@@ -16077,8 +16481,8 @@ function modelSupportsToolCalling(modelName) {
16077
16481
  return false;
16078
16482
  }
16079
16483
  function ask(rl, question) {
16080
- return new Promise((resolve22) => {
16081
- rl.question(question, (answer) => resolve22(answer.trim()));
16484
+ return new Promise((resolve23) => {
16485
+ rl.question(question, (answer) => resolve23(answer.trim()));
16082
16486
  });
16083
16487
  }
16084
16488
  async function autoInstallOllama(rl) {
@@ -16145,7 +16549,7 @@ async function installOllamaMac(rl) {
16145
16549
  execSync16('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"', { stdio: "inherit", timeout: 6e5 });
16146
16550
  if (!hasCmd("brew")) {
16147
16551
  try {
16148
- const brewPrefix = existsSync19("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
16552
+ const brewPrefix = existsSync20("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
16149
16553
  process.env["PATH"] = `${brewPrefix}/bin:${process.env["PATH"]}`;
16150
16554
  } catch {
16151
16555
  }
@@ -16436,7 +16840,7 @@ async function doSetup(config, rl) {
16436
16840
  try {
16437
16841
  const child = spawn8("ollama", ["serve"], { stdio: "ignore", detached: true });
16438
16842
  child.unref();
16439
- await new Promise((resolve22) => setTimeout(resolve22, 3e3));
16843
+ await new Promise((resolve23) => setTimeout(resolve23, 3e3));
16440
16844
  try {
16441
16845
  models = await fetchOllamaModels(config.backendUrl);
16442
16846
  process.stdout.write(` ${c2.green("\u2714")} Ollama is running.
@@ -16464,7 +16868,7 @@ async function doSetup(config, rl) {
16464
16868
  try {
16465
16869
  const child = spawn8("ollama", ["serve"], { stdio: "ignore", detached: true });
16466
16870
  child.unref();
16467
- await new Promise((resolve22) => setTimeout(resolve22, 3e3));
16871
+ await new Promise((resolve23) => setTimeout(resolve23, 3e3));
16468
16872
  try {
16469
16873
  models = await fetchOllamaModels(config.backendUrl);
16470
16874
  process.stdout.write(` ${c2.green("\u2714")} Ollama is running.
@@ -16619,9 +17023,9 @@ async function doSetup(config, rl) {
16619
17023
  `PARAMETER num_predict ${numPredict}`,
16620
17024
  `PARAMETER stop "<|endoftext|>"`
16621
17025
  ].join("\n");
16622
- const modelDir2 = join25(homedir9(), ".open-agents", "models");
17026
+ const modelDir2 = join26(homedir10(), ".open-agents", "models");
16623
17027
  mkdirSync7(modelDir2, { recursive: true });
16624
- const modelfilePath = join25(modelDir2, `Modelfile.${customName}`);
17028
+ const modelfilePath = join26(modelDir2, `Modelfile.${customName}`);
16625
17029
  writeFileSync7(modelfilePath, modelfileContent + "\n", "utf8");
16626
17030
  process.stdout.write(` ${c2.dim("Creating model...")} `);
16627
17031
  execSync16(`ollama create ${customName} -f ${modelfilePath}`, {
@@ -16667,7 +17071,7 @@ async function isModelAvailable(config) {
16667
17071
  }
16668
17072
  function isFirstRun() {
16669
17073
  try {
16670
- return !existsSync19(join25(homedir9(), ".open-agents", "config.json"));
17074
+ return !existsSync20(join26(homedir10(), ".open-agents", "config.json"));
16671
17075
  } catch {
16672
17076
  return true;
16673
17077
  }
@@ -16704,7 +17108,7 @@ function detectPkgManager() {
16704
17108
  return null;
16705
17109
  }
16706
17110
  function getVenvDir() {
16707
- return join25(homedir9(), ".open-agents", "venv");
17111
+ return join26(homedir10(), ".open-agents", "venv");
16708
17112
  }
16709
17113
  function hasVenvModule() {
16710
17114
  try {
@@ -16716,8 +17120,8 @@ function hasVenvModule() {
16716
17120
  }
16717
17121
  function ensureVenv(log) {
16718
17122
  const venvDir = getVenvDir();
16719
- const venvPip = join25(venvDir, "bin", "pip");
16720
- if (existsSync19(venvPip))
17123
+ const venvPip = join26(venvDir, "bin", "pip");
17124
+ if (existsSync20(venvPip))
16721
17125
  return venvDir;
16722
17126
  log("Creating Python venv for vision deps...");
16723
17127
  if (!hasCmd("python3")) {
@@ -16729,9 +17133,9 @@ function ensureVenv(log) {
16729
17133
  return null;
16730
17134
  }
16731
17135
  try {
16732
- mkdirSync7(join25(homedir9(), ".open-agents"), { recursive: true });
17136
+ mkdirSync7(join26(homedir10(), ".open-agents"), { recursive: true });
16733
17137
  execSync16(`python3 -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
16734
- execSync16(`"${join25(venvDir, "bin", "pip")}" install --upgrade pip`, {
17138
+ execSync16(`"${join26(venvDir, "bin", "pip")}" install --upgrade pip`, {
16735
17139
  stdio: "pipe",
16736
17140
  timeout: 6e4
16737
17141
  });
@@ -16940,15 +17344,15 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
16940
17344
  }
16941
17345
  }
16942
17346
  const venvDir = getVenvDir();
16943
- const venvBin = join25(venvDir, "bin");
16944
- const venvMoondream = join25(venvBin, "moondream-station");
17347
+ const venvBin = join26(venvDir, "bin");
17348
+ const venvMoondream = join26(venvBin, "moondream-station");
16945
17349
  const venv = ensureVenv(log);
16946
- if (venv && !hasCmd("moondream-station") && !existsSync19(venvMoondream)) {
16947
- const venvPip = join25(venvBin, "pip");
17350
+ if (venv && !hasCmd("moondream-station") && !existsSync20(venvMoondream)) {
17351
+ const venvPip = join26(venvBin, "pip");
16948
17352
  log("Installing moondream-station in ~/.open-agents/venv...");
16949
17353
  try {
16950
17354
  execSync16(`"${venvPip}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
16951
- if (existsSync19(venvMoondream)) {
17355
+ if (existsSync20(venvMoondream)) {
16952
17356
  log("moondream-station installed successfully.");
16953
17357
  } else {
16954
17358
  try {
@@ -16965,8 +17369,8 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
16965
17369
  }
16966
17370
  }
16967
17371
  if (venv) {
16968
- const venvPython = join25(venvBin, "python");
16969
- const venvPip2 = join25(venvBin, "pip");
17372
+ const venvPython = join26(venvBin, "python");
17373
+ const venvPip2 = join26(venvBin, "pip");
16970
17374
  let ocrStackInstalled = false;
16971
17375
  try {
16972
17376
  execSync16(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
@@ -17026,9 +17430,9 @@ function createExpandedVariant(baseModel, specs, sizeGB) {
17026
17430
  `PARAMETER num_predict ${numPredict}`,
17027
17431
  `PARAMETER stop "<|endoftext|>"`
17028
17432
  ].join("\n");
17029
- const modelDir2 = join25(homedir9(), ".open-agents", "models");
17433
+ const modelDir2 = join26(homedir10(), ".open-agents", "models");
17030
17434
  mkdirSync7(modelDir2, { recursive: true });
17031
- const modelfilePath = join25(modelDir2, `Modelfile.${customName}`);
17435
+ const modelfilePath = join26(modelDir2, `Modelfile.${customName}`);
17032
17436
  writeFileSync7(modelfilePath, modelfileContent + "\n", "utf8");
17033
17437
  execSync16(`ollama create ${customName} -f ${modelfilePath}`, {
17034
17438
  stdio: "pipe",
@@ -17792,17 +18196,17 @@ async function handleUpdate(subcommand, ctx) {
17792
18196
  try {
17793
18197
  const { createRequire: createRequire4 } = await import("node:module");
17794
18198
  const { fileURLToPath: fileURLToPath9 } = await import("node:url");
17795
- const { dirname: dirname12, join: join36 } = await import("node:path");
17796
- const { existsSync: existsSync26 } = await import("node:fs");
18199
+ const { dirname: dirname12, join: join37 } = await import("node:path");
18200
+ const { existsSync: existsSync27 } = await import("node:fs");
17797
18201
  const req = createRequire4(import.meta.url);
17798
18202
  const thisDir = dirname12(fileURLToPath9(import.meta.url));
17799
18203
  const candidates = [
17800
- join36(thisDir, "..", "package.json"),
17801
- join36(thisDir, "..", "..", "package.json"),
17802
- join36(thisDir, "..", "..", "..", "package.json")
18204
+ join37(thisDir, "..", "package.json"),
18205
+ join37(thisDir, "..", "..", "package.json"),
18206
+ join37(thisDir, "..", "..", "..", "package.json")
17803
18207
  ];
17804
18208
  for (const pkgPath of candidates) {
17805
- if (existsSync26(pkgPath)) {
18209
+ if (existsSync27(pkgPath)) {
17806
18210
  const pkg = req(pkgPath);
17807
18211
  if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
17808
18212
  currentVersion = pkg.version ?? "0.0.0";
@@ -17917,10 +18321,10 @@ var init_commands = __esm({
17917
18321
  });
17918
18322
 
17919
18323
  // packages/cli/dist/tui/project-context.js
17920
- import { existsSync as existsSync20, readFileSync as readFileSync14, readdirSync as readdirSync8 } from "node:fs";
17921
- import { join as join26, basename as basename9 } from "node:path";
18324
+ import { existsSync as existsSync21, readFileSync as readFileSync14, readdirSync as readdirSync8 } from "node:fs";
18325
+ import { join as join27, basename as basename10 } from "node:path";
17922
18326
  import { execSync as execSync17 } from "node:child_process";
17923
- import { homedir as homedir10, platform as platform2, release } from "node:os";
18327
+ import { homedir as homedir11, platform as platform2, release } from "node:os";
17924
18328
  function getModelTier(modelName) {
17925
18329
  const m = modelName.toLowerCase();
17926
18330
  const sizeMatch = m.match(/\b(\d+)b\b/);
@@ -17953,8 +18357,8 @@ function loadProjectMap(repoRoot) {
17953
18357
  if (!hasOaDirectory(repoRoot)) {
17954
18358
  initOaDirectory(repoRoot);
17955
18359
  }
17956
- const mapPath = join26(repoRoot, OA_DIR, "context", "project-map.md");
17957
- if (existsSync20(mapPath)) {
18360
+ const mapPath = join27(repoRoot, OA_DIR, "context", "project-map.md");
18361
+ if (existsSync21(mapPath)) {
17958
18362
  try {
17959
18363
  const content = readFileSync14(mapPath, "utf-8");
17960
18364
  return content;
@@ -17997,33 +18401,33 @@ ${log}`);
17997
18401
  }
17998
18402
  function loadMemoryContext(repoRoot) {
17999
18403
  const sections = [];
18000
- const oaMemDir = join26(repoRoot, OA_DIR, "memory");
18404
+ const oaMemDir = join27(repoRoot, OA_DIR, "memory");
18001
18405
  const oaEntries = loadMemoryDir(oaMemDir, "project");
18002
18406
  if (oaEntries)
18003
18407
  sections.push(oaEntries);
18004
- const legacyMemDir = join26(repoRoot, ".open-agents", "memory");
18005
- if (legacyMemDir !== oaMemDir && existsSync20(legacyMemDir)) {
18408
+ const legacyMemDir = join27(repoRoot, ".open-agents", "memory");
18409
+ if (legacyMemDir !== oaMemDir && existsSync21(legacyMemDir)) {
18006
18410
  const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
18007
18411
  if (legacyEntries)
18008
18412
  sections.push(legacyEntries);
18009
18413
  }
18010
- const globalMemDir = join26(homedir10(), ".open-agents", "memory");
18414
+ const globalMemDir = join27(homedir11(), ".open-agents", "memory");
18011
18415
  const globalEntries = loadMemoryDir(globalMemDir, "global");
18012
18416
  if (globalEntries)
18013
18417
  sections.push(globalEntries);
18014
18418
  return sections.join("\n\n");
18015
18419
  }
18016
18420
  function loadMemoryDir(memDir, scope) {
18017
- if (!existsSync20(memDir))
18421
+ if (!existsSync21(memDir))
18018
18422
  return "";
18019
18423
  const lines = [];
18020
18424
  try {
18021
18425
  const files = readdirSync8(memDir).filter((f) => f.endsWith(".json"));
18022
18426
  for (const file of files.slice(0, 10)) {
18023
18427
  try {
18024
- const raw = readFileSync14(join26(memDir, file), "utf-8");
18428
+ const raw = readFileSync14(join27(memDir, file), "utf-8");
18025
18429
  const entries = JSON.parse(raw);
18026
- const topic = basename9(file, ".json");
18430
+ const topic = basename10(file, ".json");
18027
18431
  const keys = Object.keys(entries);
18028
18432
  if (keys.length === 0)
18029
18433
  continue;
@@ -19048,12 +19452,12 @@ var init_carousel = __esm({
19048
19452
  });
19049
19453
 
19050
19454
  // packages/cli/dist/tui/carousel-descriptors.js
19051
- import { existsSync as existsSync21, readFileSync as readFileSync15, writeFileSync as writeFileSync8, mkdirSync as mkdirSync8, readdirSync as readdirSync9 } from "node:fs";
19052
- import { join as join27, basename as basename10 } from "node:path";
19455
+ import { existsSync as existsSync22, readFileSync as readFileSync15, writeFileSync as writeFileSync8, mkdirSync as mkdirSync8, readdirSync as readdirSync9 } from "node:fs";
19456
+ import { join as join28, basename as basename11 } from "node:path";
19053
19457
  function loadToolProfile(repoRoot) {
19054
- const filePath = join27(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
19458
+ const filePath = join28(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
19055
19459
  try {
19056
- if (!existsSync21(filePath))
19460
+ if (!existsSync22(filePath))
19057
19461
  return null;
19058
19462
  return JSON.parse(readFileSync15(filePath, "utf-8"));
19059
19463
  } catch {
@@ -19061,9 +19465,9 @@ function loadToolProfile(repoRoot) {
19061
19465
  }
19062
19466
  }
19063
19467
  function saveToolProfile(repoRoot, profile) {
19064
- const contextDir = join27(repoRoot, OA_DIR, "context");
19468
+ const contextDir = join28(repoRoot, OA_DIR, "context");
19065
19469
  mkdirSync8(contextDir, { recursive: true });
19066
- writeFileSync8(join27(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
19470
+ writeFileSync8(join28(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
19067
19471
  }
19068
19472
  function categorizeToolCall(toolName) {
19069
19473
  for (const cat of TOOL_CATEGORIES) {
@@ -19121,9 +19525,9 @@ function weightedColor(profile) {
19121
19525
  return selectedCat.colors[Math.floor(Math.random() * selectedCat.colors.length)];
19122
19526
  }
19123
19527
  function loadCachedDescriptors(repoRoot) {
19124
- const filePath = join27(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
19528
+ const filePath = join28(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
19125
19529
  try {
19126
- if (!existsSync21(filePath))
19530
+ if (!existsSync22(filePath))
19127
19531
  return null;
19128
19532
  const cached = JSON.parse(readFileSync15(filePath, "utf-8"));
19129
19533
  return cached.phrases.length > 0 ? cached.phrases : null;
@@ -19132,14 +19536,14 @@ function loadCachedDescriptors(repoRoot) {
19132
19536
  }
19133
19537
  }
19134
19538
  function saveCachedDescriptors(repoRoot, phrases, sourceHash) {
19135
- const contextDir = join27(repoRoot, OA_DIR, "context");
19539
+ const contextDir = join28(repoRoot, OA_DIR, "context");
19136
19540
  mkdirSync8(contextDir, { recursive: true });
19137
19541
  const cached = {
19138
19542
  phrases,
19139
19543
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
19140
19544
  sourceHash
19141
19545
  };
19142
- writeFileSync8(join27(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
19546
+ writeFileSync8(join28(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
19143
19547
  }
19144
19548
  function generateDescriptors(repoRoot) {
19145
19549
  const profile = loadToolProfile(repoRoot);
@@ -19150,7 +19554,7 @@ function generateDescriptors(repoRoot) {
19150
19554
  extractFromSessions(repoRoot, tags);
19151
19555
  extractFromMemory(repoRoot, tags);
19152
19556
  extractFromToolProfile(profile, tags);
19153
- const repoName2 = basename10(repoRoot);
19557
+ const repoName2 = basename11(repoRoot);
19154
19558
  if (repoName2 && !tags.includes(repoName2)) {
19155
19559
  tags.push(repoName2);
19156
19560
  }
@@ -19187,9 +19591,9 @@ function generateDescriptors(repoRoot) {
19187
19591
  return phrases;
19188
19592
  }
19189
19593
  function extractFromPackageJson(repoRoot, tags) {
19190
- const pkgPath = join27(repoRoot, "package.json");
19594
+ const pkgPath = join28(repoRoot, "package.json");
19191
19595
  try {
19192
- if (!existsSync21(pkgPath))
19596
+ if (!existsSync22(pkgPath))
19193
19597
  return;
19194
19598
  const pkg = JSON.parse(readFileSync15(pkgPath, "utf-8"));
19195
19599
  if (pkg.name && typeof pkg.name === "string") {
@@ -19235,7 +19639,7 @@ function extractFromManifests(repoRoot, tags) {
19235
19639
  { file: ".github/workflows", tag: "ci/cd" }
19236
19640
  ];
19237
19641
  for (const check of manifestChecks) {
19238
- if (existsSync21(join27(repoRoot, check.file))) {
19642
+ if (existsSync22(join28(repoRoot, check.file))) {
19239
19643
  tags.push(check.tag);
19240
19644
  }
19241
19645
  }
@@ -19257,16 +19661,16 @@ function extractFromSessions(repoRoot, tags) {
19257
19661
  }
19258
19662
  }
19259
19663
  function extractFromMemory(repoRoot, tags) {
19260
- const memoryDir = join27(repoRoot, OA_DIR, "memory");
19664
+ const memoryDir = join28(repoRoot, OA_DIR, "memory");
19261
19665
  try {
19262
- if (!existsSync21(memoryDir))
19666
+ if (!existsSync22(memoryDir))
19263
19667
  return;
19264
19668
  const files = readdirSync9(memoryDir).filter((f) => f.endsWith(".json"));
19265
19669
  for (const file of files) {
19266
19670
  const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
19267
19671
  tags.push(topic);
19268
19672
  try {
19269
- const data = JSON.parse(readFileSync15(join27(memoryDir, file), "utf-8"));
19673
+ const data = JSON.parse(readFileSync15(join28(memoryDir, file), "utf-8"));
19270
19674
  if (data && typeof data === "object") {
19271
19675
  const keys = Object.keys(data).slice(0, 3);
19272
19676
  for (const key of keys) {
@@ -19401,25 +19805,25 @@ var init_carousel_descriptors = __esm({
19401
19805
  });
19402
19806
 
19403
19807
  // packages/cli/dist/tui/voice.js
19404
- import { existsSync as existsSync22, mkdirSync as mkdirSync9, writeFileSync as writeFileSync9, readFileSync as readFileSync16, unlinkSync as unlinkSync4 } from "node:fs";
19405
- import { join as join28 } from "node:path";
19406
- import { homedir as homedir11, tmpdir as tmpdir6, platform as platform3 } from "node:os";
19808
+ import { existsSync as existsSync23, mkdirSync as mkdirSync9, writeFileSync as writeFileSync9, readFileSync as readFileSync16, unlinkSync as unlinkSync4 } from "node:fs";
19809
+ import { join as join29 } from "node:path";
19810
+ import { homedir as homedir12, tmpdir as tmpdir6, platform as platform3 } from "node:os";
19407
19811
  import { execSync as execSync18, spawn as nodeSpawn } from "node:child_process";
19408
19812
  import { createRequire } from "node:module";
19409
19813
  function voiceDir() {
19410
- return join28(homedir11(), ".open-agents", "voice");
19814
+ return join29(homedir12(), ".open-agents", "voice");
19411
19815
  }
19412
19816
  function modelsDir() {
19413
- return join28(voiceDir(), "models");
19817
+ return join29(voiceDir(), "models");
19414
19818
  }
19415
19819
  function modelDir(id) {
19416
- return join28(modelsDir(), id);
19820
+ return join29(modelsDir(), id);
19417
19821
  }
19418
19822
  function modelOnnxPath(id) {
19419
- return join28(modelDir(id), "model.onnx");
19823
+ return join29(modelDir(id), "model.onnx");
19420
19824
  }
19421
19825
  function modelConfigPath(id) {
19422
- return join28(modelDir(id), "config.json");
19826
+ return join29(modelDir(id), "config.json");
19423
19827
  }
19424
19828
  function describeToolCall(toolName, args) {
19425
19829
  const path = args["path"];
@@ -19692,7 +20096,7 @@ var init_voice = __esm({
19692
20096
  const audioData = result["output"].data;
19693
20097
  if (audioData.length === 0)
19694
20098
  return;
19695
- const wavPath = join28(tmpdir6(), `oa-voice-${Date.now()}.wav`);
20099
+ const wavPath = join29(tmpdir6(), `oa-voice-${Date.now()}.wav`);
19696
20100
  this.writeWav(audioData, this.config.audio.sample_rate, wavPath);
19697
20101
  await this.playWav(wavPath);
19698
20102
  try {
@@ -19781,7 +20185,7 @@ var init_voice = __esm({
19781
20185
  const cmd = this.getPlayCommand(path);
19782
20186
  if (!cmd)
19783
20187
  return;
19784
- return new Promise((resolve22) => {
20188
+ return new Promise((resolve23) => {
19785
20189
  const child = nodeSpawn(cmd[0], cmd.slice(1), {
19786
20190
  stdio: "ignore",
19787
20191
  detached: false
@@ -19790,12 +20194,12 @@ var init_voice = __esm({
19790
20194
  child.on("close", () => {
19791
20195
  if (this.currentPlayback === child)
19792
20196
  this.currentPlayback = null;
19793
- resolve22();
20197
+ resolve23();
19794
20198
  });
19795
20199
  child.on("error", () => {
19796
20200
  if (this.currentPlayback === child)
19797
20201
  this.currentPlayback = null;
19798
- resolve22();
20202
+ resolve23();
19799
20203
  });
19800
20204
  setTimeout(() => {
19801
20205
  if (this.currentPlayback === child) {
@@ -19805,7 +20209,7 @@ var init_voice = __esm({
19805
20209
  }
19806
20210
  this.currentPlayback = null;
19807
20211
  }
19808
- resolve22();
20212
+ resolve23();
19809
20213
  }, 15e3);
19810
20214
  });
19811
20215
  }
@@ -19847,12 +20251,12 @@ var init_voice = __esm({
19847
20251
  const arch = process.arch;
19848
20252
  const isArmLinux = (arch === "arm64" || arch === "arm") && process.platform === "linux";
19849
20253
  mkdirSync9(voiceDir(), { recursive: true });
19850
- const pkgPath = join28(voiceDir(), "package.json");
20254
+ const pkgPath = join29(voiceDir(), "package.json");
19851
20255
  const expectedDeps = {
19852
20256
  "onnxruntime-node": "^1.21.0",
19853
20257
  "phonemizer": "^1.2.1"
19854
20258
  };
19855
- if (existsSync22(pkgPath)) {
20259
+ if (existsSync23(pkgPath)) {
19856
20260
  try {
19857
20261
  const existing = JSON.parse(readFileSync16(pkgPath, "utf8"));
19858
20262
  if (!existing.dependencies?.["phonemizer"]) {
@@ -19862,14 +20266,14 @@ var init_voice = __esm({
19862
20266
  } catch {
19863
20267
  }
19864
20268
  }
19865
- if (!existsSync22(pkgPath)) {
20269
+ if (!existsSync23(pkgPath)) {
19866
20270
  writeFileSync9(pkgPath, JSON.stringify({
19867
20271
  name: "open-agents-voice",
19868
20272
  private: true,
19869
20273
  dependencies: expectedDeps
19870
20274
  }, null, 2));
19871
20275
  }
19872
- const voiceRequire = createRequire(join28(voiceDir(), "index.js"));
20276
+ const voiceRequire = createRequire(join29(voiceDir(), "index.js"));
19873
20277
  try {
19874
20278
  this.ort = voiceRequire("onnxruntime-node");
19875
20279
  } catch {
@@ -19923,10 +20327,10 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
19923
20327
  const dir = modelDir(id);
19924
20328
  const onnxPath = modelOnnxPath(id);
19925
20329
  const configPath = modelConfigPath(id);
19926
- if (existsSync22(onnxPath) && existsSync22(configPath))
20330
+ if (existsSync23(onnxPath) && existsSync23(configPath))
19927
20331
  return;
19928
20332
  mkdirSync9(dir, { recursive: true });
19929
- if (!existsSync22(configPath)) {
20333
+ if (!existsSync23(configPath)) {
19930
20334
  renderInfo(`Downloading ${model.label} voice config...`);
19931
20335
  const configResp = await fetch(model.configUrl);
19932
20336
  if (!configResp.ok)
@@ -19934,7 +20338,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
19934
20338
  const configText = await configResp.text();
19935
20339
  writeFileSync9(configPath, configText);
19936
20340
  }
19937
- if (!existsSync22(onnxPath)) {
20341
+ if (!existsSync23(onnxPath)) {
19938
20342
  renderInfo(`Downloading ${model.label} voice model (this may take a minute)...`);
19939
20343
  const onnxResp = await fetch(model.onnxUrl);
19940
20344
  if (!onnxResp.ok)
@@ -19970,7 +20374,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
19970
20374
  throw new Error("ONNX runtime not loaded");
19971
20375
  const onnxPath = modelOnnxPath(this.modelId);
19972
20376
  const configPath = modelConfigPath(this.modelId);
19973
- if (!existsSync22(onnxPath) || !existsSync22(configPath)) {
20377
+ if (!existsSync23(onnxPath) || !existsSync23(configPath)) {
19974
20378
  throw new Error(`Model files not found for ${this.modelId}`);
19975
20379
  }
19976
20380
  this.config = JSON.parse(readFileSync16(configPath, "utf8"));
@@ -20474,10 +20878,10 @@ var init_stream_renderer = __esm({
20474
20878
 
20475
20879
  // packages/cli/dist/tui/edit-history.js
20476
20880
  import { appendFileSync, mkdirSync as mkdirSync10 } from "node:fs";
20477
- import { join as join29 } from "node:path";
20881
+ import { join as join30 } from "node:path";
20478
20882
  function createEditHistoryLogger(repoRoot, sessionId) {
20479
- const historyDir = join29(repoRoot, ".oa", "history");
20480
- const logPath = join29(historyDir, "edits.jsonl");
20883
+ const historyDir = join30(repoRoot, ".oa", "history");
20884
+ const logPath = join30(historyDir, "edits.jsonl");
20481
20885
  try {
20482
20886
  mkdirSync10(historyDir, { recursive: true });
20483
20887
  } catch {
@@ -20588,8 +20992,8 @@ var init_edit_history = __esm({
20588
20992
  });
20589
20993
 
20590
20994
  // packages/cli/dist/tui/dream-engine.js
20591
- import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync10, readFileSync as readFileSync17, existsSync as existsSync23, cpSync, rmSync, readdirSync as readdirSync10 } from "node:fs";
20592
- import { join as join30, basename as basename11 } from "node:path";
20995
+ import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync10, readFileSync as readFileSync17, existsSync as existsSync24, cpSync, rmSync, readdirSync as readdirSync10 } from "node:fs";
20996
+ import { join as join31, basename as basename12 } from "node:path";
20593
20997
  import { execSync as execSync19 } from "node:child_process";
20594
20998
  function adaptTool(tool) {
20595
20999
  return {
@@ -20764,12 +21168,12 @@ var init_dream_engine = __esm({
20764
21168
  const content = String(args["content"] ?? "");
20765
21169
  if (!rawPath)
20766
21170
  return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
20767
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join30(this.dreamsDir, basename11(rawPath)) : join30(this.dreamsDir, rawPath);
21171
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join31(this.dreamsDir, basename12(rawPath)) : join31(this.dreamsDir, rawPath);
20768
21172
  if (!targetPath.startsWith(this.dreamsDir)) {
20769
21173
  return { success: false, output: "", error: "Dream mode: writes are confined to .oa/dreams/", durationMs: Date.now() - start };
20770
21174
  }
20771
21175
  try {
20772
- const dir = join30(targetPath, "..");
21176
+ const dir = join31(targetPath, "..");
20773
21177
  mkdirSync11(dir, { recursive: true });
20774
21178
  writeFileSync10(targetPath, content, "utf-8");
20775
21179
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
@@ -20799,12 +21203,12 @@ var init_dream_engine = __esm({
20799
21203
  const rawPath = String(args["path"] ?? "");
20800
21204
  const oldStr = String(args["old_string"] ?? "");
20801
21205
  const newStr = String(args["new_string"] ?? "");
20802
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join30(this.dreamsDir, basename11(rawPath)) : join30(this.dreamsDir, rawPath);
21206
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join31(this.dreamsDir, basename12(rawPath)) : join31(this.dreamsDir, rawPath);
20803
21207
  if (!targetPath.startsWith(this.dreamsDir)) {
20804
21208
  return { success: false, output: "", error: "Dream mode: edits are confined to .oa/dreams/", durationMs: Date.now() - start };
20805
21209
  }
20806
21210
  try {
20807
- if (!existsSync23(targetPath)) {
21211
+ if (!existsSync24(targetPath)) {
20808
21212
  return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
20809
21213
  }
20810
21214
  let content = readFileSync17(targetPath, "utf-8");
@@ -20866,7 +21270,7 @@ var init_dream_engine = __esm({
20866
21270
  constructor(config, repoRoot) {
20867
21271
  this.config = config;
20868
21272
  this.repoRoot = repoRoot;
20869
- this.dreamsDir = join30(repoRoot, ".oa", "dreams");
21273
+ this.dreamsDir = join31(repoRoot, ".oa", "dreams");
20870
21274
  this.state = {
20871
21275
  mode: "default",
20872
21276
  active: false,
@@ -20938,7 +21342,7 @@ ${result.summary}`;
20938
21342
  if (mode !== "default" || cycle === totalCycles) {
20939
21343
  renderDreamContraction(cycle);
20940
21344
  const cycleSummary = this.buildCycleSummary(cycle, previousFindings);
20941
- const summaryPath = join30(this.dreamsDir, `cycle-${cycle}-summary.md`);
21345
+ const summaryPath = join31(this.dreamsDir, `cycle-${cycle}-summary.md`);
20942
21346
  writeFileSync10(summaryPath, cycleSummary, "utf-8");
20943
21347
  }
20944
21348
  if (mode === "lucid" && !this.abortController.signal.aborted) {
@@ -21061,7 +21465,7 @@ Dreams directory: ${this.dreamsDir}`);
21061
21465
  }
21062
21466
  /** Save workspace backup for lucid mode */
21063
21467
  saveVersionCheckpoint(cycle) {
21064
- const checkpointDir = join30(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
21468
+ const checkpointDir = join31(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
21065
21469
  try {
21066
21470
  mkdirSync11(checkpointDir, { recursive: true });
21067
21471
  try {
@@ -21080,10 +21484,10 @@ Dreams directory: ${this.dreamsDir}`);
21080
21484
  encoding: "utf-8",
21081
21485
  timeout: 5e3
21082
21486
  }).trim();
21083
- writeFileSync10(join30(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
21084
- writeFileSync10(join30(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
21085
- writeFileSync10(join30(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
21086
- writeFileSync10(join30(checkpointDir, "checkpoint.json"), JSON.stringify({
21487
+ writeFileSync10(join31(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
21488
+ writeFileSync10(join31(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
21489
+ writeFileSync10(join31(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
21490
+ writeFileSync10(join31(checkpointDir, "checkpoint.json"), JSON.stringify({
21087
21491
  cycle,
21088
21492
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
21089
21493
  gitHash,
@@ -21091,7 +21495,7 @@ Dreams directory: ${this.dreamsDir}`);
21091
21495
  }, null, 2), "utf-8");
21092
21496
  renderInfo(`Checkpoint saved: cycle ${cycle} (${gitHash.slice(0, 8)})`);
21093
21497
  } catch {
21094
- writeFileSync10(join30(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
21498
+ writeFileSync10(join31(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
21095
21499
  renderInfo(`Checkpoint saved: cycle ${cycle} (no git)`);
21096
21500
  }
21097
21501
  } catch (err) {
@@ -21149,14 +21553,14 @@ ${files.map((f) => `- [\`${f}\`](./${f})`).join("\n")}
21149
21553
  ---
21150
21554
  *Auto-generated by open-agents dream engine*
21151
21555
  `;
21152
- writeFileSync10(join30(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
21556
+ writeFileSync10(join31(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
21153
21557
  } catch {
21154
21558
  }
21155
21559
  }
21156
21560
  /** Save dream state for resume/inspection */
21157
21561
  saveDreamState() {
21158
21562
  try {
21159
- writeFileSync10(join30(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
21563
+ writeFileSync10(join31(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
21160
21564
  } catch {
21161
21565
  }
21162
21566
  }
@@ -22024,11 +22428,11 @@ var init_status_bar = __esm({
22024
22428
  import * as readline2 from "node:readline";
22025
22429
  import { Writable } from "node:stream";
22026
22430
  import { cwd } from "node:process";
22027
- import { resolve as resolve19, join as join31, dirname as dirname10, extname as extname9 } from "node:path";
22431
+ import { resolve as resolve20, join as join32, dirname as dirname10, extname as extname9 } from "node:path";
22028
22432
  import { createRequire as createRequire2 } from "node:module";
22029
22433
  import { fileURLToPath as fileURLToPath7 } from "node:url";
22030
22434
  import { readFileSync as readFileSync18, rmSync as rmSync2 } from "node:fs";
22031
- import { existsSync as existsSync24 } from "node:fs";
22435
+ import { existsSync as existsSync25 } from "node:fs";
22032
22436
  function formatTimeAgo(date) {
22033
22437
  const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
22034
22438
  if (seconds < 60)
@@ -22047,12 +22451,12 @@ function getVersion() {
22047
22451
  const require2 = createRequire2(import.meta.url);
22048
22452
  const thisDir = dirname10(fileURLToPath7(import.meta.url));
22049
22453
  const candidates = [
22050
- join31(thisDir, "..", "package.json"),
22051
- join31(thisDir, "..", "..", "package.json"),
22052
- join31(thisDir, "..", "..", "..", "package.json")
22454
+ join32(thisDir, "..", "package.json"),
22455
+ join32(thisDir, "..", "..", "package.json"),
22456
+ join32(thisDir, "..", "..", "..", "package.json")
22053
22457
  ];
22054
22458
  for (const pkgPath of candidates) {
22055
- if (existsSync24(pkgPath)) {
22459
+ if (existsSync25(pkgPath)) {
22056
22460
  const pkg = require2(pkgPath);
22057
22461
  if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
22058
22462
  return pkg.version ?? "0.0.0";
@@ -22104,6 +22508,8 @@ function buildTools(repoRoot, config, contextWindowSize) {
22104
22508
  new WebCrawlTool(repoRoot),
22105
22509
  new MemoryReadTool(repoRoot),
22106
22510
  new MemoryWriteTool(repoRoot),
22511
+ new MemorySearchTool(repoRoot),
22512
+ new ExploreToolsTool(),
22107
22513
  // AIWG SDLC tools (auto-detect if aiwg is installed)
22108
22514
  new AiwgSetupTool(repoRoot),
22109
22515
  new AiwgHealthTool(repoRoot),
@@ -22519,7 +22925,7 @@ ${entry.fullContent}`
22519
22925
  } };
22520
22926
  }
22521
22927
  async function startInteractive(config, repoPath) {
22522
- const repoRoot = resolve19(repoPath ?? cwd());
22928
+ const repoRoot = resolve20(repoPath ?? cwd());
22523
22929
  const resumeFlag = process.env.__OA_RESUMED ?? "";
22524
22930
  const isResumed = resumeFlag !== "";
22525
22931
  const hasTaskToResume = resumeFlag === "1";
@@ -22671,14 +23077,14 @@ async function startInteractive(config, repoPath) {
22671
23077
  renderInfo(msg);
22672
23078
  statusBar.endContentWrite();
22673
23079
  }
22674
- }, () => new Promise((resolve22) => {
23080
+ }, () => new Promise((resolve23) => {
22675
23081
  depSudoPromptPending = true;
22676
23082
  depSudoResolver = (pw) => {
22677
23083
  depSudoPromptPending = false;
22678
23084
  depSudoResolver = null;
22679
23085
  if (pw)
22680
23086
  sessionSudoPassword = pw;
22681
- resolve22(pw);
23087
+ resolve23(pw);
22682
23088
  };
22683
23089
  if (statusBar?.isActive) {
22684
23090
  statusBar.beginContentWrite();
@@ -23092,8 +23498,8 @@ async function startInteractive(config, repoPath) {
23092
23498
  return true;
23093
23499
  },
23094
23500
  destroyProject() {
23095
- const oaPath = join31(repoRoot, OA_DIR);
23096
- if (existsSync24(oaPath)) {
23501
+ const oaPath = join32(repoRoot, OA_DIR);
23502
+ if (existsSync25(oaPath)) {
23097
23503
  try {
23098
23504
  rmSync2(oaPath, { recursive: true, force: true });
23099
23505
  writeContent(() => renderInfo(`Removed ${OA_DIR}/ directory.`));
@@ -23325,12 +23731,12 @@ Execute this skill now. Follow the behavioral guidance above.`;
23325
23731
  }
23326
23732
  }
23327
23733
  const cleanPath = input.replace(/^['"]|['"]$/g, "").trim();
23328
- const isImage = isImagePath(cleanPath) && existsSync24(resolve19(repoRoot, cleanPath));
23329
- const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync24(resolve19(repoRoot, cleanPath));
23734
+ const isImage = isImagePath(cleanPath) && existsSync25(resolve20(repoRoot, cleanPath));
23735
+ const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync25(resolve20(repoRoot, cleanPath));
23330
23736
  if (activeTask) {
23331
23737
  if (isImage) {
23332
23738
  try {
23333
- const imgPath = resolve19(repoRoot, cleanPath);
23739
+ const imgPath = resolve20(repoRoot, cleanPath);
23334
23740
  const imgBuffer = readFileSync18(imgPath);
23335
23741
  const base64 = imgBuffer.toString("base64");
23336
23742
  const ext = extname9(cleanPath).toLowerCase();
@@ -23344,7 +23750,7 @@ Execute this skill now. Follow the behavioral guidance above.`;
23344
23750
  } else if (isMedia) {
23345
23751
  writeContent(() => renderInfo(`Transcribing: ${cleanPath}...`));
23346
23752
  const engine = getListenEngine();
23347
- const result = await engine.transcribeFile(resolve19(repoRoot, cleanPath), repoRoot);
23753
+ const result = await engine.transcribeFile(resolve20(repoRoot, cleanPath), repoRoot);
23348
23754
  if (result) {
23349
23755
  const transcript = `[Transcription of ${cleanPath}]
23350
23756
  ${result.text}`;
@@ -23377,7 +23783,7 @@ ${result.text}`;
23377
23783
  if (isMedia && fullInput === input) {
23378
23784
  writeContent(() => renderInfo(`Transcribing: ${cleanPath}...`));
23379
23785
  const engine = getListenEngine();
23380
- const result = await engine.transcribeFile(resolve19(repoRoot, cleanPath), repoRoot);
23786
+ const result = await engine.transcribeFile(resolve20(repoRoot, cleanPath), repoRoot);
23381
23787
  if (result) {
23382
23788
  fullInput = `The user has provided an audio/video file: ${cleanPath}.
23383
23789
 
@@ -23506,7 +23912,7 @@ ${c2.dim("(Use /quit to exit)")}
23506
23912
  });
23507
23913
  }
23508
23914
  async function runWithTUI(task, config, repoPath) {
23509
- const repoRoot = resolve19(repoPath ?? cwd());
23915
+ const repoRoot = resolve20(repoPath ?? cwd());
23510
23916
  const needsSetup = isFirstRun() || !await isModelAvailable(config);
23511
23917
  if (needsSetup && config.backendType === "ollama") {
23512
23918
  const setupModel = await runSetupWizard(config);
@@ -23609,9 +24015,9 @@ var init_run = __esm({
23609
24015
  // packages/indexer/dist/codebase-indexer.js
23610
24016
  import { glob } from "glob";
23611
24017
  import ignore from "ignore";
23612
- import { readFile as readFile10, stat as stat4 } from "node:fs/promises";
24018
+ import { readFile as readFile11, stat as stat4 } from "node:fs/promises";
23613
24019
  import { createHash } from "node:crypto";
23614
- import { join as join32, relative as relative3, extname as extname10, basename as basename12 } from "node:path";
24020
+ import { join as join33, relative as relative3, extname as extname10, basename as basename13 } from "node:path";
23615
24021
  var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
23616
24022
  var init_codebase_indexer = __esm({
23617
24023
  "packages/indexer/dist/codebase-indexer.js"() {
@@ -23655,7 +24061,7 @@ var init_codebase_indexer = __esm({
23655
24061
  const ig = ignore.default();
23656
24062
  if (this.config.respectGitignore) {
23657
24063
  try {
23658
- const gitignoreContent = await readFile10(join32(this.config.rootDir, ".gitignore"), "utf-8");
24064
+ const gitignoreContent = await readFile11(join33(this.config.rootDir, ".gitignore"), "utf-8");
23659
24065
  ig.add(gitignoreContent);
23660
24066
  } catch {
23661
24067
  }
@@ -23670,12 +24076,12 @@ var init_codebase_indexer = __esm({
23670
24076
  for (const relativePath of files) {
23671
24077
  if (ig.ignores(relativePath))
23672
24078
  continue;
23673
- const fullPath = join32(this.config.rootDir, relativePath);
24079
+ const fullPath = join33(this.config.rootDir, relativePath);
23674
24080
  try {
23675
24081
  const fileStat = await stat4(fullPath);
23676
24082
  if (fileStat.size > this.config.maxFileSize)
23677
24083
  continue;
23678
- const content = await readFile10(fullPath);
24084
+ const content = await readFile11(fullPath);
23679
24085
  const hash = createHash("sha256").update(content).digest("hex");
23680
24086
  const ext = extname10(relativePath);
23681
24087
  indexed.push({
@@ -23693,7 +24099,7 @@ var init_codebase_indexer = __esm({
23693
24099
  }
23694
24100
  buildTree(files) {
23695
24101
  const root = {
23696
- name: basename12(this.config.rootDir),
24102
+ name: basename13(this.config.rootDir),
23697
24103
  path: this.config.rootDir,
23698
24104
  type: "directory",
23699
24105
  children: []
@@ -23716,7 +24122,7 @@ var init_codebase_indexer = __esm({
23716
24122
  if (!child) {
23717
24123
  child = {
23718
24124
  name: part,
23719
- path: join32(current.path, part),
24125
+ path: join33(current.path, part),
23720
24126
  type: "directory",
23721
24127
  children: []
23722
24128
  };
@@ -23772,6 +24178,13 @@ var init_embeddings = __esm({
23772
24178
  }
23773
24179
  });
23774
24180
 
24181
+ // packages/indexer/dist/ollamaEmbeddings.js
24182
+ var init_ollamaEmbeddings = __esm({
24183
+ "packages/indexer/dist/ollamaEmbeddings.js"() {
24184
+ "use strict";
24185
+ }
24186
+ });
24187
+
23775
24188
  // packages/indexer/dist/index.js
23776
24189
  var init_dist8 = __esm({
23777
24190
  "packages/indexer/dist/index.js"() {
@@ -23782,6 +24195,7 @@ var init_dist8 = __esm({
23782
24195
  init_graphBuilder();
23783
24196
  init_fileSummarizer();
23784
24197
  init_embeddings();
24198
+ init_ollamaEmbeddings();
23785
24199
  }
23786
24200
  });
23787
24201
 
@@ -23790,14 +24204,14 @@ var index_repo_exports = {};
23790
24204
  __export(index_repo_exports, {
23791
24205
  indexRepoCommand: () => indexRepoCommand
23792
24206
  });
23793
- import { resolve as resolve20 } from "node:path";
23794
- import { existsSync as existsSync25, statSync as statSync10 } from "node:fs";
24207
+ import { resolve as resolve21 } from "node:path";
24208
+ import { existsSync as existsSync26, statSync as statSync10 } from "node:fs";
23795
24209
  import { cwd as cwd2 } from "node:process";
23796
24210
  async function indexRepoCommand(opts, _config) {
23797
- const repoRoot = resolve20(opts.repoPath ?? cwd2());
24211
+ const repoRoot = resolve21(opts.repoPath ?? cwd2());
23798
24212
  printHeader("Index Repository");
23799
24213
  printInfo(`Indexing: ${repoRoot}`);
23800
- if (!existsSync25(repoRoot)) {
24214
+ if (!existsSync26(repoRoot)) {
23801
24215
  printError(`Path does not exist: ${repoRoot}`);
23802
24216
  process.exit(1);
23803
24217
  }
@@ -24043,8 +24457,8 @@ var config_exports = {};
24043
24457
  __export(config_exports, {
24044
24458
  configCommand: () => configCommand
24045
24459
  });
24046
- import { join as join33, resolve as resolve21 } from "node:path";
24047
- import { homedir as homedir12 } from "node:os";
24460
+ import { join as join34, resolve as resolve22 } from "node:path";
24461
+ import { homedir as homedir13 } from "node:os";
24048
24462
  import { cwd as cwd3 } from "node:process";
24049
24463
  function coerceForSettings(key, value) {
24050
24464
  if (INT_KEYS.has(key))
@@ -24064,7 +24478,7 @@ async function configCommand(opts, config) {
24064
24478
  return handleShow(opts, config);
24065
24479
  }
24066
24480
  function handleShow(opts, config) {
24067
- const repoRoot = resolve21(opts.repoPath ?? cwd3());
24481
+ const repoRoot = resolve22(opts.repoPath ?? cwd3());
24068
24482
  printHeader("Configuration");
24069
24483
  printSection("Active Settings (merged)");
24070
24484
  printKeyValue("backendUrl", config.backendUrl, 2);
@@ -24096,7 +24510,7 @@ function handleShow(opts, config) {
24096
24510
  }
24097
24511
  }
24098
24512
  printSection("Config File");
24099
- printInfo(`~/.open-agents/config.json (${join33(homedir12(), ".open-agents", "config.json")})`);
24513
+ printInfo(`~/.open-agents/config.json (${join34(homedir13(), ".open-agents", "config.json")})`);
24100
24514
  printSection("Priority Chain");
24101
24515
  printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
24102
24516
  printInfo(" 2. Project .oa/settings.json (--local)");
@@ -24129,13 +24543,13 @@ function handleSet(opts, _config) {
24129
24543
  process.exit(1);
24130
24544
  }
24131
24545
  if (opts.local) {
24132
- const repoRoot = resolve21(opts.repoPath ?? cwd3());
24546
+ const repoRoot = resolve22(opts.repoPath ?? cwd3());
24133
24547
  try {
24134
24548
  initOaDirectory(repoRoot);
24135
24549
  const coerced = coerceForSettings(key, value);
24136
24550
  saveProjectSettings(repoRoot, { [key]: coerced });
24137
24551
  printSuccess(`Project override set: ${key} = ${value}`);
24138
- printInfo(`Saved to ${join33(repoRoot, ".oa", "settings.json")}`);
24552
+ printInfo(`Saved to ${join34(repoRoot, ".oa", "settings.json")}`);
24139
24553
  printInfo("This override applies only when running in this workspace.");
24140
24554
  } catch (err) {
24141
24555
  printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
@@ -24287,7 +24701,7 @@ async function serveVllm(opts, config) {
24287
24701
  await runVllmServer(args, opts.verbose ?? false);
24288
24702
  }
24289
24703
  async function runVllmServer(args, verbose) {
24290
- return new Promise((resolve22, reject) => {
24704
+ return new Promise((resolve23, reject) => {
24291
24705
  const child = spawn9("python", args, {
24292
24706
  stdio: verbose ? "inherit" : ["ignore", "pipe", "pipe"],
24293
24707
  env: { ...process.env }
@@ -24322,10 +24736,10 @@ async function runVllmServer(args, verbose) {
24322
24736
  child.once("exit", (code, signal) => {
24323
24737
  if (signal) {
24324
24738
  printInfo(`vLLM server stopped by signal ${signal}`);
24325
- resolve22();
24739
+ resolve23();
24326
24740
  } else if (code === 0) {
24327
24741
  printSuccess("vLLM server exited cleanly");
24328
- resolve22();
24742
+ resolve23();
24329
24743
  } else {
24330
24744
  printError(`vLLM server exited with code ${code}`);
24331
24745
  reject(new Error(`vLLM exited with code ${code}`));
@@ -24354,7 +24768,7 @@ __export(eval_exports, {
24354
24768
  });
24355
24769
  import { tmpdir as tmpdir7 } from "node:os";
24356
24770
  import { mkdirSync as mkdirSync12, writeFileSync as writeFileSync11 } from "node:fs";
24357
- import { join as join34 } from "node:path";
24771
+ import { join as join35 } from "node:path";
24358
24772
  async function evalCommand(opts, config) {
24359
24773
  const suiteName = opts.suite ?? "basic";
24360
24774
  const suite = SUITES[suiteName];
@@ -24475,9 +24889,9 @@ async function evalCommand(opts, config) {
24475
24889
  process.exit(failed > 0 ? 1 : 0);
24476
24890
  }
24477
24891
  function createTempEvalRepo() {
24478
- const dir = join34(tmpdir7(), `open-agents-eval-${Date.now()}`);
24892
+ const dir = join35(tmpdir7(), `open-agents-eval-${Date.now()}`);
24479
24893
  mkdirSync12(dir, { recursive: true });
24480
- writeFileSync11(join34(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
24894
+ writeFileSync11(join35(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
24481
24895
  return dir;
24482
24896
  }
24483
24897
  var BASIC_SUITE, FULL_SUITE, SUITES;
@@ -24537,7 +24951,7 @@ init_updater();
24537
24951
  import { parseArgs as nodeParseArgs2 } from "node:util";
24538
24952
  import { createRequire as createRequire3 } from "node:module";
24539
24953
  import { fileURLToPath as fileURLToPath8 } from "node:url";
24540
- import { dirname as dirname11, join as join35 } from "node:path";
24954
+ import { dirname as dirname11, join as join36 } from "node:path";
24541
24955
 
24542
24956
  // packages/cli/dist/cli.js
24543
24957
  import { createInterface } from "node:readline";
@@ -24644,7 +25058,7 @@ init_output();
24644
25058
  function getVersion2() {
24645
25059
  try {
24646
25060
  const require2 = createRequire3(import.meta.url);
24647
- const pkgPath = join35(dirname11(fileURLToPath8(import.meta.url)), "..", "package.json");
25061
+ const pkgPath = join36(dirname11(fileURLToPath8(import.meta.url)), "..", "package.json");
24648
25062
  const pkg = require2(pkgPath);
24649
25063
  return pkg.version;
24650
25064
  } catch {