open-agents-ai 0.32.2 → 0.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1067 -468
- 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((
|
|
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
|
-
|
|
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((
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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(
|
|
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
|
|
2787
|
-
import { join as
|
|
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 =
|
|
2820
|
-
const hasAiwg =
|
|
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 =
|
|
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) =>
|
|
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 =
|
|
2916
|
-
if (
|
|
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) =>
|
|
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 =
|
|
2930
|
-
if (
|
|
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(
|
|
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
|
|
3083
|
-
import { resolve as
|
|
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 =
|
|
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
|
|
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
|
|
3209
|
-
import { resolve as
|
|
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 =
|
|
3278
|
-
const content = await
|
|
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
|
|
3381
|
-
import { join as
|
|
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 =
|
|
3466
|
-
if (
|
|
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 (
|
|
3867
|
+
if (existsSync6(join9(dir, "tsconfig.json")))
|
|
3475
3868
|
info.language = "TypeScript";
|
|
3476
|
-
else if (
|
|
3869
|
+
else if (existsSync6(join9(dir, "package.json")))
|
|
3477
3870
|
info.language = "JavaScript";
|
|
3478
|
-
else if (
|
|
3871
|
+
else if (existsSync6(join9(dir, "Cargo.toml")))
|
|
3479
3872
|
info.language = "Rust";
|
|
3480
|
-
else if (
|
|
3873
|
+
else if (existsSync6(join9(dir, "go.mod")))
|
|
3481
3874
|
info.language = "Go";
|
|
3482
|
-
else if (
|
|
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 (
|
|
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 =
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
3670
|
-
import { join as
|
|
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) =>
|
|
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(
|
|
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(
|
|
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
|
|
3815
|
-
import { join as
|
|
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 (!
|
|
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
|
|
4425
|
-
import { resolve as
|
|
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
|
|
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 =
|
|
4551
|
-
if (!
|
|
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: ${
|
|
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"] ?
|
|
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 (!
|
|
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 =
|
|
4753
|
-
if (!
|
|
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 =
|
|
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 ${
|
|
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
|
|
4813
|
-
import { join as
|
|
4814
|
-
import { homedir as
|
|
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
|
|
5210
|
+
return join13(homedir4(), ".open-agents", "tools");
|
|
4818
5211
|
}
|
|
4819
5212
|
function projectToolsDir(repoRoot) {
|
|
4820
|
-
return
|
|
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 =
|
|
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 =
|
|
4847
|
-
if (
|
|
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 (!
|
|
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(
|
|
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((
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
5310
|
-
import { join as
|
|
5311
|
-
import { homedir as
|
|
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 =
|
|
5707
|
+
const dataDir = join14(homedir5(), ".local", "share", "ai-writing-guide");
|
|
5315
5708
|
return {
|
|
5316
|
-
frameworksDir:
|
|
5317
|
-
addonsDir:
|
|
5318
|
-
pluginsDir:
|
|
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 =
|
|
5331
|
-
if (
|
|
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
|
-
|
|
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 (
|
|
5738
|
+
if (existsSync11(c3)) {
|
|
5346
5739
|
try {
|
|
5347
|
-
for (const ver of readdirSync5(
|
|
5740
|
+
for (const ver of readdirSync5(join14(c3, "node"), { withFileTypes: true })) {
|
|
5348
5741
|
if (!ver.isDirectory())
|
|
5349
5742
|
continue;
|
|
5350
|
-
const nvmPath =
|
|
5351
|
-
if (
|
|
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 (
|
|
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(
|
|
5372
|
-
loadCommandsFromDir(
|
|
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 =
|
|
5377
|
-
if (
|
|
5769
|
+
const pkgFrameworks = join14(pkgRoot, "agentic", "code", "frameworks");
|
|
5770
|
+
if (existsSync11(pkgFrameworks)) {
|
|
5378
5771
|
for (const fw of safeReaddir(pkgFrameworks)) {
|
|
5379
|
-
loadComponent(
|
|
5772
|
+
loadComponent(join14(pkgFrameworks, fw), `framework:${fw}`);
|
|
5380
5773
|
}
|
|
5381
5774
|
}
|
|
5382
|
-
const pkgAddons =
|
|
5383
|
-
if (
|
|
5775
|
+
const pkgAddons = join14(pkgRoot, "agentic", "code", "addons");
|
|
5776
|
+
if (existsSync11(pkgAddons)) {
|
|
5384
5777
|
for (const addon of safeReaddir(pkgAddons)) {
|
|
5385
|
-
loadComponent(
|
|
5778
|
+
loadComponent(join14(pkgAddons, addon), `addon:${addon}`);
|
|
5386
5779
|
}
|
|
5387
5780
|
}
|
|
5388
|
-
const pkgPlugins =
|
|
5389
|
-
if (
|
|
5781
|
+
const pkgPlugins = join14(pkgRoot, "plugins");
|
|
5782
|
+
if (existsSync11(pkgPlugins)) {
|
|
5390
5783
|
for (const plugin of safeReaddir(pkgPlugins)) {
|
|
5391
|
-
loadComponent(
|
|
5784
|
+
loadComponent(join14(pkgPlugins, plugin), `plugin:${plugin}`);
|
|
5392
5785
|
}
|
|
5393
5786
|
}
|
|
5394
5787
|
}
|
|
5395
|
-
if (
|
|
5788
|
+
if (existsSync11(frameworksDir)) {
|
|
5396
5789
|
for (const framework of safeReaddir(frameworksDir)) {
|
|
5397
|
-
loadComponent(
|
|
5790
|
+
loadComponent(join14(frameworksDir, framework), `framework:${framework}`);
|
|
5398
5791
|
}
|
|
5399
5792
|
}
|
|
5400
|
-
if (
|
|
5793
|
+
if (existsSync11(addonsDir)) {
|
|
5401
5794
|
for (const addon of safeReaddir(addonsDir)) {
|
|
5402
|
-
loadComponent(
|
|
5795
|
+
loadComponent(join14(addonsDir, addon), `addon:${addon}`);
|
|
5403
5796
|
}
|
|
5404
5797
|
}
|
|
5405
|
-
if (
|
|
5798
|
+
if (existsSync11(pluginsDir)) {
|
|
5406
5799
|
for (const plugin of safeReaddir(pluginsDir)) {
|
|
5407
|
-
loadComponent(
|
|
5800
|
+
loadComponent(join14(pluginsDir, plugin), `plugin:${plugin}`);
|
|
5408
5801
|
}
|
|
5409
5802
|
}
|
|
5410
|
-
const projectAiwg =
|
|
5411
|
-
loadSkillsFromDir(
|
|
5412
|
-
loadCommandsFromDir(
|
|
5413
|
-
const projectOaSkills =
|
|
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 (!
|
|
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 =
|
|
5465
|
-
if (!
|
|
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 (!
|
|
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 =
|
|
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 =
|
|
5526
|
-
if (!
|
|
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
|
|
5710
|
-
import { join as
|
|
5711
|
-
import { homedir as
|
|
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 =
|
|
5728
|
-
if (
|
|
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(
|
|
6124
|
+
_tcModule = req(join15(tcPath, "dist", "index.js"));
|
|
5732
6125
|
return _tcModule;
|
|
5733
6126
|
}
|
|
5734
6127
|
} catch {
|
|
5735
6128
|
}
|
|
5736
|
-
const nvmBase =
|
|
5737
|
-
if (
|
|
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 =
|
|
5742
|
-
if (
|
|
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(
|
|
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 =
|
|
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 (!
|
|
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 =
|
|
6237
|
+
const transcriptDir = join15(this.workingDir, ".oa", "transcripts");
|
|
5845
6238
|
mkdirSync4(transcriptDir, { recursive: true });
|
|
5846
|
-
const outFile =
|
|
6239
|
+
const outFile = join15(transcriptDir, `${basename4(filePath)}.txt`);
|
|
5847
6240
|
writeFileSync4(outFile, result.text, "utf-8");
|
|
5848
6241
|
const lines = [
|
|
5849
|
-
`Transcription of: ${
|
|
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 =
|
|
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 =
|
|
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 (!
|
|
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
|
|
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 =
|
|
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
|
|
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((
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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(
|
|
6764
|
+
const sandboxDir = await mkdtemp(join16(tmpdir2(), "oa-sandbox-"));
|
|
6372
6765
|
try {
|
|
6373
|
-
const scriptFile =
|
|
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(
|
|
6791
|
+
const sandboxDir = await mkdtemp(join16(tmpdir2(), "oa-docker-sandbox-"));
|
|
6399
6792
|
try {
|
|
6400
6793
|
const scriptFile = `_sandbox_script${langConfig.ext}`;
|
|
6401
|
-
await writeFile7(
|
|
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
|
|
6437
|
-
import { resolve as
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
6789
|
-
if (
|
|
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 =
|
|
6797
|
-
if (
|
|
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
|
-
|
|
6802
|
-
|
|
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 (
|
|
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 =
|
|
6827
|
-
if (!
|
|
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 =
|
|
6902
|
-
if (!
|
|
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 =
|
|
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
|
|
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
|
|
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 (
|
|
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 (!
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
7651
|
-
import { resolve as
|
|
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 =
|
|
7702
|
-
if (!
|
|
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 ?
|
|
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 ${
|
|
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
|
|
7774
|
-
import { resolve as
|
|
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 =
|
|
7826
|
-
if (!
|
|
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 ${
|
|
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 ${
|
|
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 ${
|
|
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 ${
|
|
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 =
|
|
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
|
|
7959
|
-
import { resolve as
|
|
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
|
|
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 =
|
|
7966
|
-
if (
|
|
8358
|
+
const devPath = resolve19(thisDir, "../../scripts/ocr-advanced.py");
|
|
8359
|
+
if (existsSync17(devPath))
|
|
7967
8360
|
return devPath;
|
|
7968
|
-
const bundledPath =
|
|
7969
|
-
if (
|
|
8361
|
+
const bundledPath = resolve19(thisDir, "../scripts/ocr-advanced.py");
|
|
8362
|
+
if (existsSync17(bundledPath))
|
|
7970
8363
|
return bundledPath;
|
|
7971
|
-
const sameDirPath =
|
|
7972
|
-
if (
|
|
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 =
|
|
7978
|
-
if (
|
|
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 =
|
|
8062
|
-
if (!
|
|
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(
|
|
8513
|
+
cmdParts.push("--output-dir", JSON.stringify(resolve19(this.workingDir, outputDir)));
|
|
8121
8514
|
let debugDir;
|
|
8122
8515
|
if (debug) {
|
|
8123
|
-
debugDir =
|
|
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 ${
|
|
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 =
|
|
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 ${
|
|
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 ${
|
|
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:
|
|
9489
|
-
const content = await
|
|
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
|
|
9505
|
-
import { join as
|
|
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
|
|
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
|
|
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 =
|
|
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()) {
|
|
@@ -9688,6 +10083,55 @@ var init_lexicalSearch = __esm({
|
|
|
9688
10083
|
});
|
|
9689
10084
|
|
|
9690
10085
|
// packages/retrieval/dist/semanticSearch.js
|
|
10086
|
+
function parseTagFilter(query) {
|
|
10087
|
+
const required = [];
|
|
10088
|
+
const anyOf = [];
|
|
10089
|
+
const excluded = [];
|
|
10090
|
+
const cleanParts = [];
|
|
10091
|
+
for (const token of query.split(/\s+/)) {
|
|
10092
|
+
if (token.startsWith("+") && token.length > 1) {
|
|
10093
|
+
required.push(token.slice(1).toLowerCase());
|
|
10094
|
+
} else if (token.startsWith("~") && token.length > 1) {
|
|
10095
|
+
anyOf.push(token.slice(1).toLowerCase());
|
|
10096
|
+
} else if (token.startsWith("-") && token.length > 1 && !/^\d/.test(token.slice(1))) {
|
|
10097
|
+
excluded.push(token.slice(1).toLowerCase());
|
|
10098
|
+
} else {
|
|
10099
|
+
cleanParts.push(token);
|
|
10100
|
+
}
|
|
10101
|
+
}
|
|
10102
|
+
const hasFilter = required.length > 0 || anyOf.length > 0 || excluded.length > 0;
|
|
10103
|
+
return {
|
|
10104
|
+
cleanQuery: cleanParts.join(" "),
|
|
10105
|
+
tagFilter: hasFilter ? { required, anyOf, excluded } : null
|
|
10106
|
+
};
|
|
10107
|
+
}
|
|
10108
|
+
function matchesTagFilter(text, filter) {
|
|
10109
|
+
const lowerText = text.toLowerCase();
|
|
10110
|
+
const clusteringTags = /* @__PURE__ */ new Set();
|
|
10111
|
+
for (const match of lowerText.matchAll(/clustering:(\S+)/g)) {
|
|
10112
|
+
clusteringTags.add(match[1]);
|
|
10113
|
+
}
|
|
10114
|
+
const domainMatch = lowerText.match(/domain:\s*(\S+)/);
|
|
10115
|
+
if (domainMatch)
|
|
10116
|
+
clusteringTags.add(domainMatch[1]);
|
|
10117
|
+
const riskMatch = lowerText.match(/risk:\s*(\S+)/);
|
|
10118
|
+
if (riskMatch)
|
|
10119
|
+
clusteringTags.add(riskMatch[1]);
|
|
10120
|
+
for (const tag of filter.required) {
|
|
10121
|
+
if (!clusteringTags.has(tag) && !lowerText.includes(tag))
|
|
10122
|
+
return false;
|
|
10123
|
+
}
|
|
10124
|
+
if (filter.anyOf.length > 0) {
|
|
10125
|
+
const hasAny = filter.anyOf.some((tag) => clusteringTags.has(tag) || lowerText.includes(tag));
|
|
10126
|
+
if (!hasAny)
|
|
10127
|
+
return false;
|
|
10128
|
+
}
|
|
10129
|
+
for (const tag of filter.excluded) {
|
|
10130
|
+
if (clusteringTags.has(tag))
|
|
10131
|
+
return false;
|
|
10132
|
+
}
|
|
10133
|
+
return true;
|
|
10134
|
+
}
|
|
9691
10135
|
function cosineSimilarity(a, b) {
|
|
9692
10136
|
if (a.length !== b.length || a.length === 0)
|
|
9693
10137
|
return 0;
|
|
@@ -9713,7 +10157,7 @@ function makePlaceholderSummary(filePath) {
|
|
|
9713
10157
|
lastIndexed: (/* @__PURE__ */ new Date()).toISOString()
|
|
9714
10158
|
};
|
|
9715
10159
|
}
|
|
9716
|
-
var StubSemanticSearchEngine, IndexBackedSemanticSearchEngine;
|
|
10160
|
+
var StubSemanticSearchEngine, IndexBackedSemanticSearchEngine, LazySemanticSearchEngine;
|
|
9717
10161
|
var init_semanticSearch = __esm({
|
|
9718
10162
|
"packages/retrieval/dist/semanticSearch.js"() {
|
|
9719
10163
|
"use strict";
|
|
@@ -9734,11 +10178,26 @@ var init_semanticSearch = __esm({
|
|
|
9734
10178
|
if (!this.isAvailable)
|
|
9735
10179
|
return [];
|
|
9736
10180
|
const queryVector = await this.options.embedQuery(query);
|
|
10181
|
+
const { cleanQuery, tagFilter } = parseTagFilter(query);
|
|
10182
|
+
const searchVector = cleanQuery !== query ? await this.options.embedQuery(cleanQuery) : queryVector;
|
|
9737
10183
|
const scored = this.options.index.map((item) => ({
|
|
9738
10184
|
filePath: item.filePath,
|
|
9739
|
-
score: cosineSimilarity(
|
|
10185
|
+
score: cosineSimilarity(searchVector, item.vector),
|
|
10186
|
+
text: item.text
|
|
9740
10187
|
}));
|
|
9741
|
-
|
|
10188
|
+
let filtered = scored;
|
|
10189
|
+
if (tagFilter) {
|
|
10190
|
+
filtered = scored.filter((item) => matchesTagFilter(item.text, tagFilter));
|
|
10191
|
+
}
|
|
10192
|
+
const byFile = /* @__PURE__ */ new Map();
|
|
10193
|
+
for (const item of filtered) {
|
|
10194
|
+
const existing = byFile.get(item.filePath);
|
|
10195
|
+
if (!existing || item.score > existing.score) {
|
|
10196
|
+
byFile.set(item.filePath, item);
|
|
10197
|
+
}
|
|
10198
|
+
}
|
|
10199
|
+
const deduped = Array.from(byFile.values());
|
|
10200
|
+
return deduped.sort((a, b) => b.score - a.score).slice(0, topK).map(({ filePath, score }) => {
|
|
9742
10201
|
const summary = this.options.summaryMap.get(filePath);
|
|
9743
10202
|
return {
|
|
9744
10203
|
filePath,
|
|
@@ -9748,6 +10207,74 @@ var init_semanticSearch = __esm({
|
|
|
9748
10207
|
};
|
|
9749
10208
|
});
|
|
9750
10209
|
}
|
|
10210
|
+
/**
|
|
10211
|
+
* Pattern 7: Find semantically related items in the index.
|
|
10212
|
+
* Returns pairs of items with >threshold similarity.
|
|
10213
|
+
* Useful for auto-linking related memories/files.
|
|
10214
|
+
*/
|
|
10215
|
+
findRelated(filePath, threshold = 0.7, maxResults = 5) {
|
|
10216
|
+
const sourceItem = this.options.index.find((i) => i.filePath === filePath);
|
|
10217
|
+
if (!sourceItem)
|
|
10218
|
+
return [];
|
|
10219
|
+
const scored = this.options.index.filter((i) => i.filePath !== filePath).map((item) => ({
|
|
10220
|
+
filePath: item.filePath,
|
|
10221
|
+
score: cosineSimilarity(sourceItem.vector, item.vector)
|
|
10222
|
+
})).filter((r) => r.score >= threshold).sort((a, b) => b.score - a.score).slice(0, maxResults);
|
|
10223
|
+
return scored;
|
|
10224
|
+
}
|
|
10225
|
+
};
|
|
10226
|
+
LazySemanticSearchEngine = class {
|
|
10227
|
+
inner = null;
|
|
10228
|
+
buildPromise = null;
|
|
10229
|
+
buildFailed = false;
|
|
10230
|
+
opts;
|
|
10231
|
+
constructor(opts) {
|
|
10232
|
+
this.opts = opts;
|
|
10233
|
+
}
|
|
10234
|
+
get isAvailable() {
|
|
10235
|
+
return this.inner?.isAvailable ?? false;
|
|
10236
|
+
}
|
|
10237
|
+
/**
|
|
10238
|
+
* Trigger index building in the background.
|
|
10239
|
+
* Call this during idle time to pre-warm the index.
|
|
10240
|
+
*/
|
|
10241
|
+
warmUp() {
|
|
10242
|
+
if (!this.buildPromise && !this.inner && !this.buildFailed) {
|
|
10243
|
+
this.buildPromise = this.build();
|
|
10244
|
+
}
|
|
10245
|
+
}
|
|
10246
|
+
async search(query, topK = 10) {
|
|
10247
|
+
if (this.inner)
|
|
10248
|
+
return this.inner.search(query, topK);
|
|
10249
|
+
if (this.buildFailed)
|
|
10250
|
+
return [];
|
|
10251
|
+
if (!this.buildPromise) {
|
|
10252
|
+
this.buildPromise = this.build();
|
|
10253
|
+
}
|
|
10254
|
+
const timeoutMs = this.opts.timeoutMs ?? 6e4;
|
|
10255
|
+
try {
|
|
10256
|
+
await Promise.race([
|
|
10257
|
+
this.buildPromise,
|
|
10258
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error("Index build timeout")), timeoutMs))
|
|
10259
|
+
]);
|
|
10260
|
+
} catch {
|
|
10261
|
+
return [];
|
|
10262
|
+
}
|
|
10263
|
+
return this.searchInner(query, topK);
|
|
10264
|
+
}
|
|
10265
|
+
searchInner(query, topK) {
|
|
10266
|
+
if (this.inner)
|
|
10267
|
+
return this.inner.search(query, topK);
|
|
10268
|
+
return Promise.resolve([]);
|
|
10269
|
+
}
|
|
10270
|
+
async build() {
|
|
10271
|
+
try {
|
|
10272
|
+
const options = await this.opts.buildIndex();
|
|
10273
|
+
this.inner = new IndexBackedSemanticSearchEngine(options);
|
|
10274
|
+
} catch {
|
|
10275
|
+
this.buildFailed = true;
|
|
10276
|
+
}
|
|
10277
|
+
}
|
|
9751
10278
|
};
|
|
9752
10279
|
}
|
|
9753
10280
|
});
|
|
@@ -9818,8 +10345,8 @@ var init_graphExpand = __esm({
|
|
|
9818
10345
|
});
|
|
9819
10346
|
|
|
9820
10347
|
// packages/retrieval/dist/snippetPacker.js
|
|
9821
|
-
import { readFile as
|
|
9822
|
-
import { join as
|
|
10348
|
+
import { readFile as readFile10 } from "node:fs/promises";
|
|
10349
|
+
import { join as join22 } from "node:path";
|
|
9823
10350
|
async function packSnippets(requests, opts = {}) {
|
|
9824
10351
|
const maxTokens = opts.maxTokens ?? DEFAULT_MAX_TOKENS;
|
|
9825
10352
|
const contextLines = opts.contextLines ?? DEFAULT_CONTEXT_LINES;
|
|
@@ -9845,10 +10372,10 @@ async function packSnippets(requests, opts = {}) {
|
|
|
9845
10372
|
return { packed, dropped, totalTokens };
|
|
9846
10373
|
}
|
|
9847
10374
|
async function extractSnippet(req, repoRoot, contextLines = DEFAULT_CONTEXT_LINES) {
|
|
9848
|
-
const absPath = req.filePath.startsWith("/") ? req.filePath :
|
|
10375
|
+
const absPath = req.filePath.startsWith("/") ? req.filePath : join22(repoRoot, req.filePath);
|
|
9849
10376
|
let content;
|
|
9850
10377
|
try {
|
|
9851
|
-
content = await
|
|
10378
|
+
content = await readFile10(absPath, "utf-8");
|
|
9852
10379
|
} catch {
|
|
9853
10380
|
return null;
|
|
9854
10381
|
}
|
|
@@ -9904,24 +10431,41 @@ async function assembleContext(request, opts) {
|
|
|
9904
10431
|
Promise.all(request.errorHint.slice(0, maxLogs).map((e) => searchByError(e, { rootDir: repoRoot, maxMatches: 5 }))).then((res) => res.flat()),
|
|
9905
10432
|
semanticEngine?.isAvailable ? semanticEngine.search(request.query, maxFiles) : Promise.resolve([])
|
|
9906
10433
|
]);
|
|
9907
|
-
const
|
|
9908
|
-
const
|
|
9909
|
-
|
|
9910
|
-
|
|
9911
|
-
|
|
9912
|
-
seenFiles.add(relativePath);
|
|
9913
|
-
candidateFiles.push({ relativePath, priority });
|
|
9914
|
-
}
|
|
10434
|
+
const queryType = classifyQuery(request.query);
|
|
10435
|
+
const rrfK = adaptiveK(queryType, opts.rrfConfig?.k);
|
|
10436
|
+
const wFts = opts.rrfConfig?.weightFts ?? 1;
|
|
10437
|
+
const wSem = opts.rrfConfig?.weightSemantic ?? 1;
|
|
10438
|
+
const lexicalCandidates = [];
|
|
9915
10439
|
for (const m of pathMatches)
|
|
9916
|
-
|
|
10440
|
+
lexicalCandidates.push({ relativePath: m.relativePath, basePriority: 100 });
|
|
9917
10441
|
for (const m of symbolMatches)
|
|
9918
|
-
|
|
9919
|
-
for (const r of semanticResults) {
|
|
9920
|
-
addCandidate(r.filePath, Math.round(50 + r.score * 30));
|
|
9921
|
-
}
|
|
10442
|
+
lexicalCandidates.push({ relativePath: m.relativePath, basePriority: 80 });
|
|
9922
10443
|
for (const m of errorMatches)
|
|
9923
|
-
|
|
9924
|
-
const
|
|
10444
|
+
lexicalCandidates.push({ relativePath: m.relativePath, basePriority: 40 });
|
|
10445
|
+
const lexDedup = /* @__PURE__ */ new Map();
|
|
10446
|
+
for (const c3 of lexicalCandidates) {
|
|
10447
|
+
const existing = lexDedup.get(c3.relativePath) ?? 0;
|
|
10448
|
+
lexDedup.set(c3.relativePath, Math.max(existing, c3.basePriority));
|
|
10449
|
+
}
|
|
10450
|
+
const lexRanked = Array.from(lexDedup.entries()).sort((a, b) => b[1] - a[1]).map(([path], idx) => ({ path, rank: idx + 1 }));
|
|
10451
|
+
const semRanked = semanticResults.sort((a, b) => b.score - a.score).map((r, idx) => ({ path: r.filePath, rank: idx + 1, score: r.score }));
|
|
10452
|
+
const rrfScores = /* @__PURE__ */ new Map();
|
|
10453
|
+
const lexRankMap = new Map(lexRanked.map((l) => [l.path, l.rank]));
|
|
10454
|
+
const semRankMap = new Map(semRanked.map((s) => [s.path, s.rank]));
|
|
10455
|
+
const allPaths = /* @__PURE__ */ new Set([...lexRankMap.keys(), ...semRankMap.keys()]);
|
|
10456
|
+
for (const p of allPaths) {
|
|
10457
|
+
const lexRank = lexRankMap.get(p);
|
|
10458
|
+
const semRank = semRankMap.get(p);
|
|
10459
|
+
let score = 0;
|
|
10460
|
+
if (lexRank !== void 0)
|
|
10461
|
+
score += wFts / (rrfK + lexRank);
|
|
10462
|
+
if (semRank !== void 0)
|
|
10463
|
+
score += wSem / (rrfK + semRank);
|
|
10464
|
+
rrfScores.set(p, score);
|
|
10465
|
+
}
|
|
10466
|
+
const candidateFiles = Array.from(rrfScores.entries()).sort((a, b) => b[1] - a[1]).map(([relativePath, priority]) => ({ relativePath, priority: Math.round(priority * 1e3) }));
|
|
10467
|
+
const seenFiles = new Set(candidateFiles.map((c3) => c3.relativePath));
|
|
10468
|
+
const topFiles = candidateFiles.slice(0, maxFiles);
|
|
9925
10469
|
const neighborFiles = [];
|
|
9926
10470
|
if (expandNeighbors && graph) {
|
|
9927
10471
|
const seedPaths = topFiles.map((f) => f.relativePath);
|
|
@@ -9966,6 +10510,39 @@ async function assembleContext(request, opts) {
|
|
|
9966
10510
|
assembledAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
9967
10511
|
};
|
|
9968
10512
|
}
|
|
10513
|
+
function classifyQuery(query) {
|
|
10514
|
+
const trimmed = query.trim();
|
|
10515
|
+
if (/^["'].*["']$/.test(trimmed) || /"[^"]+"/.test(trimmed))
|
|
10516
|
+
return "quoted";
|
|
10517
|
+
if (/(?:error|exception|stack|traceback|ENOENT|EPERM|TypeError|SyntaxError)/i.test(trimmed))
|
|
10518
|
+
return "error";
|
|
10519
|
+
if (/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(trimmed))
|
|
10520
|
+
return "symbol";
|
|
10521
|
+
const wordCount = trimmed.split(/\s+/).length;
|
|
10522
|
+
if (wordCount <= 3)
|
|
10523
|
+
return "short";
|
|
10524
|
+
return "long";
|
|
10525
|
+
}
|
|
10526
|
+
function adaptiveK(queryType, overrideK) {
|
|
10527
|
+
if (overrideK !== void 0)
|
|
10528
|
+
return overrideK;
|
|
10529
|
+
switch (queryType) {
|
|
10530
|
+
case "short":
|
|
10531
|
+
return 30;
|
|
10532
|
+
// tight — top results matter more
|
|
10533
|
+
case "quoted":
|
|
10534
|
+
return 20;
|
|
10535
|
+
// very tight — exact match should win
|
|
10536
|
+
case "symbol":
|
|
10537
|
+
return 25;
|
|
10538
|
+
// tight — symbol search is precise
|
|
10539
|
+
case "error":
|
|
10540
|
+
return 40;
|
|
10541
|
+
// moderate — errors need breadth
|
|
10542
|
+
case "long":
|
|
10543
|
+
return 60;
|
|
10544
|
+
}
|
|
10545
|
+
}
|
|
9969
10546
|
function buildSymbolSnippets(symbolMatches, maxSnippets) {
|
|
9970
10547
|
const byFile = /* @__PURE__ */ new Map();
|
|
9971
10548
|
for (const m of symbolMatches) {
|
|
@@ -10008,8 +10585,10 @@ __export(dist_exports, {
|
|
|
10008
10585
|
CodeRetriever: () => CodeRetriever,
|
|
10009
10586
|
GrepSearch: () => GrepSearch,
|
|
10010
10587
|
IndexBackedSemanticSearchEngine: () => IndexBackedSemanticSearchEngine,
|
|
10588
|
+
LazySemanticSearchEngine: () => LazySemanticSearchEngine,
|
|
10011
10589
|
StubSemanticSearchEngine: () => StubSemanticSearchEngine,
|
|
10012
10590
|
assembleContext: () => assembleContext,
|
|
10591
|
+
classifyQuery: () => classifyQuery,
|
|
10013
10592
|
estimatePacketTokens: () => estimatePacketTokens,
|
|
10014
10593
|
estimateTokens: () => estimateTokens,
|
|
10015
10594
|
expandGraph: () => expandGraph,
|
|
@@ -10017,6 +10596,7 @@ __export(dist_exports, {
|
|
|
10017
10596
|
oneHopNeighbors: () => oneHopNeighbors,
|
|
10018
10597
|
packFiles: () => packFiles,
|
|
10019
10598
|
packSnippets: () => packSnippets,
|
|
10599
|
+
parseTagFilter: () => parseTagFilter,
|
|
10020
10600
|
searchByError: () => searchByError,
|
|
10021
10601
|
searchByPath: () => searchByPath,
|
|
10022
10602
|
searchByQuery: () => searchByQuery,
|
|
@@ -11451,8 +12031,8 @@ Rules:
|
|
|
11451
12031
|
async waitIfPaused() {
|
|
11452
12032
|
if (!this._paused)
|
|
11453
12033
|
return true;
|
|
11454
|
-
await new Promise((
|
|
11455
|
-
this._pauseResolve =
|
|
12034
|
+
await new Promise((resolve23) => {
|
|
12035
|
+
this._pauseResolve = resolve23;
|
|
11456
12036
|
});
|
|
11457
12037
|
return !this.aborted;
|
|
11458
12038
|
}
|
|
@@ -11709,6 +12289,15 @@ Integrate this guidance into your current approach. Continue working on the task
|
|
|
11709
12289
|
}
|
|
11710
12290
|
}
|
|
11711
12291
|
}
|
|
12292
|
+
if (tc.name === "explore_tools" && result.success && result.output.startsWith("UNLOCK_TOOL:")) {
|
|
12293
|
+
const unlockName = result.output.slice("UNLOCK_TOOL:".length).trim();
|
|
12294
|
+
const existingTool = this.tools.get(unlockName);
|
|
12295
|
+
if (existingTool) {
|
|
12296
|
+
result = { success: true, output: `Tool '${unlockName}' is now unlocked and available. You can use it in your next response.` };
|
|
12297
|
+
} else {
|
|
12298
|
+
result = { success: false, output: "", error: `Unknown tool '${unlockName}'. Call explore_tools() with no args to see available tools.` };
|
|
12299
|
+
}
|
|
12300
|
+
}
|
|
11712
12301
|
const { toolOutputMaxChars: maxLen } = this.contextLimits();
|
|
11713
12302
|
const output = result.success ? result.output.length > maxLen ? this.foldOutput(result.output, maxLen) : result.output : `Error: ${result.error || "unknown error"}
|
|
11714
12303
|
${result.output.length > maxLen ? this.foldOutput(result.output, maxLen) : result.output}`;
|
|
@@ -12020,14 +12609,14 @@ ${result.output}`;
|
|
|
12020
12609
|
waitForSudoPassword(timeoutMs = 12e4) {
|
|
12021
12610
|
if (this._sudoPassword)
|
|
12022
12611
|
return Promise.resolve(this._sudoPassword);
|
|
12023
|
-
return new Promise((
|
|
12612
|
+
return new Promise((resolve23) => {
|
|
12024
12613
|
const timer = setTimeout(() => {
|
|
12025
12614
|
this._sudoResolve = null;
|
|
12026
|
-
|
|
12615
|
+
resolve23(null);
|
|
12027
12616
|
}, timeoutMs);
|
|
12028
12617
|
this._sudoResolve = (pw) => {
|
|
12029
12618
|
clearTimeout(timer);
|
|
12030
|
-
|
|
12619
|
+
resolve23(pw);
|
|
12031
12620
|
};
|
|
12032
12621
|
});
|
|
12033
12622
|
}
|
|
@@ -12150,8 +12739,8 @@ ${marker}` : marker);
|
|
|
12150
12739
|
return;
|
|
12151
12740
|
try {
|
|
12152
12741
|
const { mkdirSync: mkdirSync13, writeFileSync: writeFileSync12 } = __require("node:fs");
|
|
12153
|
-
const { join:
|
|
12154
|
-
const sessionDir =
|
|
12742
|
+
const { join: join37 } = __require("node:path");
|
|
12743
|
+
const sessionDir = join37(this._workingDirectory, ".oa", "session", this._sessionId);
|
|
12155
12744
|
mkdirSync13(sessionDir, { recursive: true });
|
|
12156
12745
|
const checkpoint = {
|
|
12157
12746
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -12164,7 +12753,7 @@ ${marker}` : marker);
|
|
|
12164
12753
|
memexEntryCount: this._memexArchive.size,
|
|
12165
12754
|
fileRegistrySize: this._fileRegistry.size
|
|
12166
12755
|
};
|
|
12167
|
-
writeFileSync12(
|
|
12756
|
+
writeFileSync12(join37(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
|
|
12168
12757
|
} catch {
|
|
12169
12758
|
}
|
|
12170
12759
|
}
|
|
@@ -13697,9 +14286,9 @@ var init_dist5 = __esm({
|
|
|
13697
14286
|
|
|
13698
14287
|
// packages/cli/dist/tui/listen.js
|
|
13699
14288
|
import { spawn as spawn7, execSync as execSync15 } from "node:child_process";
|
|
13700
|
-
import { existsSync as
|
|
13701
|
-
import { join as
|
|
13702
|
-
import { homedir as
|
|
14289
|
+
import { existsSync as existsSync18, mkdirSync as mkdirSync5, writeFileSync as writeFileSync5, readdirSync as readdirSync6 } from "node:fs";
|
|
14290
|
+
import { join as join23, dirname as dirname8 } from "node:path";
|
|
14291
|
+
import { homedir as homedir8 } from "node:os";
|
|
13703
14292
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
13704
14293
|
import { EventEmitter } from "node:events";
|
|
13705
14294
|
import { createInterface as createInterface2 } from "node:readline";
|
|
@@ -13784,15 +14373,15 @@ function findMicCaptureCommand() {
|
|
|
13784
14373
|
function findLiveWhisperScript() {
|
|
13785
14374
|
const thisDir = dirname8(fileURLToPath5(import.meta.url));
|
|
13786
14375
|
const candidates = [
|
|
13787
|
-
|
|
13788
|
-
|
|
13789
|
-
|
|
14376
|
+
join23(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
|
|
14377
|
+
join23(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
|
|
14378
|
+
join23(thisDir, "../../execution/scripts/live-whisper.py"),
|
|
13790
14379
|
// npm install layout — scripts bundled alongside dist
|
|
13791
|
-
|
|
13792
|
-
|
|
14380
|
+
join23(thisDir, "../scripts/live-whisper.py"),
|
|
14381
|
+
join23(thisDir, "../../scripts/live-whisper.py")
|
|
13793
14382
|
];
|
|
13794
14383
|
for (const p of candidates) {
|
|
13795
|
-
if (
|
|
14384
|
+
if (existsSync18(p))
|
|
13796
14385
|
return p;
|
|
13797
14386
|
}
|
|
13798
14387
|
try {
|
|
@@ -13802,21 +14391,21 @@ function findLiveWhisperScript() {
|
|
|
13802
14391
|
stdio: ["pipe", "pipe", "pipe"]
|
|
13803
14392
|
}).trim();
|
|
13804
14393
|
const candidates2 = [
|
|
13805
|
-
|
|
13806
|
-
|
|
14394
|
+
join23(globalRoot, "open-agents-ai", "dist", "scripts", "live-whisper.py"),
|
|
14395
|
+
join23(globalRoot, "open-agents-ai", "scripts", "live-whisper.py")
|
|
13807
14396
|
];
|
|
13808
14397
|
for (const p of candidates2) {
|
|
13809
|
-
if (
|
|
14398
|
+
if (existsSync18(p))
|
|
13810
14399
|
return p;
|
|
13811
14400
|
}
|
|
13812
14401
|
} catch {
|
|
13813
14402
|
}
|
|
13814
|
-
const nvmBase =
|
|
13815
|
-
if (
|
|
14403
|
+
const nvmBase = join23(homedir8(), ".nvm", "versions", "node");
|
|
14404
|
+
if (existsSync18(nvmBase)) {
|
|
13816
14405
|
try {
|
|
13817
14406
|
for (const ver of readdirSync6(nvmBase)) {
|
|
13818
|
-
const p =
|
|
13819
|
-
if (
|
|
14407
|
+
const p = join23(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
|
|
14408
|
+
if (existsSync18(p))
|
|
13820
14409
|
return p;
|
|
13821
14410
|
}
|
|
13822
14411
|
} catch {
|
|
@@ -13834,16 +14423,16 @@ function ensureTranscribeCliBackground() {
|
|
|
13834
14423
|
timeout: 5e3,
|
|
13835
14424
|
stdio: ["pipe", "pipe", "pipe"]
|
|
13836
14425
|
}).trim();
|
|
13837
|
-
if (
|
|
14426
|
+
if (existsSync18(join23(globalRoot, "transcribe-cli", "dist", "index.js"))) {
|
|
13838
14427
|
return true;
|
|
13839
14428
|
}
|
|
13840
14429
|
} catch {
|
|
13841
14430
|
}
|
|
13842
14431
|
try {
|
|
13843
14432
|
const { exec } = await import("node:child_process");
|
|
13844
|
-
return new Promise((
|
|
14433
|
+
return new Promise((resolve23) => {
|
|
13845
14434
|
exec("npm i -g transcribe-cli", { timeout: 18e4 }, (err) => {
|
|
13846
|
-
|
|
14435
|
+
resolve23(!err);
|
|
13847
14436
|
});
|
|
13848
14437
|
});
|
|
13849
14438
|
} catch {
|
|
@@ -13896,7 +14485,7 @@ var init_listen = __esm({
|
|
|
13896
14485
|
return this._ready;
|
|
13897
14486
|
}
|
|
13898
14487
|
async start() {
|
|
13899
|
-
return new Promise((
|
|
14488
|
+
return new Promise((resolve23, reject) => {
|
|
13900
14489
|
const timeout = setTimeout(() => {
|
|
13901
14490
|
reject(new Error("Whisper fallback: model load timeout (5 min). First run downloads the model."));
|
|
13902
14491
|
}, 3e5);
|
|
@@ -13924,7 +14513,7 @@ var init_listen = __esm({
|
|
|
13924
14513
|
this._ready = true;
|
|
13925
14514
|
clearTimeout(timeout);
|
|
13926
14515
|
this.emit("ready");
|
|
13927
|
-
|
|
14516
|
+
resolve23();
|
|
13928
14517
|
break;
|
|
13929
14518
|
case "transcript":
|
|
13930
14519
|
this.emit("transcript", {
|
|
@@ -14051,24 +14640,24 @@ var init_listen = __esm({
|
|
|
14051
14640
|
timeout: 5e3,
|
|
14052
14641
|
stdio: ["pipe", "pipe", "pipe"]
|
|
14053
14642
|
}).trim();
|
|
14054
|
-
const tcPath =
|
|
14055
|
-
if (
|
|
14643
|
+
const tcPath = join23(globalRoot, "transcribe-cli");
|
|
14644
|
+
if (existsSync18(join23(tcPath, "dist", "index.js"))) {
|
|
14056
14645
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
14057
14646
|
const req = createRequire4(import.meta.url);
|
|
14058
|
-
return req(
|
|
14647
|
+
return req(join23(tcPath, "dist", "index.js"));
|
|
14059
14648
|
}
|
|
14060
14649
|
} catch {
|
|
14061
14650
|
}
|
|
14062
|
-
const nvmBase =
|
|
14063
|
-
if (
|
|
14651
|
+
const nvmBase = join23(homedir8(), ".nvm", "versions", "node");
|
|
14652
|
+
if (existsSync18(nvmBase)) {
|
|
14064
14653
|
try {
|
|
14065
14654
|
const { readdirSync: readdirSync11 } = await import("node:fs");
|
|
14066
14655
|
for (const ver of readdirSync11(nvmBase)) {
|
|
14067
|
-
const tcPath =
|
|
14068
|
-
if (
|
|
14656
|
+
const tcPath = join23(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
|
|
14657
|
+
if (existsSync18(join23(tcPath, "dist", "index.js"))) {
|
|
14069
14658
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
14070
14659
|
const req = createRequire4(import.meta.url);
|
|
14071
|
-
return req(
|
|
14660
|
+
return req(join23(tcPath, "dist", "index.js"));
|
|
14072
14661
|
}
|
|
14073
14662
|
}
|
|
14074
14663
|
} catch {
|
|
@@ -14128,11 +14717,11 @@ var init_listen = __esm({
|
|
|
14128
14717
|
this.liveTranscriber.on("error", (err) => {
|
|
14129
14718
|
this.emit("error", err);
|
|
14130
14719
|
});
|
|
14131
|
-
await new Promise((
|
|
14720
|
+
await new Promise((resolve23, reject) => {
|
|
14132
14721
|
const timeout = setTimeout(() => reject(new Error("Model load timeout (60s)")), 6e4);
|
|
14133
14722
|
this.liveTranscriber.on("ready", () => {
|
|
14134
14723
|
clearTimeout(timeout);
|
|
14135
|
-
|
|
14724
|
+
resolve23();
|
|
14136
14725
|
});
|
|
14137
14726
|
this.liveTranscriber.on("error", (err) => {
|
|
14138
14727
|
clearTimeout(timeout);
|
|
@@ -14293,10 +14882,10 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
14293
14882
|
wordTimestamps: false
|
|
14294
14883
|
});
|
|
14295
14884
|
if (outputDir) {
|
|
14296
|
-
const { basename:
|
|
14297
|
-
const transcriptDir =
|
|
14885
|
+
const { basename: basename14 } = await import("node:path");
|
|
14886
|
+
const transcriptDir = join23(outputDir, ".oa", "transcripts");
|
|
14298
14887
|
mkdirSync5(transcriptDir, { recursive: true });
|
|
14299
|
-
const outFile =
|
|
14888
|
+
const outFile = join23(transcriptDir, `${basename14(filePath)}.txt`);
|
|
14300
14889
|
writeFileSync5(outFile, result.text, "utf-8");
|
|
14301
14890
|
}
|
|
14302
14891
|
return {
|
|
@@ -15568,7 +16157,7 @@ Approach this task thoughtfully:
|
|
|
15568
16157
|
});
|
|
15569
16158
|
|
|
15570
16159
|
// packages/prompts/dist/index.js
|
|
15571
|
-
import { join as
|
|
16160
|
+
import { join as join24, dirname as dirname9 } from "node:path";
|
|
15572
16161
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
15573
16162
|
var _dir, _packageRoot;
|
|
15574
16163
|
var init_dist6 = __esm({
|
|
@@ -15579,28 +16168,28 @@ var init_dist6 = __esm({
|
|
|
15579
16168
|
init_task_templates();
|
|
15580
16169
|
init_render2();
|
|
15581
16170
|
_dir = dirname9(fileURLToPath6(import.meta.url));
|
|
15582
|
-
_packageRoot =
|
|
16171
|
+
_packageRoot = join24(_dir, "..");
|
|
15583
16172
|
}
|
|
15584
16173
|
});
|
|
15585
16174
|
|
|
15586
16175
|
// packages/cli/dist/tui/oa-directory.js
|
|
15587
|
-
import { existsSync as
|
|
15588
|
-
import { join as
|
|
15589
|
-
import { homedir as
|
|
16176
|
+
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";
|
|
16177
|
+
import { join as join25, relative as relative2, basename as basename9, extname as extname8 } from "node:path";
|
|
16178
|
+
import { homedir as homedir9 } from "node:os";
|
|
15590
16179
|
function initOaDirectory(repoRoot) {
|
|
15591
|
-
const oaPath =
|
|
16180
|
+
const oaPath = join25(repoRoot, OA_DIR);
|
|
15592
16181
|
for (const sub of SUBDIRS) {
|
|
15593
|
-
mkdirSync6(
|
|
16182
|
+
mkdirSync6(join25(oaPath, sub), { recursive: true });
|
|
15594
16183
|
}
|
|
15595
16184
|
return oaPath;
|
|
15596
16185
|
}
|
|
15597
16186
|
function hasOaDirectory(repoRoot) {
|
|
15598
|
-
return
|
|
16187
|
+
return existsSync19(join25(repoRoot, OA_DIR, "index"));
|
|
15599
16188
|
}
|
|
15600
16189
|
function loadProjectSettings(repoRoot) {
|
|
15601
|
-
const settingsPath =
|
|
16190
|
+
const settingsPath = join25(repoRoot, OA_DIR, "settings.json");
|
|
15602
16191
|
try {
|
|
15603
|
-
if (
|
|
16192
|
+
if (existsSync19(settingsPath)) {
|
|
15604
16193
|
return JSON.parse(readFileSync13(settingsPath, "utf-8"));
|
|
15605
16194
|
}
|
|
15606
16195
|
} catch {
|
|
@@ -15608,16 +16197,16 @@ function loadProjectSettings(repoRoot) {
|
|
|
15608
16197
|
return {};
|
|
15609
16198
|
}
|
|
15610
16199
|
function saveProjectSettings(repoRoot, settings) {
|
|
15611
|
-
const oaPath =
|
|
16200
|
+
const oaPath = join25(repoRoot, OA_DIR);
|
|
15612
16201
|
mkdirSync6(oaPath, { recursive: true });
|
|
15613
16202
|
const existing = loadProjectSettings(repoRoot);
|
|
15614
16203
|
const merged = { ...existing, ...settings };
|
|
15615
|
-
writeFileSync6(
|
|
16204
|
+
writeFileSync6(join25(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", "utf-8");
|
|
15616
16205
|
}
|
|
15617
16206
|
function loadGlobalSettings() {
|
|
15618
|
-
const settingsPath =
|
|
16207
|
+
const settingsPath = join25(homedir9(), ".open-agents", "settings.json");
|
|
15619
16208
|
try {
|
|
15620
|
-
if (
|
|
16209
|
+
if (existsSync19(settingsPath)) {
|
|
15621
16210
|
return JSON.parse(readFileSync13(settingsPath, "utf-8"));
|
|
15622
16211
|
}
|
|
15623
16212
|
} catch {
|
|
@@ -15625,11 +16214,11 @@ function loadGlobalSettings() {
|
|
|
15625
16214
|
return {};
|
|
15626
16215
|
}
|
|
15627
16216
|
function saveGlobalSettings(settings) {
|
|
15628
|
-
const dir =
|
|
16217
|
+
const dir = join25(homedir9(), ".open-agents");
|
|
15629
16218
|
mkdirSync6(dir, { recursive: true });
|
|
15630
16219
|
const existing = loadGlobalSettings();
|
|
15631
16220
|
const merged = { ...existing, ...settings };
|
|
15632
|
-
writeFileSync6(
|
|
16221
|
+
writeFileSync6(join25(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", "utf-8");
|
|
15633
16222
|
}
|
|
15634
16223
|
function resolveSettings(repoRoot) {
|
|
15635
16224
|
const global = loadGlobalSettings();
|
|
@@ -15644,9 +16233,9 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
15644
16233
|
while (dir && !visited.has(dir)) {
|
|
15645
16234
|
visited.add(dir);
|
|
15646
16235
|
for (const name of CONTEXT_FILES) {
|
|
15647
|
-
const filePath =
|
|
16236
|
+
const filePath = join25(dir, name);
|
|
15648
16237
|
const normalizedName = name.toLowerCase();
|
|
15649
|
-
if (
|
|
16238
|
+
if (existsSync19(filePath) && !seen.has(filePath)) {
|
|
15650
16239
|
seen.add(filePath);
|
|
15651
16240
|
try {
|
|
15652
16241
|
let content = readFileSync13(filePath, "utf-8");
|
|
@@ -15663,8 +16252,8 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
15663
16252
|
}
|
|
15664
16253
|
}
|
|
15665
16254
|
}
|
|
15666
|
-
const projectMap =
|
|
15667
|
-
if (
|
|
16255
|
+
const projectMap = join25(dir, OA_DIR, "context", "project-map.md");
|
|
16256
|
+
if (existsSync19(projectMap) && !seen.has(projectMap)) {
|
|
15668
16257
|
seen.add(projectMap);
|
|
15669
16258
|
try {
|
|
15670
16259
|
let content = readFileSync13(projectMap, "utf-8");
|
|
@@ -15679,7 +16268,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
15679
16268
|
} catch {
|
|
15680
16269
|
}
|
|
15681
16270
|
}
|
|
15682
|
-
const parent =
|
|
16271
|
+
const parent = join25(dir, "..");
|
|
15683
16272
|
if (parent === dir)
|
|
15684
16273
|
break;
|
|
15685
16274
|
dir = parent;
|
|
@@ -15697,7 +16286,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
15697
16286
|
return found;
|
|
15698
16287
|
}
|
|
15699
16288
|
function readIndexMeta(repoRoot) {
|
|
15700
|
-
const metaPath =
|
|
16289
|
+
const metaPath = join25(repoRoot, OA_DIR, "index", "meta.json");
|
|
15701
16290
|
try {
|
|
15702
16291
|
return JSON.parse(readFileSync13(metaPath, "utf-8"));
|
|
15703
16292
|
} catch {
|
|
@@ -15706,7 +16295,7 @@ function readIndexMeta(repoRoot) {
|
|
|
15706
16295
|
}
|
|
15707
16296
|
function generateProjectMap(repoRoot) {
|
|
15708
16297
|
const sections = [];
|
|
15709
|
-
const repoName2 =
|
|
16298
|
+
const repoName2 = basename9(repoRoot);
|
|
15710
16299
|
sections.push(`# Project Map: ${repoName2}
|
|
15711
16300
|
`);
|
|
15712
16301
|
sections.push(`> Auto-generated by open-agents. Updated: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
|
|
@@ -15750,28 +16339,28 @@ ${tree}\`\`\`
|
|
|
15750
16339
|
sections.push("");
|
|
15751
16340
|
}
|
|
15752
16341
|
const content = sections.join("\n");
|
|
15753
|
-
const contextDir =
|
|
16342
|
+
const contextDir = join25(repoRoot, OA_DIR, "context");
|
|
15754
16343
|
mkdirSync6(contextDir, { recursive: true });
|
|
15755
|
-
writeFileSync6(
|
|
16344
|
+
writeFileSync6(join25(contextDir, "project-map.md"), content, "utf-8");
|
|
15756
16345
|
return content;
|
|
15757
16346
|
}
|
|
15758
16347
|
function saveSession(repoRoot, session) {
|
|
15759
|
-
const historyDir =
|
|
16348
|
+
const historyDir = join25(repoRoot, OA_DIR, "history");
|
|
15760
16349
|
mkdirSync6(historyDir, { recursive: true });
|
|
15761
|
-
writeFileSync6(
|
|
16350
|
+
writeFileSync6(join25(historyDir, `${session.id}.json`), JSON.stringify(session, null, 2), "utf-8");
|
|
15762
16351
|
}
|
|
15763
16352
|
function loadRecentSessions(repoRoot, limit = 5) {
|
|
15764
|
-
const historyDir =
|
|
15765
|
-
if (!
|
|
16353
|
+
const historyDir = join25(repoRoot, OA_DIR, "history");
|
|
16354
|
+
if (!existsSync19(historyDir))
|
|
15766
16355
|
return [];
|
|
15767
16356
|
try {
|
|
15768
16357
|
const files = readdirSync7(historyDir).filter((f) => f.endsWith(".json") && f !== "pending-task.json").map((f) => {
|
|
15769
|
-
const stat5 = statSync9(
|
|
16358
|
+
const stat5 = statSync9(join25(historyDir, f));
|
|
15770
16359
|
return { file: f, mtime: stat5.mtimeMs };
|
|
15771
16360
|
}).sort((a, b) => b.mtime - a.mtime).slice(0, limit);
|
|
15772
16361
|
return files.map((f) => {
|
|
15773
16362
|
try {
|
|
15774
|
-
return JSON.parse(readFileSync13(
|
|
16363
|
+
return JSON.parse(readFileSync13(join25(historyDir, f.file), "utf-8"));
|
|
15775
16364
|
} catch {
|
|
15776
16365
|
return null;
|
|
15777
16366
|
}
|
|
@@ -15781,14 +16370,14 @@ function loadRecentSessions(repoRoot, limit = 5) {
|
|
|
15781
16370
|
}
|
|
15782
16371
|
}
|
|
15783
16372
|
function savePendingTask(repoRoot, task) {
|
|
15784
|
-
const historyDir =
|
|
16373
|
+
const historyDir = join25(repoRoot, OA_DIR, "history");
|
|
15785
16374
|
mkdirSync6(historyDir, { recursive: true });
|
|
15786
|
-
writeFileSync6(
|
|
16375
|
+
writeFileSync6(join25(historyDir, PENDING_TASK_FILE), JSON.stringify(task, null, 2) + "\n", "utf-8");
|
|
15787
16376
|
}
|
|
15788
16377
|
function loadPendingTask(repoRoot) {
|
|
15789
|
-
const filePath =
|
|
16378
|
+
const filePath = join25(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
|
|
15790
16379
|
try {
|
|
15791
|
-
if (!
|
|
16380
|
+
if (!existsSync19(filePath))
|
|
15792
16381
|
return null;
|
|
15793
16382
|
const data = JSON.parse(readFileSync13(filePath, "utf-8"));
|
|
15794
16383
|
try {
|
|
@@ -15801,12 +16390,12 @@ function loadPendingTask(repoRoot) {
|
|
|
15801
16390
|
}
|
|
15802
16391
|
}
|
|
15803
16392
|
function saveSessionContext(repoRoot, entry) {
|
|
15804
|
-
const contextDir =
|
|
16393
|
+
const contextDir = join25(repoRoot, OA_DIR, "context");
|
|
15805
16394
|
mkdirSync6(contextDir, { recursive: true });
|
|
15806
|
-
const filePath =
|
|
16395
|
+
const filePath = join25(contextDir, CONTEXT_SAVE_FILE);
|
|
15807
16396
|
let ctx;
|
|
15808
16397
|
try {
|
|
15809
|
-
if (
|
|
16398
|
+
if (existsSync19(filePath)) {
|
|
15810
16399
|
ctx = JSON.parse(readFileSync13(filePath, "utf-8"));
|
|
15811
16400
|
} else {
|
|
15812
16401
|
ctx = { entries: [], maxEntries: MAX_CONTEXT_ENTRIES, updatedAt: "" };
|
|
@@ -15822,9 +16411,9 @@ function saveSessionContext(repoRoot, entry) {
|
|
|
15822
16411
|
writeFileSync6(filePath, JSON.stringify(ctx, null, 2) + "\n", "utf-8");
|
|
15823
16412
|
}
|
|
15824
16413
|
function loadSessionContext(repoRoot) {
|
|
15825
|
-
const filePath =
|
|
16414
|
+
const filePath = join25(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
|
|
15826
16415
|
try {
|
|
15827
|
-
if (!
|
|
16416
|
+
if (!existsSync19(filePath))
|
|
15828
16417
|
return null;
|
|
15829
16418
|
return JSON.parse(readFileSync13(filePath, "utf-8"));
|
|
15830
16419
|
} catch {
|
|
@@ -15873,8 +16462,8 @@ function detectManifests(repoRoot) {
|
|
|
15873
16462
|
{ file: "docker-compose.yaml", type: "Docker Compose" }
|
|
15874
16463
|
];
|
|
15875
16464
|
for (const check of checks) {
|
|
15876
|
-
const filePath =
|
|
15877
|
-
if (
|
|
16465
|
+
const filePath = join25(repoRoot, check.file);
|
|
16466
|
+
if (existsSync19(filePath)) {
|
|
15878
16467
|
let name;
|
|
15879
16468
|
if (check.nameField) {
|
|
15880
16469
|
try {
|
|
@@ -15907,7 +16496,7 @@ function findKeyFiles(repoRoot) {
|
|
|
15907
16496
|
{ pattern: "CLAUDE.md", description: "Claude Code context" }
|
|
15908
16497
|
];
|
|
15909
16498
|
for (const check of checks) {
|
|
15910
|
-
if (
|
|
16499
|
+
if (existsSync19(join25(repoRoot, check.pattern))) {
|
|
15911
16500
|
keyFiles.push({ path: check.pattern, description: check.description });
|
|
15912
16501
|
}
|
|
15913
16502
|
}
|
|
@@ -15933,12 +16522,12 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
|
|
|
15933
16522
|
if (entry.isDirectory()) {
|
|
15934
16523
|
let fileCount = 0;
|
|
15935
16524
|
try {
|
|
15936
|
-
fileCount = readdirSync7(
|
|
16525
|
+
fileCount = readdirSync7(join25(root, entry.name)).filter((f) => !f.startsWith(".")).length;
|
|
15937
16526
|
} catch {
|
|
15938
16527
|
}
|
|
15939
16528
|
result += `${prefix}${connector}${entry.name}/ (${fileCount})
|
|
15940
16529
|
`;
|
|
15941
|
-
result += buildDirTree(
|
|
16530
|
+
result += buildDirTree(join25(root, entry.name), maxDepth, childPrefix, depth + 1);
|
|
15942
16531
|
} else if (depth < maxDepth) {
|
|
15943
16532
|
result += `${prefix}${connector}${entry.name}
|
|
15944
16533
|
`;
|
|
@@ -15992,9 +16581,9 @@ var init_oa_directory = __esm({
|
|
|
15992
16581
|
// packages/cli/dist/tui/setup.js
|
|
15993
16582
|
import * as readline from "node:readline";
|
|
15994
16583
|
import { execSync as execSync16, spawn as spawn8 } from "node:child_process";
|
|
15995
|
-
import { existsSync as
|
|
15996
|
-
import { join as
|
|
15997
|
-
import { homedir as
|
|
16584
|
+
import { existsSync as existsSync20, writeFileSync as writeFileSync7, mkdirSync as mkdirSync7 } from "node:fs";
|
|
16585
|
+
import { join as join26 } from "node:path";
|
|
16586
|
+
import { homedir as homedir10, platform } from "node:os";
|
|
15998
16587
|
function detectSystemSpecs() {
|
|
15999
16588
|
let totalRamGB = 0;
|
|
16000
16589
|
let availableRamGB = 0;
|
|
@@ -16077,8 +16666,8 @@ function modelSupportsToolCalling(modelName) {
|
|
|
16077
16666
|
return false;
|
|
16078
16667
|
}
|
|
16079
16668
|
function ask(rl, question) {
|
|
16080
|
-
return new Promise((
|
|
16081
|
-
rl.question(question, (answer) =>
|
|
16669
|
+
return new Promise((resolve23) => {
|
|
16670
|
+
rl.question(question, (answer) => resolve23(answer.trim()));
|
|
16082
16671
|
});
|
|
16083
16672
|
}
|
|
16084
16673
|
async function autoInstallOllama(rl) {
|
|
@@ -16145,7 +16734,7 @@ async function installOllamaMac(rl) {
|
|
|
16145
16734
|
execSync16('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"', { stdio: "inherit", timeout: 6e5 });
|
|
16146
16735
|
if (!hasCmd("brew")) {
|
|
16147
16736
|
try {
|
|
16148
|
-
const brewPrefix =
|
|
16737
|
+
const brewPrefix = existsSync20("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
|
|
16149
16738
|
process.env["PATH"] = `${brewPrefix}/bin:${process.env["PATH"]}`;
|
|
16150
16739
|
} catch {
|
|
16151
16740
|
}
|
|
@@ -16436,7 +17025,7 @@ async function doSetup(config, rl) {
|
|
|
16436
17025
|
try {
|
|
16437
17026
|
const child = spawn8("ollama", ["serve"], { stdio: "ignore", detached: true });
|
|
16438
17027
|
child.unref();
|
|
16439
|
-
await new Promise((
|
|
17028
|
+
await new Promise((resolve23) => setTimeout(resolve23, 3e3));
|
|
16440
17029
|
try {
|
|
16441
17030
|
models = await fetchOllamaModels(config.backendUrl);
|
|
16442
17031
|
process.stdout.write(` ${c2.green("\u2714")} Ollama is running.
|
|
@@ -16464,7 +17053,7 @@ async function doSetup(config, rl) {
|
|
|
16464
17053
|
try {
|
|
16465
17054
|
const child = spawn8("ollama", ["serve"], { stdio: "ignore", detached: true });
|
|
16466
17055
|
child.unref();
|
|
16467
|
-
await new Promise((
|
|
17056
|
+
await new Promise((resolve23) => setTimeout(resolve23, 3e3));
|
|
16468
17057
|
try {
|
|
16469
17058
|
models = await fetchOllamaModels(config.backendUrl);
|
|
16470
17059
|
process.stdout.write(` ${c2.green("\u2714")} Ollama is running.
|
|
@@ -16619,9 +17208,9 @@ async function doSetup(config, rl) {
|
|
|
16619
17208
|
`PARAMETER num_predict ${numPredict}`,
|
|
16620
17209
|
`PARAMETER stop "<|endoftext|>"`
|
|
16621
17210
|
].join("\n");
|
|
16622
|
-
const modelDir2 =
|
|
17211
|
+
const modelDir2 = join26(homedir10(), ".open-agents", "models");
|
|
16623
17212
|
mkdirSync7(modelDir2, { recursive: true });
|
|
16624
|
-
const modelfilePath =
|
|
17213
|
+
const modelfilePath = join26(modelDir2, `Modelfile.${customName}`);
|
|
16625
17214
|
writeFileSync7(modelfilePath, modelfileContent + "\n", "utf8");
|
|
16626
17215
|
process.stdout.write(` ${c2.dim("Creating model...")} `);
|
|
16627
17216
|
execSync16(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
@@ -16667,7 +17256,7 @@ async function isModelAvailable(config) {
|
|
|
16667
17256
|
}
|
|
16668
17257
|
function isFirstRun() {
|
|
16669
17258
|
try {
|
|
16670
|
-
return !
|
|
17259
|
+
return !existsSync20(join26(homedir10(), ".open-agents", "config.json"));
|
|
16671
17260
|
} catch {
|
|
16672
17261
|
return true;
|
|
16673
17262
|
}
|
|
@@ -16704,7 +17293,7 @@ function detectPkgManager() {
|
|
|
16704
17293
|
return null;
|
|
16705
17294
|
}
|
|
16706
17295
|
function getVenvDir() {
|
|
16707
|
-
return
|
|
17296
|
+
return join26(homedir10(), ".open-agents", "venv");
|
|
16708
17297
|
}
|
|
16709
17298
|
function hasVenvModule() {
|
|
16710
17299
|
try {
|
|
@@ -16716,8 +17305,8 @@ function hasVenvModule() {
|
|
|
16716
17305
|
}
|
|
16717
17306
|
function ensureVenv(log) {
|
|
16718
17307
|
const venvDir = getVenvDir();
|
|
16719
|
-
const venvPip =
|
|
16720
|
-
if (
|
|
17308
|
+
const venvPip = join26(venvDir, "bin", "pip");
|
|
17309
|
+
if (existsSync20(venvPip))
|
|
16721
17310
|
return venvDir;
|
|
16722
17311
|
log("Creating Python venv for vision deps...");
|
|
16723
17312
|
if (!hasCmd("python3")) {
|
|
@@ -16729,9 +17318,9 @@ function ensureVenv(log) {
|
|
|
16729
17318
|
return null;
|
|
16730
17319
|
}
|
|
16731
17320
|
try {
|
|
16732
|
-
mkdirSync7(
|
|
17321
|
+
mkdirSync7(join26(homedir10(), ".open-agents"), { recursive: true });
|
|
16733
17322
|
execSync16(`python3 -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
|
|
16734
|
-
execSync16(`"${
|
|
17323
|
+
execSync16(`"${join26(venvDir, "bin", "pip")}" install --upgrade pip`, {
|
|
16735
17324
|
stdio: "pipe",
|
|
16736
17325
|
timeout: 6e4
|
|
16737
17326
|
});
|
|
@@ -16940,15 +17529,15 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
16940
17529
|
}
|
|
16941
17530
|
}
|
|
16942
17531
|
const venvDir = getVenvDir();
|
|
16943
|
-
const venvBin =
|
|
16944
|
-
const venvMoondream =
|
|
17532
|
+
const venvBin = join26(venvDir, "bin");
|
|
17533
|
+
const venvMoondream = join26(venvBin, "moondream-station");
|
|
16945
17534
|
const venv = ensureVenv(log);
|
|
16946
|
-
if (venv && !hasCmd("moondream-station") && !
|
|
16947
|
-
const venvPip =
|
|
17535
|
+
if (venv && !hasCmd("moondream-station") && !existsSync20(venvMoondream)) {
|
|
17536
|
+
const venvPip = join26(venvBin, "pip");
|
|
16948
17537
|
log("Installing moondream-station in ~/.open-agents/venv...");
|
|
16949
17538
|
try {
|
|
16950
17539
|
execSync16(`"${venvPip}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
|
|
16951
|
-
if (
|
|
17540
|
+
if (existsSync20(venvMoondream)) {
|
|
16952
17541
|
log("moondream-station installed successfully.");
|
|
16953
17542
|
} else {
|
|
16954
17543
|
try {
|
|
@@ -16965,8 +17554,8 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
16965
17554
|
}
|
|
16966
17555
|
}
|
|
16967
17556
|
if (venv) {
|
|
16968
|
-
const venvPython =
|
|
16969
|
-
const venvPip2 =
|
|
17557
|
+
const venvPython = join26(venvBin, "python");
|
|
17558
|
+
const venvPip2 = join26(venvBin, "pip");
|
|
16970
17559
|
let ocrStackInstalled = false;
|
|
16971
17560
|
try {
|
|
16972
17561
|
execSync16(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
|
|
@@ -17026,9 +17615,9 @@ function createExpandedVariant(baseModel, specs, sizeGB) {
|
|
|
17026
17615
|
`PARAMETER num_predict ${numPredict}`,
|
|
17027
17616
|
`PARAMETER stop "<|endoftext|>"`
|
|
17028
17617
|
].join("\n");
|
|
17029
|
-
const modelDir2 =
|
|
17618
|
+
const modelDir2 = join26(homedir10(), ".open-agents", "models");
|
|
17030
17619
|
mkdirSync7(modelDir2, { recursive: true });
|
|
17031
|
-
const modelfilePath =
|
|
17620
|
+
const modelfilePath = join26(modelDir2, `Modelfile.${customName}`);
|
|
17032
17621
|
writeFileSync7(modelfilePath, modelfileContent + "\n", "utf8");
|
|
17033
17622
|
execSync16(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
17034
17623
|
stdio: "pipe",
|
|
@@ -17792,17 +18381,17 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
17792
18381
|
try {
|
|
17793
18382
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
17794
18383
|
const { fileURLToPath: fileURLToPath9 } = await import("node:url");
|
|
17795
|
-
const { dirname: dirname12, join:
|
|
17796
|
-
const { existsSync:
|
|
18384
|
+
const { dirname: dirname12, join: join37 } = await import("node:path");
|
|
18385
|
+
const { existsSync: existsSync27 } = await import("node:fs");
|
|
17797
18386
|
const req = createRequire4(import.meta.url);
|
|
17798
18387
|
const thisDir = dirname12(fileURLToPath9(import.meta.url));
|
|
17799
18388
|
const candidates = [
|
|
17800
|
-
|
|
17801
|
-
|
|
17802
|
-
|
|
18389
|
+
join37(thisDir, "..", "package.json"),
|
|
18390
|
+
join37(thisDir, "..", "..", "package.json"),
|
|
18391
|
+
join37(thisDir, "..", "..", "..", "package.json")
|
|
17803
18392
|
];
|
|
17804
18393
|
for (const pkgPath of candidates) {
|
|
17805
|
-
if (
|
|
18394
|
+
if (existsSync27(pkgPath)) {
|
|
17806
18395
|
const pkg = req(pkgPath);
|
|
17807
18396
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
|
|
17808
18397
|
currentVersion = pkg.version ?? "0.0.0";
|
|
@@ -17917,10 +18506,10 @@ var init_commands = __esm({
|
|
|
17917
18506
|
});
|
|
17918
18507
|
|
|
17919
18508
|
// packages/cli/dist/tui/project-context.js
|
|
17920
|
-
import { existsSync as
|
|
17921
|
-
import { join as
|
|
18509
|
+
import { existsSync as existsSync21, readFileSync as readFileSync14, readdirSync as readdirSync8 } from "node:fs";
|
|
18510
|
+
import { join as join27, basename as basename10 } from "node:path";
|
|
17922
18511
|
import { execSync as execSync17 } from "node:child_process";
|
|
17923
|
-
import { homedir as
|
|
18512
|
+
import { homedir as homedir11, platform as platform2, release } from "node:os";
|
|
17924
18513
|
function getModelTier(modelName) {
|
|
17925
18514
|
const m = modelName.toLowerCase();
|
|
17926
18515
|
const sizeMatch = m.match(/\b(\d+)b\b/);
|
|
@@ -17953,8 +18542,8 @@ function loadProjectMap(repoRoot) {
|
|
|
17953
18542
|
if (!hasOaDirectory(repoRoot)) {
|
|
17954
18543
|
initOaDirectory(repoRoot);
|
|
17955
18544
|
}
|
|
17956
|
-
const mapPath =
|
|
17957
|
-
if (
|
|
18545
|
+
const mapPath = join27(repoRoot, OA_DIR, "context", "project-map.md");
|
|
18546
|
+
if (existsSync21(mapPath)) {
|
|
17958
18547
|
try {
|
|
17959
18548
|
const content = readFileSync14(mapPath, "utf-8");
|
|
17960
18549
|
return content;
|
|
@@ -17997,33 +18586,33 @@ ${log}`);
|
|
|
17997
18586
|
}
|
|
17998
18587
|
function loadMemoryContext(repoRoot) {
|
|
17999
18588
|
const sections = [];
|
|
18000
|
-
const oaMemDir =
|
|
18589
|
+
const oaMemDir = join27(repoRoot, OA_DIR, "memory");
|
|
18001
18590
|
const oaEntries = loadMemoryDir(oaMemDir, "project");
|
|
18002
18591
|
if (oaEntries)
|
|
18003
18592
|
sections.push(oaEntries);
|
|
18004
|
-
const legacyMemDir =
|
|
18005
|
-
if (legacyMemDir !== oaMemDir &&
|
|
18593
|
+
const legacyMemDir = join27(repoRoot, ".open-agents", "memory");
|
|
18594
|
+
if (legacyMemDir !== oaMemDir && existsSync21(legacyMemDir)) {
|
|
18006
18595
|
const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
|
|
18007
18596
|
if (legacyEntries)
|
|
18008
18597
|
sections.push(legacyEntries);
|
|
18009
18598
|
}
|
|
18010
|
-
const globalMemDir =
|
|
18599
|
+
const globalMemDir = join27(homedir11(), ".open-agents", "memory");
|
|
18011
18600
|
const globalEntries = loadMemoryDir(globalMemDir, "global");
|
|
18012
18601
|
if (globalEntries)
|
|
18013
18602
|
sections.push(globalEntries);
|
|
18014
18603
|
return sections.join("\n\n");
|
|
18015
18604
|
}
|
|
18016
18605
|
function loadMemoryDir(memDir, scope) {
|
|
18017
|
-
if (!
|
|
18606
|
+
if (!existsSync21(memDir))
|
|
18018
18607
|
return "";
|
|
18019
18608
|
const lines = [];
|
|
18020
18609
|
try {
|
|
18021
18610
|
const files = readdirSync8(memDir).filter((f) => f.endsWith(".json"));
|
|
18022
18611
|
for (const file of files.slice(0, 10)) {
|
|
18023
18612
|
try {
|
|
18024
|
-
const raw = readFileSync14(
|
|
18613
|
+
const raw = readFileSync14(join27(memDir, file), "utf-8");
|
|
18025
18614
|
const entries = JSON.parse(raw);
|
|
18026
|
-
const topic =
|
|
18615
|
+
const topic = basename10(file, ".json");
|
|
18027
18616
|
const keys = Object.keys(entries);
|
|
18028
18617
|
if (keys.length === 0)
|
|
18029
18618
|
continue;
|
|
@@ -19048,12 +19637,12 @@ var init_carousel = __esm({
|
|
|
19048
19637
|
});
|
|
19049
19638
|
|
|
19050
19639
|
// packages/cli/dist/tui/carousel-descriptors.js
|
|
19051
|
-
import { existsSync as
|
|
19052
|
-
import { join as
|
|
19640
|
+
import { existsSync as existsSync22, readFileSync as readFileSync15, writeFileSync as writeFileSync8, mkdirSync as mkdirSync8, readdirSync as readdirSync9 } from "node:fs";
|
|
19641
|
+
import { join as join28, basename as basename11 } from "node:path";
|
|
19053
19642
|
function loadToolProfile(repoRoot) {
|
|
19054
|
-
const filePath =
|
|
19643
|
+
const filePath = join28(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
|
|
19055
19644
|
try {
|
|
19056
|
-
if (!
|
|
19645
|
+
if (!existsSync22(filePath))
|
|
19057
19646
|
return null;
|
|
19058
19647
|
return JSON.parse(readFileSync15(filePath, "utf-8"));
|
|
19059
19648
|
} catch {
|
|
@@ -19061,9 +19650,9 @@ function loadToolProfile(repoRoot) {
|
|
|
19061
19650
|
}
|
|
19062
19651
|
}
|
|
19063
19652
|
function saveToolProfile(repoRoot, profile) {
|
|
19064
|
-
const contextDir =
|
|
19653
|
+
const contextDir = join28(repoRoot, OA_DIR, "context");
|
|
19065
19654
|
mkdirSync8(contextDir, { recursive: true });
|
|
19066
|
-
writeFileSync8(
|
|
19655
|
+
writeFileSync8(join28(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
|
|
19067
19656
|
}
|
|
19068
19657
|
function categorizeToolCall(toolName) {
|
|
19069
19658
|
for (const cat of TOOL_CATEGORIES) {
|
|
@@ -19121,9 +19710,9 @@ function weightedColor(profile) {
|
|
|
19121
19710
|
return selectedCat.colors[Math.floor(Math.random() * selectedCat.colors.length)];
|
|
19122
19711
|
}
|
|
19123
19712
|
function loadCachedDescriptors(repoRoot) {
|
|
19124
|
-
const filePath =
|
|
19713
|
+
const filePath = join28(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
|
|
19125
19714
|
try {
|
|
19126
|
-
if (!
|
|
19715
|
+
if (!existsSync22(filePath))
|
|
19127
19716
|
return null;
|
|
19128
19717
|
const cached = JSON.parse(readFileSync15(filePath, "utf-8"));
|
|
19129
19718
|
return cached.phrases.length > 0 ? cached.phrases : null;
|
|
@@ -19132,14 +19721,14 @@ function loadCachedDescriptors(repoRoot) {
|
|
|
19132
19721
|
}
|
|
19133
19722
|
}
|
|
19134
19723
|
function saveCachedDescriptors(repoRoot, phrases, sourceHash) {
|
|
19135
|
-
const contextDir =
|
|
19724
|
+
const contextDir = join28(repoRoot, OA_DIR, "context");
|
|
19136
19725
|
mkdirSync8(contextDir, { recursive: true });
|
|
19137
19726
|
const cached = {
|
|
19138
19727
|
phrases,
|
|
19139
19728
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
19140
19729
|
sourceHash
|
|
19141
19730
|
};
|
|
19142
|
-
writeFileSync8(
|
|
19731
|
+
writeFileSync8(join28(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
|
|
19143
19732
|
}
|
|
19144
19733
|
function generateDescriptors(repoRoot) {
|
|
19145
19734
|
const profile = loadToolProfile(repoRoot);
|
|
@@ -19150,7 +19739,7 @@ function generateDescriptors(repoRoot) {
|
|
|
19150
19739
|
extractFromSessions(repoRoot, tags);
|
|
19151
19740
|
extractFromMemory(repoRoot, tags);
|
|
19152
19741
|
extractFromToolProfile(profile, tags);
|
|
19153
|
-
const repoName2 =
|
|
19742
|
+
const repoName2 = basename11(repoRoot);
|
|
19154
19743
|
if (repoName2 && !tags.includes(repoName2)) {
|
|
19155
19744
|
tags.push(repoName2);
|
|
19156
19745
|
}
|
|
@@ -19187,9 +19776,9 @@ function generateDescriptors(repoRoot) {
|
|
|
19187
19776
|
return phrases;
|
|
19188
19777
|
}
|
|
19189
19778
|
function extractFromPackageJson(repoRoot, tags) {
|
|
19190
|
-
const pkgPath =
|
|
19779
|
+
const pkgPath = join28(repoRoot, "package.json");
|
|
19191
19780
|
try {
|
|
19192
|
-
if (!
|
|
19781
|
+
if (!existsSync22(pkgPath))
|
|
19193
19782
|
return;
|
|
19194
19783
|
const pkg = JSON.parse(readFileSync15(pkgPath, "utf-8"));
|
|
19195
19784
|
if (pkg.name && typeof pkg.name === "string") {
|
|
@@ -19235,7 +19824,7 @@ function extractFromManifests(repoRoot, tags) {
|
|
|
19235
19824
|
{ file: ".github/workflows", tag: "ci/cd" }
|
|
19236
19825
|
];
|
|
19237
19826
|
for (const check of manifestChecks) {
|
|
19238
|
-
if (
|
|
19827
|
+
if (existsSync22(join28(repoRoot, check.file))) {
|
|
19239
19828
|
tags.push(check.tag);
|
|
19240
19829
|
}
|
|
19241
19830
|
}
|
|
@@ -19257,16 +19846,16 @@ function extractFromSessions(repoRoot, tags) {
|
|
|
19257
19846
|
}
|
|
19258
19847
|
}
|
|
19259
19848
|
function extractFromMemory(repoRoot, tags) {
|
|
19260
|
-
const memoryDir =
|
|
19849
|
+
const memoryDir = join28(repoRoot, OA_DIR, "memory");
|
|
19261
19850
|
try {
|
|
19262
|
-
if (!
|
|
19851
|
+
if (!existsSync22(memoryDir))
|
|
19263
19852
|
return;
|
|
19264
19853
|
const files = readdirSync9(memoryDir).filter((f) => f.endsWith(".json"));
|
|
19265
19854
|
for (const file of files) {
|
|
19266
19855
|
const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
|
|
19267
19856
|
tags.push(topic);
|
|
19268
19857
|
try {
|
|
19269
|
-
const data = JSON.parse(readFileSync15(
|
|
19858
|
+
const data = JSON.parse(readFileSync15(join28(memoryDir, file), "utf-8"));
|
|
19270
19859
|
if (data && typeof data === "object") {
|
|
19271
19860
|
const keys = Object.keys(data).slice(0, 3);
|
|
19272
19861
|
for (const key of keys) {
|
|
@@ -19401,25 +19990,25 @@ var init_carousel_descriptors = __esm({
|
|
|
19401
19990
|
});
|
|
19402
19991
|
|
|
19403
19992
|
// packages/cli/dist/tui/voice.js
|
|
19404
|
-
import { existsSync as
|
|
19405
|
-
import { join as
|
|
19406
|
-
import { homedir as
|
|
19993
|
+
import { existsSync as existsSync23, mkdirSync as mkdirSync9, writeFileSync as writeFileSync9, readFileSync as readFileSync16, unlinkSync as unlinkSync4 } from "node:fs";
|
|
19994
|
+
import { join as join29 } from "node:path";
|
|
19995
|
+
import { homedir as homedir12, tmpdir as tmpdir6, platform as platform3 } from "node:os";
|
|
19407
19996
|
import { execSync as execSync18, spawn as nodeSpawn } from "node:child_process";
|
|
19408
19997
|
import { createRequire } from "node:module";
|
|
19409
19998
|
function voiceDir() {
|
|
19410
|
-
return
|
|
19999
|
+
return join29(homedir12(), ".open-agents", "voice");
|
|
19411
20000
|
}
|
|
19412
20001
|
function modelsDir() {
|
|
19413
|
-
return
|
|
20002
|
+
return join29(voiceDir(), "models");
|
|
19414
20003
|
}
|
|
19415
20004
|
function modelDir(id) {
|
|
19416
|
-
return
|
|
20005
|
+
return join29(modelsDir(), id);
|
|
19417
20006
|
}
|
|
19418
20007
|
function modelOnnxPath(id) {
|
|
19419
|
-
return
|
|
20008
|
+
return join29(modelDir(id), "model.onnx");
|
|
19420
20009
|
}
|
|
19421
20010
|
function modelConfigPath(id) {
|
|
19422
|
-
return
|
|
20011
|
+
return join29(modelDir(id), "config.json");
|
|
19423
20012
|
}
|
|
19424
20013
|
function describeToolCall(toolName, args) {
|
|
19425
20014
|
const path = args["path"];
|
|
@@ -19692,7 +20281,7 @@ var init_voice = __esm({
|
|
|
19692
20281
|
const audioData = result["output"].data;
|
|
19693
20282
|
if (audioData.length === 0)
|
|
19694
20283
|
return;
|
|
19695
|
-
const wavPath =
|
|
20284
|
+
const wavPath = join29(tmpdir6(), `oa-voice-${Date.now()}.wav`);
|
|
19696
20285
|
this.writeWav(audioData, this.config.audio.sample_rate, wavPath);
|
|
19697
20286
|
await this.playWav(wavPath);
|
|
19698
20287
|
try {
|
|
@@ -19781,7 +20370,7 @@ var init_voice = __esm({
|
|
|
19781
20370
|
const cmd = this.getPlayCommand(path);
|
|
19782
20371
|
if (!cmd)
|
|
19783
20372
|
return;
|
|
19784
|
-
return new Promise((
|
|
20373
|
+
return new Promise((resolve23) => {
|
|
19785
20374
|
const child = nodeSpawn(cmd[0], cmd.slice(1), {
|
|
19786
20375
|
stdio: "ignore",
|
|
19787
20376
|
detached: false
|
|
@@ -19790,12 +20379,12 @@ var init_voice = __esm({
|
|
|
19790
20379
|
child.on("close", () => {
|
|
19791
20380
|
if (this.currentPlayback === child)
|
|
19792
20381
|
this.currentPlayback = null;
|
|
19793
|
-
|
|
20382
|
+
resolve23();
|
|
19794
20383
|
});
|
|
19795
20384
|
child.on("error", () => {
|
|
19796
20385
|
if (this.currentPlayback === child)
|
|
19797
20386
|
this.currentPlayback = null;
|
|
19798
|
-
|
|
20387
|
+
resolve23();
|
|
19799
20388
|
});
|
|
19800
20389
|
setTimeout(() => {
|
|
19801
20390
|
if (this.currentPlayback === child) {
|
|
@@ -19805,7 +20394,7 @@ var init_voice = __esm({
|
|
|
19805
20394
|
}
|
|
19806
20395
|
this.currentPlayback = null;
|
|
19807
20396
|
}
|
|
19808
|
-
|
|
20397
|
+
resolve23();
|
|
19809
20398
|
}, 15e3);
|
|
19810
20399
|
});
|
|
19811
20400
|
}
|
|
@@ -19847,12 +20436,12 @@ var init_voice = __esm({
|
|
|
19847
20436
|
const arch = process.arch;
|
|
19848
20437
|
const isArmLinux = (arch === "arm64" || arch === "arm") && process.platform === "linux";
|
|
19849
20438
|
mkdirSync9(voiceDir(), { recursive: true });
|
|
19850
|
-
const pkgPath =
|
|
20439
|
+
const pkgPath = join29(voiceDir(), "package.json");
|
|
19851
20440
|
const expectedDeps = {
|
|
19852
20441
|
"onnxruntime-node": "^1.21.0",
|
|
19853
20442
|
"phonemizer": "^1.2.1"
|
|
19854
20443
|
};
|
|
19855
|
-
if (
|
|
20444
|
+
if (existsSync23(pkgPath)) {
|
|
19856
20445
|
try {
|
|
19857
20446
|
const existing = JSON.parse(readFileSync16(pkgPath, "utf8"));
|
|
19858
20447
|
if (!existing.dependencies?.["phonemizer"]) {
|
|
@@ -19862,14 +20451,14 @@ var init_voice = __esm({
|
|
|
19862
20451
|
} catch {
|
|
19863
20452
|
}
|
|
19864
20453
|
}
|
|
19865
|
-
if (!
|
|
20454
|
+
if (!existsSync23(pkgPath)) {
|
|
19866
20455
|
writeFileSync9(pkgPath, JSON.stringify({
|
|
19867
20456
|
name: "open-agents-voice",
|
|
19868
20457
|
private: true,
|
|
19869
20458
|
dependencies: expectedDeps
|
|
19870
20459
|
}, null, 2));
|
|
19871
20460
|
}
|
|
19872
|
-
const voiceRequire = createRequire(
|
|
20461
|
+
const voiceRequire = createRequire(join29(voiceDir(), "index.js"));
|
|
19873
20462
|
try {
|
|
19874
20463
|
this.ort = voiceRequire("onnxruntime-node");
|
|
19875
20464
|
} catch {
|
|
@@ -19923,10 +20512,10 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
19923
20512
|
const dir = modelDir(id);
|
|
19924
20513
|
const onnxPath = modelOnnxPath(id);
|
|
19925
20514
|
const configPath = modelConfigPath(id);
|
|
19926
|
-
if (
|
|
20515
|
+
if (existsSync23(onnxPath) && existsSync23(configPath))
|
|
19927
20516
|
return;
|
|
19928
20517
|
mkdirSync9(dir, { recursive: true });
|
|
19929
|
-
if (!
|
|
20518
|
+
if (!existsSync23(configPath)) {
|
|
19930
20519
|
renderInfo(`Downloading ${model.label} voice config...`);
|
|
19931
20520
|
const configResp = await fetch(model.configUrl);
|
|
19932
20521
|
if (!configResp.ok)
|
|
@@ -19934,7 +20523,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
19934
20523
|
const configText = await configResp.text();
|
|
19935
20524
|
writeFileSync9(configPath, configText);
|
|
19936
20525
|
}
|
|
19937
|
-
if (!
|
|
20526
|
+
if (!existsSync23(onnxPath)) {
|
|
19938
20527
|
renderInfo(`Downloading ${model.label} voice model (this may take a minute)...`);
|
|
19939
20528
|
const onnxResp = await fetch(model.onnxUrl);
|
|
19940
20529
|
if (!onnxResp.ok)
|
|
@@ -19970,7 +20559,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
19970
20559
|
throw new Error("ONNX runtime not loaded");
|
|
19971
20560
|
const onnxPath = modelOnnxPath(this.modelId);
|
|
19972
20561
|
const configPath = modelConfigPath(this.modelId);
|
|
19973
|
-
if (!
|
|
20562
|
+
if (!existsSync23(onnxPath) || !existsSync23(configPath)) {
|
|
19974
20563
|
throw new Error(`Model files not found for ${this.modelId}`);
|
|
19975
20564
|
}
|
|
19976
20565
|
this.config = JSON.parse(readFileSync16(configPath, "utf8"));
|
|
@@ -20474,10 +21063,10 @@ var init_stream_renderer = __esm({
|
|
|
20474
21063
|
|
|
20475
21064
|
// packages/cli/dist/tui/edit-history.js
|
|
20476
21065
|
import { appendFileSync, mkdirSync as mkdirSync10 } from "node:fs";
|
|
20477
|
-
import { join as
|
|
21066
|
+
import { join as join30 } from "node:path";
|
|
20478
21067
|
function createEditHistoryLogger(repoRoot, sessionId) {
|
|
20479
|
-
const historyDir =
|
|
20480
|
-
const logPath =
|
|
21068
|
+
const historyDir = join30(repoRoot, ".oa", "history");
|
|
21069
|
+
const logPath = join30(historyDir, "edits.jsonl");
|
|
20481
21070
|
try {
|
|
20482
21071
|
mkdirSync10(historyDir, { recursive: true });
|
|
20483
21072
|
} catch {
|
|
@@ -20588,8 +21177,8 @@ var init_edit_history = __esm({
|
|
|
20588
21177
|
});
|
|
20589
21178
|
|
|
20590
21179
|
// packages/cli/dist/tui/dream-engine.js
|
|
20591
|
-
import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync10, readFileSync as readFileSync17, existsSync as
|
|
20592
|
-
import { join as
|
|
21180
|
+
import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync10, readFileSync as readFileSync17, existsSync as existsSync24, cpSync, rmSync, readdirSync as readdirSync10 } from "node:fs";
|
|
21181
|
+
import { join as join31, basename as basename12 } from "node:path";
|
|
20593
21182
|
import { execSync as execSync19 } from "node:child_process";
|
|
20594
21183
|
function adaptTool(tool) {
|
|
20595
21184
|
return {
|
|
@@ -20764,12 +21353,12 @@ var init_dream_engine = __esm({
|
|
|
20764
21353
|
const content = String(args["content"] ?? "");
|
|
20765
21354
|
if (!rawPath)
|
|
20766
21355
|
return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
|
|
20767
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ?
|
|
21356
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join31(this.dreamsDir, basename12(rawPath)) : join31(this.dreamsDir, rawPath);
|
|
20768
21357
|
if (!targetPath.startsWith(this.dreamsDir)) {
|
|
20769
21358
|
return { success: false, output: "", error: "Dream mode: writes are confined to .oa/dreams/", durationMs: Date.now() - start };
|
|
20770
21359
|
}
|
|
20771
21360
|
try {
|
|
20772
|
-
const dir =
|
|
21361
|
+
const dir = join31(targetPath, "..");
|
|
20773
21362
|
mkdirSync11(dir, { recursive: true });
|
|
20774
21363
|
writeFileSync10(targetPath, content, "utf-8");
|
|
20775
21364
|
return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
|
|
@@ -20799,12 +21388,12 @@ var init_dream_engine = __esm({
|
|
|
20799
21388
|
const rawPath = String(args["path"] ?? "");
|
|
20800
21389
|
const oldStr = String(args["old_string"] ?? "");
|
|
20801
21390
|
const newStr = String(args["new_string"] ?? "");
|
|
20802
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ?
|
|
21391
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join31(this.dreamsDir, basename12(rawPath)) : join31(this.dreamsDir, rawPath);
|
|
20803
21392
|
if (!targetPath.startsWith(this.dreamsDir)) {
|
|
20804
21393
|
return { success: false, output: "", error: "Dream mode: edits are confined to .oa/dreams/", durationMs: Date.now() - start };
|
|
20805
21394
|
}
|
|
20806
21395
|
try {
|
|
20807
|
-
if (!
|
|
21396
|
+
if (!existsSync24(targetPath)) {
|
|
20808
21397
|
return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
|
|
20809
21398
|
}
|
|
20810
21399
|
let content = readFileSync17(targetPath, "utf-8");
|
|
@@ -20866,7 +21455,7 @@ var init_dream_engine = __esm({
|
|
|
20866
21455
|
constructor(config, repoRoot) {
|
|
20867
21456
|
this.config = config;
|
|
20868
21457
|
this.repoRoot = repoRoot;
|
|
20869
|
-
this.dreamsDir =
|
|
21458
|
+
this.dreamsDir = join31(repoRoot, ".oa", "dreams");
|
|
20870
21459
|
this.state = {
|
|
20871
21460
|
mode: "default",
|
|
20872
21461
|
active: false,
|
|
@@ -20938,7 +21527,7 @@ ${result.summary}`;
|
|
|
20938
21527
|
if (mode !== "default" || cycle === totalCycles) {
|
|
20939
21528
|
renderDreamContraction(cycle);
|
|
20940
21529
|
const cycleSummary = this.buildCycleSummary(cycle, previousFindings);
|
|
20941
|
-
const summaryPath =
|
|
21530
|
+
const summaryPath = join31(this.dreamsDir, `cycle-${cycle}-summary.md`);
|
|
20942
21531
|
writeFileSync10(summaryPath, cycleSummary, "utf-8");
|
|
20943
21532
|
}
|
|
20944
21533
|
if (mode === "lucid" && !this.abortController.signal.aborted) {
|
|
@@ -21061,7 +21650,7 @@ Dreams directory: ${this.dreamsDir}`);
|
|
|
21061
21650
|
}
|
|
21062
21651
|
/** Save workspace backup for lucid mode */
|
|
21063
21652
|
saveVersionCheckpoint(cycle) {
|
|
21064
|
-
const checkpointDir =
|
|
21653
|
+
const checkpointDir = join31(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
|
|
21065
21654
|
try {
|
|
21066
21655
|
mkdirSync11(checkpointDir, { recursive: true });
|
|
21067
21656
|
try {
|
|
@@ -21080,10 +21669,10 @@ Dreams directory: ${this.dreamsDir}`);
|
|
|
21080
21669
|
encoding: "utf-8",
|
|
21081
21670
|
timeout: 5e3
|
|
21082
21671
|
}).trim();
|
|
21083
|
-
writeFileSync10(
|
|
21084
|
-
writeFileSync10(
|
|
21085
|
-
writeFileSync10(
|
|
21086
|
-
writeFileSync10(
|
|
21672
|
+
writeFileSync10(join31(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
|
|
21673
|
+
writeFileSync10(join31(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
|
|
21674
|
+
writeFileSync10(join31(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
|
|
21675
|
+
writeFileSync10(join31(checkpointDir, "checkpoint.json"), JSON.stringify({
|
|
21087
21676
|
cycle,
|
|
21088
21677
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
21089
21678
|
gitHash,
|
|
@@ -21091,7 +21680,7 @@ Dreams directory: ${this.dreamsDir}`);
|
|
|
21091
21680
|
}, null, 2), "utf-8");
|
|
21092
21681
|
renderInfo(`Checkpoint saved: cycle ${cycle} (${gitHash.slice(0, 8)})`);
|
|
21093
21682
|
} catch {
|
|
21094
|
-
writeFileSync10(
|
|
21683
|
+
writeFileSync10(join31(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
|
|
21095
21684
|
renderInfo(`Checkpoint saved: cycle ${cycle} (no git)`);
|
|
21096
21685
|
}
|
|
21097
21686
|
} catch (err) {
|
|
@@ -21149,14 +21738,14 @@ ${files.map((f) => `- [\`${f}\`](./${f})`).join("\n")}
|
|
|
21149
21738
|
---
|
|
21150
21739
|
*Auto-generated by open-agents dream engine*
|
|
21151
21740
|
`;
|
|
21152
|
-
writeFileSync10(
|
|
21741
|
+
writeFileSync10(join31(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
|
|
21153
21742
|
} catch {
|
|
21154
21743
|
}
|
|
21155
21744
|
}
|
|
21156
21745
|
/** Save dream state for resume/inspection */
|
|
21157
21746
|
saveDreamState() {
|
|
21158
21747
|
try {
|
|
21159
|
-
writeFileSync10(
|
|
21748
|
+
writeFileSync10(join31(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
|
|
21160
21749
|
} catch {
|
|
21161
21750
|
}
|
|
21162
21751
|
}
|
|
@@ -22024,11 +22613,11 @@ var init_status_bar = __esm({
|
|
|
22024
22613
|
import * as readline2 from "node:readline";
|
|
22025
22614
|
import { Writable } from "node:stream";
|
|
22026
22615
|
import { cwd } from "node:process";
|
|
22027
|
-
import { resolve as
|
|
22616
|
+
import { resolve as resolve20, join as join32, dirname as dirname10, extname as extname9 } from "node:path";
|
|
22028
22617
|
import { createRequire as createRequire2 } from "node:module";
|
|
22029
22618
|
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
22030
22619
|
import { readFileSync as readFileSync18, rmSync as rmSync2 } from "node:fs";
|
|
22031
|
-
import { existsSync as
|
|
22620
|
+
import { existsSync as existsSync25 } from "node:fs";
|
|
22032
22621
|
function formatTimeAgo(date) {
|
|
22033
22622
|
const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
|
|
22034
22623
|
if (seconds < 60)
|
|
@@ -22047,12 +22636,12 @@ function getVersion() {
|
|
|
22047
22636
|
const require2 = createRequire2(import.meta.url);
|
|
22048
22637
|
const thisDir = dirname10(fileURLToPath7(import.meta.url));
|
|
22049
22638
|
const candidates = [
|
|
22050
|
-
|
|
22051
|
-
|
|
22052
|
-
|
|
22639
|
+
join32(thisDir, "..", "package.json"),
|
|
22640
|
+
join32(thisDir, "..", "..", "package.json"),
|
|
22641
|
+
join32(thisDir, "..", "..", "..", "package.json")
|
|
22053
22642
|
];
|
|
22054
22643
|
for (const pkgPath of candidates) {
|
|
22055
|
-
if (
|
|
22644
|
+
if (existsSync25(pkgPath)) {
|
|
22056
22645
|
const pkg = require2(pkgPath);
|
|
22057
22646
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
|
|
22058
22647
|
return pkg.version ?? "0.0.0";
|
|
@@ -22104,6 +22693,8 @@ function buildTools(repoRoot, config, contextWindowSize) {
|
|
|
22104
22693
|
new WebCrawlTool(repoRoot),
|
|
22105
22694
|
new MemoryReadTool(repoRoot),
|
|
22106
22695
|
new MemoryWriteTool(repoRoot),
|
|
22696
|
+
new MemorySearchTool(repoRoot),
|
|
22697
|
+
new ExploreToolsTool(),
|
|
22107
22698
|
// AIWG SDLC tools (auto-detect if aiwg is installed)
|
|
22108
22699
|
new AiwgSetupTool(repoRoot),
|
|
22109
22700
|
new AiwgHealthTool(repoRoot),
|
|
@@ -22519,7 +23110,7 @@ ${entry.fullContent}`
|
|
|
22519
23110
|
} };
|
|
22520
23111
|
}
|
|
22521
23112
|
async function startInteractive(config, repoPath) {
|
|
22522
|
-
const repoRoot =
|
|
23113
|
+
const repoRoot = resolve20(repoPath ?? cwd());
|
|
22523
23114
|
const resumeFlag = process.env.__OA_RESUMED ?? "";
|
|
22524
23115
|
const isResumed = resumeFlag !== "";
|
|
22525
23116
|
const hasTaskToResume = resumeFlag === "1";
|
|
@@ -22671,14 +23262,14 @@ async function startInteractive(config, repoPath) {
|
|
|
22671
23262
|
renderInfo(msg);
|
|
22672
23263
|
statusBar.endContentWrite();
|
|
22673
23264
|
}
|
|
22674
|
-
}, () => new Promise((
|
|
23265
|
+
}, () => new Promise((resolve23) => {
|
|
22675
23266
|
depSudoPromptPending = true;
|
|
22676
23267
|
depSudoResolver = (pw) => {
|
|
22677
23268
|
depSudoPromptPending = false;
|
|
22678
23269
|
depSudoResolver = null;
|
|
22679
23270
|
if (pw)
|
|
22680
23271
|
sessionSudoPassword = pw;
|
|
22681
|
-
|
|
23272
|
+
resolve23(pw);
|
|
22682
23273
|
};
|
|
22683
23274
|
if (statusBar?.isActive) {
|
|
22684
23275
|
statusBar.beginContentWrite();
|
|
@@ -23092,8 +23683,8 @@ async function startInteractive(config, repoPath) {
|
|
|
23092
23683
|
return true;
|
|
23093
23684
|
},
|
|
23094
23685
|
destroyProject() {
|
|
23095
|
-
const oaPath =
|
|
23096
|
-
if (
|
|
23686
|
+
const oaPath = join32(repoRoot, OA_DIR);
|
|
23687
|
+
if (existsSync25(oaPath)) {
|
|
23097
23688
|
try {
|
|
23098
23689
|
rmSync2(oaPath, { recursive: true, force: true });
|
|
23099
23690
|
writeContent(() => renderInfo(`Removed ${OA_DIR}/ directory.`));
|
|
@@ -23325,12 +23916,12 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
23325
23916
|
}
|
|
23326
23917
|
}
|
|
23327
23918
|
const cleanPath = input.replace(/^['"]|['"]$/g, "").trim();
|
|
23328
|
-
const isImage = isImagePath(cleanPath) &&
|
|
23329
|
-
const isMedia = !isImage && isTranscribablePath(cleanPath) &&
|
|
23919
|
+
const isImage = isImagePath(cleanPath) && existsSync25(resolve20(repoRoot, cleanPath));
|
|
23920
|
+
const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync25(resolve20(repoRoot, cleanPath));
|
|
23330
23921
|
if (activeTask) {
|
|
23331
23922
|
if (isImage) {
|
|
23332
23923
|
try {
|
|
23333
|
-
const imgPath =
|
|
23924
|
+
const imgPath = resolve20(repoRoot, cleanPath);
|
|
23334
23925
|
const imgBuffer = readFileSync18(imgPath);
|
|
23335
23926
|
const base64 = imgBuffer.toString("base64");
|
|
23336
23927
|
const ext = extname9(cleanPath).toLowerCase();
|
|
@@ -23344,7 +23935,7 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
23344
23935
|
} else if (isMedia) {
|
|
23345
23936
|
writeContent(() => renderInfo(`Transcribing: ${cleanPath}...`));
|
|
23346
23937
|
const engine = getListenEngine();
|
|
23347
|
-
const result = await engine.transcribeFile(
|
|
23938
|
+
const result = await engine.transcribeFile(resolve20(repoRoot, cleanPath), repoRoot);
|
|
23348
23939
|
if (result) {
|
|
23349
23940
|
const transcript = `[Transcription of ${cleanPath}]
|
|
23350
23941
|
${result.text}`;
|
|
@@ -23377,7 +23968,7 @@ ${result.text}`;
|
|
|
23377
23968
|
if (isMedia && fullInput === input) {
|
|
23378
23969
|
writeContent(() => renderInfo(`Transcribing: ${cleanPath}...`));
|
|
23379
23970
|
const engine = getListenEngine();
|
|
23380
|
-
const result = await engine.transcribeFile(
|
|
23971
|
+
const result = await engine.transcribeFile(resolve20(repoRoot, cleanPath), repoRoot);
|
|
23381
23972
|
if (result) {
|
|
23382
23973
|
fullInput = `The user has provided an audio/video file: ${cleanPath}.
|
|
23383
23974
|
|
|
@@ -23506,7 +24097,7 @@ ${c2.dim("(Use /quit to exit)")}
|
|
|
23506
24097
|
});
|
|
23507
24098
|
}
|
|
23508
24099
|
async function runWithTUI(task, config, repoPath) {
|
|
23509
|
-
const repoRoot =
|
|
24100
|
+
const repoRoot = resolve20(repoPath ?? cwd());
|
|
23510
24101
|
const needsSetup = isFirstRun() || !await isModelAvailable(config);
|
|
23511
24102
|
if (needsSetup && config.backendType === "ollama") {
|
|
23512
24103
|
const setupModel = await runSetupWizard(config);
|
|
@@ -23609,9 +24200,9 @@ var init_run = __esm({
|
|
|
23609
24200
|
// packages/indexer/dist/codebase-indexer.js
|
|
23610
24201
|
import { glob } from "glob";
|
|
23611
24202
|
import ignore from "ignore";
|
|
23612
|
-
import { readFile as
|
|
24203
|
+
import { readFile as readFile11, stat as stat4 } from "node:fs/promises";
|
|
23613
24204
|
import { createHash } from "node:crypto";
|
|
23614
|
-
import { join as
|
|
24205
|
+
import { join as join33, relative as relative3, extname as extname10, basename as basename13 } from "node:path";
|
|
23615
24206
|
var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
|
|
23616
24207
|
var init_codebase_indexer = __esm({
|
|
23617
24208
|
"packages/indexer/dist/codebase-indexer.js"() {
|
|
@@ -23655,7 +24246,7 @@ var init_codebase_indexer = __esm({
|
|
|
23655
24246
|
const ig = ignore.default();
|
|
23656
24247
|
if (this.config.respectGitignore) {
|
|
23657
24248
|
try {
|
|
23658
|
-
const gitignoreContent = await
|
|
24249
|
+
const gitignoreContent = await readFile11(join33(this.config.rootDir, ".gitignore"), "utf-8");
|
|
23659
24250
|
ig.add(gitignoreContent);
|
|
23660
24251
|
} catch {
|
|
23661
24252
|
}
|
|
@@ -23670,12 +24261,12 @@ var init_codebase_indexer = __esm({
|
|
|
23670
24261
|
for (const relativePath of files) {
|
|
23671
24262
|
if (ig.ignores(relativePath))
|
|
23672
24263
|
continue;
|
|
23673
|
-
const fullPath =
|
|
24264
|
+
const fullPath = join33(this.config.rootDir, relativePath);
|
|
23674
24265
|
try {
|
|
23675
24266
|
const fileStat = await stat4(fullPath);
|
|
23676
24267
|
if (fileStat.size > this.config.maxFileSize)
|
|
23677
24268
|
continue;
|
|
23678
|
-
const content = await
|
|
24269
|
+
const content = await readFile11(fullPath);
|
|
23679
24270
|
const hash = createHash("sha256").update(content).digest("hex");
|
|
23680
24271
|
const ext = extname10(relativePath);
|
|
23681
24272
|
indexed.push({
|
|
@@ -23693,7 +24284,7 @@ var init_codebase_indexer = __esm({
|
|
|
23693
24284
|
}
|
|
23694
24285
|
buildTree(files) {
|
|
23695
24286
|
const root = {
|
|
23696
|
-
name:
|
|
24287
|
+
name: basename13(this.config.rootDir),
|
|
23697
24288
|
path: this.config.rootDir,
|
|
23698
24289
|
type: "directory",
|
|
23699
24290
|
children: []
|
|
@@ -23716,7 +24307,7 @@ var init_codebase_indexer = __esm({
|
|
|
23716
24307
|
if (!child) {
|
|
23717
24308
|
child = {
|
|
23718
24309
|
name: part,
|
|
23719
|
-
path:
|
|
24310
|
+
path: join33(current.path, part),
|
|
23720
24311
|
type: "directory",
|
|
23721
24312
|
children: []
|
|
23722
24313
|
};
|
|
@@ -23772,6 +24363,13 @@ var init_embeddings = __esm({
|
|
|
23772
24363
|
}
|
|
23773
24364
|
});
|
|
23774
24365
|
|
|
24366
|
+
// packages/indexer/dist/ollamaEmbeddings.js
|
|
24367
|
+
var init_ollamaEmbeddings = __esm({
|
|
24368
|
+
"packages/indexer/dist/ollamaEmbeddings.js"() {
|
|
24369
|
+
"use strict";
|
|
24370
|
+
}
|
|
24371
|
+
});
|
|
24372
|
+
|
|
23775
24373
|
// packages/indexer/dist/index.js
|
|
23776
24374
|
var init_dist8 = __esm({
|
|
23777
24375
|
"packages/indexer/dist/index.js"() {
|
|
@@ -23782,6 +24380,7 @@ var init_dist8 = __esm({
|
|
|
23782
24380
|
init_graphBuilder();
|
|
23783
24381
|
init_fileSummarizer();
|
|
23784
24382
|
init_embeddings();
|
|
24383
|
+
init_ollamaEmbeddings();
|
|
23785
24384
|
}
|
|
23786
24385
|
});
|
|
23787
24386
|
|
|
@@ -23790,14 +24389,14 @@ var index_repo_exports = {};
|
|
|
23790
24389
|
__export(index_repo_exports, {
|
|
23791
24390
|
indexRepoCommand: () => indexRepoCommand
|
|
23792
24391
|
});
|
|
23793
|
-
import { resolve as
|
|
23794
|
-
import { existsSync as
|
|
24392
|
+
import { resolve as resolve21 } from "node:path";
|
|
24393
|
+
import { existsSync as existsSync26, statSync as statSync10 } from "node:fs";
|
|
23795
24394
|
import { cwd as cwd2 } from "node:process";
|
|
23796
24395
|
async function indexRepoCommand(opts, _config) {
|
|
23797
|
-
const repoRoot =
|
|
24396
|
+
const repoRoot = resolve21(opts.repoPath ?? cwd2());
|
|
23798
24397
|
printHeader("Index Repository");
|
|
23799
24398
|
printInfo(`Indexing: ${repoRoot}`);
|
|
23800
|
-
if (!
|
|
24399
|
+
if (!existsSync26(repoRoot)) {
|
|
23801
24400
|
printError(`Path does not exist: ${repoRoot}`);
|
|
23802
24401
|
process.exit(1);
|
|
23803
24402
|
}
|
|
@@ -24043,8 +24642,8 @@ var config_exports = {};
|
|
|
24043
24642
|
__export(config_exports, {
|
|
24044
24643
|
configCommand: () => configCommand
|
|
24045
24644
|
});
|
|
24046
|
-
import { join as
|
|
24047
|
-
import { homedir as
|
|
24645
|
+
import { join as join34, resolve as resolve22 } from "node:path";
|
|
24646
|
+
import { homedir as homedir13 } from "node:os";
|
|
24048
24647
|
import { cwd as cwd3 } from "node:process";
|
|
24049
24648
|
function coerceForSettings(key, value) {
|
|
24050
24649
|
if (INT_KEYS.has(key))
|
|
@@ -24064,7 +24663,7 @@ async function configCommand(opts, config) {
|
|
|
24064
24663
|
return handleShow(opts, config);
|
|
24065
24664
|
}
|
|
24066
24665
|
function handleShow(opts, config) {
|
|
24067
|
-
const repoRoot =
|
|
24666
|
+
const repoRoot = resolve22(opts.repoPath ?? cwd3());
|
|
24068
24667
|
printHeader("Configuration");
|
|
24069
24668
|
printSection("Active Settings (merged)");
|
|
24070
24669
|
printKeyValue("backendUrl", config.backendUrl, 2);
|
|
@@ -24096,7 +24695,7 @@ function handleShow(opts, config) {
|
|
|
24096
24695
|
}
|
|
24097
24696
|
}
|
|
24098
24697
|
printSection("Config File");
|
|
24099
|
-
printInfo(`~/.open-agents/config.json (${
|
|
24698
|
+
printInfo(`~/.open-agents/config.json (${join34(homedir13(), ".open-agents", "config.json")})`);
|
|
24100
24699
|
printSection("Priority Chain");
|
|
24101
24700
|
printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
|
|
24102
24701
|
printInfo(" 2. Project .oa/settings.json (--local)");
|
|
@@ -24129,13 +24728,13 @@ function handleSet(opts, _config) {
|
|
|
24129
24728
|
process.exit(1);
|
|
24130
24729
|
}
|
|
24131
24730
|
if (opts.local) {
|
|
24132
|
-
const repoRoot =
|
|
24731
|
+
const repoRoot = resolve22(opts.repoPath ?? cwd3());
|
|
24133
24732
|
try {
|
|
24134
24733
|
initOaDirectory(repoRoot);
|
|
24135
24734
|
const coerced = coerceForSettings(key, value);
|
|
24136
24735
|
saveProjectSettings(repoRoot, { [key]: coerced });
|
|
24137
24736
|
printSuccess(`Project override set: ${key} = ${value}`);
|
|
24138
|
-
printInfo(`Saved to ${
|
|
24737
|
+
printInfo(`Saved to ${join34(repoRoot, ".oa", "settings.json")}`);
|
|
24139
24738
|
printInfo("This override applies only when running in this workspace.");
|
|
24140
24739
|
} catch (err) {
|
|
24141
24740
|
printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -24287,7 +24886,7 @@ async function serveVllm(opts, config) {
|
|
|
24287
24886
|
await runVllmServer(args, opts.verbose ?? false);
|
|
24288
24887
|
}
|
|
24289
24888
|
async function runVllmServer(args, verbose) {
|
|
24290
|
-
return new Promise((
|
|
24889
|
+
return new Promise((resolve23, reject) => {
|
|
24291
24890
|
const child = spawn9("python", args, {
|
|
24292
24891
|
stdio: verbose ? "inherit" : ["ignore", "pipe", "pipe"],
|
|
24293
24892
|
env: { ...process.env }
|
|
@@ -24322,10 +24921,10 @@ async function runVllmServer(args, verbose) {
|
|
|
24322
24921
|
child.once("exit", (code, signal) => {
|
|
24323
24922
|
if (signal) {
|
|
24324
24923
|
printInfo(`vLLM server stopped by signal ${signal}`);
|
|
24325
|
-
|
|
24924
|
+
resolve23();
|
|
24326
24925
|
} else if (code === 0) {
|
|
24327
24926
|
printSuccess("vLLM server exited cleanly");
|
|
24328
|
-
|
|
24927
|
+
resolve23();
|
|
24329
24928
|
} else {
|
|
24330
24929
|
printError(`vLLM server exited with code ${code}`);
|
|
24331
24930
|
reject(new Error(`vLLM exited with code ${code}`));
|
|
@@ -24354,7 +24953,7 @@ __export(eval_exports, {
|
|
|
24354
24953
|
});
|
|
24355
24954
|
import { tmpdir as tmpdir7 } from "node:os";
|
|
24356
24955
|
import { mkdirSync as mkdirSync12, writeFileSync as writeFileSync11 } from "node:fs";
|
|
24357
|
-
import { join as
|
|
24956
|
+
import { join as join35 } from "node:path";
|
|
24358
24957
|
async function evalCommand(opts, config) {
|
|
24359
24958
|
const suiteName = opts.suite ?? "basic";
|
|
24360
24959
|
const suite = SUITES[suiteName];
|
|
@@ -24475,9 +25074,9 @@ async function evalCommand(opts, config) {
|
|
|
24475
25074
|
process.exit(failed > 0 ? 1 : 0);
|
|
24476
25075
|
}
|
|
24477
25076
|
function createTempEvalRepo() {
|
|
24478
|
-
const dir =
|
|
25077
|
+
const dir = join35(tmpdir7(), `open-agents-eval-${Date.now()}`);
|
|
24479
25078
|
mkdirSync12(dir, { recursive: true });
|
|
24480
|
-
writeFileSync11(
|
|
25079
|
+
writeFileSync11(join35(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
|
|
24481
25080
|
return dir;
|
|
24482
25081
|
}
|
|
24483
25082
|
var BASIC_SUITE, FULL_SUITE, SUITES;
|
|
@@ -24537,7 +25136,7 @@ init_updater();
|
|
|
24537
25136
|
import { parseArgs as nodeParseArgs2 } from "node:util";
|
|
24538
25137
|
import { createRequire as createRequire3 } from "node:module";
|
|
24539
25138
|
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
24540
|
-
import { dirname as dirname11, join as
|
|
25139
|
+
import { dirname as dirname11, join as join36 } from "node:path";
|
|
24541
25140
|
|
|
24542
25141
|
// packages/cli/dist/cli.js
|
|
24543
25142
|
import { createInterface } from "node:readline";
|
|
@@ -24644,7 +25243,7 @@ init_output();
|
|
|
24644
25243
|
function getVersion2() {
|
|
24645
25244
|
try {
|
|
24646
25245
|
const require2 = createRequire3(import.meta.url);
|
|
24647
|
-
const pkgPath =
|
|
25246
|
+
const pkgPath = join36(dirname11(fileURLToPath8(import.meta.url)), "..", "package.json");
|
|
24648
25247
|
const pkg = require2(pkgPath);
|
|
24649
25248
|
return pkg.version;
|
|
24650
25249
|
} catch {
|