agent-valley 2.3.0 → 2.3.1
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/assets/plugin.json +1 -1
- package/dist/index.js +310 -219
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -20825,9 +20825,9 @@ class NodeFsHandler {
|
|
|
20825
20825
|
_watchWithNodeFs(path, listener) {
|
|
20826
20826
|
const opts = this.fsw.options;
|
|
20827
20827
|
const directory = sp.dirname(path);
|
|
20828
|
-
const
|
|
20828
|
+
const basename = sp.basename(path);
|
|
20829
20829
|
const parent = this.fsw._getWatchedDir(directory);
|
|
20830
|
-
parent.add(
|
|
20830
|
+
parent.add(basename);
|
|
20831
20831
|
const absolutePath = sp.resolve(path);
|
|
20832
20832
|
const options = {
|
|
20833
20833
|
persistent: opts.persistent
|
|
@@ -20837,7 +20837,7 @@ class NodeFsHandler {
|
|
|
20837
20837
|
let closer;
|
|
20838
20838
|
if (opts.usePolling) {
|
|
20839
20839
|
const enableBin = opts.interval !== opts.binaryInterval;
|
|
20840
|
-
options.interval = enableBin && isBinaryPath(
|
|
20840
|
+
options.interval = enableBin && isBinaryPath(basename) ? opts.binaryInterval : opts.interval;
|
|
20841
20841
|
closer = setFsWatchFileListener(path, absolutePath, options, {
|
|
20842
20842
|
listener,
|
|
20843
20843
|
rawEmitter: this.fsw._emitRaw
|
|
@@ -20856,10 +20856,10 @@ class NodeFsHandler {
|
|
|
20856
20856
|
return;
|
|
20857
20857
|
}
|
|
20858
20858
|
const dirname = sp.dirname(file);
|
|
20859
|
-
const
|
|
20859
|
+
const basename = sp.basename(file);
|
|
20860
20860
|
const parent = this.fsw._getWatchedDir(dirname);
|
|
20861
20861
|
let prevStats = stats;
|
|
20862
|
-
if (parent.has(
|
|
20862
|
+
if (parent.has(basename))
|
|
20863
20863
|
return;
|
|
20864
20864
|
const listener = async (path, newStats) => {
|
|
20865
20865
|
if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
|
|
@@ -20884,9 +20884,9 @@ class NodeFsHandler {
|
|
|
20884
20884
|
prevStats = newStats;
|
|
20885
20885
|
}
|
|
20886
20886
|
} catch (error) {
|
|
20887
|
-
this.fsw._remove(dirname,
|
|
20887
|
+
this.fsw._remove(dirname, basename);
|
|
20888
20888
|
}
|
|
20889
|
-
} else if (parent.has(
|
|
20889
|
+
} else if (parent.has(basename)) {
|
|
20890
20890
|
const at = newStats.atimeMs;
|
|
20891
20891
|
const mt = newStats.mtimeMs;
|
|
20892
20892
|
if (!at || at <= mt || mt !== prevStats.mtimeMs) {
|
|
@@ -22518,8 +22518,8 @@ function canonicalConfig(config) {
|
|
|
22518
22518
|
// src/agent-provisioning.ts
|
|
22519
22519
|
import { spawn as spawn17 } from "node:child_process";
|
|
22520
22520
|
import { mkdtempSync, rmSync as rmSync2 } from "node:fs";
|
|
22521
|
-
import { homedir as
|
|
22522
|
-
import { delimiter as delimiter3, join as
|
|
22521
|
+
import { homedir as homedir8, tmpdir as tmpdir4 } from "node:os";
|
|
22522
|
+
import { delimiter as delimiter3, join as join47 } from "node:path";
|
|
22523
22523
|
function runTerminalCommand(request, spawnCommand = spawn17) {
|
|
22524
22524
|
return new Promise((resolve) => {
|
|
22525
22525
|
let child;
|
|
@@ -22562,13 +22562,13 @@ function runTerminalCommand(request, spawnCommand = spawn17) {
|
|
|
22562
22562
|
function defaults() {
|
|
22563
22563
|
return {
|
|
22564
22564
|
platform: process.platform,
|
|
22565
|
-
home:
|
|
22565
|
+
home: homedir8(),
|
|
22566
22566
|
env: process.env,
|
|
22567
22567
|
resolveBinary: resolveBinaryPath,
|
|
22568
22568
|
discover: discoverAgents,
|
|
22569
22569
|
runCommand: runTerminalCommand,
|
|
22570
22570
|
supportsLoginCommand: (agent, path, env) => supportsNativeLoginCommand(agent, path, { env }),
|
|
22571
|
-
makeTempDir: () => mkdtempSync(
|
|
22571
|
+
makeTempDir: () => mkdtempSync(join47(tmpdir4(), "av-agent-install-")),
|
|
22572
22572
|
removeTempDir: (path) => rmSync2(path, { recursive: true, force: true })
|
|
22573
22573
|
};
|
|
22574
22574
|
}
|
|
@@ -22595,7 +22595,7 @@ async function runOfficialInstaller(installerUrl, deps, options = {}) {
|
|
|
22595
22595
|
let directory;
|
|
22596
22596
|
try {
|
|
22597
22597
|
directory = deps.makeTempDir();
|
|
22598
|
-
const scriptPath =
|
|
22598
|
+
const scriptPath = join47(directory, "install.sh");
|
|
22599
22599
|
const request = { env: options.env ?? deps.env, ...options.cwd ? { cwd: options.cwd } : {} };
|
|
22600
22600
|
const download = await deps.runCommand({
|
|
22601
22601
|
command: curl,
|
|
@@ -22666,7 +22666,7 @@ async function installChiefAgent(agent, overrides = {}) {
|
|
|
22666
22666
|
const install = await runOfficialInstaller(plan.installerUrl, deps);
|
|
22667
22667
|
if (!install.success)
|
|
22668
22668
|
return commandFailure(install.stage === "download" ? "Installer download" : "Installation", install, plan.documentation);
|
|
22669
|
-
const localBin =
|
|
22669
|
+
const localBin = join47(deps.home, ".local", "bin");
|
|
22670
22670
|
const pathParts = (deps.env.PATH ?? "").split(delimiter3);
|
|
22671
22671
|
if (!pathParts.includes(localBin))
|
|
22672
22672
|
deps.env.PATH = [localBin, ...pathParts.filter(Boolean)].join(delimiter3);
|
|
@@ -22768,17 +22768,17 @@ var init_agent_provisioning = __esm(() => {
|
|
|
22768
22768
|
// src/oma-provisioning.ts
|
|
22769
22769
|
import { mkdtempSync as mkdtempSync2, rmSync as rmSync3 } from "node:fs";
|
|
22770
22770
|
import { chmod as chmod4, lstat as lstat19, readdir as readdir12, readFile as readFile16, realpath as realpath25, unlink as unlink8, writeFile as writeFile14 } from "node:fs/promises";
|
|
22771
|
-
import { homedir as
|
|
22772
|
-
import { delimiter as delimiter4, isAbsolute as
|
|
22771
|
+
import { homedir as homedir9, tmpdir as tmpdir5 } from "node:os";
|
|
22772
|
+
import { delimiter as delimiter4, isAbsolute as isAbsolute16, join as join48, relative as relative15, resolve as resolve29 } from "node:path";
|
|
22773
22773
|
function defaults2() {
|
|
22774
|
-
const home =
|
|
22774
|
+
const home = homedir9();
|
|
22775
22775
|
return {
|
|
22776
22776
|
platform: process.platform,
|
|
22777
22777
|
home,
|
|
22778
22778
|
env: process.env,
|
|
22779
|
-
resolveBinary: (name) => resolveBinaryPath(name, name === "bun" ? [
|
|
22779
|
+
resolveBinary: (name) => resolveBinaryPath(name, name === "bun" ? [join48(process.env.BUN_INSTALL ?? join48(home, ".bun"), "bin", "bun")] : []),
|
|
22780
22780
|
runCommand: runTerminalCommand,
|
|
22781
|
-
makeTempDir: () => mkdtempSync2(
|
|
22781
|
+
makeTempDir: () => mkdtempSync2(join48(tmpdir5(), "av-oma-install-")),
|
|
22782
22782
|
removeTempDir: (path) => rmSync3(path, { recursive: true, force: true })
|
|
22783
22783
|
};
|
|
22784
22784
|
}
|
|
@@ -22799,7 +22799,7 @@ async function present(path) {
|
|
|
22799
22799
|
}
|
|
22800
22800
|
async function installedVersion2(skills) {
|
|
22801
22801
|
try {
|
|
22802
|
-
const marker = JSON.parse(await readFile16(
|
|
22802
|
+
const marker = JSON.parse(await readFile16(join48(skills, "_version.json"), "utf8"));
|
|
22803
22803
|
return marker.schemaVersion === 2 && marker.mode === "project" && typeof marker.version === "string" && /^\d+\.\d+\.\d+(?:-[a-zA-Z0-9.-]+)?$/.test(marker.version) ? marker.version : null;
|
|
22804
22804
|
} catch {
|
|
22805
22805
|
return null;
|
|
@@ -22808,7 +22808,7 @@ async function installedVersion2(skills) {
|
|
|
22808
22808
|
async function snapshotConfig(agents) {
|
|
22809
22809
|
const snapshots = [];
|
|
22810
22810
|
for (const name of CUSTOM_CONFIG_NAMES) {
|
|
22811
|
-
const path =
|
|
22811
|
+
const path = join48(agents, name);
|
|
22812
22812
|
if (!await present(path))
|
|
22813
22813
|
continue;
|
|
22814
22814
|
const file = await lstat19(path);
|
|
@@ -22828,10 +22828,10 @@ async function restoreConfig(agents, snapshots) {
|
|
|
22828
22828
|
["oma-config.yaml", "oma-config.cue"],
|
|
22829
22829
|
["oma-config.local.yaml", "oma-config.local.cue"]
|
|
22830
22830
|
]) {
|
|
22831
|
-
if (!pair.some((name) => original.has(
|
|
22831
|
+
if (!pair.some((name) => original.has(join48(agents, name))))
|
|
22832
22832
|
continue;
|
|
22833
22833
|
for (const name of pair) {
|
|
22834
|
-
const path =
|
|
22834
|
+
const path = join48(agents, name);
|
|
22835
22835
|
if (!original.has(path))
|
|
22836
22836
|
await unlink8(path).catch((error) => {
|
|
22837
22837
|
if (error.code !== "ENOENT")
|
|
@@ -22841,17 +22841,17 @@ async function restoreConfig(agents, snapshots) {
|
|
|
22841
22841
|
}
|
|
22842
22842
|
}
|
|
22843
22843
|
async function workspacePath(input) {
|
|
22844
|
-
if (!input.trim() || !
|
|
22844
|
+
if (!input.trim() || !isAbsolute16(input))
|
|
22845
22845
|
return null;
|
|
22846
|
-
const root =
|
|
22846
|
+
const root = resolve29(input);
|
|
22847
22847
|
if (!await directory2(root))
|
|
22848
22848
|
return null;
|
|
22849
|
-
for (const path of [
|
|
22849
|
+
for (const path of [join48(root, ".agents"), join48(root, ".agents", "skills")]) {
|
|
22850
22850
|
if (!await present(path))
|
|
22851
22851
|
continue;
|
|
22852
22852
|
const actual = await realpath25(path);
|
|
22853
|
-
const location =
|
|
22854
|
-
if (location === ".." || location.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) ||
|
|
22853
|
+
const location = relative15(await realpath25(root), actual);
|
|
22854
|
+
if (location === ".." || location.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) || isAbsolute16(location))
|
|
22855
22855
|
return null;
|
|
22856
22856
|
}
|
|
22857
22857
|
return root;
|
|
@@ -22861,7 +22861,7 @@ async function inspectOma(workspaceRoot, _overrides = {}) {
|
|
|
22861
22861
|
const root = await workspacePath(workspaceRoot);
|
|
22862
22862
|
if (!root)
|
|
22863
22863
|
return { success: false, message: "Choose an existing absolute workspace with project-local OMA files." };
|
|
22864
|
-
const skills =
|
|
22864
|
+
const skills = join48(root, ".agents", "skills");
|
|
22865
22865
|
const version = await installedVersion2(skills);
|
|
22866
22866
|
if (!version)
|
|
22867
22867
|
throw new Error("Invalid installed metadata");
|
|
@@ -22869,7 +22869,7 @@ async function inspectOma(workspaceRoot, _overrides = {}) {
|
|
|
22869
22869
|
if (!entries.length)
|
|
22870
22870
|
throw new Error("No installed skills");
|
|
22871
22871
|
for (const entry of entries) {
|
|
22872
|
-
if (!entry.isDirectory() || !(await lstat19(
|
|
22872
|
+
if (!entry.isDirectory() || !(await lstat19(join48(skills, entry.name, "SKILL.md"))).isFile())
|
|
22873
22873
|
throw new Error("Incomplete installed skill");
|
|
22874
22874
|
}
|
|
22875
22875
|
return {
|
|
@@ -22917,16 +22917,16 @@ async function prepareOma(workspaceRoot, overrides = {}) {
|
|
|
22917
22917
|
delete environment.OMA_YES;
|
|
22918
22918
|
environment.CI = "true";
|
|
22919
22919
|
const paths = [
|
|
22920
|
-
deps.env.BUN_INSTALL_BIN ??
|
|
22921
|
-
|
|
22920
|
+
deps.env.BUN_INSTALL_BIN ?? join48(deps.env.BUN_INSTALL ?? join48(deps.home, ".bun"), "bin"),
|
|
22921
|
+
join48(deps.home, ".local", "bin")
|
|
22922
22922
|
];
|
|
22923
22923
|
environment.PATH = [...new Set([...paths, ...(environment.PATH ?? "").split(delimiter4).filter(Boolean)])].join(delimiter4);
|
|
22924
22924
|
const request = { command: bun, env: environment, cwd: root, timeoutMs: 300000 };
|
|
22925
22925
|
const latest = await deps.runCommand({ ...request, args: ["install", "--global", LATEST_PACKAGE] });
|
|
22926
22926
|
if (!latest.success)
|
|
22927
22927
|
return failure3("OMA CLI update", latest);
|
|
22928
|
-
const agents =
|
|
22929
|
-
const existing = await installedVersion2(
|
|
22928
|
+
const agents = join48(root, ".agents");
|
|
22929
|
+
const existing = await installedVersion2(join48(agents, "skills")) !== null || await directory2(join48(agents, "skills")) && (await present(join48(agents, "oma-config.yaml")) || await present(join48(agents, "mcp.json")) || await directory2(join48(agents, "workflows")));
|
|
22930
22930
|
const custom = await snapshotConfig(agents);
|
|
22931
22931
|
const args = existing ? ["update", "--yes", "--with-new-skills", "--all"] : ["install"];
|
|
22932
22932
|
let installed;
|
|
@@ -24413,9 +24413,9 @@ var init_ui = __esm(() => {
|
|
|
24413
24413
|
|
|
24414
24414
|
// src/setup/workspace-step.ts
|
|
24415
24415
|
import { statSync as statSync3 } from "node:fs";
|
|
24416
|
-
import { isAbsolute as
|
|
24416
|
+
import { isAbsolute as isAbsolute17 } from "node:path";
|
|
24417
24417
|
async function validateOrderWorkspace(path) {
|
|
24418
|
-
if (!
|
|
24418
|
+
if (!isAbsolute17(path))
|
|
24419
24419
|
return "Set workspace.root in av.yaml to an absolute Git repository path.";
|
|
24420
24420
|
try {
|
|
24421
24421
|
if (!statSync3(path).isDirectory())
|
|
@@ -24442,7 +24442,7 @@ async function stepWorkspace(ctx, step, total) {
|
|
|
24442
24442
|
validate: (v) => {
|
|
24443
24443
|
if (!v?.trim())
|
|
24444
24444
|
return "Required";
|
|
24445
|
-
if (!
|
|
24445
|
+
if (!isAbsolute17(v.trim()))
|
|
24446
24446
|
return "Must be an absolute path";
|
|
24447
24447
|
}
|
|
24448
24448
|
});
|
|
@@ -24469,7 +24469,7 @@ var init_workspace_step = __esm(() => {
|
|
|
24469
24469
|
|
|
24470
24470
|
// src/setup/noninteractive-config.ts
|
|
24471
24471
|
import { lstat as lstat20, realpath as realpath26 } from "node:fs/promises";
|
|
24472
|
-
import { isAbsolute as
|
|
24472
|
+
import { isAbsolute as isAbsolute18, join as join49, parse as parsePath, resolve as resolve30 } from "node:path";
|
|
24473
24473
|
function validateNoninteractiveOptions(options) {
|
|
24474
24474
|
if (!options.yes || options.edit || options.mode !== undefined && options.mode !== "order")
|
|
24475
24475
|
throw new Error("Use av setup --yes only for local order setup; --edit and --mode tracker require interactive setup.");
|
|
@@ -24512,7 +24512,7 @@ function selectChief(options, deps, project, global2) {
|
|
|
24512
24512
|
const globalActor = actor(global2);
|
|
24513
24513
|
const selected = options.actor ?? runtime?.actorType ?? projectActor.type ?? globalActor.type;
|
|
24514
24514
|
if (!selected)
|
|
24515
|
-
throw new Error(`actor.type is missing in ${
|
|
24515
|
+
throw new Error(`actor.type is missing in ${join49(deps.projectRoot, "av.yaml")} and ${deps.globalConfigPath}, and the current agent runtime is unknown. Rerun av setup --yes --actor <current-vendor> --model <current-model-or-empty>.`);
|
|
24516
24516
|
const actorType = selected;
|
|
24517
24517
|
const actorSource = options.actor !== undefined ? "explicit" : runtime ? "runtime" : projectActor.type ? "project" : "global";
|
|
24518
24518
|
const previousType = projectActor.type ?? globalActor.type;
|
|
@@ -24550,14 +24550,14 @@ async function prepareNoninteractiveConfig(options, deps) {
|
|
|
24550
24550
|
validateNoninteractiveOptions(options);
|
|
24551
24551
|
let projectRoot;
|
|
24552
24552
|
try {
|
|
24553
|
-
projectRoot = await realpath26(
|
|
24553
|
+
projectRoot = await realpath26(resolve30(deps.projectRoot));
|
|
24554
24554
|
if (!(await lstat20(projectRoot)).isDirectory())
|
|
24555
24555
|
throw new Error("not a directory");
|
|
24556
24556
|
} catch {
|
|
24557
24557
|
throw new Error(`AV configuration directory ${deps.projectRoot} does not exist. Run av setup from an existing directory.`);
|
|
24558
24558
|
}
|
|
24559
|
-
const globalPath =
|
|
24560
|
-
const projectPath =
|
|
24559
|
+
const globalPath = resolve30(deps.globalConfigPath);
|
|
24560
|
+
const projectPath = join49(projectRoot, "av.yaml");
|
|
24561
24561
|
const project = await configFile(projectPath, projectConfigSchema);
|
|
24562
24562
|
const global2 = await configFile(globalPath, globalConfigSchema);
|
|
24563
24563
|
const chief = selectChief(options, { ...deps, projectRoot, globalConfigPath: globalPath }, project.raw, global2.raw);
|
|
@@ -24574,7 +24574,7 @@ async function prepareNoninteractiveConfig(options, deps) {
|
|
|
24574
24574
|
}
|
|
24575
24575
|
const savedWorkspace = project.raw.workspace?.root;
|
|
24576
24576
|
const selectedWorkspace = options.workspace ?? savedWorkspace ?? projectRoot;
|
|
24577
|
-
const workspacePath =
|
|
24577
|
+
const workspacePath = isAbsolute18(selectedWorkspace) ? selectedWorkspace : resolve30(projectRoot, selectedWorkspace);
|
|
24578
24578
|
const workspaceError = await validateOrderWorkspace(workspacePath);
|
|
24579
24579
|
if (workspaceError)
|
|
24580
24580
|
throw new Error(workspaceError);
|
|
@@ -24609,7 +24609,7 @@ var init_noninteractive_config = __esm(() => {
|
|
|
24609
24609
|
});
|
|
24610
24610
|
|
|
24611
24611
|
// src/setup/noninteractive.ts
|
|
24612
|
-
import { join as
|
|
24612
|
+
import { join as join50, parse as parsePath2, resolve as resolve31 } from "node:path";
|
|
24613
24613
|
function rerunCommand(result, options) {
|
|
24614
24614
|
const quote = (value) => `'${value.replace(/'/g, "'\\''")}'`;
|
|
24615
24615
|
return `cd ${quote(result.projectRoot)} && av setup --yes --actor ${result.chief.actorType} --model ${quote(result.chief.model ?? "")} --workspace ${quote(result.workspace ?? result.projectRoot)} --oma ${options.oma ?? "prepare"} --json`;
|
|
@@ -24620,11 +24620,11 @@ async function setupNoninteractive(options, overrides = {}) {
|
|
|
24620
24620
|
version: 1,
|
|
24621
24621
|
status: "failed",
|
|
24622
24622
|
exitCode: 1,
|
|
24623
|
-
projectRoot:
|
|
24623
|
+
projectRoot: resolve31(deps.projectRoot),
|
|
24624
24624
|
workspace: null,
|
|
24625
24625
|
config: {
|
|
24626
|
-
project:
|
|
24627
|
-
global:
|
|
24626
|
+
project: join50(resolve31(deps.projectRoot), "av.yaml"),
|
|
24627
|
+
global: resolve31(deps.globalConfigPath),
|
|
24628
24628
|
saved: false
|
|
24629
24629
|
},
|
|
24630
24630
|
chief: {
|
|
@@ -25105,7 +25105,7 @@ var init_container_step = __esm(() => {
|
|
|
25105
25105
|
});
|
|
25106
25106
|
|
|
25107
25107
|
// src/setup/metric-step.ts
|
|
25108
|
-
import { isAbsolute as
|
|
25108
|
+
import { isAbsolute as isAbsolute19 } from "node:path";
|
|
25109
25109
|
async function text12(message, initialValue, validate) {
|
|
25110
25110
|
const value = await text10({
|
|
25111
25111
|
message: `${message} (:back goes back)`,
|
|
@@ -25189,7 +25189,7 @@ async function stepMetrics(ctx) {
|
|
|
25189
25189
|
draft.token_env = token;
|
|
25190
25190
|
} else {
|
|
25191
25191
|
const file = await text12("Repository-relative JSON file", old?.file ?? "metrics/revenue.json", (value) => {
|
|
25192
|
-
if (!value || value.length > 2000 ||
|
|
25192
|
+
if (!value || value.length > 2000 || isAbsolute19(value) || /^[A-Za-z]:/.test(value) || value.startsWith("\\") || value.split(/[\\/]/).includes(".."))
|
|
25193
25193
|
return "Use a relative file inside the repository, without ..";
|
|
25194
25194
|
});
|
|
25195
25195
|
if (navigated2(file))
|
|
@@ -27647,8 +27647,8 @@ var init_issue = __esm(() => {
|
|
|
27647
27647
|
|
|
27648
27648
|
// src/login.ts
|
|
27649
27649
|
import { existsSync as existsSync9, mkdirSync as mkdirSync4, readFileSync as readFileSync11, writeFileSync as writeFileSync5 } from "node:fs";
|
|
27650
|
-
import { homedir as
|
|
27651
|
-
import { join as
|
|
27650
|
+
import { homedir as homedir10 } from "node:os";
|
|
27651
|
+
import { join as join51 } from "node:path";
|
|
27652
27652
|
function ensureConfigDir() {
|
|
27653
27653
|
if (!existsSync9(CONFIG_DIR)) {
|
|
27654
27654
|
mkdirSync4(CONFIG_DIR, { recursive: true, mode: 448 });
|
|
@@ -27823,8 +27823,8 @@ var import_picocolors14, CONFIG_DIR, CREDENTIALS_FILE;
|
|
|
27823
27823
|
var init_login = __esm(() => {
|
|
27824
27824
|
init_dist6();
|
|
27825
27825
|
import_picocolors14 = __toESM(require_picocolors(), 1);
|
|
27826
|
-
CONFIG_DIR =
|
|
27827
|
-
CREDENTIALS_FILE =
|
|
27826
|
+
CONFIG_DIR = join51(homedir10(), ".agent-valley");
|
|
27827
|
+
CREDENTIALS_FILE = join51(CONFIG_DIR, "credentials.json");
|
|
27828
27828
|
});
|
|
27829
27829
|
|
|
27830
27830
|
// src/index.ts
|
|
@@ -27832,7 +27832,7 @@ init_project_config_path();
|
|
|
27832
27832
|
init_yaml_loader();
|
|
27833
27833
|
import { spawn as spawn24, spawnSync as spawnSync5 } from "node:child_process";
|
|
27834
27834
|
import { existsSync as existsSync10, unlinkSync as unlinkSync2 } from "node:fs";
|
|
27835
|
-
import { resolve as
|
|
27835
|
+
import { resolve as resolve32 } from "node:path";
|
|
27836
27836
|
|
|
27837
27837
|
// ../../packages/core/src/version.ts
|
|
27838
27838
|
import { readFileSync as readFileSync2 } from "node:fs";
|
|
@@ -29894,7 +29894,7 @@ var import_picocolors15 = __toESM(require_picocolors(), 1);
|
|
|
29894
29894
|
|
|
29895
29895
|
// src/agent-client-commands.ts
|
|
29896
29896
|
init_client_integrations();
|
|
29897
|
-
import { resolve as
|
|
29897
|
+
import { resolve as resolve22 } from "node:path";
|
|
29898
29898
|
|
|
29899
29899
|
// src/mcp-oauth.ts
|
|
29900
29900
|
init_webapi();
|
|
@@ -48245,7 +48245,7 @@ async function startAvMcpHttp(api, options) {
|
|
|
48245
48245
|
// src/mission-api.ts
|
|
48246
48246
|
import { randomUUID as randomUUID17 } from "node:crypto";
|
|
48247
48247
|
import { lstat as lstat15, readdir as readdir8, realpath as realpath21 } from "node:fs/promises";
|
|
48248
|
-
import { isAbsolute as
|
|
48248
|
+
import { isAbsolute as isAbsolute13, join as join38 } from "node:path";
|
|
48249
48249
|
|
|
48250
48250
|
// ../../packages/core/src/chief/reports.ts
|
|
48251
48251
|
init_zod();
|
|
@@ -66567,7 +66567,7 @@ async function launchMission(input) {
|
|
|
66567
66567
|
// src/operation-api.ts
|
|
66568
66568
|
import { randomUUID as randomUUID16 } from "node:crypto";
|
|
66569
66569
|
import { realpath as realpath20 } from "node:fs/promises";
|
|
66570
|
-
import { join as
|
|
66570
|
+
import { join as join37 } from "node:path";
|
|
66571
66571
|
|
|
66572
66572
|
// ../../packages/core/src/chief/continuous-store.ts
|
|
66573
66573
|
import { randomUUID as randomUUID9 } from "node:crypto";
|
|
@@ -66774,7 +66774,7 @@ class ContinuousOperationStore {
|
|
|
66774
66774
|
import { execFile as execFile5 } from "node:child_process";
|
|
66775
66775
|
import { randomUUID as randomUUID15 } from "node:crypto";
|
|
66776
66776
|
import { mkdir as mkdir17, realpath as realpath19, rename as rename7, unlink as unlink7, writeFile as writeFile13 } from "node:fs/promises";
|
|
66777
|
-
import { join as
|
|
66777
|
+
import { join as join36, resolve as resolve20 } from "node:path";
|
|
66778
66778
|
import { promisify as promisify2 } from "node:util";
|
|
66779
66779
|
|
|
66780
66780
|
// ../../packages/core/src/chief/container-observation-command.ts
|
|
@@ -67771,7 +67771,7 @@ async function createContinuousMissionWorkspace(repositoryRoot, operationId, bas
|
|
|
67771
67771
|
init_execution();
|
|
67772
67772
|
|
|
67773
67773
|
// src/chief-continuous-decision.ts
|
|
67774
|
-
import { join as
|
|
67774
|
+
import { join as join35 } from "node:path";
|
|
67775
67775
|
|
|
67776
67776
|
// ../../packages/core/src/chief/coordinator-run.ts
|
|
67777
67777
|
init_execution();
|
|
@@ -67866,13 +67866,13 @@ init_execution();
|
|
|
67866
67866
|
|
|
67867
67867
|
// ../../packages/core/src/chief/runtime.ts
|
|
67868
67868
|
import { randomUUID as randomUUID11 } from "node:crypto";
|
|
67869
|
-
import { join as
|
|
67869
|
+
import { join as join28, resolve as resolve16 } from "node:path";
|
|
67870
67870
|
|
|
67871
67871
|
// ../../packages/core/src/oma/receipt-adapter.ts
|
|
67872
67872
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
67873
|
-
import { existsSync as existsSync4, lstatSync as
|
|
67873
|
+
import { existsSync as existsSync4, lstatSync as lstatSync3, readFileSync as readFileSync9 } from "node:fs";
|
|
67874
67874
|
import { mkdir as mkdir12, writeFile as writeFile9 } from "node:fs/promises";
|
|
67875
|
-
import { isAbsolute as
|
|
67875
|
+
import { basename as basename2, dirname as dirname7, isAbsolute as isAbsolute8, join as join26, relative as relative8, resolve as resolve15, sep as sep10 } from "node:path";
|
|
67876
67876
|
|
|
67877
67877
|
// ../../packages/core/src/config/workflow-router.ts
|
|
67878
67878
|
import { readFileSync as readFileSync8 } from "node:fs";
|
|
@@ -68188,27 +68188,107 @@ function ensureLatestOmaCli(options = {}) {
|
|
|
68188
68188
|
return pending;
|
|
68189
68189
|
}
|
|
68190
68190
|
|
|
68191
|
+
// ../../packages/core/src/oma/receipt-storage.ts
|
|
68192
|
+
import { createHash as createHash16 } from "node:crypto";
|
|
68193
|
+
import { lstatSync as lstatSync2, readdirSync, realpathSync as realpathSync5 } from "node:fs";
|
|
68194
|
+
import { homedir as homedir6 } from "node:os";
|
|
68195
|
+
import { basename, dirname as dirname6, isAbsolute as isAbsolute7, join as join25, relative as relative7, resolve as resolve14, sep as sep9 } from "node:path";
|
|
68196
|
+
var OMA_RUN_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
68197
|
+
function absolutePath(value, key) {
|
|
68198
|
+
if (!isAbsolute7(value) || Array.from(value).some((character) => character.charCodeAt(0) < 32 || character.charCodeAt(0) === 127))
|
|
68199
|
+
throw new Error(`${key} must be an absolute path without control characters`);
|
|
68200
|
+
return resolve14(value);
|
|
68201
|
+
}
|
|
68202
|
+
function omaReceiptDirectories(workspace, options = {}) {
|
|
68203
|
+
const env = options.env ?? process.env;
|
|
68204
|
+
const profile = env.OMA_PROFILE ?? "0";
|
|
68205
|
+
if (!/^(0|[1-9][0-9]{0,9})$/.test(profile))
|
|
68206
|
+
throw new Error("OMA_PROFILE must be a non-negative profile number");
|
|
68207
|
+
const stateHome = env.OMA_STATE_HOME === undefined ? absolutePath(env.OMA_HOME || join25(options.home ?? homedir6(), ".oma"), "OMA_HOME") : absolutePath(env.OMA_STATE_HOME, "OMA_STATE_HOME");
|
|
68208
|
+
const project = createHash16("sha256").update(realpathSync5(resolve14(workspace))).digest("hex");
|
|
68209
|
+
return [
|
|
68210
|
+
join25(stateHome, "u", profile, "projects", project, "agent-runs"),
|
|
68211
|
+
...profile === "0" ? [join25(resolve14(workspace), ".agents", "state", "agent-runs")] : []
|
|
68212
|
+
];
|
|
68213
|
+
}
|
|
68214
|
+
function regularDirectory(path) {
|
|
68215
|
+
try {
|
|
68216
|
+
const stat = lstatSync2(path);
|
|
68217
|
+
if (!stat.isDirectory() || stat.isSymbolicLink())
|
|
68218
|
+
throw new Error("OMA receipt directory is not a regular directory");
|
|
68219
|
+
return true;
|
|
68220
|
+
} catch (error) {
|
|
68221
|
+
if (error.code === "ENOENT")
|
|
68222
|
+
return false;
|
|
68223
|
+
throw error;
|
|
68224
|
+
}
|
|
68225
|
+
}
|
|
68226
|
+
function validateDirectory(directory, workspace) {
|
|
68227
|
+
if (!regularDirectory(directory))
|
|
68228
|
+
return false;
|
|
68229
|
+
const legacy = join25(resolve14(workspace), ".agents", "state", "agent-runs");
|
|
68230
|
+
const boundary = directory === legacy ? resolve14(workspace) : dirname6(dirname6(dirname6(dirname6(dirname6(directory)))));
|
|
68231
|
+
const components = relative7(boundary, directory).split(sep9).filter(Boolean);
|
|
68232
|
+
let path = boundary;
|
|
68233
|
+
for (const component of components) {
|
|
68234
|
+
path = join25(path, component);
|
|
68235
|
+
if (!regularDirectory(path))
|
|
68236
|
+
throw new Error("OMA receipt directory changed during inspection");
|
|
68237
|
+
}
|
|
68238
|
+
return true;
|
|
68239
|
+
}
|
|
68240
|
+
function listOmaRunFiles(workspace, options = {}) {
|
|
68241
|
+
return omaReceiptDirectories(workspace, options).flatMap((directory) => {
|
|
68242
|
+
if (!validateDirectory(directory, workspace))
|
|
68243
|
+
return [];
|
|
68244
|
+
return readdirSync(directory).filter((name) => name.endsWith(".json") && OMA_RUN_ID.test(name.slice(0, -5))).map((name) => join25(directory, name));
|
|
68245
|
+
});
|
|
68246
|
+
}
|
|
68247
|
+
function resolveOmaReceiptPath(workspace, entry, options = {}) {
|
|
68248
|
+
const name = basename(entry);
|
|
68249
|
+
if (!name.endsWith(".json") || !OMA_RUN_ID.test(name.slice(0, -5)))
|
|
68250
|
+
throw new Error("Invalid receipt filename");
|
|
68251
|
+
if (entry === name)
|
|
68252
|
+
return join25(resolve14(workspace), ".agents", "state", "agent-runs", name);
|
|
68253
|
+
if (!isAbsolute7(entry) || resolve14(entry) !== entry)
|
|
68254
|
+
throw new Error("Invalid receipt path");
|
|
68255
|
+
if (!omaReceiptDirectories(workspace, options).includes(dirname6(entry)))
|
|
68256
|
+
throw new Error("OMA receipt is outside the selected project/profile");
|
|
68257
|
+
if (!validateDirectory(dirname6(entry), workspace))
|
|
68258
|
+
throw new Error("OMA receipt directory is missing");
|
|
68259
|
+
return entry;
|
|
68260
|
+
}
|
|
68261
|
+
|
|
68191
68262
|
// ../../packages/core/src/oma/receipt-adapter.ts
|
|
68192
68263
|
var OMA_RECEIPT_SCHEMA_VERSION = 1;
|
|
68193
|
-
var RUN_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
68194
68264
|
var HASH = /^[a-f0-9]{64}$/;
|
|
68195
|
-
|
|
68196
|
-
|
|
68197
|
-
|
|
68198
|
-
|
|
68199
|
-
}
|
|
68200
|
-
|
|
68201
|
-
|
|
68202
|
-
|
|
68203
|
-
|
|
68204
|
-
|
|
68205
|
-
|
|
68206
|
-
|
|
68207
|
-
|
|
68208
|
-
|
|
68209
|
-
|
|
68210
|
-
|
|
68211
|
-
|
|
68265
|
+
function createOmaEvidenceIO(options = {}) {
|
|
68266
|
+
const env = { ...options.env ?? process.env, OMA_SKIP_VERSION_CHECK: "1" };
|
|
68267
|
+
if (options.home !== undefined && !env.OMA_HOME)
|
|
68268
|
+
env.OMA_HOME = join26(options.home, ".oma");
|
|
68269
|
+
const storage = { ...options, env };
|
|
68270
|
+
return {
|
|
68271
|
+
listRunFiles: (workspacePath) => listOmaRunFiles(workspacePath, storage),
|
|
68272
|
+
resolveRunFile: (workspacePath, entry) => resolveOmaReceiptPath(workspacePath, entry, storage),
|
|
68273
|
+
readReceipt: (path) => {
|
|
68274
|
+
if (!lstatSync3(path).isFile())
|
|
68275
|
+
throw new Error("Receipt is not a regular file");
|
|
68276
|
+
return readFileSync9(path, "utf-8");
|
|
68277
|
+
},
|
|
68278
|
+
runCli: (args, cwd) => {
|
|
68279
|
+
const result = spawnSync2("oma", args, {
|
|
68280
|
+
cwd,
|
|
68281
|
+
env,
|
|
68282
|
+
encoding: "utf-8",
|
|
68283
|
+
timeout: 15000,
|
|
68284
|
+
maxBuffer: 1024 * 1024
|
|
68285
|
+
});
|
|
68286
|
+
if (result.error)
|
|
68287
|
+
throw result.error;
|
|
68288
|
+
return { exitCode: result.status, stdout: result.stdout };
|
|
68289
|
+
}
|
|
68290
|
+
};
|
|
68291
|
+
}
|
|
68212
68292
|
function fail(reason) {
|
|
68213
68293
|
return { ok: false, reason };
|
|
68214
68294
|
}
|
|
@@ -68232,17 +68312,17 @@ async function prepareOmaAttempt(request, dependencies = {}) {
|
|
|
68232
68312
|
const routed = routeIssue(`${request.issue.title}
|
|
68233
68313
|
${request.issue.description ?? ""}`, table);
|
|
68234
68314
|
for (const workflow of routed.workflows) {
|
|
68235
|
-
const file =
|
|
68315
|
+
const file = join26(request.workspace.path, ".agents", "workflows", `${workflow}.md`);
|
|
68236
68316
|
if (!existsSync4(file))
|
|
68237
68317
|
throw new Error(`OMA workflow file missing in target worktree: ${file}`);
|
|
68238
68318
|
}
|
|
68239
68319
|
await ensureLatestOmaCli({ io: dependencies.latestCliIO });
|
|
68240
|
-
const path =
|
|
68320
|
+
const path = join26(request.workspace.path, ".agents", "results", `plan-${request.attempt.id}.json`);
|
|
68241
68321
|
const plan = {
|
|
68242
68322
|
session_id: request.attempt.id,
|
|
68243
68323
|
lineage_id: request.attempt.id,
|
|
68244
68324
|
valley_issue_id: request.issue.id,
|
|
68245
|
-
valley_workspace:
|
|
68325
|
+
valley_workspace: resolve15(request.workspace.path),
|
|
68246
68326
|
tasks: [
|
|
68247
68327
|
{
|
|
68248
68328
|
id: request.attempt.id,
|
|
@@ -68262,7 +68342,7 @@ ${request.issue.description ?? ""}`, table);
|
|
|
68262
68342
|
}
|
|
68263
68343
|
]
|
|
68264
68344
|
};
|
|
68265
|
-
await mkdir12(
|
|
68345
|
+
await mkdir12(join26(request.workspace.path, ".agents", "results"), { recursive: true });
|
|
68266
68346
|
await writeFile9(path, JSON.stringify(plan, null, 2), { encoding: "utf-8", flag: "wx" });
|
|
68267
68347
|
return path;
|
|
68268
68348
|
}
|
|
@@ -68290,8 +68370,8 @@ function buildOmaGuidance(request) {
|
|
|
68290
68370
|
].join(`
|
|
68291
68371
|
`);
|
|
68292
68372
|
}
|
|
68293
|
-
function validateOmaEvidence(request, io =
|
|
68294
|
-
const root =
|
|
68373
|
+
function validateOmaEvidence(request, io = createOmaEvidenceIO()) {
|
|
68374
|
+
const root = resolve15(request.workspace.path);
|
|
68295
68375
|
if (!request.verifyCommand.trim())
|
|
68296
68376
|
return fail("Strict OMA mode has no configured verify command");
|
|
68297
68377
|
let cliVersion;
|
|
@@ -68305,26 +68385,37 @@ function validateOmaEvidence(request, io = defaultIO2) {
|
|
|
68305
68385
|
return fail(`OMA CLI unavailable: ${String(err)}`);
|
|
68306
68386
|
}
|
|
68307
68387
|
let receipts;
|
|
68388
|
+
const locations = new Map;
|
|
68308
68389
|
try {
|
|
68309
|
-
receipts = io.listRunFiles(root).map((
|
|
68310
|
-
|
|
68390
|
+
receipts = io.listRunFiles(root).map((entry) => {
|
|
68391
|
+
const name = basename2(entry);
|
|
68392
|
+
const path = (io.resolveRunFile ?? resolveOmaReceiptPath)(root, entry);
|
|
68393
|
+
if (!OMA_RUN_ID.test(name.slice(0, -5)) || !name.endsWith(".json"))
|
|
68311
68394
|
throw new Error("Invalid receipt filename");
|
|
68312
|
-
const parsed = JSON.parse(io.readReceipt(
|
|
68395
|
+
const parsed = JSON.parse(io.readReceipt(path));
|
|
68313
68396
|
if (!isRecord(parsed) || parsed.runId !== name.slice(0, -5))
|
|
68314
68397
|
throw new Error("Malformed run receipt");
|
|
68398
|
+
locations.set(parsed, dirname7(path));
|
|
68315
68399
|
return parsed;
|
|
68316
68400
|
});
|
|
68317
68401
|
} catch (err) {
|
|
68318
68402
|
return fail(`Missing or malformed OMA receipt: ${String(err)}`);
|
|
68319
68403
|
}
|
|
68320
|
-
const forAttempt = receipts.filter((run) => run.sessionId === request.attempt.id && run.agentId === request.agentId)
|
|
68404
|
+
const forAttempt = receipts.filter((run) => run.sessionId === request.attempt.id && run.agentId === request.agentId);
|
|
68405
|
+
if (forAttempt.some((run) => !Number.isSafeInteger(run.sequence) || Number(run.sequence) < 1))
|
|
68406
|
+
return fail("OMA receipt sequence is malformed");
|
|
68407
|
+
if (new Set(forAttempt.map((run) => run.sequence)).size !== forAttempt.length)
|
|
68408
|
+
return fail("OMA receipt sequence is ambiguous across matching runs");
|
|
68409
|
+
if (new Set(forAttempt.map((run) => locations.get(run))).size > 1)
|
|
68410
|
+
return fail("Matching OMA receipts span multiple stores; generate current evidence in the active CLI's selected project/profile");
|
|
68411
|
+
forAttempt.sort((a, b) => Number(a.sequence) - Number(b.sequence));
|
|
68321
68412
|
const run = forAttempt.at(-1);
|
|
68322
68413
|
if (!run)
|
|
68323
68414
|
return fail("No OMA receipt is bound to this Valley attempt");
|
|
68324
68415
|
if (run.schemaVersion !== OMA_RECEIPT_SCHEMA_VERSION) {
|
|
68325
68416
|
return fail(`OMA CLI ${cliVersion} returned an unsupported receipt schema. AV requires agent-run schema v${OMA_RECEIPT_SCHEMA_VERSION}; update AV and OMA (npm install -g oh-my-agent@latest), then generate and verify a compatible receipt.`);
|
|
68326
68417
|
}
|
|
68327
|
-
if (run.taskId !== request.attempt.id || !
|
|
68418
|
+
if (run.taskId !== request.attempt.id || !OMA_RUN_ID.test(String(run.runId))) {
|
|
68328
68419
|
return fail("OMA receipt task identity is incompatible");
|
|
68329
68420
|
}
|
|
68330
68421
|
if (run.workspace !== root || run.artifactRoot !== root || run.status !== "completed" || run.exitCode !== 0) {
|
|
@@ -68358,12 +68449,12 @@ function validateOmaEvidence(request, io = defaultIO2) {
|
|
|
68358
68449
|
if (!template?.includes("{{attempt.id}}"))
|
|
68359
68450
|
return fail("Analysis requires a configured current-attempt report path");
|
|
68360
68451
|
const expanded = template.replaceAll("{{attempt.id}}", request.attempt.id);
|
|
68361
|
-
const target =
|
|
68362
|
-
const subpath =
|
|
68363
|
-
if (
|
|
68452
|
+
const target = resolve15(root, expanded);
|
|
68453
|
+
const subpath = relative8(root, target);
|
|
68454
|
+
if (isAbsolute8(expanded) || expanded.split(/[\\/]/).includes("..") || subpath === "" || subpath === ".." || subpath.startsWith(`..${sep10}`) || isAbsolute8(subpath)) {
|
|
68364
68455
|
return fail("Configured analysis report escapes the workspace");
|
|
68365
68456
|
}
|
|
68366
|
-
if (!isRecord(run.artifacts) || !Object.entries(run.artifacts).some(([path, hash]) => !
|
|
68457
|
+
if (!isRecord(run.artifacts) || !Object.entries(run.artifacts).some(([path, hash]) => !isAbsolute8(path) && !path.split(/[\\/]/).includes("..") && resolve15(root, path) === target && HASH.test(String(hash)))) {
|
|
68367
68458
|
return fail("OMA receipt does not bind the configured current-attempt report");
|
|
68368
68459
|
}
|
|
68369
68460
|
}
|
|
@@ -68380,7 +68471,7 @@ function validateOmaEvidence(request, io = defaultIO2) {
|
|
|
68380
68471
|
for (const check of run.checks) {
|
|
68381
68472
|
if (!isRecord(check) || !stringArray(check.command) || !check.command.length || typeof check.cwd !== "string")
|
|
68382
68473
|
return fail("OMA verification receipt is malformed");
|
|
68383
|
-
latestChecks.set(JSON.stringify([check.command,
|
|
68474
|
+
latestChecks.set(JSON.stringify([check.command, resolve15(check.cwd)]), check);
|
|
68384
68475
|
}
|
|
68385
68476
|
if ([...latestChecks.values()].some((check) => check.exitCode !== 0 || check.before !== run.after || check.after !== run.after)) {
|
|
68386
68477
|
return fail("An OMA verification check failed or is stale");
|
|
@@ -69103,7 +69194,7 @@ async function withMissionDeadline(mission, parent, run) {
|
|
|
69103
69194
|
init_dist();
|
|
69104
69195
|
import { constants as constants6 } from "node:fs";
|
|
69105
69196
|
import { lstat as lstat11, mkdir as mkdir13, open as open8, readdir as readdir6, realpath as realpath14, stat, writeFile as writeFile10 } from "node:fs/promises";
|
|
69106
|
-
import { isAbsolute as
|
|
69197
|
+
import { isAbsolute as isAbsolute9, join as join27, relative as relative9, sep as sep11 } from "node:path";
|
|
69107
69198
|
var MAX_SKILL_BYTES = 256000;
|
|
69108
69199
|
var MAX_METADATA_BYTES = 16384;
|
|
69109
69200
|
var MAX_CATALOG_SIZE = 100;
|
|
@@ -69112,8 +69203,8 @@ var MAX_HARNESS_ENTRIES = 5000;
|
|
|
69112
69203
|
var SKILL_NAME = /^[a-z0-9][a-z0-9-]{0,127}$/;
|
|
69113
69204
|
var OMA_SKILL_NAME = /^oma-[a-z0-9][a-z0-9-]{0,123}$/;
|
|
69114
69205
|
function inside(root, path) {
|
|
69115
|
-
const child =
|
|
69116
|
-
return child !== "" && child !== ".." && !child.startsWith(`..${
|
|
69206
|
+
const child = relative9(root, path);
|
|
69207
|
+
return child !== "" && child !== ".." && !child.startsWith(`..${sep11}`) && !isAbsolute9(child);
|
|
69117
69208
|
}
|
|
69118
69209
|
function excludedResource(name) {
|
|
69119
69210
|
return [
|
|
@@ -69136,11 +69227,11 @@ async function prepareMissionSkills(sourceRepositoryPath, workspacePath) {
|
|
|
69136
69227
|
if (!source)
|
|
69137
69228
|
return;
|
|
69138
69229
|
const workspace = await realpath14(workspacePath);
|
|
69139
|
-
const agents =
|
|
69230
|
+
const agents = join27(workspace, ".agents");
|
|
69140
69231
|
await mkdir13(agents, { recursive: true });
|
|
69141
69232
|
if (!inside(workspace, await realpath14(agents)))
|
|
69142
69233
|
throw new Error("The target .agents directory escapes the mission worktree. Fix its symlink before creating this order.");
|
|
69143
|
-
const target =
|
|
69234
|
+
const target = join27(agents, "skills");
|
|
69144
69235
|
await mkdir13(target, { recursive: true });
|
|
69145
69236
|
const targetRoot = await skillRoot(workspace);
|
|
69146
69237
|
if (!targetRoot)
|
|
@@ -69161,13 +69252,13 @@ async function prepareMissionSkills(sourceRepositoryPath, workspacePath) {
|
|
|
69161
69252
|
continue;
|
|
69162
69253
|
if (++entries > MAX_HARNESS_ENTRIES)
|
|
69163
69254
|
throw new Error("The installed skill resources exceed 5,000 entries. Remove unused resources before creating this order.");
|
|
69164
|
-
const from = await realpath14(
|
|
69255
|
+
const from = await realpath14(join27(sourceDirectory, name)).catch(() => {
|
|
69165
69256
|
return;
|
|
69166
69257
|
});
|
|
69167
69258
|
if (!from || !inside(sourceRoot, from))
|
|
69168
69259
|
continue;
|
|
69169
69260
|
const info = await stat(from);
|
|
69170
|
-
const to =
|
|
69261
|
+
const to = join27(targetDirectory, name);
|
|
69171
69262
|
const existing = await lstat11(to).catch(() => {
|
|
69172
69263
|
return;
|
|
69173
69264
|
});
|
|
@@ -69222,7 +69313,7 @@ async function skillRoot(workspacePath) {
|
|
|
69222
69313
|
});
|
|
69223
69314
|
if (!workspace)
|
|
69224
69315
|
return;
|
|
69225
|
-
const root = await realpath14(
|
|
69316
|
+
const root = await realpath14(join27(workspace, ".agents", "skills")).catch(() => {
|
|
69226
69317
|
return;
|
|
69227
69318
|
});
|
|
69228
69319
|
if (!root)
|
|
@@ -69236,7 +69327,7 @@ async function skillRoot(workspacePath) {
|
|
|
69236
69327
|
async function skillPath(root, name) {
|
|
69237
69328
|
if (!SKILL_NAME.test(name))
|
|
69238
69329
|
throw new Error(`Invalid skill name: ${name}. Select an installed skill directory name.`);
|
|
69239
|
-
const path = await realpath14(
|
|
69330
|
+
const path = await realpath14(join27(root, name, "SKILL.md")).catch(() => {
|
|
69240
69331
|
throw new Error(`Skill ${name}/SKILL.md is missing. Restore that installed skill in ${root} before resuming.`);
|
|
69241
69332
|
});
|
|
69242
69333
|
if (!inside(root, path))
|
|
@@ -69292,7 +69383,7 @@ function metadata(source, name, path) {
|
|
|
69292
69383
|
async function descriptor(root, name) {
|
|
69293
69384
|
if (!OMA_SKILL_NAME.test(name))
|
|
69294
69385
|
return;
|
|
69295
|
-
const directory = await realpath14(
|
|
69386
|
+
const directory = await realpath14(join27(root, name));
|
|
69296
69387
|
if (!inside(root, directory) || !(await stat(directory)).isDirectory())
|
|
69297
69388
|
return;
|
|
69298
69389
|
const path = await skillPath(root, name);
|
|
@@ -69549,7 +69640,7 @@ class ChiefRuntime {
|
|
|
69549
69640
|
workspace,
|
|
69550
69641
|
availableSkills: mission.availableSkills?.map((skill) => ({
|
|
69551
69642
|
...skill,
|
|
69552
|
-
path:
|
|
69643
|
+
path: join28(workspace.path, ".agents", "skills", skill.name, "SKILL.md")
|
|
69553
69644
|
}))
|
|
69554
69645
|
};
|
|
69555
69646
|
if (signal?.aborted)
|
|
@@ -69574,7 +69665,7 @@ class ChiefRuntime {
|
|
|
69574
69665
|
const attempt = {
|
|
69575
69666
|
id: randomUUID11(),
|
|
69576
69667
|
issueId: mission.id,
|
|
69577
|
-
workspacePath:
|
|
69668
|
+
workspacePath: resolve16(workspace.path),
|
|
69578
69669
|
startedAt: new Date().toISOString(),
|
|
69579
69670
|
finishedAt: null,
|
|
69580
69671
|
exitCode: null,
|
|
@@ -69780,16 +69871,16 @@ init_execution();
|
|
|
69780
69871
|
// src/chief-supervisor.ts
|
|
69781
69872
|
import { spawn as spawn16 } from "node:child_process";
|
|
69782
69873
|
import { randomUUID as randomUUID13 } from "node:crypto";
|
|
69783
|
-
import { join as
|
|
69874
|
+
import { join as join32 } from "node:path";
|
|
69784
69875
|
init_execution();
|
|
69785
69876
|
|
|
69786
69877
|
// src/chief-delivery.ts
|
|
69787
|
-
import { createHash as
|
|
69878
|
+
import { createHash as createHash18 } from "node:crypto";
|
|
69788
69879
|
import { mkdir as mkdir15, writeFile as writeFile12 } from "node:fs/promises";
|
|
69789
|
-
import { join as
|
|
69880
|
+
import { join as join31 } from "node:path";
|
|
69790
69881
|
|
|
69791
69882
|
// ../../packages/core/src/chief/report-delivery.ts
|
|
69792
|
-
import { join as
|
|
69883
|
+
import { join as join30 } from "node:path";
|
|
69793
69884
|
|
|
69794
69885
|
// ../../packages/core/src/chief/report-delivery-adapters.ts
|
|
69795
69886
|
init_report_delivery_contract();
|
|
@@ -70170,10 +70261,10 @@ init_report_delivery_contract();
|
|
|
70170
70261
|
// ../../packages/core/src/chief/report-delivery-outbox.ts
|
|
70171
70262
|
init_zod();
|
|
70172
70263
|
init_report_delivery_contract();
|
|
70173
|
-
import { createHash as
|
|
70264
|
+
import { createHash as createHash17, randomUUID as randomUUID12 } from "node:crypto";
|
|
70174
70265
|
import { constants as constants7 } from "node:fs";
|
|
70175
70266
|
import { mkdir as mkdir14, open as open9, readdir as readdir7, readFile as readFile11, realpath as realpath15, rename as rename6, unlink as unlink5, writeFile as writeFile11 } from "node:fs/promises";
|
|
70176
|
-
import { isAbsolute as
|
|
70267
|
+
import { isAbsolute as isAbsolute10, join as join29, relative as relative10, resolve as resolve17 } from "node:path";
|
|
70177
70268
|
var hash3 = string2().regex(/^[a-f0-9]{64}$/);
|
|
70178
70269
|
var outboxRecordSchema = strictObject({
|
|
70179
70270
|
version: literal(1),
|
|
@@ -70197,7 +70288,7 @@ var outboxRecordSchema = strictObject({
|
|
|
70197
70288
|
message: string2().max(1000)
|
|
70198
70289
|
}).refine((record) => record.nextPart <= record.parts && (record.status !== "delivered" || record.nextPart === record.parts));
|
|
70199
70290
|
function sha2562(content) {
|
|
70200
|
-
return
|
|
70291
|
+
return createHash17("sha256").update(content).digest("hex");
|
|
70201
70292
|
}
|
|
70202
70293
|
function receipt(record) {
|
|
70203
70294
|
const {
|
|
@@ -70215,12 +70306,12 @@ function receipt(record) {
|
|
|
70215
70306
|
class ReportOutbox {
|
|
70216
70307
|
directory;
|
|
70217
70308
|
constructor(stateDir) {
|
|
70218
|
-
this.directory =
|
|
70309
|
+
this.directory = join29(stateDir, "report-outbox");
|
|
70219
70310
|
}
|
|
70220
70311
|
path(id) {
|
|
70221
70312
|
if (!hash3.safeParse(id).success)
|
|
70222
70313
|
throw new Error("Invalid report receipt ID. Use av reports to find a receipt.");
|
|
70223
|
-
return
|
|
70314
|
+
return join29(this.directory, `${id}.json`);
|
|
70224
70315
|
}
|
|
70225
70316
|
lock(id) {
|
|
70226
70317
|
return new MissionStore(this.directory).lock(id);
|
|
@@ -70276,10 +70367,10 @@ async function verifiedAttachment(attachment, artifactRoot, readBytes) {
|
|
|
70276
70367
|
try {
|
|
70277
70368
|
const root = await realpath15(artifactRoot);
|
|
70278
70369
|
const path = await realpath15(attachment.path);
|
|
70279
|
-
const local =
|
|
70280
|
-
if (!local || local.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) || local === ".." ||
|
|
70370
|
+
const local = relative10(root, path);
|
|
70371
|
+
if (!local || local.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) || local === ".." || isAbsolute10(local))
|
|
70281
70372
|
throw failure;
|
|
70282
|
-
if (
|
|
70373
|
+
if (resolve17(attachment.path) !== attachment.path)
|
|
70283
70374
|
throw failure;
|
|
70284
70375
|
const file = await open9(attachment.path, constants7.O_RDONLY | constants7.O_NOFOLLOW);
|
|
70285
70376
|
try {
|
|
@@ -70287,7 +70378,7 @@ async function verifiedAttachment(attachment, artifactRoot, readBytes) {
|
|
|
70287
70378
|
if (!stat.isFile() || stat.size !== attachment.sizeBytes)
|
|
70288
70379
|
throw failure;
|
|
70289
70380
|
if (!readBytes) {
|
|
70290
|
-
const digest =
|
|
70381
|
+
const digest = createHash17("sha256");
|
|
70291
70382
|
for await (const chunk of file.createReadStream({ autoClose: false }))
|
|
70292
70383
|
digest.update(chunk);
|
|
70293
70384
|
if (digest.digest("hex") !== attachment.sha256)
|
|
@@ -70334,7 +70425,7 @@ function dependencies(stateDir, overrides) {
|
|
|
70334
70425
|
env: overrides.env ?? process.env,
|
|
70335
70426
|
registry: { ...createReportChannelRegistry(fetch2), ...overrides.registry },
|
|
70336
70427
|
attachments: overrides.attachments ?? [],
|
|
70337
|
-
artifactRoot: overrides.artifactRoot ??
|
|
70428
|
+
artifactRoot: overrides.artifactRoot ?? join30(stateDir, "captures"),
|
|
70338
70429
|
now: overrides.now ?? (() => new Date)
|
|
70339
70430
|
};
|
|
70340
70431
|
}
|
|
@@ -70515,8 +70606,8 @@ init_chief_schema();
|
|
|
70515
70606
|
init_yaml_loader();
|
|
70516
70607
|
async function saveAndDeliverMissionReport(mission, root) {
|
|
70517
70608
|
const repository = mission.repositoryRoot ?? root;
|
|
70518
|
-
const directory =
|
|
70519
|
-
const reportPath =
|
|
70609
|
+
const directory = join31(root, ".agent-valley/reports");
|
|
70610
|
+
const reportPath = join31(directory, `${mission.id}.md`);
|
|
70520
70611
|
const report = renderReport(mission);
|
|
70521
70612
|
await mkdir15(directory, { recursive: true, mode: 448 });
|
|
70522
70613
|
await writeFile12(reportPath, report, { mode: 384 });
|
|
@@ -70531,12 +70622,12 @@ ${explanation.eli5}`);
|
|
|
70531
70622
|
try {
|
|
70532
70623
|
const config = mergeChiefConfig(loadGlobalConfig()?.chief, loadProjectConfig(root)?.chief);
|
|
70533
70624
|
const attachments = [...mission.capture?.attachments ?? []];
|
|
70534
|
-
const artifactRoot =
|
|
70625
|
+
const artifactRoot = join31(repository, ".agent-valley/captures");
|
|
70535
70626
|
if (config.reporting?.destinations.length) {
|
|
70536
70627
|
const bytes = Buffer.from(report);
|
|
70537
|
-
const sha256 =
|
|
70538
|
-
const reportDirectory =
|
|
70539
|
-
const attachmentPath =
|
|
70628
|
+
const sha256 = createHash18("sha256").update(bytes).digest("hex");
|
|
70629
|
+
const reportDirectory = join31(artifactRoot, mission.id);
|
|
70630
|
+
const attachmentPath = join31(reportDirectory, `report-${sha256}.md`);
|
|
70540
70631
|
await mkdir15(reportDirectory, { recursive: true, mode: 448 });
|
|
70541
70632
|
await writeFile12(attachmentPath, bytes, { mode: 384 });
|
|
70542
70633
|
attachments.push({
|
|
@@ -70547,7 +70638,7 @@ ${explanation.eli5}`);
|
|
|
70547
70638
|
sha256
|
|
70548
70639
|
});
|
|
70549
70640
|
}
|
|
70550
|
-
const receipts = await dispatchMissionReport(mission, report, reportPath, config.reporting,
|
|
70641
|
+
const receipts = await dispatchMissionReport(mission, report, reportPath, config.reporting, join31(repository, ".agent-valley"), {
|
|
70551
70642
|
attachments,
|
|
70552
70643
|
artifactRoot
|
|
70553
70644
|
});
|
|
@@ -70637,7 +70728,7 @@ function runWorker(args, root, signal) {
|
|
|
70637
70728
|
async function superviseOrder(goal, options, root, dependencies = {}) {
|
|
70638
70729
|
assertNotManagedRun();
|
|
70639
70730
|
const id = options.resume ?? options.missionId ?? randomUUID13();
|
|
70640
|
-
const store = new MissionStore(
|
|
70731
|
+
const store = new MissionStore(join32(root, ".agent-valley/missions"));
|
|
70641
70732
|
const controller = new AbortController;
|
|
70642
70733
|
const interrupt = () => controller.abort();
|
|
70643
70734
|
dependencies.signal?.addEventListener("abort", interrupt, { once: true });
|
|
@@ -70818,7 +70909,7 @@ Return one valid JSON object under the original charter and pinned evidence.` :
|
|
|
70818
70909
|
init_metric_source_policy();
|
|
70819
70910
|
import { constants as constants8 } from "node:fs";
|
|
70820
70911
|
import { lstat as lstat12, open as open10, realpath as realpath16 } from "node:fs/promises";
|
|
70821
|
-
import { isAbsolute as
|
|
70912
|
+
import { isAbsolute as isAbsolute11, relative as relative11, resolve as resolve18, sep as sep12 } from "node:path";
|
|
70822
70913
|
var MAX_METRIC_RESPONSE_BYTES = 2000000;
|
|
70823
70914
|
function metricSourceEnvironment(request, name) {
|
|
70824
70915
|
if (!name || !request.env[name]?.trim())
|
|
@@ -70903,15 +70994,15 @@ var jsonFileMetricAdapter = {
|
|
|
70903
70994
|
async collect(request) {
|
|
70904
70995
|
const root = await realpath16(request.repositoryRoot);
|
|
70905
70996
|
const name = request.source.file;
|
|
70906
|
-
if (!name ||
|
|
70997
|
+
if (!name || isAbsolute11(name))
|
|
70907
70998
|
throw new MetricSourceError("Metric file must be relative to the source repository. Set chief.metric_sources.sources[].file in av.yaml.");
|
|
70908
|
-
const path =
|
|
70909
|
-
const within =
|
|
70910
|
-
if (!within || within.startsWith(`..${
|
|
70999
|
+
const path = resolve18(root, name);
|
|
71000
|
+
const within = relative11(root, path);
|
|
71001
|
+
if (!within || within.startsWith(`..${sep12}`) || within === ".." || isAbsolute11(within))
|
|
70911
71002
|
throw new MetricSourceError("Metric file escapes the source repository. Choose a repository-relative JSON file.");
|
|
70912
71003
|
let current = root;
|
|
70913
|
-
for (const part of within.split(
|
|
70914
|
-
current =
|
|
71004
|
+
for (const part of within.split(sep12)) {
|
|
71005
|
+
current = resolve18(current, part);
|
|
70915
71006
|
if ((await lstat12(current)).isSymbolicLink())
|
|
70916
71007
|
throw new MetricSourceError("Metric file and parent directories must not be symlinks. Choose a regular JSON file inside the source repository.");
|
|
70917
71008
|
}
|
|
@@ -71318,7 +71409,7 @@ function createMissionMetricPorts(repository, mission, dependencies = {}) {
|
|
|
71318
71409
|
import { randomUUID as randomUUID14 } from "node:crypto";
|
|
71319
71410
|
import { constants as constants9 } from "node:fs";
|
|
71320
71411
|
import { link as link2, lstat as lstat13, mkdir as mkdir16, open as open11, realpath as realpath17, unlink as unlink6 } from "node:fs/promises";
|
|
71321
|
-
import { join as
|
|
71412
|
+
import { join as join33 } from "node:path";
|
|
71322
71413
|
init_dist2();
|
|
71323
71414
|
init_client_toml();
|
|
71324
71415
|
var maximumBytes = 1024 * 1024;
|
|
@@ -71337,7 +71428,7 @@ async function assertLocalPath(root, local) {
|
|
|
71337
71428
|
const parts = local.split("/");
|
|
71338
71429
|
let current = root;
|
|
71339
71430
|
for (const [index, part] of parts.entries()) {
|
|
71340
|
-
current =
|
|
71431
|
+
current = join33(current, part);
|
|
71341
71432
|
const stats = await lstat13(current).catch((error) => {
|
|
71342
71433
|
if (error.code === "ENOENT")
|
|
71343
71434
|
return;
|
|
@@ -71394,9 +71485,9 @@ async function privateExclude(original, target, paths) {
|
|
|
71394
71485
|
]);
|
|
71395
71486
|
const common = targetCommon.trim();
|
|
71396
71487
|
const path = exclude.trim();
|
|
71397
|
-
if (common !==
|
|
71488
|
+
if (common !== join33(target, ".git") && common !== originalCommon.trim() || path !== join33(common, "info", "exclude") || await realpath17(common) !== common)
|
|
71398
71489
|
throw new ChiefToolConfigError("Chief MCP configuration requires the workspace's own Git metadata or its original repository's shared worktree metadata.");
|
|
71399
|
-
const info =
|
|
71490
|
+
const info = join33(common, "info");
|
|
71400
71491
|
const infoStats = await lstat13(info).catch((error) => {
|
|
71401
71492
|
if (error.code === "ENOENT")
|
|
71402
71493
|
return;
|
|
@@ -71435,14 +71526,14 @@ async function prepareToolConfig(originalRepository, targetWorkspace) {
|
|
|
71435
71526
|
continue;
|
|
71436
71527
|
if (!await assertLocalPath(original, config.path))
|
|
71437
71528
|
continue;
|
|
71438
|
-
const content = selectedNamespace(await readPrivateFile(
|
|
71529
|
+
const content = selectedNamespace(await readPrivateFile(join33(original, config.path)), config.namespace, config.toml);
|
|
71439
71530
|
if (content)
|
|
71440
71531
|
selected.push({ path: config.path, content });
|
|
71441
71532
|
}
|
|
71442
71533
|
if (!selected.length)
|
|
71443
71534
|
return;
|
|
71444
71535
|
for (const root of [original, target]) {
|
|
71445
|
-
const stats = await lstat13(
|
|
71536
|
+
const stats = await lstat13(join33(root, ".git"));
|
|
71446
71537
|
if (stats.isSymbolicLink() || !stats.isFile() && !stats.isDirectory() || await realpath17((await parallelGit(root, ["rev-parse", "--show-toplevel"])).trim()) !== root)
|
|
71447
71538
|
throw new ChiefToolConfigError("Chief MCP tools require original local Git repository metadata. Restore the workspace before starting Chief.");
|
|
71448
71539
|
}
|
|
@@ -71450,14 +71541,14 @@ async function prepareToolConfig(originalRepository, targetWorkspace) {
|
|
|
71450
71541
|
for (const config of selected) {
|
|
71451
71542
|
const parts = config.path.split("/");
|
|
71452
71543
|
if (parts.length > 1) {
|
|
71453
|
-
const parent =
|
|
71544
|
+
const parent = join33(target, ...parts.slice(0, -1));
|
|
71454
71545
|
await mkdir16(parent, { recursive: true, mode: 448 });
|
|
71455
71546
|
if (await realpath17(parent) !== parent)
|
|
71456
71547
|
throw new ChiefToolConfigError("Chief MCP configuration parent redirects through a symlink. Restore its local directory.");
|
|
71457
71548
|
}
|
|
71458
71549
|
if (await assertLocalPath(target, config.path))
|
|
71459
71550
|
continue;
|
|
71460
|
-
const path =
|
|
71551
|
+
const path = join33(target, config.path);
|
|
71461
71552
|
const temporary = `${path}.av-mcp-${randomUUID14()}.tmp`;
|
|
71462
71553
|
const file = await open11(temporary, "wx", 384);
|
|
71463
71554
|
try {
|
|
@@ -71490,8 +71581,8 @@ async function prepareChiefToolConfig(originalRepository, targetWorkspace) {
|
|
|
71490
71581
|
init_client_toml();
|
|
71491
71582
|
import { constants as constants10 } from "node:fs";
|
|
71492
71583
|
import { access, lstat as lstat14, readFile as readFile12, realpath as realpath18 } from "node:fs/promises";
|
|
71493
|
-
import { homedir as
|
|
71494
|
-
import { delimiter as delimiter2, isAbsolute as
|
|
71584
|
+
import { homedir as homedir7 } from "node:os";
|
|
71585
|
+
import { delimiter as delimiter2, isAbsolute as isAbsolute12, join as join34, resolve as resolve19 } from "node:path";
|
|
71495
71586
|
var binaries = [
|
|
71496
71587
|
"docker",
|
|
71497
71588
|
"orb",
|
|
@@ -71507,9 +71598,9 @@ var binaries = [
|
|
|
71507
71598
|
var MAX_CONFIG_BYTES = 1048576;
|
|
71508
71599
|
var record4 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
71509
71600
|
async function executable(name, env) {
|
|
71510
|
-
for (const directory of (env.PATH ?? "").split(delimiter2).filter(
|
|
71601
|
+
for (const directory of (env.PATH ?? "").split(delimiter2).filter(isAbsolute12)) {
|
|
71511
71602
|
try {
|
|
71512
|
-
const path =
|
|
71603
|
+
const path = join34(directory, name);
|
|
71513
71604
|
await access(path, constants10.X_OK);
|
|
71514
71605
|
if ((await lstat14(await realpath18(path))).isFile())
|
|
71515
71606
|
return true;
|
|
@@ -71563,7 +71654,7 @@ async function mcpNames(path, scope, project, requestedRoot) {
|
|
|
71563
71654
|
}
|
|
71564
71655
|
async function discoverTools(root, dependencies = {}) {
|
|
71565
71656
|
const env = dependencies.env ?? process.env;
|
|
71566
|
-
const home = dependencies.home ??
|
|
71657
|
+
const home = dependencies.home ?? homedir7();
|
|
71567
71658
|
const project = await realpath18(root);
|
|
71568
71659
|
const projectFiles = [
|
|
71569
71660
|
".mcp.json",
|
|
@@ -71574,11 +71665,11 @@ async function discoverTools(root, dependencies = {}) {
|
|
|
71574
71665
|
".codex/config.toml"
|
|
71575
71666
|
];
|
|
71576
71667
|
const userFiles = [".claude.json", ".cursor/mcp.json", ".qwen/settings.json", ".gemini/settings.json"];
|
|
71577
|
-
const codexHome = env.CODEX_HOME &&
|
|
71668
|
+
const codexHome = env.CODEX_HOME && isAbsolute12(env.CODEX_HOME) ? env.CODEX_HOME : join34(home, ".codex");
|
|
71578
71669
|
const configs = [
|
|
71579
|
-
...projectFiles.map((path) => ({ path:
|
|
71580
|
-
...userFiles.map((path) => ({ path:
|
|
71581
|
-
{ path:
|
|
71670
|
+
...projectFiles.map((path) => ({ path: join34(project, path), scope: "project" })),
|
|
71671
|
+
...userFiles.map((path) => ({ path: resolve19(home, path), scope: "user" })),
|
|
71672
|
+
{ path: join34(codexHome, "config.toml"), scope: "user" }
|
|
71582
71673
|
];
|
|
71583
71674
|
const [cli, mcp] = await Promise.all([
|
|
71584
71675
|
Promise.all(binaries.map(async (name) => ({
|
|
@@ -71590,7 +71681,7 @@ async function discoverTools(root, dependencies = {}) {
|
|
|
71590
71681
|
availability: await executable(name, env) ? "available" : "unavailable",
|
|
71591
71682
|
reason: "Executable presence only; service access, daemon state and login are unverified."
|
|
71592
71683
|
}))),
|
|
71593
|
-
Promise.all(configs.map(({ path, scope }) => mcpNames(path, scope, project,
|
|
71684
|
+
Promise.all(configs.map(({ path, scope }) => mcpNames(path, scope, project, resolve19(root))))
|
|
71594
71685
|
]);
|
|
71595
71686
|
return [...cli, ...mcp.flat()];
|
|
71596
71687
|
}
|
|
@@ -71625,7 +71716,7 @@ function continuousDecisionPrompt(operation, mission, tools, previousReport) {
|
|
|
71625
71716
|
async function decideContinuousGoal(operation, decisionId, root, dependencies = {}) {
|
|
71626
71717
|
if (!operation.baseline)
|
|
71627
71718
|
throw new Error("An accepted operation baseline is required before selecting a goal.");
|
|
71628
|
-
const store = new MissionStore(
|
|
71719
|
+
const store = new MissionStore(join35(root, ".agent-valley", "operation-decisions", operation.id));
|
|
71629
71720
|
const unlock = await store.lock(decisionId);
|
|
71630
71721
|
const runtime = (dependencies.runtime ?? ((storage, signal) => new ChiefRuntime(storage, signal)))(store, dependencies.signal);
|
|
71631
71722
|
let mission;
|
|
@@ -71734,7 +71825,7 @@ async function decideContinuousGoal(operation, decisionId, root, dependencies =
|
|
|
71734
71825
|
const previousId = operation.history.at(-1)?.missionId;
|
|
71735
71826
|
let previousReport;
|
|
71736
71827
|
if (previousId) {
|
|
71737
|
-
const previous = await new MissionStore(
|
|
71828
|
+
const previous = await new MissionStore(join35(root, ".agent-valley", "missions")).load(previousId);
|
|
71738
71829
|
if (previous.repositoryRoot !== operation.repositoryRoot || previous.status !== "completed")
|
|
71739
71830
|
throw new Error("The previous accepted child's evidence no longer matches this operation. Restore its saved checkpoint before selecting another goal.");
|
|
71740
71831
|
previousReport = renderReport(previous).slice(0, 16000);
|
|
@@ -71793,7 +71884,7 @@ function integerOption(value, name, maximum) {
|
|
|
71793
71884
|
return number;
|
|
71794
71885
|
}
|
|
71795
71886
|
function operationStore(root) {
|
|
71796
|
-
return new ContinuousOperationStore(
|
|
71887
|
+
return new ContinuousOperationStore(join36(resolve20(root), ".agent-valley", "operations"));
|
|
71797
71888
|
}
|
|
71798
71889
|
async function restoreOperationOrigin(repository, workspace) {
|
|
71799
71890
|
const env = { ...process.env, ...clearedGitEnvironment };
|
|
@@ -71849,7 +71940,7 @@ async function newOperation(charter, options, root, id) {
|
|
|
71849
71940
|
...config.executionPolicy.maxEstimatedCostUsd !== undefined ? { cost: String(config.executionPolicy.maxEstimatedCostUsd) } : {}
|
|
71850
71941
|
});
|
|
71851
71942
|
if (typeof settings.actors === "string")
|
|
71852
|
-
settings.actors =
|
|
71943
|
+
settings.actors = resolve20(root, settings.actors);
|
|
71853
71944
|
const now = new Date().toISOString();
|
|
71854
71945
|
return operationSchema.parse({
|
|
71855
71946
|
id,
|
|
@@ -71911,9 +72002,9 @@ function renderOperationReport(operation) {
|
|
|
71911
72002
|
`);
|
|
71912
72003
|
}
|
|
71913
72004
|
async function saveOperationReport(root, operation) {
|
|
71914
|
-
const directory =
|
|
72005
|
+
const directory = join36(root, ".agent-valley", "operation-reports");
|
|
71915
72006
|
await mkdir17(directory, { recursive: true, mode: 448 });
|
|
71916
|
-
const path =
|
|
72007
|
+
const path = join36(directory, `${operation.id}.md`);
|
|
71917
72008
|
const temporary = `${path}.${randomUUID15()}.tmp`;
|
|
71918
72009
|
try {
|
|
71919
72010
|
await writeFile13(temporary, renderOperationReport(operation), { mode: 384, flag: "wx" });
|
|
@@ -71948,7 +72039,7 @@ async function runOperation(charter, options, root = process.cwd(), dependencies
|
|
|
71948
72039
|
if (decisionBudgetKeys.some((key) => options[key] !== undefined)) {
|
|
71949
72040
|
if (operation.currentMissionId || !operation.decisionId)
|
|
71950
72041
|
throw new Error("Operation resume budget reconciliation applies only to an active decision checkpoint. Adjust the current child's budget with av order --resume <child-id>.");
|
|
71951
|
-
const decisions = new MissionStore(
|
|
72042
|
+
const decisions = new MissionStore(join36(root, ".agent-valley", "operation-decisions", operation.id));
|
|
71952
72043
|
const unlockDecision = await decisions.lock(operation.decisionId);
|
|
71953
72044
|
try {
|
|
71954
72045
|
const decision = await decisions.load(operation.decisionId);
|
|
@@ -71994,7 +72085,7 @@ async function runOperation(charter, options, root = process.cwd(), dependencies
|
|
|
71994
72085
|
console.log(`Operation ${id}
|
|
71995
72086
|
Charter: ${operation.charter}
|
|
71996
72087
|
Resume: av order --resume ${id}`);
|
|
71997
|
-
const missions = new MissionStore(
|
|
72088
|
+
const missions = new MissionStore(join36(root, ".agent-valley", "missions"));
|
|
71998
72089
|
return await runContinuousOperation(operation, {
|
|
71999
72090
|
signal: controller.signal,
|
|
72000
72091
|
...dependencies.now ? { now: dependencies.now } : {},
|
|
@@ -72102,7 +72193,7 @@ class OperationApi {
|
|
|
72102
72193
|
this.root = root;
|
|
72103
72194
|
this.workspace = workspace;
|
|
72104
72195
|
this.dependencies = dependencies;
|
|
72105
|
-
this.store = new ContinuousOperationStore(
|
|
72196
|
+
this.store = new ContinuousOperationStore(join37(root, ".agent-valley/operations"));
|
|
72106
72197
|
this.jobs = new MissionJobs(root, "operation-jobs");
|
|
72107
72198
|
}
|
|
72108
72199
|
order(raw) {
|
|
@@ -72340,17 +72431,17 @@ class MissionApi {
|
|
|
72340
72431
|
this.projectRoot = projectRoot;
|
|
72341
72432
|
this.workspace = workspace;
|
|
72342
72433
|
this.dependencies = dependencies;
|
|
72343
|
-
this.store = new MissionStore(
|
|
72434
|
+
this.store = new MissionStore(join38(projectRoot, ".agent-valley/missions"));
|
|
72344
72435
|
this.jobs = new MissionJobs(projectRoot);
|
|
72345
72436
|
this.operationApi = new OperationApi(projectRoot, workspace, dependencies);
|
|
72346
72437
|
this.operationJobs = new MissionJobs(projectRoot, "operation-jobs");
|
|
72347
72438
|
}
|
|
72348
72439
|
static async create(workspace, dependencies = {}) {
|
|
72349
|
-
if (!
|
|
72440
|
+
if (!isAbsolute13(workspace))
|
|
72350
72441
|
throw new Error("Set an absolute Git repository path in av mcp --workspace <path>.");
|
|
72351
72442
|
const projectRoot = await realpath21(workspace);
|
|
72352
72443
|
const target = loadProjectConfig(projectRoot)?.workspace?.root ?? projectRoot;
|
|
72353
|
-
if (!
|
|
72444
|
+
if (!isAbsolute13(target))
|
|
72354
72445
|
throw new Error("Set workspace.root in av.yaml to an absolute Git repository path.");
|
|
72355
72446
|
return new MissionApi(projectRoot, await realpath21(target), dependencies);
|
|
72356
72447
|
}
|
|
@@ -72379,7 +72470,7 @@ class MissionApi {
|
|
|
72379
72470
|
async order(raw) {
|
|
72380
72471
|
assertNotManagedRun(this.dependencies.env);
|
|
72381
72472
|
const input = mcpOrderSchema.parse(raw);
|
|
72382
|
-
if (input.workspace && (!
|
|
72473
|
+
if (input.workspace && (!isAbsolute13(input.workspace) || await realpath21(input.workspace) !== this.workspace))
|
|
72383
72474
|
throw new Error("This AV server is bound to another workspace. Start av mcp --workspace for the target repository.");
|
|
72384
72475
|
return this.serializeOrder(async () => {
|
|
72385
72476
|
if (input.requestId) {
|
|
@@ -72402,7 +72493,7 @@ class MissionApi {
|
|
|
72402
72493
|
async list() {
|
|
72403
72494
|
this.assertOpen();
|
|
72404
72495
|
await ensureAvDirectory(this.projectRoot, ["missions"]);
|
|
72405
|
-
const ids = new Set((await readdir8(
|
|
72496
|
+
const ids = new Set((await readdir8(join38(this.projectRoot, ".agent-valley/missions"))).filter((name) => name.endsWith(".json")).map((name) => missionIdSchema.parse(name.slice(0, -5))));
|
|
72406
72497
|
for (const job of await this.jobs.list())
|
|
72407
72498
|
ids.add(job.missionId);
|
|
72408
72499
|
return {
|
|
@@ -72556,7 +72647,7 @@ class MissionApi {
|
|
|
72556
72647
|
async load(id) {
|
|
72557
72648
|
await ensureAvDirectory(this.projectRoot, ["missions"]);
|
|
72558
72649
|
try {
|
|
72559
|
-
const path =
|
|
72650
|
+
const path = join38(this.projectRoot, ".agent-valley/missions", `${missionIdSchema.parse(id)}.json`);
|
|
72560
72651
|
const stat = await lstat15(path);
|
|
72561
72652
|
if (!stat.isFile() || stat.isSymbolicLink())
|
|
72562
72653
|
throw new Error(`Mission record must be a regular file: ${path}. Remove the symlink before retrying.`);
|
|
@@ -72582,7 +72673,7 @@ class MissionApi {
|
|
|
72582
72673
|
init_client_integrations_assets();
|
|
72583
72674
|
init_client_integrations_files();
|
|
72584
72675
|
import { lstat as lstat16, readdir as readdir9, realpath as realpath22 } from "node:fs/promises";
|
|
72585
|
-
import { dirname as
|
|
72676
|
+
import { dirname as dirname8, join as join39, relative as relative12, resolve as resolve21 } from "node:path";
|
|
72586
72677
|
|
|
72587
72678
|
// src/plugin-assets.ts
|
|
72588
72679
|
import { copyFile as copyFile2, mkdir as mkdir18, readFile as readFile13 } from "node:fs/promises";
|
|
@@ -72749,7 +72840,7 @@ async function projectDirectory(workspace) {
|
|
|
72749
72840
|
if (typeof workspace !== "string" || !workspace.trim())
|
|
72750
72841
|
throw new Error("Pass --workspace /absolute/AV-project to bind every exported MCP server to its AV configuration.");
|
|
72751
72842
|
try {
|
|
72752
|
-
const project = await realpath22(
|
|
72843
|
+
const project = await realpath22(resolve21(workspace));
|
|
72753
72844
|
if (!(await lstat16(project)).isDirectory())
|
|
72754
72845
|
throw new Error("not a directory");
|
|
72755
72846
|
return project;
|
|
@@ -72772,7 +72863,7 @@ function remoteEndpoint(value) {
|
|
|
72772
72863
|
async function outputDirectory(output) {
|
|
72773
72864
|
if (typeof output !== "string" || !output.trim())
|
|
72774
72865
|
throw new Error("Pass --output /absolute/export-directory to write the generated AV plugin packages.");
|
|
72775
|
-
const target =
|
|
72866
|
+
const target = resolve21(output);
|
|
72776
72867
|
let ancestor = target;
|
|
72777
72868
|
for (;; ) {
|
|
72778
72869
|
try {
|
|
@@ -72781,11 +72872,11 @@ async function outputDirectory(output) {
|
|
|
72781
72872
|
throw exportConflict(ancestor, "symbolic link exports are not modified");
|
|
72782
72873
|
if (!info.isDirectory())
|
|
72783
72874
|
throw exportConflict(ancestor, "expected an output directory");
|
|
72784
|
-
return
|
|
72875
|
+
return join39(await realpath22(ancestor), relative12(ancestor, target));
|
|
72785
72876
|
} catch (error) {
|
|
72786
72877
|
if (error.code !== "ENOENT")
|
|
72787
72878
|
throw error;
|
|
72788
|
-
ancestor =
|
|
72879
|
+
ancestor = dirname8(ancestor);
|
|
72789
72880
|
}
|
|
72790
72881
|
}
|
|
72791
72882
|
}
|
|
@@ -72800,13 +72891,13 @@ async function outputFiles(root, directory = root) {
|
|
|
72800
72891
|
}
|
|
72801
72892
|
const files = [];
|
|
72802
72893
|
for (const entry of entries) {
|
|
72803
|
-
const path =
|
|
72894
|
+
const path = join39(directory, entry.name);
|
|
72804
72895
|
if (entry.isSymbolicLink())
|
|
72805
72896
|
throw exportConflict(path, "symbolic links are not modified");
|
|
72806
72897
|
if (entry.isDirectory())
|
|
72807
72898
|
files.push(...await outputFiles(root, path));
|
|
72808
72899
|
else if (entry.isFile())
|
|
72809
|
-
files.push(
|
|
72900
|
+
files.push(relative12(root, path).split("\\").join("/"));
|
|
72810
72901
|
else
|
|
72811
72902
|
throw exportConflict(path, "expected regular export files");
|
|
72812
72903
|
}
|
|
@@ -72837,21 +72928,21 @@ async function exportPluginPackages(options) {
|
|
|
72837
72928
|
if (output === workspace)
|
|
72838
72929
|
throw exportConflict(output, "the output directory must be separate from the AV project root");
|
|
72839
72930
|
const { manifest } = await loadPluginManifestAsset(options.sourceManifest ? [options.sourceManifest] : undefined);
|
|
72840
|
-
const { content: skill } = await loadClientSkillAsset(options.sourceSkillRoot ? [
|
|
72931
|
+
const { content: skill } = await loadClientSkillAsset(options.sourceSkillRoot ? [join39(options.sourceSkillRoot, "SKILL.md")] : clientSkillAssetCandidates());
|
|
72841
72932
|
const { content: license } = await loadPluginLicenseAsset(options.sourceLicense ? [options.sourceLicense] : undefined);
|
|
72842
72933
|
const packageFiles = pluginPackageFiles(manifest, skill, license, { workspace, remoteUrl });
|
|
72843
|
-
const receipt = await integrationFile(output,
|
|
72934
|
+
const receipt = await integrationFile(output, join39(output, receiptName2), "", 384);
|
|
72844
72935
|
const hashes = ownedFileHashes(receipt.before, receipt.path);
|
|
72845
72936
|
const existing = await outputFiles(output);
|
|
72846
72937
|
for (const path of existing) {
|
|
72847
72938
|
if (path === receiptName2)
|
|
72848
72939
|
continue;
|
|
72849
72940
|
if (!packageFiles.has(path) || hashes[path] === undefined)
|
|
72850
|
-
throw exportConflict(
|
|
72941
|
+
throw exportConflict(join39(output, path), "unowned files are retained");
|
|
72851
72942
|
}
|
|
72852
72943
|
const files = [];
|
|
72853
72944
|
for (const [path, content] of packageFiles) {
|
|
72854
|
-
const file = await integrationFile(output,
|
|
72945
|
+
const file = await integrationFile(output, join39(output, path), content, 420);
|
|
72855
72946
|
if (hashes[path] !== undefined && (file.before === null || contentHash(file.before) !== hashes[path]))
|
|
72856
72947
|
throw exportConflict(file.path, "the exported file was changed or removed locally");
|
|
72857
72948
|
if (hashes[path] === undefined && file.before !== null)
|
|
@@ -72870,11 +72961,11 @@ async function exportPluginPackages(options) {
|
|
|
72870
72961
|
transport: remoteUrl ? "streamable-http" : "stdio",
|
|
72871
72962
|
files: await applyIntegrationFiles(output, [...files, receipt]),
|
|
72872
72963
|
packages: {
|
|
72873
|
-
portable:
|
|
72874
|
-
claude:
|
|
72875
|
-
cursor:
|
|
72876
|
-
qwen:
|
|
72877
|
-
antigravity:
|
|
72964
|
+
portable: join39(output, "portable/av"),
|
|
72965
|
+
claude: join39(output, "claude/plugins/av"),
|
|
72966
|
+
cursor: join39(output, "cursor/plugins/av"),
|
|
72967
|
+
qwen: join39(output, "qwen/av"),
|
|
72968
|
+
antigravity: join39(output, "antigravity/av")
|
|
72878
72969
|
}
|
|
72879
72970
|
};
|
|
72880
72971
|
}
|
|
@@ -72907,7 +72998,7 @@ function registerAgentClientCommands(program) {
|
|
|
72907
72998
|
].some((value) => value !== undefined))
|
|
72908
72999
|
throw new Error("OAuth gateway options require av mcp --http. Omit them to use local stdio.");
|
|
72909
73000
|
const oauth = options.http ? resolveMcpOAuthOptions(options) : undefined;
|
|
72910
|
-
const project =
|
|
73001
|
+
const project = resolve22(options.workspace);
|
|
72911
73002
|
const api = await MissionApi.create(project);
|
|
72912
73003
|
const workspace = api.targetWorkspace;
|
|
72913
73004
|
try {
|
|
@@ -72937,7 +73028,7 @@ function registerAgentClientCommands(program) {
|
|
|
72937
73028
|
// src/chief.ts
|
|
72938
73029
|
import { randomUUID as randomUUID19 } from "node:crypto";
|
|
72939
73030
|
import { realpath as realpath23 } from "node:fs/promises";
|
|
72940
|
-
import { join as
|
|
73031
|
+
import { join as join41 } from "node:path";
|
|
72941
73032
|
|
|
72942
73033
|
// ../../packages/core/src/chief/coordinator-container.ts
|
|
72943
73034
|
init_execution();
|
|
@@ -73825,14 +73916,14 @@ init_execution();
|
|
|
73825
73916
|
|
|
73826
73917
|
// ../../packages/core/src/workspace/delivery-strategy.ts
|
|
73827
73918
|
init_logger();
|
|
73828
|
-
import { lstatSync as
|
|
73919
|
+
import { lstatSync as lstatSync4 } from "node:fs";
|
|
73829
73920
|
|
|
73830
73921
|
// ../../packages/core/src/workspace/isolated-branch-import.ts
|
|
73831
73922
|
init_worktree_lifecycle();
|
|
73832
73923
|
import { randomUUID as randomUUID18 } from "node:crypto";
|
|
73833
73924
|
import { mkdtemp, rm as rm5 } from "node:fs/promises";
|
|
73834
73925
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
73835
|
-
import { join as
|
|
73926
|
+
import { join as join40 } from "node:path";
|
|
73836
73927
|
async function importIsolatedBranch(workspace, root) {
|
|
73837
73928
|
if (!isIsolatedGitWorkspace(workspace))
|
|
73838
73929
|
return null;
|
|
@@ -73879,7 +73970,7 @@ async function importIsolatedBranch(workspace, root) {
|
|
|
73879
73970
|
`).filter(Boolean);
|
|
73880
73971
|
if (commits.length === 0)
|
|
73881
73972
|
return null;
|
|
73882
|
-
temporaryWorktree = await mkdtemp(
|
|
73973
|
+
temporaryWorktree = await mkdtemp(join40(tmpdir3(), "av-branch-import-"));
|
|
73883
73974
|
const added = await runCommand("git", ["worktree", "add", "--detach", temporaryWorktree, currentHead], {
|
|
73884
73975
|
cwd: root
|
|
73885
73976
|
});
|
|
@@ -74152,7 +74243,7 @@ function gitFailure(action, result, fix) {
|
|
|
74152
74243
|
}
|
|
74153
74244
|
function linkedWorktreePath(workspace) {
|
|
74154
74245
|
try {
|
|
74155
|
-
return
|
|
74246
|
+
return lstatSync4(`${workspace.path}/.git`).isFile() ? workspace.path : null;
|
|
74156
74247
|
} catch {
|
|
74157
74248
|
return null;
|
|
74158
74249
|
}
|
|
@@ -74459,7 +74550,7 @@ async function runOrder(goal, options, root = process.cwd()) {
|
|
|
74459
74550
|
assertNotManagedRun();
|
|
74460
74551
|
if (!options.resume && [options.retry, options.resolveEffect, options.effectResult, options.accountRun, options.accountCost].some((value) => value !== undefined && value !== false))
|
|
74461
74552
|
throw new Error("Use --resume <id> for retry, external-effect resolution or cost reconciliation.");
|
|
74462
|
-
const store = new MissionStore(
|
|
74553
|
+
const store = new MissionStore(join41(root, ".agent-valley/missions"));
|
|
74463
74554
|
const id = options.resume ?? options.missionId ?? randomUUID19();
|
|
74464
74555
|
const unlock = await store.lock(id);
|
|
74465
74556
|
const abortController = new AbortController;
|
|
@@ -74637,7 +74728,7 @@ async function dispatchOrder(goal, options, root = process.cwd(), dependencies =
|
|
|
74637
74728
|
};
|
|
74638
74729
|
const [operation, mission] = await Promise.all([
|
|
74639
74730
|
operationStore(root).load(options.resume).catch(missing),
|
|
74640
|
-
new MissionStore(
|
|
74731
|
+
new MissionStore(join41(root, ".agent-valley", "missions")).load(options.resume).catch(missing)
|
|
74641
74732
|
]);
|
|
74642
74733
|
if (operation && mission)
|
|
74643
74734
|
throw new Error(`Saved ID ${options.resume} names both an operation and a mission. Use --once to resume the mission; inspect av operations before resuming the operation.`);
|
|
@@ -74695,7 +74786,7 @@ function registerChiefCommands(program) {
|
|
|
74695
74786
|
process.once("SIGTERM", stop);
|
|
74696
74787
|
try {
|
|
74697
74788
|
while (!controller.signal.aborted) {
|
|
74698
|
-
const store = new MissionStore(
|
|
74789
|
+
const store = new MissionStore(join41(process.cwd(), ".agent-valley/missions"));
|
|
74699
74790
|
for (const mission of await store.list()) {
|
|
74700
74791
|
if (controller.signal.aborted)
|
|
74701
74792
|
break;
|
|
@@ -74718,7 +74809,7 @@ function registerChiefCommands(program) {
|
|
|
74718
74809
|
}
|
|
74719
74810
|
return;
|
|
74720
74811
|
}
|
|
74721
|
-
const missions = await new MissionStore(
|
|
74812
|
+
const missions = await new MissionStore(join41(process.cwd(), ".agent-valley/missions")).list();
|
|
74722
74813
|
if (!missions.length)
|
|
74723
74814
|
console.log("No orders yet. Run bun av order --help.");
|
|
74724
74815
|
for (const mission of missions) {
|
|
@@ -74731,17 +74822,17 @@ function registerChiefCommands(program) {
|
|
|
74731
74822
|
|
|
74732
74823
|
// src/chief-organization.ts
|
|
74733
74824
|
import { readFile as readFile15, stat as stat2 } from "node:fs/promises";
|
|
74734
|
-
import { isAbsolute as
|
|
74825
|
+
import { isAbsolute as isAbsolute14, join as join42, resolve as resolve23 } from "node:path";
|
|
74735
74826
|
init_chief_schema();
|
|
74736
74827
|
init_yaml_loader();
|
|
74737
74828
|
function organizationRepository(root, workspace) {
|
|
74738
74829
|
const repository = workspace ?? loadProjectConfig(root)?.workspace?.root ?? root;
|
|
74739
|
-
if (!
|
|
74830
|
+
if (!isAbsolute14(repository))
|
|
74740
74831
|
throw new Error("Set workspace.root in av.yaml or --workspace to an absolute source repository path.");
|
|
74741
74832
|
return repository;
|
|
74742
74833
|
}
|
|
74743
74834
|
async function inputFile(file) {
|
|
74744
|
-
const path =
|
|
74835
|
+
const path = resolve23(file);
|
|
74745
74836
|
const info = await stat2(path);
|
|
74746
74837
|
if (!info.isFile() || info.size > 2000000)
|
|
74747
74838
|
throw new Error("Use a regular JSON input file no larger than 2 MB.");
|
|
@@ -74785,22 +74876,22 @@ function registerOrganizationCommands(program) {
|
|
|
74785
74876
|
});
|
|
74786
74877
|
const reports = program.command("reports").description("Inspect and retry third-party report attachments");
|
|
74787
74878
|
reports.command("list").option("--workspace <path>", "Source repository").action(async (opts) => {
|
|
74788
|
-
console.log(JSON.stringify(await listReportDeliveries(
|
|
74879
|
+
console.log(JSON.stringify(await listReportDeliveries(join42(organizationRepository(process.cwd(), opts.workspace), ".agent-valley")), null, 2));
|
|
74789
74880
|
});
|
|
74790
74881
|
reports.command("retry").option("--workspace <path>", "Source repository").action(async (opts) => {
|
|
74791
74882
|
const config = mergeChiefConfig(loadGlobalConfig()?.chief, loadProjectConfig()?.chief);
|
|
74792
74883
|
if (!config.reporting)
|
|
74793
74884
|
throw new Error("Set chief.reporting.destinations in av.yaml before retrying reports.");
|
|
74794
|
-
console.log(JSON.stringify(await retryPendingReports(config.reporting,
|
|
74885
|
+
console.log(JSON.stringify(await retryPendingReports(config.reporting, join42(organizationRepository(process.cwd(), opts.workspace), ".agent-valley")), null, 2));
|
|
74795
74886
|
});
|
|
74796
74887
|
}
|
|
74797
74888
|
|
|
74798
74889
|
// src/config-watch.ts
|
|
74799
74890
|
init_project_config_path();
|
|
74800
|
-
import { resolve as
|
|
74891
|
+
import { resolve as resolve26 } from "node:path";
|
|
74801
74892
|
async function watchConfig(root, globalPath, onChange) {
|
|
74802
74893
|
await Promise.resolve().then(() => init_chokidar());
|
|
74803
|
-
const watcher = watch([
|
|
74894
|
+
const watcher = watch([resolve26(root, PROJECT_CONFIG_FILENAME), globalPath], { ignoreInitial: true });
|
|
74804
74895
|
watcher.on("all", (event, path) => {
|
|
74805
74896
|
if (["add", "change", "unlink"].includes(event))
|
|
74806
74897
|
onChange(path);
|
|
@@ -74816,10 +74907,10 @@ var import_picocolors = __toESM(require_picocolors(), 1);
|
|
|
74816
74907
|
init_project_config_path();
|
|
74817
74908
|
init_yaml_loader();
|
|
74818
74909
|
init_doctor_checks();
|
|
74819
|
-
import { join as
|
|
74910
|
+
import { join as join46 } from "node:path";
|
|
74820
74911
|
|
|
74821
74912
|
// src/doctor-oma-checks.ts
|
|
74822
|
-
import { join as
|
|
74913
|
+
import { join as join45 } from "node:path";
|
|
74823
74914
|
function checkOma(project, deps) {
|
|
74824
74915
|
const strict = project?.oma?.mode === "strict";
|
|
74825
74916
|
const order = !!project && !project.tracker && !project.linear && !project.github;
|
|
@@ -74907,7 +74998,7 @@ function checkOma(project, deps) {
|
|
|
74907
74998
|
fix: "Set verify.command to a deterministic non-build check in av.yaml before using oma.mode: strict.",
|
|
74908
74999
|
critical: true
|
|
74909
75000
|
});
|
|
74910
|
-
const triggerPath =
|
|
75001
|
+
const triggerPath = join45(deps.cwd, ".agents", "hooks", "core", "triggers.json");
|
|
74911
75002
|
let table = null;
|
|
74912
75003
|
try {
|
|
74913
75004
|
table = parseTriggerTable(deps.readFileSync(triggerPath));
|
|
@@ -74924,7 +75015,7 @@ function checkOma(project, deps) {
|
|
|
74924
75015
|
return results;
|
|
74925
75016
|
}
|
|
74926
75017
|
results.push({ id: "oma.triggers", name: "OMA trigger table", status: "pass", message: triggerPath, critical: false });
|
|
74927
|
-
const missing = Object.entries(table.workflows).filter(([name, workflow]) => !workflow.persistent && !table.excludedWorkflows.includes(name)).map(([name]) =>
|
|
75018
|
+
const missing = Object.entries(table.workflows).filter(([name, workflow]) => !workflow.persistent && !table.excludedWorkflows.includes(name)).map(([name]) => join45(deps.cwd, ".agents", "workflows", `${name}.md`)).filter((path) => !deps.existsSync(path));
|
|
74928
75019
|
results.push(missing.length === 0 ? {
|
|
74929
75020
|
id: "oma.workflows",
|
|
74930
75021
|
name: "OMA workflow files",
|
|
@@ -74943,7 +75034,7 @@ function checkOma(project, deps) {
|
|
|
74943
75034
|
}
|
|
74944
75035
|
|
|
74945
75036
|
// src/doctor-skill-matrix-checks.ts
|
|
74946
|
-
import { resolve as
|
|
75037
|
+
import { resolve as resolve27 } from "node:path";
|
|
74947
75038
|
async function checkSkillMatrix(project, global2, deps) {
|
|
74948
75039
|
const config = project?.oma?.skill_compatibility;
|
|
74949
75040
|
if (!config)
|
|
@@ -74953,10 +75044,10 @@ async function checkSkillMatrix(project, global2, deps) {
|
|
|
74953
75044
|
const actorType = projectActor?.type ?? globalActor?.type ?? "claude";
|
|
74954
75045
|
const model = projectActor?.model ?? (globalActor?.type === actorType ? globalActor.model : undefined);
|
|
74955
75046
|
const inspection = await inspectSkillCompatibility({
|
|
74956
|
-
reportPath:
|
|
75047
|
+
reportPath: resolve27(deps.cwd, config.report_path),
|
|
74957
75048
|
maxAgeHours: config.max_age_hours,
|
|
74958
75049
|
mode: config.mode
|
|
74959
|
-
},
|
|
75050
|
+
}, resolve27(deps.cwd, project?.workspace?.root ?? "."), undefined, [{ actorType, model }], deps.skillMatrix);
|
|
74960
75051
|
const route = inspection.routes[0];
|
|
74961
75052
|
const status = route?.status ?? "unknown";
|
|
74962
75053
|
return [
|
|
@@ -74999,7 +75090,7 @@ function checkTunnel(project, deps) {
|
|
|
74999
75090
|
}
|
|
75000
75091
|
const mode = project?.tunnel?.cloudflare?.mode ?? "quick";
|
|
75001
75092
|
if (mode === "named") {
|
|
75002
|
-
const certPath =
|
|
75093
|
+
const certPath = join46(deps.home, ".cloudflared", "cert.pem");
|
|
75003
75094
|
if (!deps.existsSync(certPath)) {
|
|
75004
75095
|
return {
|
|
75005
75096
|
id: "tunnel",
|
|
@@ -75039,7 +75130,7 @@ function checkTunnel(project, deps) {
|
|
|
75039
75130
|
critical: false
|
|
75040
75131
|
};
|
|
75041
75132
|
}
|
|
75042
|
-
const ngrokConfigPath = deps.platform === "darwin" ?
|
|
75133
|
+
const ngrokConfigPath = deps.platform === "darwin" ? join46(deps.home, "Library", "Application Support", "ngrok", "ngrok.yml") : join46(deps.home, ".config", "ngrok", "ngrok.yml");
|
|
75043
75134
|
if (!deps.existsSync(ngrokConfigPath)) {
|
|
75044
75135
|
return {
|
|
75045
75136
|
id: "tunnel",
|
|
@@ -75110,7 +75201,7 @@ function checkConfig(deps) {
|
|
|
75110
75201
|
critical: true
|
|
75111
75202
|
});
|
|
75112
75203
|
}
|
|
75113
|
-
const projectPath =
|
|
75204
|
+
const projectPath = join46(deps.cwd, PROJECT_CONFIG_FILENAME);
|
|
75114
75205
|
try {
|
|
75115
75206
|
project = deps.loadProjectConfig(deps.cwd);
|
|
75116
75207
|
results.push(project ? {
|
|
@@ -75306,7 +75397,7 @@ async function registerLinearWebhook(root, tunnelUrl) {
|
|
|
75306
75397
|
init_yaml_loader();
|
|
75307
75398
|
import { existsSync as existsSync5, readFileSync as readFileSync10, writeFileSync as writeFileSync2 } from "node:fs";
|
|
75308
75399
|
import { createServer as createServer3 } from "node:net";
|
|
75309
|
-
import { resolve as
|
|
75400
|
+
import { resolve as resolve28 } from "node:path";
|
|
75310
75401
|
import { setTimeout as delay } from "node:timers/promises";
|
|
75311
75402
|
|
|
75312
75403
|
// src/webhook-proxy.ts
|
|
@@ -75421,12 +75512,12 @@ function resolveServerPort(root, runningPort) {
|
|
|
75421
75512
|
return String(port);
|
|
75422
75513
|
}
|
|
75423
75514
|
function resolveRuntimePaths(root, cliDir) {
|
|
75424
|
-
const dashboardCwd =
|
|
75425
|
-
if (!existsSync5(
|
|
75515
|
+
const dashboardCwd = resolve28(root, "apps/dashboard");
|
|
75516
|
+
if (!existsSync5(resolve28(dashboardCwd, "package.json"))) {
|
|
75426
75517
|
throw new Error(`Dashboard source is missing at ${dashboardCwd}. Clone https://github.com/first-fluke/agent-valley, run bun install, then run bun av setup and bun av dev from that checkout. The standalone CLI does not include the dashboard.`);
|
|
75427
75518
|
}
|
|
75428
|
-
const bundled =
|
|
75429
|
-
const supervisorScript = existsSync5(bundled) ? bundled :
|
|
75519
|
+
const bundled = resolve28(cliDir, "supervisor.js");
|
|
75520
|
+
const supervisorScript = existsSync5(bundled) ? bundled : resolve28(cliDir, "supervisor.ts");
|
|
75430
75521
|
if (!existsSync5(supervisorScript)) {
|
|
75431
75522
|
throw new Error(`Supervisor is missing at ${supervisorScript}. Run bun av up from an intact Agent Valley checkout.`);
|
|
75432
75523
|
}
|
|
@@ -75705,8 +75796,8 @@ function spawnTunnel(config, input) {
|
|
|
75705
75796
|
|
|
75706
75797
|
// src/index.ts
|
|
75707
75798
|
var ROOT = process.cwd();
|
|
75708
|
-
var PID_FILE =
|
|
75709
|
-
var LOG_FILE =
|
|
75799
|
+
var PID_FILE = resolve32(ROOT, ".av.pid");
|
|
75800
|
+
var LOG_FILE = resolve32(ROOT, ".av.log");
|
|
75710
75801
|
function ensureConfig() {
|
|
75711
75802
|
if (!existsSync10(resolveProjectConfigPath(ROOT))) {
|
|
75712
75803
|
console.log(import_picocolors15.default.red("No av.yaml found. Run `av setup` first."));
|