omnexx 0.11.1 → 0.11.2
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/{chat-server-KRKEX6ID.js → chat-server-ILVKG5TB.js} +2 -2
- package/dist/{chunk-RZK4KYXQ.js → chunk-3KIPB3HQ.js} +3 -3
- package/dist/{chunk-VDO3EKC4.js → chunk-4DX4BPIF.js} +81 -14
- package/dist/chunk-4DX4BPIF.js.map +1 -0
- package/dist/{chunk-OGGJJABC.js → chunk-GIL6EOVE.js} +4 -4
- package/dist/{chunk-CP53ICXW.js → chunk-MNTMFQJV.js} +2 -2
- package/dist/{chunk-32JVRGO6.js → chunk-WXO45ZPF.js} +3 -3
- package/dist/cli.js +8 -8
- package/dist/cli.js.map +1 -1
- package/dist/{list-S2S26L5B.js → list-4L6TDLAZ.js} +2 -2
- package/dist/{print-AHR62FRB.js → print-UFTNJI7N.js} +4 -4
- package/dist/{session-A75AZD4D.js → session-D4JHZJSQ.js} +6 -6
- package/dist/{start-X7F44E5W.js → start-G76XSQAH.js} +6 -6
- package/package.json +1 -1
- package/dist/chunk-VDO3EKC4.js.map +0 -1
- /package/dist/{chat-server-KRKEX6ID.js.map → chat-server-ILVKG5TB.js.map} +0 -0
- /package/dist/{chunk-RZK4KYXQ.js.map → chunk-3KIPB3HQ.js.map} +0 -0
- /package/dist/{chunk-OGGJJABC.js.map → chunk-GIL6EOVE.js.map} +0 -0
- /package/dist/{chunk-CP53ICXW.js.map → chunk-MNTMFQJV.js.map} +0 -0
- /package/dist/{chunk-32JVRGO6.js.map → chunk-WXO45ZPF.js.map} +0 -0
- /package/dist/{list-S2S26L5B.js.map → list-4L6TDLAZ.js.map} +0 -0
- /package/dist/{print-AHR62FRB.js.map → print-UFTNJI7N.js.map} +0 -0
- /package/dist/{session-A75AZD4D.js.map → session-D4JHZJSQ.js.map} +0 -0
- /package/dist/{start-X7F44E5W.js.map → start-G76XSQAH.js.map} +0 -0
|
@@ -34,7 +34,7 @@ function text(c, key) {
|
|
|
34
34
|
return v;
|
|
35
35
|
}
|
|
36
36
|
async function serveChat(io, runCli, opts) {
|
|
37
|
-
const { Session } = await import("./session-
|
|
37
|
+
const { Session } = await import("./session-D4JHZJSQ.js");
|
|
38
38
|
const session = new Session(io, runCli);
|
|
39
39
|
const write = (msg) => {
|
|
40
40
|
println(io.stdout, JSON.stringify(msg));
|
|
@@ -299,4 +299,4 @@ async function serveChat(io, runCli, opts) {
|
|
|
299
299
|
export {
|
|
300
300
|
serveChat
|
|
301
301
|
};
|
|
302
|
-
//# sourceMappingURL=chat-server-
|
|
302
|
+
//# sourceMappingURL=chat-server-ILVKG5TB.js.map
|
|
@@ -56,7 +56,7 @@ import {
|
|
|
56
56
|
withoutVendored,
|
|
57
57
|
workerTools,
|
|
58
58
|
writeIntentTool
|
|
59
|
-
} from "./chunk-
|
|
59
|
+
} from "./chunk-MNTMFQJV.js";
|
|
60
60
|
import {
|
|
61
61
|
RunStore,
|
|
62
62
|
applyPlanUpdate,
|
|
@@ -86,7 +86,7 @@ import {
|
|
|
86
86
|
fail,
|
|
87
87
|
isSecretPath,
|
|
88
88
|
ok
|
|
89
|
-
} from "./chunk-
|
|
89
|
+
} from "./chunk-4DX4BPIF.js";
|
|
90
90
|
import {
|
|
91
91
|
QuotaLedger
|
|
92
92
|
} from "./chunk-DGKPM32R.js";
|
|
@@ -5864,4 +5864,4 @@ export {
|
|
|
5864
5864
|
EventTail,
|
|
5865
5865
|
LiveFeed
|
|
5866
5866
|
};
|
|
5867
|
-
//# sourceMappingURL=chunk-
|
|
5867
|
+
//# sourceMappingURL=chunk-3KIPB3HQ.js.map
|
|
@@ -88,7 +88,8 @@ var PathJail = class {
|
|
|
88
88
|
|
|
89
89
|
// src/tools/search.ts
|
|
90
90
|
import { readdir, readFile, stat } from "fs/promises";
|
|
91
|
-
import {
|
|
91
|
+
import { homedir } from "os";
|
|
92
|
+
import { basename as basename2, dirname as dirname2, join, relative as relative2, resolve as resolve2 } from "path";
|
|
92
93
|
import { execa } from "execa";
|
|
93
94
|
import { z } from "zod";
|
|
94
95
|
|
|
@@ -148,7 +149,33 @@ var schema = z.strictObject({
|
|
|
148
149
|
glob: z.string().optional().describe('Only files matching this glob, e.g. "src/**/*.ts"'),
|
|
149
150
|
path: z.string().optional().describe("Directory to search, relative to the repo root")
|
|
150
151
|
});
|
|
151
|
-
|
|
152
|
+
var NOISE_DIRS = [...SKIP_DIRS, ".cache", ".turbo", ".parcel-cache", "vendor"];
|
|
153
|
+
var HOME_NOISE = [
|
|
154
|
+
"Library",
|
|
155
|
+
".Trash",
|
|
156
|
+
"Applications",
|
|
157
|
+
"Pictures",
|
|
158
|
+
"Movies",
|
|
159
|
+
"Music",
|
|
160
|
+
".npm",
|
|
161
|
+
".npm-cache",
|
|
162
|
+
".cargo",
|
|
163
|
+
".rustup",
|
|
164
|
+
".gradle",
|
|
165
|
+
".m2",
|
|
166
|
+
".config",
|
|
167
|
+
".local",
|
|
168
|
+
".vscode",
|
|
169
|
+
".cursor",
|
|
170
|
+
".docker",
|
|
171
|
+
".ollama"
|
|
172
|
+
];
|
|
173
|
+
var PER_FILE = 20;
|
|
174
|
+
function excludes(atHome) {
|
|
175
|
+
const dirs = atHome ? [...NOISE_DIRS, ...HOME_NOISE] : NOISE_DIRS;
|
|
176
|
+
return dirs.flatMap((d) => ["--glob", `!**/${d}/**`]);
|
|
177
|
+
}
|
|
178
|
+
async function viaRg(pattern, dir, glob, target = ".", atHome = false) {
|
|
152
179
|
const args = [
|
|
153
180
|
"-n",
|
|
154
181
|
"--with-filename",
|
|
@@ -164,12 +191,18 @@ async function viaRg(pattern, dir, glob, target = ".") {
|
|
|
164
191
|
"--glob",
|
|
165
192
|
"!*.pem",
|
|
166
193
|
"--glob",
|
|
167
|
-
"!*.key"
|
|
194
|
+
"!*.key",
|
|
195
|
+
"--max-count",
|
|
196
|
+
String(PER_FILE),
|
|
197
|
+
"--max-filesize",
|
|
198
|
+
"2M",
|
|
199
|
+
...excludes(atHome)
|
|
168
200
|
];
|
|
169
201
|
if (glob) args.push("--glob", glob);
|
|
170
|
-
args.push("-e", pattern, target);
|
|
202
|
+
args.push("--no-messages", "-e", pattern, target);
|
|
171
203
|
const r = await execa("rg", args, { cwd: dir, reject: false, stdin: "ignore", timeout: 6e4 });
|
|
172
|
-
if (r.
|
|
204
|
+
if (r.exitCode === 2 && r.stdout.trim()) return r.stdout.split("\n").filter(Boolean);
|
|
205
|
+
if (r.failed && r.exitCode !== 1 && !(r.exitCode === 2 && !r.stderr.trim())) {
|
|
173
206
|
if (r.code === "ENOENT") return void 0;
|
|
174
207
|
const first = r.stderr?.split("\n")[0];
|
|
175
208
|
if (first) throw new Error(first);
|
|
@@ -189,7 +222,8 @@ async function viaJs(pattern, dir, glob, target = ".") {
|
|
|
189
222
|
return out;
|
|
190
223
|
}
|
|
191
224
|
const walk = async (d) => {
|
|
192
|
-
|
|
225
|
+
const entries = await readdir(d, { withFileTypes: true }).catch(() => []);
|
|
226
|
+
for (const entry of entries) {
|
|
193
227
|
if (out.length >= MAX_HITS * 5) return;
|
|
194
228
|
const abs = join(d, entry.name);
|
|
195
229
|
const rel = relative2(dir, abs);
|
|
@@ -198,8 +232,14 @@ async function viaJs(pattern, dir, glob, target = ".") {
|
|
|
198
232
|
continue;
|
|
199
233
|
}
|
|
200
234
|
if (!entry.isFile() || isSecretPath(rel) || globRe && !globRe.test(rel)) continue;
|
|
201
|
-
|
|
202
|
-
|
|
235
|
+
const size = await stat(abs).then(
|
|
236
|
+
(st) => st.size,
|
|
237
|
+
() => Infinity
|
|
238
|
+
);
|
|
239
|
+
if (size > 2e6) continue;
|
|
240
|
+
const text = await readFile(abs, "utf8").catch(() => void 0);
|
|
241
|
+
if (text === void 0) continue;
|
|
242
|
+
const lines = text.split("\n");
|
|
203
243
|
lines.forEach((l, i) => {
|
|
204
244
|
if (re.test(l)) out.push(`${rel}:${i + 1}:${l.slice(0, 300)}`);
|
|
205
245
|
});
|
|
@@ -210,7 +250,7 @@ async function viaJs(pattern, dir, glob, target = ".") {
|
|
|
210
250
|
}
|
|
211
251
|
var searchTool = {
|
|
212
252
|
name: "search",
|
|
213
|
-
description: `Search file contents with a regex (ripgrep). Returns up to ${MAX_HITS} matching lines with 2 lines of context.`,
|
|
253
|
+
description: `Search file contents with a regex (ripgrep). Returns up to ${MAX_HITS} matching lines with 2 lines of context (at most ${PER_FILE} per file). Scope it: pass path (a folder) and glob (e.g. "**/*.ts") whenever you know where to look; dependency, build and cache folders are skipped.`,
|
|
214
254
|
schema,
|
|
215
255
|
readOnly: true,
|
|
216
256
|
async run(input, ctx) {
|
|
@@ -221,7 +261,7 @@ var searchTool = {
|
|
|
221
261
|
return fail(err instanceof OmnexxError ? err.message : String(err));
|
|
222
262
|
}
|
|
223
263
|
if (!input.pattern.trim()) {
|
|
224
|
-
const { listTree: listTree2 } = await import("./list-
|
|
264
|
+
const { listTree: listTree2 } = await import("./list-4L6TDLAZ.js");
|
|
225
265
|
return ok(await listTree2(dir, ctx.jail.resolve(".", "read"), 3));
|
|
226
266
|
}
|
|
227
267
|
try {
|
|
@@ -235,7 +275,8 @@ var searchTool = {
|
|
|
235
275
|
target = basename2(dir);
|
|
236
276
|
dir = dirname2(dir);
|
|
237
277
|
}
|
|
238
|
-
const
|
|
278
|
+
const atHome = resolve2(ctx.jail.root) === resolve2(homedir());
|
|
279
|
+
const lines = await viaRg(input.pattern, dir, input.glob, target, atHome) ?? await viaJs(input.pattern, dir, input.glob, target);
|
|
239
280
|
const hits = lines.filter((l) => /^[^:]+:\d+:/.test(l));
|
|
240
281
|
if (!hits.length) return ok("no matches");
|
|
241
282
|
let shown = 0;
|
|
@@ -245,14 +286,40 @@ var searchTool = {
|
|
|
245
286
|
if (shown > MAX_HITS) break;
|
|
246
287
|
kept.push(l.replace(/^\.\//, ""));
|
|
247
288
|
}
|
|
248
|
-
const
|
|
249
|
-
|
|
289
|
+
const capped = cappedFiles(hits);
|
|
290
|
+
const perFile = capped.length ? `
|
|
291
|
+
(${capped.slice(0, 5).join(", ")} ${capped.length === 1 ? "has" : "have"} more than ${String(PER_FILE)} matches; search one with path set to it to see them all)` : "";
|
|
292
|
+
const note = perFile + (hits.length > MAX_HITS ? `
|
|
293
|
+
(${hits.length - MAX_HITS} more matches not shown. Most are in: ${whereMatches(hits)}. Narrow with path or glob.)` : "");
|
|
250
294
|
return ok(ctx.redactor.text(kept.join("\n")) + note);
|
|
251
295
|
} catch (err) {
|
|
252
296
|
return fail(`search failed: ${err.message}`);
|
|
253
297
|
}
|
|
254
298
|
}
|
|
255
299
|
};
|
|
300
|
+
function folderOf(parts) {
|
|
301
|
+
if (parts.length > 2) return parts.slice(0, 2).join("/");
|
|
302
|
+
if (parts.length === 2) return parts[0] ?? ".";
|
|
303
|
+
return ".";
|
|
304
|
+
}
|
|
305
|
+
function whereMatches(hits, top = 6) {
|
|
306
|
+
const counts = /* @__PURE__ */ new Map();
|
|
307
|
+
for (const h of hits) {
|
|
308
|
+
const file = h.replace(/^\.\//, "").split(":")[0] ?? "";
|
|
309
|
+
const parts = file.split("/");
|
|
310
|
+
const key = folderOf(parts);
|
|
311
|
+
counts.set(key, (counts.get(key) ?? 0) + 1);
|
|
312
|
+
}
|
|
313
|
+
return [...counts].sort((a, b) => b[1] - a[1]).slice(0, top).map(([k, n]) => `${k} (${String(n)})`).join(", ");
|
|
314
|
+
}
|
|
315
|
+
function cappedFiles(hits) {
|
|
316
|
+
const counts = /* @__PURE__ */ new Map();
|
|
317
|
+
for (const h of hits) {
|
|
318
|
+
const file = h.replace(/^\.\//, "").split(":")[0] ?? "";
|
|
319
|
+
counts.set(file, (counts.get(file) ?? 0) + 1);
|
|
320
|
+
}
|
|
321
|
+
return [...counts].filter(([, n]) => n >= PER_FILE).map(([f]) => f);
|
|
322
|
+
}
|
|
256
323
|
|
|
257
324
|
// src/tools/list.ts
|
|
258
325
|
var MAX_ENTRIES = 400;
|
|
@@ -318,4 +385,4 @@ export {
|
|
|
318
385
|
listTree,
|
|
319
386
|
listTool
|
|
320
387
|
};
|
|
321
|
-
//# sourceMappingURL=chunk-
|
|
388
|
+
//# sourceMappingURL=chunk-4DX4BPIF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/tools/list.ts","../src/security/paths.ts","../src/tools/search.ts","../src/security/glob.ts","../src/tools/types.ts"],"sourcesContent":["import { readdir } from 'node:fs/promises';\nimport { join, relative } from 'node:path';\nimport { z } from 'zod';\nimport { OmnexxError } from '../errors.js';\nimport { isSecretPath } from '../security/paths.js';\nimport { SKIP_DIRS } from './search.js';\nimport { fail, ok, type Tool } from './types.js';\n\nexport const MAX_ENTRIES = 400;\n\nconst schema = z.strictObject({\n path: z\n .string()\n .optional()\n .describe('Directory to list, relative to the repo root (default: the root)'),\n depth: z.number().int().min(1).max(8).optional().describe('How many levels down (default 3)'),\n});\n\n/** Files and folders under `root`, folders ending in \"/\", dependency and build folders left out. */\nexport async function listTree(root: string, base: string, depth: number): Promise<string> {\n const out: string[] = [];\n let more = 0;\n const walk = async (dir: string, level: number): Promise<void> => {\n const entries = (await readdir(dir, { withFileTypes: true })).sort((a, b) =>\n a.name < b.name ? -1 : 1,\n );\n for (const e of entries) {\n if (e.name === '.git' || (e.isDirectory() && SKIP_DIRS.has(e.name))) continue;\n const rel = relative(base, join(dir, e.name));\n if (isSecretPath(rel)) continue;\n if (out.length >= MAX_ENTRIES) {\n more++;\n continue;\n }\n out.push(e.isDirectory() ? `${rel}/` : rel);\n if (e.isDirectory() && level < depth) await walk(join(dir, e.name), level + 1);\n }\n };\n await walk(root, 1);\n if (!out.length) return '(empty)';\n return more ? `${out.join('\\n')}\\n… ${String(more)} more; list a subfolder` : out.join('\\n');\n}\n\nexport const listTool: Tool<typeof schema> = {\n name: 'list',\n description:\n 'List files and folders as a tree (folders end in \"/\"; dependency and build folders are left out). Use it to find your way around before reading.',\n schema,\n readOnly: true,\n async run(input, ctx) {\n let dir: string;\n try {\n dir = ctx.jail.resolve(input.path ?? '.', 'read');\n } catch (err) {\n return fail(err instanceof OmnexxError ? err.message : String(err));\n }\n try {\n return ok(await listTree(dir, ctx.jail.resolve('.', 'read'), input.depth ?? 3));\n } catch (err) {\n return fail(`cannot list ${input.path ?? '.'}: ${(err as Error).message}`);\n }\n },\n};\n","import { realpathSync } from 'node:fs';\nimport { basename, dirname, isAbsolute, relative, resolve, sep } from 'node:path';\nimport { PolicyError } from '../errors.js';\n\n/** Paths the agent may never read or write, even inside the worktree. */\nconst DENY_SEGMENTS = ['.ssh', '.aws', '.gnupg', '.git', '.docker', '.kube'];\nconst DENY_BASENAME = [\n /^\\.env(\\..*)?$/i,\n /\\.pem$/i,\n /\\.key$/i,\n /\\.p12$/i,\n /\\.pfx$/i,\n /^id_[a-z0-9]+(\\.pub)?$/i,\n /^\\.npmrc$/i,\n /^\\.netrc$/i,\n /^\\.pypirc$/i,\n /^credentials(\\.json)?$/i,\n];\n\n/** True when a path (absolute or relative) points at something that looks like a credential. */\nexport function isSecretPath(path: string): boolean {\n const parts = path.split(/[\\\\/]+/).filter(Boolean);\n if (parts.some((p) => DENY_SEGMENTS.includes(p.toLowerCase()))) return true;\n const base = basename(path);\n return DENY_BASENAME.some((re) => re.test(base));\n}\n\n/** realpath of the deepest existing ancestor, with the missing tail re-appended. */\nfunction canonical(path: string): string {\n let current = path;\n const tail: string[] = [];\n for (;;) {\n try {\n const real = realpathSync.native(current);\n return tail.length ? resolve(real, ...tail.reverse()) : real;\n } catch {\n const parent = dirname(current);\n if (parent === current) return path;\n tail.push(basename(current));\n current = parent;\n }\n }\n}\n\nconst caseInsensitive = process.platform === 'darwin' || process.platform === 'win32';\n\nexport function isInside(root: string, target: string): boolean {\n const a = caseInsensitive ? root.toLowerCase() : root;\n const b = caseInsensitive ? target.toLowerCase() : target;\n if (a === b) return true;\n const rel = relative(a, b);\n return rel !== '' && !rel.startsWith('..') && !isAbsolute(rel);\n}\n\n/** A path outside the root: the one jail refusal a person may override in interactive chat. */\nexport class OutsideRootError extends PolicyError {}\n\n/**\n * The path jail. Every file tool goes through `resolve()`: the result is a real path inside the\n * worktree, never through a symlink that escapes it, and never a secret-looking file.\n */\nexport class PathJail {\n readonly root: string;\n\n constructor(root: string) {\n this.root = realpathSync.native(root);\n }\n\n resolve(userPath: string, mode: 'read' | 'write', opts: { allowOutside?: boolean } = {}): string {\n if (userPath.includes('\\0')) throw new PolicyError('path contains a NUL byte');\n const expanded = userPath.startsWith('~')\n ? `${this.root}${sep}__home__${userPath.slice(1)}`\n : userPath;\n const abs = resolve(this.root, expanded);\n const real = canonical(abs);\n if (!isInside(this.root, real)) {\n if (opts.allowOutside && !isSecretPath(real)) return real;\n throw new OutsideRootError(\n `${userPath} is outside the worktree`,\n 'file tools only work on paths inside the repository',\n );\n }\n const rel = relative(this.root, real);\n if (isSecretPath(rel)) {\n throw new PolicyError(\n `${mode} of ${userPath} is denied (looks like a credential or git internals)`,\n );\n }\n return real;\n }\n\n relative(abs: string): string {\n return relative(this.root, abs).split(sep).join('/');\n }\n}\n","import { readdir, readFile, stat } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { basename, dirname, join, relative, resolve } from 'node:path';\nimport { execa } from 'execa';\nimport { z } from 'zod';\nimport { OmnexxError } from '../errors.js';\nimport { globToRegExp } from '../security/glob.js';\nimport { isSecretPath } from '../security/paths.js';\nimport { fail, ok, type Tool } from './types.js';\n\nexport const MAX_HITS = 100;\nexport const SKIP_DIRS = new Set([\n '.git',\n 'node_modules',\n 'dist',\n 'build',\n 'coverage',\n '.next',\n 'target',\n '__pycache__',\n '.venv',\n]);\n\nconst schema = z.strictObject({\n pattern: z\n .string()\n .describe('Regular expression (ripgrep syntax); empty lists the files instead'),\n glob: z.string().optional().describe('Only files matching this glob, e.g. \"src/**/*.ts\"'),\n path: z.string().optional().describe('Directory to search, relative to the repo root'),\n});\n\n/**\n * Folders that are never what a search is looking for: dependencies, builds and caches anywhere,\n * plus, when the agent works in a home folder, the system and app folders in it.\n */\nconst NOISE_DIRS = [...SKIP_DIRS, '.cache', '.turbo', '.parcel-cache', 'vendor'];\nconst HOME_NOISE = [\n 'Library',\n '.Trash',\n 'Applications',\n 'Pictures',\n 'Movies',\n 'Music',\n '.npm',\n '.npm-cache',\n '.cargo',\n '.rustup',\n '.gradle',\n '.m2',\n '.config',\n '.local',\n '.vscode',\n '.cursor',\n '.docker',\n '.ollama',\n];\n/** Matches kept per file, so one huge file can't fill the result. */\nconst PER_FILE = 20;\n\nfunction excludes(atHome: boolean): string[] {\n const dirs = atHome ? [...NOISE_DIRS, ...HOME_NOISE] : NOISE_DIRS;\n return dirs.flatMap((d) => ['--glob', `!**/${d}/**`]);\n}\n\nasync function viaRg(\n pattern: string,\n dir: string,\n glob: string | undefined,\n target = '.',\n atHome = false,\n): Promise<string[] | undefined> {\n const args = [\n '-n',\n '--with-filename',\n '--no-heading',\n '--color=never',\n '-C',\n '2',\n '--max-columns=300',\n '--glob',\n '!.git',\n '--glob',\n '!.env*',\n '--glob',\n '!*.pem',\n '--glob',\n '!*.key',\n '--max-count',\n String(PER_FILE),\n '--max-filesize',\n '2M',\n ...excludes(atHome),\n ];\n if (glob) args.push('--glob', glob);\n // Files it can't read (permission denied, a socket) are skipped, not fatal.\n args.push('--no-messages', '-e', pattern, target);\n const r = await execa('rg', args, { cwd: dir, reject: false, stdin: 'ignore', timeout: 60_000 });\n // Exit 2 with output: some files were unreadable, the rest searched fine.\n if (r.exitCode === 2 && r.stdout.trim()) return r.stdout.split('\\n').filter(Boolean);\n if (r.failed && r.exitCode !== 1 && !(r.exitCode === 2 && !r.stderr.trim())) {\n if ((r as { code?: string }).code === 'ENOENT') return undefined;\n // execa leaves stderr undefined when the spawn itself fails (e.g. cwd is a file).\n const first = (r.stderr as string | undefined)?.split('\\n')[0];\n if (first) throw new Error(first);\n throw new Error(r.message);\n }\n return r.stdout.split('\\n').filter(Boolean);\n}\n\n/** Fallback when rg isn't installed: a bounded recursive scan. */\nasync function viaJs(\n pattern: string,\n dir: string,\n glob: string | undefined,\n target = '.',\n): Promise<string[]> {\n const re = new RegExp(pattern);\n const globRe = glob ? globToRegExp(glob) : undefined;\n const out: string[] = [];\n if (target !== '.') {\n const lines = (await readFile(join(dir, target), 'utf8')).split('\\n');\n lines.forEach((l, i) => {\n if (re.test(l)) out.push(`${target}:${i + 1}:${l.slice(0, 300)}`);\n });\n return out;\n }\n const walk = async (d: string): Promise<void> => {\n // Folders and files it can't read are skipped, like rg does.\n const entries = await readdir(d, { withFileTypes: true }).catch(() => []);\n for (const entry of entries) {\n if (out.length >= MAX_HITS * 5) return;\n const abs = join(d, entry.name);\n const rel = relative(dir, abs);\n if (entry.isDirectory()) {\n if (!SKIP_DIRS.has(entry.name)) await walk(abs);\n continue;\n }\n if (!entry.isFile() || isSecretPath(rel) || (globRe && !globRe.test(rel))) continue;\n const size = await stat(abs).then(\n (st) => st.size,\n () => Infinity,\n );\n if (size > 2_000_000) continue;\n const text = await readFile(abs, 'utf8').catch(() => undefined);\n if (text === undefined) continue;\n const lines = text.split('\\n');\n lines.forEach((l, i) => {\n if (re.test(l)) out.push(`${rel}:${i + 1}:${l.slice(0, 300)}`);\n });\n }\n };\n await walk(dir);\n return out;\n}\n\nexport const searchTool: Tool<typeof schema> = {\n name: 'search',\n description: `Search file contents with a regex (ripgrep). Returns up to ${MAX_HITS} matching lines with 2 lines of context (at most ${PER_FILE} per file). Scope it: pass path (a folder) and glob (e.g. \"**/*.ts\") whenever you know where to look; dependency, build and cache folders are skipped.`,\n schema,\n readOnly: true,\n async run(input, ctx) {\n let dir: string;\n try {\n dir = ctx.jail.resolve(input.path ?? '.', 'read');\n } catch (err) {\n return fail(err instanceof OmnexxError ? err.message : String(err));\n }\n // Models send an empty pattern (or \".\") when they mean \"show me the files\".\n if (!input.pattern.trim()) {\n const { listTree } = await import('./list.js');\n return ok(await listTree(dir, ctx.jail.resolve('.', 'read'), 3));\n }\n try {\n new RegExp(input.pattern);\n } catch {\n return fail(`invalid regex: ${input.pattern}`);\n }\n try {\n // A file as `path` (models do this often): search just that file, from its directory.\n let target = '.';\n if ((await stat(dir).catch(() => undefined))?.isFile()) {\n target = basename(dir);\n dir = dirname(dir);\n }\n const atHome = resolve(ctx.jail.root) === resolve(homedir());\n const lines =\n (await viaRg(input.pattern, dir, input.glob, target, atHome)) ??\n (await viaJs(input.pattern, dir, input.glob, target));\n const hits = lines.filter((l) => /^[^:]+:\\d+:/.test(l));\n if (!hits.length) return ok('no matches');\n let shown = 0;\n const kept: string[] = [];\n for (const l of lines) {\n if (/^[^:]+:\\d+:/.test(l)) shown++;\n if (shown > MAX_HITS) break;\n kept.push(l.replace(/^\\.\\//, ''));\n }\n const capped = cappedFiles(hits);\n const perFile = capped.length\n ? `\\n(${capped.slice(0, 5).join(', ')} ${capped.length === 1 ? 'has' : 'have'} more than ${String(PER_FILE)} matches; search one with path set to it to see them all)`\n : '';\n const note =\n perFile +\n (hits.length > MAX_HITS\n ? `\\n(${hits.length - MAX_HITS} more matches not shown. Most are in: ${whereMatches(hits)}. Narrow with path or glob.)`\n : '');\n return ok(ctx.redactor.text(kept.join('\\n')) + note);\n } catch (err) {\n return fail(`search failed: ${(err as Error).message}`);\n }\n },\n};\n\n/** A match's folder, two levels deep at most (\"src/api\"), or \".\" for files at the top. */\nfunction folderOf(parts: readonly string[]): string {\n if (parts.length > 2) return parts.slice(0, 2).join('/');\n if (parts.length === 2) return parts[0] ?? '.';\n return '.';\n}\n\n/** \"src/api (40), web/pages (12)\": where the matches are, by their first two folders. */\nexport function whereMatches(hits: readonly string[], top = 6): string {\n const counts = new Map<string, number>();\n for (const h of hits) {\n const file = h.replace(/^\\.\\//, '').split(':')[0] ?? '';\n const parts = file.split('/');\n const key = folderOf(parts);\n counts.set(key, (counts.get(key) ?? 0) + 1);\n }\n return [...counts]\n .sort((a, b) => b[1] - a[1])\n .slice(0, top)\n .map(([k, n]) => `${k} (${String(n)})`)\n .join(', ');\n}\n\n/** Files that reached the per-file cap, so their remaining matches weren't returned. */\nfunction cappedFiles(hits: readonly string[]): string[] {\n const counts = new Map<string, number>();\n for (const h of hits) {\n const file = h.replace(/^\\.\\//, '').split(':')[0] ?? '';\n counts.set(file, (counts.get(file) ?? 0) + 1);\n }\n return [...counts].filter(([, n]) => n >= PER_FILE).map(([f]) => f);\n}\n\nexport const _internal = { viaJs };\n","/**\n * Minimal gitignore-style glob for protected paths: `**` spans directories, `*` and `?`\n * stay within one segment. A pattern without `/` matches the basename at any depth.\n * Written here because node's path.matchesGlob is still experimental on Node 22.\n */\nexport function globToRegExp(pattern: string): RegExp {\n let p = pattern.replace(/^\\.\\//, '');\n const anchored = p.includes('/');\n if (p.endsWith('/')) p += '**';\n let re = '';\n for (let i = 0; i < p.length; i++) {\n const c = p.charAt(i);\n if (c === '*') {\n if (p[i + 1] === '*') {\n const slash = p[i + 2] === '/';\n re += slash ? '(?:.*/)?' : '.*';\n i += slash ? 2 : 1;\n } else re += '[^/]*';\n } else if (c === '?') re += '[^/]';\n else re += c.replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&');\n }\n return new RegExp(anchored ? `^${re}$` : `^(?:.*/)?${re}$`);\n}\n\nexport function matchesAny(path: string, patterns: readonly string[]): string | undefined {\n const normalized = path.replace(/\\\\/g, '/');\n return patterns.find((p) => globToRegExp(p).test(normalized));\n}\n","import type { z } from 'zod';\nimport type { EventLog } from '../core/events.js';\nimport type { Executor } from '../core/exec.js';\nimport type { RunStore } from '../core/run-store.js';\nimport type { RunningContext } from '../core/running-context.js';\nimport type { PolicyContext } from '../security/command-policy.js';\nimport { OutsideRootError, type PathJail } from '../security/paths.js';\nimport type { Redactor } from '../security/redact.js';\n\n/** An agent card a helper plays: its instructions and the tools it asked for. */\nexport interface HelperCard {\n name: string;\n prompt: string;\n tools: readonly string[];\n}\n\nexport interface ToolContext {\n /** Where `bash` runs: the host, or the run's sandbox. */\n exec?: Executor;\n jail: PathJail;\n env: Record<string, string>;\n store: RunStore;\n events: EventLog;\n redactor: Redactor;\n policy: PolicyContext;\n cycle: number;\n maxCmdTimeoutMs: number;\n notesMaxTokens: number;\n today: string;\n signal?: AbortSignal;\n /** Counter for `cmd-<cycle>-<n>` log ids. */\n nextCommandId: () => string;\n /** Advisory pre-execution safety check (judge, log-only). Must never block. */\n onBash?: (command: string) => void;\n /** Files the agent edited this cycle (for \"no edits after K turns\" and reporting). */\n edited: Set<string>;\n /**\n * Content hashes of what `read` has already returned this cycle, by path and range. A repeat\n * read of unchanged content gets a one-line pointer instead of the same text again. Cleared\n * whenever old tool results are elided or compacted, since the earlier copy is then gone.\n */\n reads?: Map<string, string>;\n /**\n * Interactive chat only: ask the person at the keyboard to allow something the harness would\n * otherwise refuse (a path outside the repo, a command the policy denies). Unattended runs never\n * set it, so there nothing can be overridden.\n */\n ask?: (question: string) => Promise<boolean>;\n /** The current task's (or chat's) running context; unset where there is none. */\n runningContext?: RunningContext;\n /**\n * Runs a read-only child agent (the `task` and `agent` tools), optionally playing an agent\n * card. Unset inside a child: no recursion.\n */\n subagent?: (description: string, kind: SubagentKind, card?: HelperCard) => Promise<string>;\n}\n\nexport const SUBAGENT_KINDS = ['explore', 'research', 'review'] as const;\nexport type SubagentKind = (typeof SUBAGENT_KINDS)[number];\n\nexport interface ToolOutput {\n content: string;\n isError?: boolean;\n /** The tool did the loop's job (e.g. the plan is written): end the loop after this turn. */\n final?: boolean;\n}\n\nexport interface Tool<S extends z.ZodType = z.ZodType> {\n name: string;\n description: string;\n schema: S;\n /** Read-only tools are the only ones the planner gets. */\n readOnly: boolean;\n /** Tidy model input before validation (shape slips only; meaning is still validated). */\n normalize?: (input: unknown) => unknown;\n run(input: z.infer<S>, ctx: ToolContext): Promise<ToolOutput>;\n}\n\nexport const ok = (content: string): ToolOutput => ({ content });\n\n/** `jail.resolve`, but a path outside the repo can be allowed by the person, when `ask` is set. */\nexport async function resolvePath(\n ctx: ToolContext,\n path: string,\n mode: 'read' | 'write',\n): Promise<string> {\n try {\n return ctx.jail.resolve(path, mode);\n } catch (err) {\n if (\n err instanceof OutsideRootError &&\n ctx.ask &&\n (await ctx.ask(`${mode} ${path}? It is outside the repo.`))\n )\n return ctx.jail.resolve(path, mode, { allowOutside: true });\n throw err;\n }\n}\nexport const fail = (content: string): ToolOutput => ({ content, isError: true });\n"],"mappings":"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","names":["readdir","join","relative","z","basename","dirname","relative","resolve","relative","listTree","basename","dirname","resolve","schema","z","readdir","relative","join"]}
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
humanize,
|
|
15
15
|
pickRun,
|
|
16
16
|
supervisorAlive
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-3KIPB3HQ.js";
|
|
18
18
|
import {
|
|
19
19
|
connect,
|
|
20
20
|
connectFromEnv,
|
|
@@ -27,14 +27,14 @@ import {
|
|
|
27
27
|
CodeChat,
|
|
28
28
|
attachImages,
|
|
29
29
|
resolveModelLenient
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-WXO45ZPF.js";
|
|
31
31
|
import {
|
|
32
32
|
emptyTelemetry,
|
|
33
33
|
fold,
|
|
34
34
|
parseFrontmatter,
|
|
35
35
|
resolveRunDeps,
|
|
36
36
|
todoItemsOf
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-MNTMFQJV.js";
|
|
38
38
|
import {
|
|
39
39
|
RunStore,
|
|
40
40
|
compactPlanView,
|
|
@@ -1750,4 +1750,4 @@ export {
|
|
|
1750
1750
|
Session,
|
|
1751
1751
|
helpText
|
|
1752
1752
|
};
|
|
1753
|
-
//# sourceMappingURL=chunk-
|
|
1753
|
+
//# sourceMappingURL=chunk-GIL6EOVE.js.map
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
ok,
|
|
26
26
|
resolvePath,
|
|
27
27
|
searchTool
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-4DX4BPIF.js";
|
|
29
29
|
import {
|
|
30
30
|
findAnthropicKey,
|
|
31
31
|
findProviderKey,
|
|
@@ -7946,4 +7946,4 @@ export {
|
|
|
7946
7946
|
cacheHitRate,
|
|
7947
7947
|
tokensPerCommit
|
|
7948
7948
|
};
|
|
7949
|
-
//# sourceMappingURL=chunk-
|
|
7949
|
+
//# sourceMappingURL=chunk-MNTMFQJV.js.map
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
toolSpec,
|
|
27
27
|
transcriptFor,
|
|
28
28
|
workerTools
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-MNTMFQJV.js";
|
|
30
30
|
import {
|
|
31
31
|
RunStore,
|
|
32
32
|
git,
|
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
} from "./chunk-LRBHQHO6.js";
|
|
37
37
|
import {
|
|
38
38
|
PathJail
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-4DX4BPIF.js";
|
|
40
40
|
import {
|
|
41
41
|
QuotaLedger
|
|
42
42
|
} from "./chunk-DGKPM32R.js";
|
|
@@ -793,4 +793,4 @@ export {
|
|
|
793
793
|
resolveModelLenient,
|
|
794
794
|
CodeChat
|
|
795
795
|
};
|
|
796
|
-
//# sourceMappingURL=chunk-
|
|
796
|
+
//# sourceMappingURL=chunk-WXO45ZPF.js.map
|
package/dist/cli.js
CHANGED
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
verbosityFrom,
|
|
26
26
|
versionAtLeast,
|
|
27
27
|
writeReport
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-3KIPB3HQ.js";
|
|
29
29
|
import {
|
|
30
30
|
EMAIL_ENV,
|
|
31
31
|
appPasswordHelp
|
|
@@ -71,7 +71,7 @@ import {
|
|
|
71
71
|
tomlFor,
|
|
72
72
|
writeServer,
|
|
73
73
|
writeServerSecrets
|
|
74
|
-
} from "./chunk-
|
|
74
|
+
} from "./chunk-MNTMFQJV.js";
|
|
75
75
|
import {
|
|
76
76
|
removeTable,
|
|
77
77
|
setTable
|
|
@@ -86,7 +86,7 @@ import {
|
|
|
86
86
|
repoRoot,
|
|
87
87
|
resolveRef
|
|
88
88
|
} from "./chunk-LRBHQHO6.js";
|
|
89
|
-
import "./chunk-
|
|
89
|
+
import "./chunk-4DX4BPIF.js";
|
|
90
90
|
import "./chunk-DGKPM32R.js";
|
|
91
91
|
import {
|
|
92
92
|
EXIT,
|
|
@@ -134,7 +134,7 @@ import { Command, CommanderError } from "commander";
|
|
|
134
134
|
// package.json
|
|
135
135
|
var package_default = {
|
|
136
136
|
name: "omnexx",
|
|
137
|
-
version: "0.11.
|
|
137
|
+
version: "0.11.2",
|
|
138
138
|
description: "Set a goal, walk away, come back to commits. One coding agent that runs for days, checks every step against your tests, and commits only what passes.",
|
|
139
139
|
license: "MIT",
|
|
140
140
|
author: "James Yaeger",
|
|
@@ -2874,7 +2874,7 @@ function createProgram(io, setExit) {
|
|
|
2874
2874
|
opts.model = await useOllama(io, typeof opts.ollama === "string" ? opts.ollama : void 0);
|
|
2875
2875
|
}
|
|
2876
2876
|
if (opts.print !== void 0) {
|
|
2877
|
-
const { printCommand } = await import("./print-
|
|
2877
|
+
const { printCommand } = await import("./print-UFTNJI7N.js");
|
|
2878
2878
|
setExit(await printCommand(io, opts.print, opts.model ? { model: opts.model } : {}));
|
|
2879
2879
|
return;
|
|
2880
2880
|
}
|
|
@@ -2882,7 +2882,7 @@ function createProgram(io, setExit) {
|
|
|
2882
2882
|
program.outputHelp();
|
|
2883
2883
|
return;
|
|
2884
2884
|
}
|
|
2885
|
-
const { startTui } = await import("./start-
|
|
2885
|
+
const { startTui } = await import("./start-G76XSQAH.js");
|
|
2886
2886
|
setExit(
|
|
2887
2887
|
await startTui(io, runCli, {
|
|
2888
2888
|
version: VERSION,
|
|
@@ -2894,7 +2894,7 @@ function createProgram(io, setExit) {
|
|
|
2894
2894
|
);
|
|
2895
2895
|
program.command("watch").alias("attach").argument("[runId]", "defaults to the most recent run").description("open the interactive session attached to a run").action(async (runId) => {
|
|
2896
2896
|
if (!io.isTTY) throw new UsageError("watch needs a terminal", "use `omnexx logs -f` instead");
|
|
2897
|
-
const { startTui } = await import("./start-
|
|
2897
|
+
const { startTui } = await import("./start-G76XSQAH.js");
|
|
2898
2898
|
setExit(await startTui(io, runCli, { version: VERSION, attach: runId ?? true }));
|
|
2899
2899
|
});
|
|
2900
2900
|
program.command("init").description("detect package manager and gates, then write omnexx.toml (asks first)").option("-y, --yes", "write without asking").action(async (opts) => {
|
|
@@ -2920,7 +2920,7 @@ function createProgram(io, setExit) {
|
|
|
2920
2920
|
setExit(opts.planOnly ? await runPlanOnly(io, text, opts) : await runCommand(io, text, opts));
|
|
2921
2921
|
});
|
|
2922
2922
|
program.command("chat-server", { hidden: true }).description("the chat session as JSON lines on stdin/stdout (used by the VS Code panel)").action(async () => {
|
|
2923
|
-
const { serveChat } = await import("./chat-server-
|
|
2923
|
+
const { serveChat } = await import("./chat-server-ILVKG5TB.js");
|
|
2924
2924
|
setExit(await serveChat(io, runCli, { version: VERSION }));
|
|
2925
2925
|
});
|
|
2926
2926
|
program.command("supervise", { hidden: true }).argument("<runId>").description("run the supervisor for one run in the foreground (used by --detach and services)").action(async (runId) => {
|