open-agents-ai 0.8.0 → 0.9.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/README.md +23 -0
- package/dist/index.js +463 -113
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -221,6 +221,29 @@ Create a `.open-agents.md` file in your project root to give the agent project-s
|
|
|
221
221
|
|
|
222
222
|
Context files are merged from parent → child directories, so you can set global defaults at `~/.open-agents.md` and override per-project.
|
|
223
223
|
|
|
224
|
+
### `.oa/` Project Directory
|
|
225
|
+
|
|
226
|
+
Each project gets a `.oa/` directory (similar to `.claude/` for Claude Code) that persists artifacts across sessions:
|
|
227
|
+
|
|
228
|
+
```
|
|
229
|
+
.oa/
|
|
230
|
+
├── config.json # Per-project configuration overrides
|
|
231
|
+
├── memory/ # Persistent memory store
|
|
232
|
+
│ └── {topic}.json # Topic-based key-value memories
|
|
233
|
+
├── index/ # Cached codebase index
|
|
234
|
+
│ ├── repo-profile.json # Repository metadata
|
|
235
|
+
│ ├── file-summaries.json # Per-file purpose, exports, domain, risk
|
|
236
|
+
│ ├── symbols.json # Symbol table cache
|
|
237
|
+
│ ├── graph.json # Import/dependency graph
|
|
238
|
+
│ └── meta.json # Index metadata (timestamp, hash)
|
|
239
|
+
├── context/ # Auto-generated project context
|
|
240
|
+
│ └── project-map.md # Generated overview for system prompt
|
|
241
|
+
└── history/ # Session history
|
|
242
|
+
└── {session-id}.json # Per-session task log
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
The agent auto-discovers `AGENTS.md`, `OA.md`, `CLAUDE.md`, and `README.md` from the project root and parent directories, injecting them into the system prompt for project-specific awareness.
|
|
246
|
+
|
|
224
247
|
### Smart Context Compaction
|
|
225
248
|
|
|
226
249
|
When conversations exceed the context window, the agent compacts older messages while preserving:
|
package/dist/index.js
CHANGED
|
@@ -1827,12 +1827,18 @@ var init_memory_read = __esm({
|
|
|
1827
1827
|
const key = args["key"];
|
|
1828
1828
|
const start = performance.now();
|
|
1829
1829
|
try {
|
|
1830
|
-
const
|
|
1831
|
-
const
|
|
1832
|
-
let raw;
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1830
|
+
const oaMemDir = resolve6(this.workingDir, ".oa", "memory");
|
|
1831
|
+
const legacyMemDir = resolve6(this.workingDir, ".open-agents", "memory");
|
|
1832
|
+
let raw = null;
|
|
1833
|
+
for (const memoryDir of [oaMemDir, legacyMemDir]) {
|
|
1834
|
+
const topicFile = join3(memoryDir, `${topic}.json`);
|
|
1835
|
+
try {
|
|
1836
|
+
raw = await readFile3(topicFile, "utf-8");
|
|
1837
|
+
break;
|
|
1838
|
+
} catch {
|
|
1839
|
+
}
|
|
1840
|
+
}
|
|
1841
|
+
if (raw === null) {
|
|
1836
1842
|
return {
|
|
1837
1843
|
success: true,
|
|
1838
1844
|
output: "(no memories found)",
|
|
@@ -1910,20 +1916,23 @@ var init_memory_write = __esm({
|
|
|
1910
1916
|
const value = args["value"];
|
|
1911
1917
|
const start = performance.now();
|
|
1912
1918
|
try {
|
|
1913
|
-
const
|
|
1914
|
-
|
|
1915
|
-
const
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1919
|
+
const oaMemDir = resolve7(this.workingDir, ".oa", "memory");
|
|
1920
|
+
const legacyMemDir = resolve7(this.workingDir, ".open-agents", "memory");
|
|
1921
|
+
for (const memoryDir of [oaMemDir, legacyMemDir]) {
|
|
1922
|
+
await mkdir2(memoryDir, { recursive: true });
|
|
1923
|
+
const topicFile = join4(memoryDir, `${topic}.json`);
|
|
1924
|
+
let entries = {};
|
|
1925
|
+
try {
|
|
1926
|
+
const raw = await readFile4(topicFile, "utf-8");
|
|
1927
|
+
entries = JSON.parse(raw);
|
|
1928
|
+
} catch {
|
|
1929
|
+
}
|
|
1930
|
+
entries[key] = {
|
|
1931
|
+
value,
|
|
1932
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1933
|
+
};
|
|
1934
|
+
await writeFile3(topicFile, JSON.stringify(entries, null, 2), "utf-8");
|
|
1921
1935
|
}
|
|
1922
|
-
entries[key] = {
|
|
1923
|
-
value,
|
|
1924
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1925
|
-
};
|
|
1926
|
-
await writeFile3(topicFile, JSON.stringify(entries, null, 2), "utf-8");
|
|
1927
1936
|
return {
|
|
1928
1937
|
success: true,
|
|
1929
1938
|
output: `Stored memory: ${topic}.${key}`,
|
|
@@ -6463,6 +6472,18 @@ Use screenshot to capture visual state for debugging UI issues.
|
|
|
6463
6472
|
- Keep tool calls focused \u2014 read only what you need
|
|
6464
6473
|
- You MUST call task_complete when the task is done
|
|
6465
6474
|
|
|
6475
|
+
## Project Awareness
|
|
6476
|
+
|
|
6477
|
+
Your system prompt is dynamically enriched with project context. Before each task:
|
|
6478
|
+
- AGENTS.md, OA.md, CLAUDE.md, and README.md are auto-discovered and loaded
|
|
6479
|
+
- The .oa/ directory stores per-project artifacts (memory, index, session history)
|
|
6480
|
+
- Git state (branch, dirty files, recent commits) is injected
|
|
6481
|
+
- Persistent memories from previous sessions are loaded
|
|
6482
|
+
- Recent session history shows what was worked on before
|
|
6483
|
+
|
|
6484
|
+
When working in a new project, use codebase_map first to orient yourself.
|
|
6485
|
+
Store important discoveries with memory_write for future sessions.
|
|
6486
|
+
|
|
6466
6487
|
## Self-Learning
|
|
6467
6488
|
|
|
6468
6489
|
When you encounter an unfamiliar API, language feature, or runtime behavior:
|
|
@@ -6689,7 +6710,7 @@ ${result.output}`;
|
|
|
6689
6710
|
});
|
|
6690
6711
|
if (/task.?complete|all tests pass/i.test(content)) {
|
|
6691
6712
|
completed = true;
|
|
6692
|
-
summary = content
|
|
6713
|
+
summary = content;
|
|
6693
6714
|
break;
|
|
6694
6715
|
}
|
|
6695
6716
|
messages.push({
|
|
@@ -7061,8 +7082,11 @@ function renderTaskComplete(summary, turns, toolCalls, durationMs) {
|
|
|
7061
7082
|
${c2.green("\u2714")} ${c2.bold("Task completed")} ${c2.dim(`(${turns} turns, ${toolCalls} tool calls, ${duration})`)}
|
|
7062
7083
|
`);
|
|
7063
7084
|
if (summary) {
|
|
7064
|
-
|
|
7085
|
+
const lines = summary.split("\n");
|
|
7086
|
+
for (const line of lines) {
|
|
7087
|
+
process.stdout.write(` ${line}
|
|
7065
7088
|
`);
|
|
7089
|
+
}
|
|
7066
7090
|
}
|
|
7067
7091
|
process.stdout.write("\n");
|
|
7068
7092
|
}
|
|
@@ -7519,17 +7543,17 @@ async function handleUpdate() {
|
|
|
7519
7543
|
try {
|
|
7520
7544
|
const { createRequire: createRequire3 } = await import("node:module");
|
|
7521
7545
|
const { fileURLToPath: fileURLToPath2 } = await import("node:url");
|
|
7522
|
-
const { dirname: dirname4, join:
|
|
7523
|
-
const { existsSync:
|
|
7546
|
+
const { dirname: dirname4, join: join21 } = await import("node:path");
|
|
7547
|
+
const { existsSync: existsSync14 } = await import("node:fs");
|
|
7524
7548
|
const req = createRequire3(import.meta.url);
|
|
7525
7549
|
const thisDir = dirname4(fileURLToPath2(import.meta.url));
|
|
7526
7550
|
const candidates = [
|
|
7527
|
-
|
|
7528
|
-
|
|
7529
|
-
|
|
7551
|
+
join21(thisDir, "..", "package.json"),
|
|
7552
|
+
join21(thisDir, "..", "..", "package.json"),
|
|
7553
|
+
join21(thisDir, "..", "..", "..", "package.json")
|
|
7530
7554
|
];
|
|
7531
7555
|
for (const pkgPath of candidates) {
|
|
7532
|
-
if (
|
|
7556
|
+
if (existsSync14(pkgPath)) {
|
|
7533
7557
|
const pkg = req(pkgPath);
|
|
7534
7558
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
|
|
7535
7559
|
currentVersion = pkg.version ?? "0.0.0";
|
|
@@ -7981,40 +8005,326 @@ var init_setup = __esm({
|
|
|
7981
8005
|
}
|
|
7982
8006
|
});
|
|
7983
8007
|
|
|
7984
|
-
// packages/cli/dist/tui/
|
|
7985
|
-
import { existsSync as existsSync9, readFileSync as readFileSync7, readdirSync as readdirSync4 } from "node:fs";
|
|
7986
|
-
import { join as join14, basename as basename2 } from "node:path";
|
|
7987
|
-
|
|
7988
|
-
|
|
7989
|
-
|
|
7990
|
-
|
|
8008
|
+
// packages/cli/dist/tui/oa-directory.js
|
|
8009
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync4, readFileSync as readFileSync7, writeFileSync as writeFileSync4, readdirSync as readdirSync4, statSync as statSync5 } from "node:fs";
|
|
8010
|
+
import { join as join14, relative as relative2, basename as basename2, extname as extname4 } from "node:path";
|
|
8011
|
+
function initOaDirectory(repoRoot) {
|
|
8012
|
+
const oaPath = join14(repoRoot, OA_DIR);
|
|
8013
|
+
for (const sub of SUBDIRS) {
|
|
8014
|
+
mkdirSync4(join14(oaPath, sub), { recursive: true });
|
|
8015
|
+
}
|
|
8016
|
+
return oaPath;
|
|
8017
|
+
}
|
|
8018
|
+
function hasOaDirectory(repoRoot) {
|
|
8019
|
+
return existsSync9(join14(repoRoot, OA_DIR, "index"));
|
|
8020
|
+
}
|
|
8021
|
+
function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
8022
|
+
const found = [];
|
|
8023
|
+
const seen = /* @__PURE__ */ new Set();
|
|
7991
8024
|
let dir = repoRoot;
|
|
7992
8025
|
const visited = /* @__PURE__ */ new Set();
|
|
7993
8026
|
while (dir && !visited.has(dir)) {
|
|
7994
8027
|
visited.add(dir);
|
|
7995
|
-
for (const name of
|
|
8028
|
+
for (const name of CONTEXT_FILES) {
|
|
7996
8029
|
const filePath = join14(dir, name);
|
|
7997
|
-
|
|
8030
|
+
const normalizedName = name.toLowerCase();
|
|
8031
|
+
if (existsSync9(filePath) && !seen.has(filePath)) {
|
|
8032
|
+
seen.add(filePath);
|
|
7998
8033
|
try {
|
|
7999
|
-
|
|
8000
|
-
if (content) {
|
|
8001
|
-
|
|
8002
|
-
sections.push(`# Project Context (${relativePath})
|
|
8003
|
-
|
|
8004
|
-
${content}`);
|
|
8034
|
+
let content = readFileSync7(filePath, "utf-8");
|
|
8035
|
+
if (content.length > maxContentLen) {
|
|
8036
|
+
content = content.slice(0, maxContentLen) + "\n\n...(truncated)";
|
|
8005
8037
|
}
|
|
8038
|
+
const type = normalizedName.includes("agents") ? "agents" : normalizedName === "oa.md" || normalizedName === ".open-agents.md" ? "oa" : normalizedName.includes("claude") ? "claude" : normalizedName.includes("readme") ? "readme" : normalizedName.includes("architect") ? "architecture" : normalizedName.includes("contribut") ? "contributing" : "other";
|
|
8039
|
+
found.push({
|
|
8040
|
+
path: relative2(repoRoot, filePath) || name,
|
|
8041
|
+
content,
|
|
8042
|
+
type
|
|
8043
|
+
});
|
|
8006
8044
|
} catch {
|
|
8007
8045
|
}
|
|
8008
8046
|
}
|
|
8009
8047
|
}
|
|
8048
|
+
const projectMap = join14(dir, OA_DIR, "context", "project-map.md");
|
|
8049
|
+
if (existsSync9(projectMap) && !seen.has(projectMap)) {
|
|
8050
|
+
seen.add(projectMap);
|
|
8051
|
+
try {
|
|
8052
|
+
let content = readFileSync7(projectMap, "utf-8");
|
|
8053
|
+
if (content.length > maxContentLen) {
|
|
8054
|
+
content = content.slice(0, maxContentLen) + "\n\n...(truncated)";
|
|
8055
|
+
}
|
|
8056
|
+
found.push({
|
|
8057
|
+
path: relative2(repoRoot, projectMap),
|
|
8058
|
+
content,
|
|
8059
|
+
type: "oa"
|
|
8060
|
+
});
|
|
8061
|
+
} catch {
|
|
8062
|
+
}
|
|
8063
|
+
}
|
|
8010
8064
|
const parent = join14(dir, "..");
|
|
8011
8065
|
if (parent === dir)
|
|
8012
8066
|
break;
|
|
8013
8067
|
dir = parent;
|
|
8014
8068
|
}
|
|
8015
|
-
|
|
8069
|
+
const priority = {
|
|
8070
|
+
agents: 0,
|
|
8071
|
+
oa: 1,
|
|
8072
|
+
claude: 2,
|
|
8073
|
+
architecture: 3,
|
|
8074
|
+
contributing: 4,
|
|
8075
|
+
readme: 5,
|
|
8076
|
+
other: 6
|
|
8077
|
+
};
|
|
8078
|
+
found.sort((a, b) => (priority[a.type] ?? 6) - (priority[b.type] ?? 6));
|
|
8079
|
+
return found;
|
|
8080
|
+
}
|
|
8081
|
+
function readIndexMeta(repoRoot) {
|
|
8082
|
+
const metaPath = join14(repoRoot, OA_DIR, "index", "meta.json");
|
|
8083
|
+
try {
|
|
8084
|
+
return JSON.parse(readFileSync7(metaPath, "utf-8"));
|
|
8085
|
+
} catch {
|
|
8086
|
+
return null;
|
|
8087
|
+
}
|
|
8088
|
+
}
|
|
8089
|
+
function generateProjectMap(repoRoot) {
|
|
8090
|
+
const sections = [];
|
|
8091
|
+
const repoName2 = basename2(repoRoot);
|
|
8092
|
+
sections.push(`# Project Map: ${repoName2}
|
|
8093
|
+
`);
|
|
8094
|
+
sections.push(`> Auto-generated by open-agents. Updated: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
|
|
8095
|
+
`);
|
|
8096
|
+
const manifests = detectManifests(repoRoot);
|
|
8097
|
+
if (manifests.length > 0) {
|
|
8098
|
+
sections.push(`## Project Type
|
|
8099
|
+
`);
|
|
8100
|
+
for (const m of manifests) {
|
|
8101
|
+
sections.push(`- ${m.type}: \`${m.file}\``);
|
|
8102
|
+
if (m.name)
|
|
8103
|
+
sections[sections.length - 1] += ` (${m.name})`;
|
|
8104
|
+
}
|
|
8105
|
+
sections.push("");
|
|
8106
|
+
}
|
|
8107
|
+
const tree = buildDirTree(repoRoot, 2);
|
|
8108
|
+
if (tree) {
|
|
8109
|
+
sections.push(`## Directory Structure
|
|
8110
|
+
|
|
8111
|
+
\`\`\`
|
|
8112
|
+
${tree}\`\`\`
|
|
8113
|
+
`);
|
|
8114
|
+
}
|
|
8115
|
+
const keyFiles = findKeyFiles(repoRoot);
|
|
8116
|
+
if (keyFiles.length > 0) {
|
|
8117
|
+
sections.push(`## Key Files
|
|
8118
|
+
`);
|
|
8119
|
+
for (const f of keyFiles) {
|
|
8120
|
+
sections.push(`- \`${f.path}\` \u2014 ${f.description}`);
|
|
8121
|
+
}
|
|
8122
|
+
sections.push("");
|
|
8123
|
+
}
|
|
8124
|
+
const meta = readIndexMeta(repoRoot);
|
|
8125
|
+
if (meta && Object.keys(meta.languages).length > 0) {
|
|
8126
|
+
sections.push(`## Languages
|
|
8127
|
+
`);
|
|
8128
|
+
const sorted = Object.entries(meta.languages).sort((a, b) => b[1] - a[1]);
|
|
8129
|
+
for (const [lang, count] of sorted.slice(0, 8)) {
|
|
8130
|
+
sections.push(`- ${lang}: ${count} files`);
|
|
8131
|
+
}
|
|
8132
|
+
sections.push("");
|
|
8133
|
+
}
|
|
8134
|
+
const content = sections.join("\n");
|
|
8135
|
+
const contextDir = join14(repoRoot, OA_DIR, "context");
|
|
8136
|
+
mkdirSync4(contextDir, { recursive: true });
|
|
8137
|
+
writeFileSync4(join14(contextDir, "project-map.md"), content, "utf-8");
|
|
8138
|
+
return content;
|
|
8139
|
+
}
|
|
8140
|
+
function saveSession(repoRoot, session) {
|
|
8141
|
+
const historyDir = join14(repoRoot, OA_DIR, "history");
|
|
8142
|
+
mkdirSync4(historyDir, { recursive: true });
|
|
8143
|
+
writeFileSync4(join14(historyDir, `${session.id}.json`), JSON.stringify(session, null, 2), "utf-8");
|
|
8144
|
+
}
|
|
8145
|
+
function loadRecentSessions(repoRoot, limit = 5) {
|
|
8146
|
+
const historyDir = join14(repoRoot, OA_DIR, "history");
|
|
8147
|
+
if (!existsSync9(historyDir))
|
|
8148
|
+
return [];
|
|
8149
|
+
try {
|
|
8150
|
+
const files = readdirSync4(historyDir).filter((f) => f.endsWith(".json")).map((f) => {
|
|
8151
|
+
const stat3 = statSync5(join14(historyDir, f));
|
|
8152
|
+
return { file: f, mtime: stat3.mtimeMs };
|
|
8153
|
+
}).sort((a, b) => b.mtime - a.mtime).slice(0, limit);
|
|
8154
|
+
return files.map((f) => {
|
|
8155
|
+
try {
|
|
8156
|
+
return JSON.parse(readFileSync7(join14(historyDir, f.file), "utf-8"));
|
|
8157
|
+
} catch {
|
|
8158
|
+
return null;
|
|
8159
|
+
}
|
|
8160
|
+
}).filter((s) => s !== null);
|
|
8161
|
+
} catch {
|
|
8162
|
+
return [];
|
|
8163
|
+
}
|
|
8164
|
+
}
|
|
8165
|
+
function detectManifests(repoRoot) {
|
|
8166
|
+
const manifests = [];
|
|
8167
|
+
const checks = [
|
|
8168
|
+
{ file: "package.json", type: "Node.js", nameField: "name" },
|
|
8169
|
+
{ file: "pyproject.toml", type: "Python" },
|
|
8170
|
+
{ file: "Cargo.toml", type: "Rust" },
|
|
8171
|
+
{ file: "go.mod", type: "Go" },
|
|
8172
|
+
{ file: "pom.xml", type: "Java (Maven)" },
|
|
8173
|
+
{ file: "build.gradle", type: "Java (Gradle)" },
|
|
8174
|
+
{ file: "Gemfile", type: "Ruby" },
|
|
8175
|
+
{ file: "composer.json", type: "PHP" },
|
|
8176
|
+
{ file: "pnpm-workspace.yaml", type: "pnpm Monorepo" },
|
|
8177
|
+
{ file: "lerna.json", type: "Lerna Monorepo" },
|
|
8178
|
+
{ file: "Dockerfile", type: "Docker" },
|
|
8179
|
+
{ file: "docker-compose.yml", type: "Docker Compose" },
|
|
8180
|
+
{ file: "docker-compose.yaml", type: "Docker Compose" }
|
|
8181
|
+
];
|
|
8182
|
+
for (const check of checks) {
|
|
8183
|
+
const filePath = join14(repoRoot, check.file);
|
|
8184
|
+
if (existsSync9(filePath)) {
|
|
8185
|
+
let name;
|
|
8186
|
+
if (check.nameField) {
|
|
8187
|
+
try {
|
|
8188
|
+
const data = JSON.parse(readFileSync7(filePath, "utf-8"));
|
|
8189
|
+
name = data[check.nameField];
|
|
8190
|
+
} catch {
|
|
8191
|
+
}
|
|
8192
|
+
}
|
|
8193
|
+
manifests.push({ file: check.file, type: check.type, name });
|
|
8194
|
+
}
|
|
8195
|
+
}
|
|
8196
|
+
return manifests;
|
|
8197
|
+
}
|
|
8198
|
+
function findKeyFiles(repoRoot) {
|
|
8199
|
+
const keyFiles = [];
|
|
8200
|
+
const checks = [
|
|
8201
|
+
{ pattern: "package.json", description: "Node.js project manifest" },
|
|
8202
|
+
{ pattern: "tsconfig.json", description: "TypeScript configuration" },
|
|
8203
|
+
{ pattern: ".eslintrc.json", description: "ESLint configuration" },
|
|
8204
|
+
{ pattern: ".prettierrc", description: "Prettier configuration" },
|
|
8205
|
+
{ pattern: "vitest.config.ts", description: "Vitest test config" },
|
|
8206
|
+
{ pattern: "jest.config.js", description: "Jest test config" },
|
|
8207
|
+
{ pattern: "Makefile", description: "Build automation" },
|
|
8208
|
+
{ pattern: ".github/workflows", description: "GitHub Actions CI/CD" },
|
|
8209
|
+
{ pattern: ".gitlab-ci.yml", description: "GitLab CI/CD" },
|
|
8210
|
+
{ pattern: "Dockerfile", description: "Container definition" },
|
|
8211
|
+
{ pattern: ".env.example", description: "Environment template" },
|
|
8212
|
+
{ pattern: "AGENTS.md", description: "Agent instructions" },
|
|
8213
|
+
{ pattern: "OA.md", description: "Open Agents context" },
|
|
8214
|
+
{ pattern: "CLAUDE.md", description: "Claude Code context" }
|
|
8215
|
+
];
|
|
8216
|
+
for (const check of checks) {
|
|
8217
|
+
if (existsSync9(join14(repoRoot, check.pattern))) {
|
|
8218
|
+
keyFiles.push({ path: check.pattern, description: check.description });
|
|
8219
|
+
}
|
|
8220
|
+
}
|
|
8221
|
+
return keyFiles;
|
|
8222
|
+
}
|
|
8223
|
+
function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
|
|
8224
|
+
if (depth > maxDepth)
|
|
8225
|
+
return "";
|
|
8226
|
+
let result = "";
|
|
8227
|
+
try {
|
|
8228
|
+
const entries = readdirSync4(root, { withFileTypes: true }).filter((e) => !e.name.startsWith(".") || e.name === ".github").filter((e) => !SKIP_DIRS.has(e.name)).sort((a, b) => {
|
|
8229
|
+
if (a.isDirectory() && !b.isDirectory())
|
|
8230
|
+
return -1;
|
|
8231
|
+
if (!a.isDirectory() && b.isDirectory())
|
|
8232
|
+
return 1;
|
|
8233
|
+
return a.name.localeCompare(b.name);
|
|
8234
|
+
});
|
|
8235
|
+
for (let i = 0; i < entries.length; i++) {
|
|
8236
|
+
const entry = entries[i];
|
|
8237
|
+
const isLast = i === entries.length - 1;
|
|
8238
|
+
const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
8239
|
+
const childPrefix = prefix + (isLast ? " " : "\u2502 ");
|
|
8240
|
+
if (entry.isDirectory()) {
|
|
8241
|
+
let fileCount = 0;
|
|
8242
|
+
try {
|
|
8243
|
+
fileCount = readdirSync4(join14(root, entry.name)).filter((f) => !f.startsWith(".")).length;
|
|
8244
|
+
} catch {
|
|
8245
|
+
}
|
|
8246
|
+
result += `${prefix}${connector}${entry.name}/ (${fileCount})
|
|
8247
|
+
`;
|
|
8248
|
+
result += buildDirTree(join14(root, entry.name), maxDepth, childPrefix, depth + 1);
|
|
8249
|
+
} else if (depth < maxDepth) {
|
|
8250
|
+
result += `${prefix}${connector}${entry.name}
|
|
8251
|
+
`;
|
|
8252
|
+
}
|
|
8253
|
+
}
|
|
8254
|
+
} catch {
|
|
8255
|
+
}
|
|
8256
|
+
return result;
|
|
8257
|
+
}
|
|
8258
|
+
var OA_DIR, SUBDIRS, CONTEXT_FILES, SKIP_DIRS;
|
|
8259
|
+
var init_oa_directory = __esm({
|
|
8260
|
+
"packages/cli/dist/tui/oa-directory.js"() {
|
|
8261
|
+
"use strict";
|
|
8262
|
+
OA_DIR = ".oa";
|
|
8263
|
+
SUBDIRS = ["memory", "index", "context", "history"];
|
|
8264
|
+
CONTEXT_FILES = [
|
|
8265
|
+
"AGENTS.md",
|
|
8266
|
+
"OA.md",
|
|
8267
|
+
".open-agents.md",
|
|
8268
|
+
"CLAUDE.md",
|
|
8269
|
+
"README.md",
|
|
8270
|
+
"ARCHITECTURE.md",
|
|
8271
|
+
"CONTRIBUTING.md",
|
|
8272
|
+
"AGENTS.md"
|
|
8273
|
+
];
|
|
8274
|
+
SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
8275
|
+
"node_modules",
|
|
8276
|
+
".git",
|
|
8277
|
+
"dist",
|
|
8278
|
+
"build",
|
|
8279
|
+
".next",
|
|
8280
|
+
"__pycache__",
|
|
8281
|
+
".venv",
|
|
8282
|
+
"venv",
|
|
8283
|
+
"coverage",
|
|
8284
|
+
".nyc_output",
|
|
8285
|
+
".oa",
|
|
8286
|
+
".open-agents",
|
|
8287
|
+
".claude",
|
|
8288
|
+
"vendor",
|
|
8289
|
+
"target",
|
|
8290
|
+
".idea",
|
|
8291
|
+
".vscode"
|
|
8292
|
+
]);
|
|
8293
|
+
}
|
|
8294
|
+
});
|
|
8295
|
+
|
|
8296
|
+
// packages/cli/dist/tui/project-context.js
|
|
8297
|
+
import { existsSync as existsSync10, readFileSync as readFileSync8, readdirSync as readdirSync5 } from "node:fs";
|
|
8298
|
+
import { join as join15, basename as basename3 } from "node:path";
|
|
8299
|
+
import { execSync as execSync9 } from "node:child_process";
|
|
8300
|
+
import { homedir as homedir4, platform, release } from "node:os";
|
|
8301
|
+
function loadProjectFiles(repoRoot) {
|
|
8302
|
+
const discovered = discoverContextFiles(repoRoot);
|
|
8303
|
+
if (discovered.length === 0)
|
|
8304
|
+
return "";
|
|
8305
|
+
const sections = [];
|
|
8306
|
+
for (const ctx of discovered) {
|
|
8307
|
+
const header = ctx.type === "agents" ? "Agent Instructions" : ctx.type === "oa" ? "Open Agents Context" : ctx.type === "claude" ? "Project Instructions" : ctx.type === "architecture" ? "Architecture" : ctx.type === "contributing" ? "Contributing Guidelines" : ctx.type === "readme" ? "Project Overview" : "Additional Context";
|
|
8308
|
+
sections.push(`# ${header} (${ctx.path})
|
|
8309
|
+
|
|
8310
|
+
${ctx.content}`);
|
|
8311
|
+
}
|
|
8016
8312
|
return sections.join("\n\n---\n\n");
|
|
8017
8313
|
}
|
|
8314
|
+
function loadProjectMap(repoRoot) {
|
|
8315
|
+
if (!hasOaDirectory(repoRoot)) {
|
|
8316
|
+
initOaDirectory(repoRoot);
|
|
8317
|
+
}
|
|
8318
|
+
const mapPath = join15(repoRoot, OA_DIR, "context", "project-map.md");
|
|
8319
|
+
if (existsSync10(mapPath)) {
|
|
8320
|
+
try {
|
|
8321
|
+
const content = readFileSync8(mapPath, "utf-8");
|
|
8322
|
+
return content;
|
|
8323
|
+
} catch {
|
|
8324
|
+
}
|
|
8325
|
+
}
|
|
8326
|
+
return generateProjectMap(repoRoot);
|
|
8327
|
+
}
|
|
8018
8328
|
function getGitInfo(repoRoot) {
|
|
8019
8329
|
try {
|
|
8020
8330
|
execSync9("git rev-parse --is-inside-work-tree", { cwd: repoRoot, stdio: "pipe" });
|
|
@@ -8049,29 +8359,33 @@ ${log}`);
|
|
|
8049
8359
|
}
|
|
8050
8360
|
function loadMemoryContext(repoRoot) {
|
|
8051
8361
|
const sections = [];
|
|
8052
|
-
const
|
|
8053
|
-
const
|
|
8054
|
-
if (
|
|
8055
|
-
sections.push(
|
|
8056
|
-
const
|
|
8057
|
-
if (
|
|
8058
|
-
const
|
|
8059
|
-
if (
|
|
8060
|
-
sections.push(
|
|
8061
|
-
}
|
|
8362
|
+
const oaMemDir = join15(repoRoot, OA_DIR, "memory");
|
|
8363
|
+
const oaEntries = loadMemoryDir(oaMemDir, "project");
|
|
8364
|
+
if (oaEntries)
|
|
8365
|
+
sections.push(oaEntries);
|
|
8366
|
+
const legacyMemDir = join15(repoRoot, ".open-agents", "memory");
|
|
8367
|
+
if (legacyMemDir !== oaMemDir && existsSync10(legacyMemDir)) {
|
|
8368
|
+
const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
|
|
8369
|
+
if (legacyEntries)
|
|
8370
|
+
sections.push(legacyEntries);
|
|
8371
|
+
}
|
|
8372
|
+
const globalMemDir = join15(homedir4(), ".open-agents", "memory");
|
|
8373
|
+
const globalEntries = loadMemoryDir(globalMemDir, "global");
|
|
8374
|
+
if (globalEntries)
|
|
8375
|
+
sections.push(globalEntries);
|
|
8062
8376
|
return sections.join("\n\n");
|
|
8063
8377
|
}
|
|
8064
8378
|
function loadMemoryDir(memDir, scope) {
|
|
8065
|
-
if (!
|
|
8379
|
+
if (!existsSync10(memDir))
|
|
8066
8380
|
return "";
|
|
8067
8381
|
const lines = [];
|
|
8068
8382
|
try {
|
|
8069
|
-
const files =
|
|
8383
|
+
const files = readdirSync5(memDir).filter((f) => f.endsWith(".json"));
|
|
8070
8384
|
for (const file of files.slice(0, 10)) {
|
|
8071
8385
|
try {
|
|
8072
|
-
const raw =
|
|
8386
|
+
const raw = readFileSync8(join15(memDir, file), "utf-8");
|
|
8073
8387
|
const entries = JSON.parse(raw);
|
|
8074
|
-
const topic =
|
|
8388
|
+
const topic = basename3(file, ".json");
|
|
8075
8389
|
const keys = Object.keys(entries);
|
|
8076
8390
|
if (keys.length === 0)
|
|
8077
8391
|
continue;
|
|
@@ -8089,6 +8403,21 @@ function loadMemoryDir(memDir, scope) {
|
|
|
8089
8403
|
}
|
|
8090
8404
|
return lines.join("\n");
|
|
8091
8405
|
}
|
|
8406
|
+
function loadSessionHistory(repoRoot) {
|
|
8407
|
+
const sessions = loadRecentSessions(repoRoot, 5);
|
|
8408
|
+
if (sessions.length === 0)
|
|
8409
|
+
return "";
|
|
8410
|
+
const lines = ["Recent tasks in this project:"];
|
|
8411
|
+
for (const s of sessions) {
|
|
8412
|
+
const status = s.completed ? "completed" : "incomplete";
|
|
8413
|
+
const date = s.startedAt.split("T")[0];
|
|
8414
|
+
lines.push(`- [${date}] ${s.task.slice(0, 80)} (${status}, ${s.turns} turns)`);
|
|
8415
|
+
if (s.summary) {
|
|
8416
|
+
lines.push(` Summary: ${s.summary.slice(0, 120)}`);
|
|
8417
|
+
}
|
|
8418
|
+
}
|
|
8419
|
+
return lines.join("\n");
|
|
8420
|
+
}
|
|
8092
8421
|
function getEnvironment(repoRoot) {
|
|
8093
8422
|
const lines = [
|
|
8094
8423
|
`Working directory: ${repoRoot}`,
|
|
@@ -8101,8 +8430,10 @@ function getEnvironment(repoRoot) {
|
|
|
8101
8430
|
function buildProjectContext(repoRoot) {
|
|
8102
8431
|
return {
|
|
8103
8432
|
projectInstructions: loadProjectFiles(repoRoot),
|
|
8433
|
+
projectMap: loadProjectMap(repoRoot),
|
|
8104
8434
|
gitInfo: getGitInfo(repoRoot),
|
|
8105
8435
|
memoryContext: loadMemoryContext(repoRoot),
|
|
8436
|
+
sessionHistory: loadSessionHistory(repoRoot),
|
|
8106
8437
|
environment: getEnvironment(repoRoot)
|
|
8107
8438
|
};
|
|
8108
8439
|
}
|
|
@@ -8117,6 +8448,11 @@ ${ctx.environment}`);
|
|
|
8117
8448
|
sections.push(`## Git State
|
|
8118
8449
|
|
|
8119
8450
|
${ctx.gitInfo}`);
|
|
8451
|
+
}
|
|
8452
|
+
if (ctx.projectMap) {
|
|
8453
|
+
sections.push(`## Project Map
|
|
8454
|
+
|
|
8455
|
+
${ctx.projectMap}`);
|
|
8120
8456
|
}
|
|
8121
8457
|
if (ctx.projectInstructions) {
|
|
8122
8458
|
sections.push(ctx.projectInstructions);
|
|
@@ -8127,36 +8463,35 @@ ${ctx.gitInfo}`);
|
|
|
8127
8463
|
${ctx.memoryContext}
|
|
8128
8464
|
|
|
8129
8465
|
Use this context to avoid re-learning known patterns. Update with memory_write if you discover new insights.`);
|
|
8466
|
+
}
|
|
8467
|
+
if (ctx.sessionHistory) {
|
|
8468
|
+
sections.push(`## Session History
|
|
8469
|
+
|
|
8470
|
+
${ctx.sessionHistory}`);
|
|
8130
8471
|
}
|
|
8131
8472
|
return sections.join("\n\n");
|
|
8132
8473
|
}
|
|
8133
|
-
var CONTEXT_FILE_NAMES;
|
|
8134
8474
|
var init_project_context = __esm({
|
|
8135
8475
|
"packages/cli/dist/tui/project-context.js"() {
|
|
8136
8476
|
"use strict";
|
|
8137
|
-
|
|
8138
|
-
".open-agents.md",
|
|
8139
|
-
"AGENTS.md",
|
|
8140
|
-
".open-agents/context.md",
|
|
8141
|
-
".open-agents/instructions.md"
|
|
8142
|
-
];
|
|
8477
|
+
init_oa_directory();
|
|
8143
8478
|
}
|
|
8144
8479
|
});
|
|
8145
8480
|
|
|
8146
8481
|
// packages/cli/dist/tui/voice.js
|
|
8147
|
-
import { existsSync as
|
|
8148
|
-
import { join as
|
|
8482
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync5, writeFileSync as writeFileSync5, readFileSync as readFileSync9, unlinkSync } from "node:fs";
|
|
8483
|
+
import { join as join16 } from "node:path";
|
|
8149
8484
|
import { homedir as homedir5, tmpdir as tmpdir2, platform as platform2 } from "node:os";
|
|
8150
8485
|
import { execSync as execSync10, spawn as nodeSpawn } from "node:child_process";
|
|
8151
8486
|
import { createRequire } from "node:module";
|
|
8152
8487
|
function modelDir(id) {
|
|
8153
|
-
return
|
|
8488
|
+
return join16(MODELS_DIR, id);
|
|
8154
8489
|
}
|
|
8155
8490
|
function modelOnnxPath(id) {
|
|
8156
|
-
return
|
|
8491
|
+
return join16(modelDir(id), "model.onnx");
|
|
8157
8492
|
}
|
|
8158
8493
|
function modelConfigPath(id) {
|
|
8159
|
-
return
|
|
8494
|
+
return join16(modelDir(id), "config.json");
|
|
8160
8495
|
}
|
|
8161
8496
|
function describeToolCall(toolName, args) {
|
|
8162
8497
|
const path = args["path"];
|
|
@@ -8265,8 +8600,8 @@ var init_voice = __esm({
|
|
|
8265
8600
|
configUrl: "https://raw.githubusercontent.com/robit-man/combine_overwatch_onnx/main/overwatch.onnx.json"
|
|
8266
8601
|
}
|
|
8267
8602
|
};
|
|
8268
|
-
VOICE_DIR =
|
|
8269
|
-
MODELS_DIR =
|
|
8603
|
+
VOICE_DIR = join16(homedir5(), ".open-agents", "voice");
|
|
8604
|
+
MODELS_DIR = join16(VOICE_DIR, "models");
|
|
8270
8605
|
VoiceEngine = class {
|
|
8271
8606
|
enabled = false;
|
|
8272
8607
|
modelId = "glados";
|
|
@@ -8386,7 +8721,7 @@ var init_voice = __esm({
|
|
|
8386
8721
|
const audioData = result["output"].data;
|
|
8387
8722
|
if (audioData.length === 0)
|
|
8388
8723
|
return;
|
|
8389
|
-
const wavPath =
|
|
8724
|
+
const wavPath = join16(tmpdir2(), `oa-voice-${Date.now()}.wav`);
|
|
8390
8725
|
this.writeWav(audioData, this.config.audio.sample_rate, wavPath);
|
|
8391
8726
|
await this.playWav(wavPath);
|
|
8392
8727
|
try {
|
|
@@ -8466,7 +8801,7 @@ var init_voice = __esm({
|
|
|
8466
8801
|
buffer.write("data", 36);
|
|
8467
8802
|
buffer.writeUInt32LE(dataSize, 40);
|
|
8468
8803
|
Buffer.from(int16.buffer, int16.byteOffset, int16.byteLength).copy(buffer, 44);
|
|
8469
|
-
|
|
8804
|
+
writeFileSync5(path, buffer);
|
|
8470
8805
|
}
|
|
8471
8806
|
// -------------------------------------------------------------------------
|
|
8472
8807
|
// Audio playback (system default speakers)
|
|
@@ -8533,30 +8868,30 @@ var init_voice = __esm({
|
|
|
8533
8868
|
async ensureRuntime() {
|
|
8534
8869
|
if (this.ort)
|
|
8535
8870
|
return;
|
|
8536
|
-
|
|
8537
|
-
const pkgPath =
|
|
8871
|
+
mkdirSync5(VOICE_DIR, { recursive: true });
|
|
8872
|
+
const pkgPath = join16(VOICE_DIR, "package.json");
|
|
8538
8873
|
const expectedDeps = {
|
|
8539
8874
|
"onnxruntime-node": "^1.21.0",
|
|
8540
8875
|
"phonemizer": "^1.2.1"
|
|
8541
8876
|
};
|
|
8542
|
-
if (
|
|
8877
|
+
if (existsSync11(pkgPath)) {
|
|
8543
8878
|
try {
|
|
8544
|
-
const existing = JSON.parse(
|
|
8879
|
+
const existing = JSON.parse(readFileSync9(pkgPath, "utf8"));
|
|
8545
8880
|
if (!existing.dependencies?.["phonemizer"]) {
|
|
8546
8881
|
existing.dependencies = { ...existing.dependencies, ...expectedDeps };
|
|
8547
|
-
|
|
8882
|
+
writeFileSync5(pkgPath, JSON.stringify(existing, null, 2));
|
|
8548
8883
|
}
|
|
8549
8884
|
} catch {
|
|
8550
8885
|
}
|
|
8551
8886
|
}
|
|
8552
|
-
if (!
|
|
8553
|
-
|
|
8887
|
+
if (!existsSync11(pkgPath)) {
|
|
8888
|
+
writeFileSync5(pkgPath, JSON.stringify({
|
|
8554
8889
|
name: "open-agents-voice",
|
|
8555
8890
|
private: true,
|
|
8556
8891
|
dependencies: expectedDeps
|
|
8557
8892
|
}, null, 2));
|
|
8558
8893
|
}
|
|
8559
|
-
const voiceRequire = createRequire(
|
|
8894
|
+
const voiceRequire = createRequire(join16(VOICE_DIR, "index.js"));
|
|
8560
8895
|
try {
|
|
8561
8896
|
this.ort = voiceRequire("onnxruntime-node");
|
|
8562
8897
|
} catch {
|
|
@@ -8602,18 +8937,18 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
8602
8937
|
const dir = modelDir(id);
|
|
8603
8938
|
const onnxPath = modelOnnxPath(id);
|
|
8604
8939
|
const configPath = modelConfigPath(id);
|
|
8605
|
-
if (
|
|
8940
|
+
if (existsSync11(onnxPath) && existsSync11(configPath))
|
|
8606
8941
|
return;
|
|
8607
|
-
|
|
8608
|
-
if (!
|
|
8942
|
+
mkdirSync5(dir, { recursive: true });
|
|
8943
|
+
if (!existsSync11(configPath)) {
|
|
8609
8944
|
renderInfo(`Downloading ${model.label} voice config...`);
|
|
8610
8945
|
const configResp = await fetch(model.configUrl);
|
|
8611
8946
|
if (!configResp.ok)
|
|
8612
8947
|
throw new Error(`Failed to download config: HTTP ${configResp.status}`);
|
|
8613
8948
|
const configText = await configResp.text();
|
|
8614
|
-
|
|
8949
|
+
writeFileSync5(configPath, configText);
|
|
8615
8950
|
}
|
|
8616
|
-
if (!
|
|
8951
|
+
if (!existsSync11(onnxPath)) {
|
|
8617
8952
|
renderInfo(`Downloading ${model.label} voice model (this may take a minute)...`);
|
|
8618
8953
|
const onnxResp = await fetch(model.onnxUrl);
|
|
8619
8954
|
if (!onnxResp.ok)
|
|
@@ -8637,7 +8972,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
8637
8972
|
}
|
|
8638
8973
|
process.stdout.write("\r" + " ".repeat(60) + "\r");
|
|
8639
8974
|
const fullBuffer = Buffer.concat(chunks);
|
|
8640
|
-
|
|
8975
|
+
writeFileSync5(onnxPath, fullBuffer);
|
|
8641
8976
|
renderInfo(`${model.label} model downloaded (${formatBytes2(fullBuffer.length)}).`);
|
|
8642
8977
|
}
|
|
8643
8978
|
}
|
|
@@ -8649,10 +8984,10 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
8649
8984
|
throw new Error("ONNX runtime not loaded");
|
|
8650
8985
|
const onnxPath = modelOnnxPath(this.modelId);
|
|
8651
8986
|
const configPath = modelConfigPath(this.modelId);
|
|
8652
|
-
if (!
|
|
8987
|
+
if (!existsSync11(onnxPath) || !existsSync11(configPath)) {
|
|
8653
8988
|
throw new Error(`Model files not found for ${this.modelId}`);
|
|
8654
8989
|
}
|
|
8655
|
-
this.config = JSON.parse(
|
|
8990
|
+
this.config = JSON.parse(readFileSync9(configPath, "utf8"));
|
|
8656
8991
|
renderInfo("Loading voice model...");
|
|
8657
8992
|
this.session = await this.ort.InferenceSession.create(onnxPath, {
|
|
8658
8993
|
executionProviders: ["cpu"],
|
|
@@ -8668,9 +9003,9 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
8668
9003
|
import * as readline2 from "node:readline";
|
|
8669
9004
|
import { cwd } from "node:process";
|
|
8670
9005
|
import { resolve as resolve11 } from "node:path";
|
|
8671
|
-
import { readFileSync as
|
|
8672
|
-
import { existsSync as
|
|
8673
|
-
import { extname as
|
|
9006
|
+
import { readFileSync as readFileSync10 } from "node:fs";
|
|
9007
|
+
import { existsSync as existsSync12 } from "node:fs";
|
|
9008
|
+
import { extname as extname5 } from "node:path";
|
|
8674
9009
|
function adaptTool(tool) {
|
|
8675
9010
|
return {
|
|
8676
9011
|
name: tool.name,
|
|
@@ -8859,12 +9194,26 @@ function startTask(task, config, repoRoot, voice) {
|
|
|
8859
9194
|
break;
|
|
8860
9195
|
}
|
|
8861
9196
|
});
|
|
9197
|
+
const sessionId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
8862
9198
|
const promise = runner.run(task, `Working directory: ${repoRoot}`).then((result) => {
|
|
8863
9199
|
if (result.completed) {
|
|
8864
9200
|
renderTaskComplete(result.summary, result.turns, result.toolCalls, result.durationMs);
|
|
8865
9201
|
} else {
|
|
8866
9202
|
renderTaskIncomplete(result.turns, result.toolCalls, result.durationMs);
|
|
8867
9203
|
}
|
|
9204
|
+
try {
|
|
9205
|
+
saveSession(repoRoot, {
|
|
9206
|
+
id: sessionId,
|
|
9207
|
+
startedAt: new Date(Date.now() - result.durationMs).toISOString(),
|
|
9208
|
+
completedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
9209
|
+
task,
|
|
9210
|
+
turns: result.turns,
|
|
9211
|
+
toolCalls: result.toolCalls,
|
|
9212
|
+
completed: result.completed,
|
|
9213
|
+
summary: result.summary.slice(0, 500)
|
|
9214
|
+
});
|
|
9215
|
+
} catch {
|
|
9216
|
+
}
|
|
8868
9217
|
});
|
|
8869
9218
|
return { runner, promise };
|
|
8870
9219
|
}
|
|
@@ -8968,14 +9317,14 @@ ${c2.dim("Goodbye!")}
|
|
|
8968
9317
|
}
|
|
8969
9318
|
}
|
|
8970
9319
|
const cleanPath = input.replace(/^['"]|['"]$/g, "").trim();
|
|
8971
|
-
const isImage = isImagePath(cleanPath) &&
|
|
9320
|
+
const isImage = isImagePath(cleanPath) && existsSync12(resolve11(repoRoot, cleanPath));
|
|
8972
9321
|
if (activeTask) {
|
|
8973
9322
|
if (isImage) {
|
|
8974
9323
|
try {
|
|
8975
9324
|
const imgPath = resolve11(repoRoot, cleanPath);
|
|
8976
|
-
const imgBuffer =
|
|
9325
|
+
const imgBuffer = readFileSync10(imgPath);
|
|
8977
9326
|
const base64 = imgBuffer.toString("base64");
|
|
8978
|
-
const ext =
|
|
9327
|
+
const ext = extname5(cleanPath).toLowerCase();
|
|
8979
9328
|
const mime = ext === ".png" ? "image/png" : ext === ".gif" ? "image/gif" : ext === ".webp" ? "image/webp" : "image/jpeg";
|
|
8980
9329
|
activeTask.runner.injectImage(base64, mime, `User shared image: ${cleanPath}`);
|
|
8981
9330
|
renderUserInterrupt(`[Image: ${cleanPath}]`);
|
|
@@ -9071,6 +9420,7 @@ var init_interactive = __esm({
|
|
|
9071
9420
|
init_commands();
|
|
9072
9421
|
init_setup();
|
|
9073
9422
|
init_project_context();
|
|
9423
|
+
init_oa_directory();
|
|
9074
9424
|
init_render();
|
|
9075
9425
|
init_voice();
|
|
9076
9426
|
taskManager = new BackgroundTaskManager();
|
|
@@ -9108,7 +9458,7 @@ import { glob } from "glob";
|
|
|
9108
9458
|
import ignore from "ignore";
|
|
9109
9459
|
import { readFile as readFile8, stat as stat2 } from "node:fs/promises";
|
|
9110
9460
|
import { createHash } from "node:crypto";
|
|
9111
|
-
import { join as
|
|
9461
|
+
import { join as join17, relative as relative3, extname as extname6, basename as basename4 } from "node:path";
|
|
9112
9462
|
var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
|
|
9113
9463
|
var init_codebase_indexer = __esm({
|
|
9114
9464
|
"packages/indexer/dist/codebase-indexer.js"() {
|
|
@@ -9152,7 +9502,7 @@ var init_codebase_indexer = __esm({
|
|
|
9152
9502
|
const ig = ignore.default();
|
|
9153
9503
|
if (this.config.respectGitignore) {
|
|
9154
9504
|
try {
|
|
9155
|
-
const gitignoreContent = await readFile8(
|
|
9505
|
+
const gitignoreContent = await readFile8(join17(this.config.rootDir, ".gitignore"), "utf-8");
|
|
9156
9506
|
ig.add(gitignoreContent);
|
|
9157
9507
|
} catch {
|
|
9158
9508
|
}
|
|
@@ -9167,14 +9517,14 @@ var init_codebase_indexer = __esm({
|
|
|
9167
9517
|
for (const relativePath of files) {
|
|
9168
9518
|
if (ig.ignores(relativePath))
|
|
9169
9519
|
continue;
|
|
9170
|
-
const fullPath =
|
|
9520
|
+
const fullPath = join17(this.config.rootDir, relativePath);
|
|
9171
9521
|
try {
|
|
9172
9522
|
const fileStat = await stat2(fullPath);
|
|
9173
9523
|
if (fileStat.size > this.config.maxFileSize)
|
|
9174
9524
|
continue;
|
|
9175
9525
|
const content = await readFile8(fullPath);
|
|
9176
9526
|
const hash = createHash("sha256").update(content).digest("hex");
|
|
9177
|
-
const ext =
|
|
9527
|
+
const ext = extname6(relativePath);
|
|
9178
9528
|
indexed.push({
|
|
9179
9529
|
path: fullPath,
|
|
9180
9530
|
relativePath,
|
|
@@ -9190,7 +9540,7 @@ var init_codebase_indexer = __esm({
|
|
|
9190
9540
|
}
|
|
9191
9541
|
buildTree(files) {
|
|
9192
9542
|
const root = {
|
|
9193
|
-
name:
|
|
9543
|
+
name: basename4(this.config.rootDir),
|
|
9194
9544
|
path: this.config.rootDir,
|
|
9195
9545
|
type: "directory",
|
|
9196
9546
|
children: []
|
|
@@ -9213,7 +9563,7 @@ var init_codebase_indexer = __esm({
|
|
|
9213
9563
|
if (!child) {
|
|
9214
9564
|
child = {
|
|
9215
9565
|
name: part,
|
|
9216
|
-
path:
|
|
9566
|
+
path: join17(current.path, part),
|
|
9217
9567
|
type: "directory",
|
|
9218
9568
|
children: []
|
|
9219
9569
|
};
|
|
@@ -9288,17 +9638,17 @@ __export(index_repo_exports, {
|
|
|
9288
9638
|
indexRepoCommand: () => indexRepoCommand
|
|
9289
9639
|
});
|
|
9290
9640
|
import { resolve as resolve12 } from "node:path";
|
|
9291
|
-
import { existsSync as
|
|
9641
|
+
import { existsSync as existsSync13, statSync as statSync6 } from "node:fs";
|
|
9292
9642
|
import { cwd as cwd2 } from "node:process";
|
|
9293
9643
|
async function indexRepoCommand(opts, _config) {
|
|
9294
9644
|
const repoRoot = resolve12(opts.repoPath ?? cwd2());
|
|
9295
9645
|
printHeader("Index Repository");
|
|
9296
9646
|
printInfo(`Indexing: ${repoRoot}`);
|
|
9297
|
-
if (!
|
|
9647
|
+
if (!existsSync13(repoRoot)) {
|
|
9298
9648
|
printError(`Path does not exist: ${repoRoot}`);
|
|
9299
9649
|
process.exit(1);
|
|
9300
9650
|
}
|
|
9301
|
-
const stat3 =
|
|
9651
|
+
const stat3 = statSync6(repoRoot);
|
|
9302
9652
|
if (!stat3.isDirectory()) {
|
|
9303
9653
|
printError(`Path is not a directory: ${repoRoot}`);
|
|
9304
9654
|
process.exit(1);
|
|
@@ -9540,7 +9890,7 @@ var config_exports = {};
|
|
|
9540
9890
|
__export(config_exports, {
|
|
9541
9891
|
configCommand: () => configCommand
|
|
9542
9892
|
});
|
|
9543
|
-
import { join as
|
|
9893
|
+
import { join as join18 } from "node:path";
|
|
9544
9894
|
import { homedir as homedir6 } from "node:os";
|
|
9545
9895
|
async function configCommand(opts, config) {
|
|
9546
9896
|
if (opts.subCommand === "set") {
|
|
@@ -9563,7 +9913,7 @@ function handleShow(opts, config) {
|
|
|
9563
9913
|
printKeyValue("verbose", String(config.verbose), 2);
|
|
9564
9914
|
printKeyValue("dbPath", config.dbPath, 2);
|
|
9565
9915
|
printSection("Config File");
|
|
9566
|
-
printInfo(`~/.open-agents/config.json (${
|
|
9916
|
+
printInfo(`~/.open-agents/config.json (${join18(homedir6(), ".open-agents", "config.json")})`);
|
|
9567
9917
|
printSection("Environment Variables");
|
|
9568
9918
|
printInfo("OPEN_AGENTS_BACKEND_URL \u2014 override backendUrl");
|
|
9569
9919
|
printInfo("OPEN_AGENTS_MODEL \u2014 override model");
|
|
@@ -9795,8 +10145,8 @@ __export(eval_exports, {
|
|
|
9795
10145
|
evalCommand: () => evalCommand
|
|
9796
10146
|
});
|
|
9797
10147
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
9798
|
-
import { mkdirSync as
|
|
9799
|
-
import { join as
|
|
10148
|
+
import { mkdirSync as mkdirSync6, writeFileSync as writeFileSync6 } from "node:fs";
|
|
10149
|
+
import { join as join19 } from "node:path";
|
|
9800
10150
|
async function evalCommand(opts, config) {
|
|
9801
10151
|
const suiteName = opts.suite ?? "basic";
|
|
9802
10152
|
const suite = SUITES[suiteName];
|
|
@@ -9917,9 +10267,9 @@ async function evalCommand(opts, config) {
|
|
|
9917
10267
|
process.exit(failed > 0 ? 1 : 0);
|
|
9918
10268
|
}
|
|
9919
10269
|
function createTempEvalRepo() {
|
|
9920
|
-
const dir =
|
|
9921
|
-
|
|
9922
|
-
|
|
10270
|
+
const dir = join19(tmpdir3(), `open-agents-eval-${Date.now()}`);
|
|
10271
|
+
mkdirSync6(dir, { recursive: true });
|
|
10272
|
+
writeFileSync6(join19(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
|
|
9923
10273
|
return dir;
|
|
9924
10274
|
}
|
|
9925
10275
|
var BASIC_SUITE, FULL_SUITE, SUITES;
|
|
@@ -9979,7 +10329,7 @@ init_updater();
|
|
|
9979
10329
|
import { parseArgs as nodeParseArgs2 } from "node:util";
|
|
9980
10330
|
import { createRequire as createRequire2 } from "node:module";
|
|
9981
10331
|
import { fileURLToPath } from "node:url";
|
|
9982
|
-
import { dirname as dirname3, join as
|
|
10332
|
+
import { dirname as dirname3, join as join20 } from "node:path";
|
|
9983
10333
|
|
|
9984
10334
|
// packages/cli/dist/cli.js
|
|
9985
10335
|
import { createInterface } from "node:readline";
|
|
@@ -10086,7 +10436,7 @@ init_output();
|
|
|
10086
10436
|
function getVersion() {
|
|
10087
10437
|
try {
|
|
10088
10438
|
const require2 = createRequire2(import.meta.url);
|
|
10089
|
-
const pkgPath =
|
|
10439
|
+
const pkgPath = join20(dirname3(fileURLToPath(import.meta.url)), "..", "package.json");
|
|
10090
10440
|
const pkg = require2(pkgPath);
|
|
10091
10441
|
return pkg.version;
|
|
10092
10442
|
} catch {
|
package/package.json
CHANGED