agent-valley 2.2.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/plugin.json +1 -1
- package/dist/index.js +678 -189
- package/dist/supervisor.js +75 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6439,6 +6439,72 @@ var init_zod = __esm(() => {
|
|
|
6439
6439
|
init_external();
|
|
6440
6440
|
});
|
|
6441
6441
|
|
|
6442
|
+
// ../../packages/core/src/oma/skill-matrix-schema.ts
|
|
6443
|
+
var hash, name, bounded, path, skillCompatibilityConfigSchema, skillCompatibilityPolicySchema, omaConfigSchema, matrixSkillSchema, matrixReportSchema;
|
|
6444
|
+
var init_skill_matrix_schema = __esm(() => {
|
|
6445
|
+
init_zod();
|
|
6446
|
+
hash = string2().regex(/^[a-f0-9]{64}$/);
|
|
6447
|
+
name = string2().regex(/^[a-z0-9][a-z0-9-]{0,127}$/);
|
|
6448
|
+
bounded = string2().trim().min(1).max(2000);
|
|
6449
|
+
path = string2().min(1).max(4096).refine((value) => !value.includes("\x00"));
|
|
6450
|
+
skillCompatibilityConfigSchema = strictObject({
|
|
6451
|
+
report_path: path,
|
|
6452
|
+
max_age_hours: number2().finite().positive().max(8760).default(168),
|
|
6453
|
+
mode: _enum(["warn", "require"])
|
|
6454
|
+
});
|
|
6455
|
+
skillCompatibilityPolicySchema = strictObject({
|
|
6456
|
+
reportPath: path,
|
|
6457
|
+
maxAgeHours: number2().finite().positive().max(8760),
|
|
6458
|
+
mode: _enum(["warn", "require"])
|
|
6459
|
+
});
|
|
6460
|
+
omaConfigSchema = strictObject({
|
|
6461
|
+
mode: _enum(["off", "strict"]).default("off"),
|
|
6462
|
+
skill_compatibility: skillCompatibilityConfigSchema.optional()
|
|
6463
|
+
});
|
|
6464
|
+
matrixSkillSchema = object({
|
|
6465
|
+
name,
|
|
6466
|
+
hash,
|
|
6467
|
+
caseId: bounded,
|
|
6468
|
+
requiredFiles: array(path).min(1).max(500),
|
|
6469
|
+
missingFiles: array(path).max(500),
|
|
6470
|
+
excludedReferences: array(object({ path, reason: bounded })).max(500)
|
|
6471
|
+
});
|
|
6472
|
+
matrixReportSchema = object({
|
|
6473
|
+
schemaVersion: literal(1),
|
|
6474
|
+
kind: literal("skill-compatibility-matrix"),
|
|
6475
|
+
mode: _enum(["plan", "live"]),
|
|
6476
|
+
status: _enum(["planned", "completed", "cancelled", "interrupted"]),
|
|
6477
|
+
createdAt: exports_iso.datetime(),
|
|
6478
|
+
omaVersion: bounded,
|
|
6479
|
+
host: object({ platform: bounded, arch: bounded, node: bounded }),
|
|
6480
|
+
suiteHash: hash,
|
|
6481
|
+
sourceKind: _enum(["synthetic", "installed"]),
|
|
6482
|
+
delivery: _enum(["native", "injected"]),
|
|
6483
|
+
auditScope: _enum(["fixture-contract", "read-reference"]),
|
|
6484
|
+
protocolVersion: literal("oma-skill-matrix-v2"),
|
|
6485
|
+
bundle: object({ hash, skills: array(matrixSkillSchema).min(1).max(100) }).optional(),
|
|
6486
|
+
cases: array(object({ id: bounded, skill: name })).max(100),
|
|
6487
|
+
models: object({ claude: bounded.nullable(), codex: bounded.nullable() }),
|
|
6488
|
+
cells: array(object({
|
|
6489
|
+
caseId: bounded,
|
|
6490
|
+
skill: name,
|
|
6491
|
+
vendor: _enum(["claude", "codex"]),
|
|
6492
|
+
status: _enum(["pass", "fail", "unverifiable", "error"]),
|
|
6493
|
+
contentHash: hash,
|
|
6494
|
+
checks: array(object({
|
|
6495
|
+
id: bounded,
|
|
6496
|
+
status: _enum(["pass", "fail", "unverifiable"]),
|
|
6497
|
+
detail: bounded,
|
|
6498
|
+
proof: _enum(["read", "canary"]).optional()
|
|
6499
|
+
})).max(1000),
|
|
6500
|
+
nativeActivation: _enum(["observed", "unobserved"]),
|
|
6501
|
+
cliVersion: string2().regex(/^[\w .()+/-]{1,160}$/).nullable(),
|
|
6502
|
+
model: bounded.nullable(),
|
|
6503
|
+
durationMs: number2().finite().nonnegative()
|
|
6504
|
+
})).max(200)
|
|
6505
|
+
});
|
|
6506
|
+
});
|
|
6507
|
+
|
|
6442
6508
|
// ../../packages/core/src/config/task-schema.ts
|
|
6443
6509
|
var reportPath, taskSchema, resolvedTaskSchema;
|
|
6444
6510
|
var init_task_schema = __esm(() => {
|
|
@@ -6896,6 +6962,7 @@ var init_execution = __esm(() => {
|
|
|
6896
6962
|
var actorType, text, amount, routingCandidateSchema, chiefOperatingPolicySchema, operatingRunSchema, routeEvidenceSchema, reviewDecisionSchema, chiefOperationsSchema;
|
|
6897
6963
|
var init_operations = __esm(() => {
|
|
6898
6964
|
init_zod();
|
|
6965
|
+
init_skill_matrix_schema();
|
|
6899
6966
|
actorType = string2().regex(/^[a-z0-9][a-z0-9-]{0,127}$/);
|
|
6900
6967
|
text = string2().trim().min(1).max(2000);
|
|
6901
6968
|
amount = number2().finite().nonnegative();
|
|
@@ -6914,6 +6981,7 @@ var init_operations = __esm(() => {
|
|
|
6914
6981
|
reviewVendor: _enum(["prefer", "require", "off"]),
|
|
6915
6982
|
readyActors: array(actorType).max(20).optional(),
|
|
6916
6983
|
memory: boolean2(),
|
|
6984
|
+
skillCompatibility: skillCompatibilityPolicySchema.optional(),
|
|
6917
6985
|
metricTargets: array(strictObject({
|
|
6918
6986
|
name: text,
|
|
6919
6987
|
unit: text.optional(),
|
|
@@ -7232,7 +7300,7 @@ function chiefExecutionPolicy(config) {
|
|
|
7232
7300
|
autoResume: execution.auto_resume
|
|
7233
7301
|
} : {});
|
|
7234
7302
|
}
|
|
7235
|
-
function chiefOperatingPolicy(config, readyActors, automatic = true) {
|
|
7303
|
+
function chiefOperatingPolicy(config, readyActors, automatic = true, skillCompatibility) {
|
|
7236
7304
|
return chiefOperatingPolicySchema.parse({
|
|
7237
7305
|
routing: config.routing ? {
|
|
7238
7306
|
candidates: config.routing.candidates.map((item) => ({
|
|
@@ -7247,7 +7315,8 @@ function chiefOperatingPolicy(config, readyActors, automatic = true) {
|
|
|
7247
7315
|
reviewVendor: config.review_vendor ?? "prefer",
|
|
7248
7316
|
memory: config.memory ?? true,
|
|
7249
7317
|
metricTargets: config.metric_targets,
|
|
7250
|
-
readyActors
|
|
7318
|
+
readyActors,
|
|
7319
|
+
skillCompatibility
|
|
7251
7320
|
});
|
|
7252
7321
|
}
|
|
7253
7322
|
function chiefCapturePolicy(config) {
|
|
@@ -14575,7 +14644,7 @@ function mergeConfigs(global2, project, env) {
|
|
|
14575
14644
|
tunnel: buildTunnelConfig(project),
|
|
14576
14645
|
verify: buildVerifyConfig(project),
|
|
14577
14646
|
task: project?.task?.kind === "analysis" ? { kind: "analysis", reportPath: project.task.report_path } : { kind: "code" },
|
|
14578
|
-
oma:
|
|
14647
|
+
oma: project?.oma ?? { mode: "off" },
|
|
14579
14648
|
chief: global2?.chief || project?.chief ? mergeChiefConfig(global2?.chief, project?.chief) : undefined
|
|
14580
14649
|
};
|
|
14581
14650
|
}
|
|
@@ -14613,6 +14682,7 @@ Symphony cannot start until all config errors are resolved.`);
|
|
|
14613
14682
|
var globalConfigSchema, projectConfigSchema, githubConfigSchema, mergedConfigSchema;
|
|
14614
14683
|
var init_yaml_loader = __esm(() => {
|
|
14615
14684
|
init_zod();
|
|
14685
|
+
init_skill_matrix_schema();
|
|
14616
14686
|
init_actor_schema();
|
|
14617
14687
|
init_budget_schema();
|
|
14618
14688
|
init_chief_schema();
|
|
@@ -14706,7 +14776,7 @@ var init_yaml_loader = __esm(() => {
|
|
|
14706
14776
|
tunnel: tunnelProjectSchema,
|
|
14707
14777
|
verify: verifyProjectSchema,
|
|
14708
14778
|
task: taskSchema.optional(),
|
|
14709
|
-
oma:
|
|
14779
|
+
oma: omaConfigSchema.optional(),
|
|
14710
14780
|
chief: chiefConfigSchema.optional()
|
|
14711
14781
|
}).strict().overwrite(normalizeActorDefaults);
|
|
14712
14782
|
githubConfigSchema = object({
|
|
@@ -14775,7 +14845,7 @@ var init_yaml_loader = __esm(() => {
|
|
|
14775
14845
|
tunnel: tunnelMergedSchema,
|
|
14776
14846
|
verify: verifyMergedSchema,
|
|
14777
14847
|
task: resolvedTaskSchema.optional(),
|
|
14778
|
-
oma:
|
|
14848
|
+
oma: omaConfigSchema.optional(),
|
|
14779
14849
|
chief: chiefConfigSchema.optional()
|
|
14780
14850
|
}).superRefine((cfg, ctx) => {
|
|
14781
14851
|
if (cfg.trackerKind === "linear") {
|
|
@@ -19037,7 +19107,7 @@ var init_sandbox = __esm(() => {
|
|
|
19037
19107
|
});
|
|
19038
19108
|
|
|
19039
19109
|
// ../../packages/core/src/sessions/codex-session.ts
|
|
19040
|
-
import { spawn as
|
|
19110
|
+
import { spawn as spawn8 } from "node:child_process";
|
|
19041
19111
|
var CodexSession;
|
|
19042
19112
|
var init_codex_session = __esm(() => {
|
|
19043
19113
|
init_base_session();
|
|
@@ -19066,7 +19136,7 @@ var init_codex_session = __esm(() => {
|
|
|
19066
19136
|
args,
|
|
19067
19137
|
workspacePath: config.workspacePath
|
|
19068
19138
|
});
|
|
19069
|
-
this.process =
|
|
19139
|
+
this.process = spawn8(plan.command, plan.args, {
|
|
19070
19140
|
detached: process.platform !== "win32",
|
|
19071
19141
|
cwd: config.workspacePath,
|
|
19072
19142
|
env: buildAgentEnv("codex", config.env),
|
|
@@ -19344,7 +19414,7 @@ var init_codex_session = __esm(() => {
|
|
|
19344
19414
|
});
|
|
19345
19415
|
|
|
19346
19416
|
// ../../packages/core/src/sessions/claude-session.ts
|
|
19347
|
-
import { spawn as
|
|
19417
|
+
import { spawn as spawn9 } from "node:child_process";
|
|
19348
19418
|
var ClaudeSession;
|
|
19349
19419
|
var init_claude_session = __esm(() => {
|
|
19350
19420
|
init_base_session();
|
|
@@ -19400,7 +19470,7 @@ var init_claude_session = __esm(() => {
|
|
|
19400
19470
|
this.emitError("CRASH", `${err}`, false);
|
|
19401
19471
|
return;
|
|
19402
19472
|
}
|
|
19403
|
-
this.process =
|
|
19473
|
+
this.process = spawn9(plan.command, plan.args, {
|
|
19404
19474
|
detached: process.platform !== "win32",
|
|
19405
19475
|
cwd: this.config.workspacePath,
|
|
19406
19476
|
env: buildAgentEnv(this.vendor, this.config.env),
|
|
@@ -19614,7 +19684,7 @@ var init_qwen_session = __esm(() => {
|
|
|
19614
19684
|
});
|
|
19615
19685
|
|
|
19616
19686
|
// ../../packages/core/src/sessions/agy-session.ts
|
|
19617
|
-
import { spawn as
|
|
19687
|
+
import { spawn as spawn10 } from "node:child_process";
|
|
19618
19688
|
function formatAgyTimeout(seconds) {
|
|
19619
19689
|
return `${Math.max(1, Math.round(seconds))}s`;
|
|
19620
19690
|
}
|
|
@@ -19660,7 +19730,7 @@ var init_agy_session = __esm(() => {
|
|
|
19660
19730
|
this.emitError("CRASH", `${err}`, false);
|
|
19661
19731
|
return;
|
|
19662
19732
|
}
|
|
19663
|
-
this.process =
|
|
19733
|
+
this.process = spawn10(plan.command, plan.args, {
|
|
19664
19734
|
detached: process.platform !== "win32",
|
|
19665
19735
|
cwd: config.workspacePath,
|
|
19666
19736
|
env: buildAgentEnv("antigravity", config.env),
|
|
@@ -19731,7 +19801,7 @@ var init_agy_session = __esm(() => {
|
|
|
19731
19801
|
});
|
|
19732
19802
|
|
|
19733
19803
|
// ../../packages/core/src/sessions/cursor-session.ts
|
|
19734
|
-
import { spawn as
|
|
19804
|
+
import { spawn as spawn11 } from "node:child_process";
|
|
19735
19805
|
var CURSOR_COMMAND = "cursor-agent", MAX_PROMPT_ARG_LENGTH = 1e5, CursorSession;
|
|
19736
19806
|
var init_cursor_session = __esm(() => {
|
|
19737
19807
|
init_base_session();
|
|
@@ -19779,7 +19849,7 @@ var init_cursor_session = __esm(() => {
|
|
|
19779
19849
|
const apiKey = process.env.CURSOR_API_KEY;
|
|
19780
19850
|
if (apiKey)
|
|
19781
19851
|
extraEnv.CURSOR_API_KEY = apiKey;
|
|
19782
|
-
this.process =
|
|
19852
|
+
this.process = spawn11(plan.command, plan.args, {
|
|
19783
19853
|
detached: process.platform !== "win32",
|
|
19784
19854
|
cwd: this.config.workspacePath,
|
|
19785
19855
|
env: buildAgentEnv("cursor", extraEnv),
|
|
@@ -19915,7 +19985,7 @@ var init_cursor_session = __esm(() => {
|
|
|
19915
19985
|
});
|
|
19916
19986
|
|
|
19917
19987
|
// ../../packages/core/src/sessions/grok-session.ts
|
|
19918
|
-
import { spawn as
|
|
19988
|
+
import { spawn as spawn12 } from "node:child_process";
|
|
19919
19989
|
function isToolUseType(type) {
|
|
19920
19990
|
return type === "tool_use" || type === "tool_call" || type === "function_call";
|
|
19921
19991
|
}
|
|
@@ -19933,11 +20003,11 @@ function normalizeToolInput(raw) {
|
|
|
19933
20003
|
}
|
|
19934
20004
|
return;
|
|
19935
20005
|
}
|
|
19936
|
-
var GROK_COMMAND = "grok",
|
|
20006
|
+
var GROK_COMMAND = "grok", MAX_OUTPUT_BYTES3, WRITE_TOOL_HINTS, EDIT_TOOL_HINTS, GrokSession;
|
|
19937
20007
|
var init_grok_session = __esm(() => {
|
|
19938
20008
|
init_base_session();
|
|
19939
20009
|
init_sandbox();
|
|
19940
|
-
|
|
20010
|
+
MAX_OUTPUT_BYTES3 = 10 * 1024;
|
|
19941
20011
|
WRITE_TOOL_HINTS = ["write"];
|
|
19942
20012
|
EDIT_TOOL_HINTS = ["edit", "str_replace", "patch"];
|
|
19943
20013
|
GrokSession = class GrokSession extends BaseSession {
|
|
@@ -19969,7 +20039,7 @@ var init_grok_session = __esm(() => {
|
|
|
19969
20039
|
this.emitError("CRASH", `${err}`, false);
|
|
19970
20040
|
return;
|
|
19971
20041
|
}
|
|
19972
|
-
this.process =
|
|
20042
|
+
this.process = spawn12(plan.command, plan.args, {
|
|
19973
20043
|
detached: process.platform !== "win32",
|
|
19974
20044
|
cwd: this.config.workspacePath,
|
|
19975
20045
|
env: buildAgentEnv("grok", this.config.env),
|
|
@@ -20022,8 +20092,8 @@ var init_grok_session = __esm(() => {
|
|
|
20022
20092
|
}
|
|
20023
20093
|
appendOutputTail(chunk) {
|
|
20024
20094
|
this.outputTail += chunk;
|
|
20025
|
-
if (this.outputTail.length >
|
|
20026
|
-
this.outputTail = this.outputTail.slice(-
|
|
20095
|
+
if (this.outputTail.length > MAX_OUTPUT_BYTES3) {
|
|
20096
|
+
this.outputTail = this.outputTail.slice(-MAX_OUTPUT_BYTES3);
|
|
20027
20097
|
}
|
|
20028
20098
|
}
|
|
20029
20099
|
handleToolUse(e) {
|
|
@@ -20084,7 +20154,7 @@ var init_grok_session = __esm(() => {
|
|
|
20084
20154
|
});
|
|
20085
20155
|
|
|
20086
20156
|
// ../../packages/core/src/sessions/kimi-session.ts
|
|
20087
|
-
import { spawn as
|
|
20157
|
+
import { spawn as spawn13 } from "node:child_process";
|
|
20088
20158
|
var KIMI_COMMAND = "kimi", MAX_RAW_TAIL_BYTES, KimiSession;
|
|
20089
20159
|
var init_kimi_session = __esm(() => {
|
|
20090
20160
|
init_base_session();
|
|
@@ -20122,7 +20192,7 @@ var init_kimi_session = __esm(() => {
|
|
|
20122
20192
|
this.emitError("CRASH", `${err}`, false);
|
|
20123
20193
|
return;
|
|
20124
20194
|
}
|
|
20125
|
-
this.process =
|
|
20195
|
+
this.process = spawn13(plan.command, plan.args, {
|
|
20126
20196
|
detached: process.platform !== "win32",
|
|
20127
20197
|
cwd: this.config.workspacePath,
|
|
20128
20198
|
env: buildAgentEnv("kimi", this.config.env),
|
|
@@ -20261,7 +20331,7 @@ var init_kimi_session = __esm(() => {
|
|
|
20261
20331
|
});
|
|
20262
20332
|
|
|
20263
20333
|
// ../../packages/core/src/sessions/opencode-session.ts
|
|
20264
|
-
import { spawn as
|
|
20334
|
+
import { spawn as spawn14 } from "node:child_process";
|
|
20265
20335
|
function normalizeToolInput2(raw) {
|
|
20266
20336
|
if (raw == null)
|
|
20267
20337
|
return;
|
|
@@ -20276,11 +20346,11 @@ function normalizeToolInput2(raw) {
|
|
|
20276
20346
|
}
|
|
20277
20347
|
return;
|
|
20278
20348
|
}
|
|
20279
|
-
var OPENCODE_COMMAND = "opencode", MAX_PROMPT_ARG_LENGTH2 = 1e5,
|
|
20349
|
+
var OPENCODE_COMMAND = "opencode", MAX_PROMPT_ARG_LENGTH2 = 1e5, MAX_OUTPUT_BYTES4, MAX_RAW_TAIL_BYTES2, WRITE_TOOL_HINTS2, EDIT_TOOL_HINTS2, AUTH_FAILURE_PATTERN, OpencodeSession, TERMINAL_TYPE_HINTS;
|
|
20280
20350
|
var init_opencode_session = __esm(() => {
|
|
20281
20351
|
init_base_session();
|
|
20282
20352
|
init_sandbox();
|
|
20283
|
-
|
|
20353
|
+
MAX_OUTPUT_BYTES4 = 10 * 1024;
|
|
20284
20354
|
MAX_RAW_TAIL_BYTES2 = 4 * 1024;
|
|
20285
20355
|
WRITE_TOOL_HINTS2 = ["write"];
|
|
20286
20356
|
EDIT_TOOL_HINTS2 = ["edit", "str_replace", "patch"];
|
|
@@ -20328,7 +20398,7 @@ var init_opencode_session = __esm(() => {
|
|
|
20328
20398
|
this.emitError("CRASH", `${err}`, false);
|
|
20329
20399
|
return;
|
|
20330
20400
|
}
|
|
20331
|
-
this.process =
|
|
20401
|
+
this.process = spawn14(plan.command, plan.args, {
|
|
20332
20402
|
detached: process.platform !== "win32",
|
|
20333
20403
|
cwd: this.config.workspacePath,
|
|
20334
20404
|
env: buildAgentEnv("opencode", this.config.env),
|
|
@@ -20381,8 +20451,8 @@ var init_opencode_session = __esm(() => {
|
|
|
20381
20451
|
}
|
|
20382
20452
|
appendOutputTail(chunk) {
|
|
20383
20453
|
this.outputTail += chunk;
|
|
20384
|
-
if (this.outputTail.length >
|
|
20385
|
-
this.outputTail = this.outputTail.slice(-
|
|
20454
|
+
if (this.outputTail.length > MAX_OUTPUT_BYTES4) {
|
|
20455
|
+
this.outputTail = this.outputTail.slice(-MAX_OUTPUT_BYTES4);
|
|
20386
20456
|
}
|
|
20387
20457
|
}
|
|
20388
20458
|
handleEvent(event) {
|
|
@@ -20455,7 +20525,7 @@ var init_opencode_session = __esm(() => {
|
|
|
20455
20525
|
return;
|
|
20456
20526
|
const text = e.result ?? e.text ?? e.output;
|
|
20457
20527
|
if (typeof text === "string" && text.length > 0) {
|
|
20458
|
-
this.explicitResult = text.length >
|
|
20528
|
+
this.explicitResult = text.length > MAX_OUTPUT_BYTES4 ? text.slice(-MAX_OUTPUT_BYTES4) : text;
|
|
20459
20529
|
}
|
|
20460
20530
|
const usage = e.usage ?? e.tokens ?? e.cost;
|
|
20461
20531
|
if (!usage)
|
|
@@ -20724,7 +20794,7 @@ var init_readdirp = __esm(() => {
|
|
|
20724
20794
|
|
|
20725
20795
|
// ../../node_modules/.bun/chokidar@5.0.0/node_modules/chokidar/handler.js
|
|
20726
20796
|
import { watch as fs_watch, unwatchFile, watchFile } from "node:fs";
|
|
20727
|
-
import { realpath as fsrealpath, lstat as lstat18, open as
|
|
20797
|
+
import { realpath as fsrealpath, lstat as lstat18, open as open12, stat as stat4 } from "node:fs/promises";
|
|
20728
20798
|
import { type as osType } from "node:os";
|
|
20729
20799
|
import * as sp from "node:path";
|
|
20730
20800
|
function createFsWatchInstance(path, options, listener, errHandler, emitRaw) {
|
|
@@ -21066,7 +21136,7 @@ var STR_DATA = "data", STR_END = "end", STR_CLOSE = "close", EMPTY_FN = () => {}
|
|
|
21066
21136
|
cont.watcherUnusable = true;
|
|
21067
21137
|
if (isWindows && error.code === "EPERM") {
|
|
21068
21138
|
try {
|
|
21069
|
-
const fd = await
|
|
21139
|
+
const fd = await open12(path, "r");
|
|
21070
21140
|
await fd.close();
|
|
21071
21141
|
broadcastErr(error);
|
|
21072
21142
|
} catch (err) {}
|
|
@@ -22446,11 +22516,11 @@ function canonicalConfig(config) {
|
|
|
22446
22516
|
}
|
|
22447
22517
|
|
|
22448
22518
|
// src/agent-provisioning.ts
|
|
22449
|
-
import { spawn as
|
|
22519
|
+
import { spawn as spawn17 } from "node:child_process";
|
|
22450
22520
|
import { mkdtempSync, rmSync as rmSync2 } from "node:fs";
|
|
22451
22521
|
import { homedir as homedir7, tmpdir as tmpdir4 } from "node:os";
|
|
22452
22522
|
import { delimiter as delimiter3, join as join46 } from "node:path";
|
|
22453
|
-
function runTerminalCommand(request, spawnCommand =
|
|
22523
|
+
function runTerminalCommand(request, spawnCommand = spawn17) {
|
|
22454
22524
|
return new Promise((resolve) => {
|
|
22455
22525
|
let child;
|
|
22456
22526
|
let timeout;
|
|
@@ -22699,7 +22769,7 @@ var init_agent_provisioning = __esm(() => {
|
|
|
22699
22769
|
import { mkdtempSync as mkdtempSync2, rmSync as rmSync3 } from "node:fs";
|
|
22700
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";
|
|
22701
22771
|
import { homedir as homedir8, tmpdir as tmpdir5 } from "node:os";
|
|
22702
|
-
import { delimiter as delimiter4, isAbsolute as isAbsolute15, join as join47, relative as relative14, resolve as
|
|
22772
|
+
import { delimiter as delimiter4, isAbsolute as isAbsolute15, join as join47, relative as relative14, resolve as resolve28 } from "node:path";
|
|
22703
22773
|
function defaults2() {
|
|
22704
22774
|
const home = homedir8();
|
|
22705
22775
|
return {
|
|
@@ -22727,7 +22797,7 @@ async function present(path) {
|
|
|
22727
22797
|
return false;
|
|
22728
22798
|
}
|
|
22729
22799
|
}
|
|
22730
|
-
async function
|
|
22800
|
+
async function installedVersion2(skills) {
|
|
22731
22801
|
try {
|
|
22732
22802
|
const marker = JSON.parse(await readFile16(join47(skills, "_version.json"), "utf8"));
|
|
22733
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;
|
|
@@ -22773,7 +22843,7 @@ async function restoreConfig(agents, snapshots) {
|
|
|
22773
22843
|
async function workspacePath(input) {
|
|
22774
22844
|
if (!input.trim() || !isAbsolute15(input))
|
|
22775
22845
|
return null;
|
|
22776
|
-
const root =
|
|
22846
|
+
const root = resolve28(input);
|
|
22777
22847
|
if (!await directory2(root))
|
|
22778
22848
|
return null;
|
|
22779
22849
|
for (const path of [join47(root, ".agents"), join47(root, ".agents", "skills")]) {
|
|
@@ -22792,7 +22862,7 @@ async function inspectOma(workspaceRoot, _overrides = {}) {
|
|
|
22792
22862
|
if (!root)
|
|
22793
22863
|
return { success: false, message: "Choose an existing absolute workspace with project-local OMA files." };
|
|
22794
22864
|
const skills = join47(root, ".agents", "skills");
|
|
22795
|
-
const version = await
|
|
22865
|
+
const version = await installedVersion2(skills);
|
|
22796
22866
|
if (!version)
|
|
22797
22867
|
throw new Error("Invalid installed metadata");
|
|
22798
22868
|
const entries = (await readdir12(skills, { withFileTypes: true })).filter((entry) => /^oma-[a-z0-9-]+$/.test(entry.name));
|
|
@@ -22813,7 +22883,7 @@ async function inspectOma(workspaceRoot, _overrides = {}) {
|
|
|
22813
22883
|
};
|
|
22814
22884
|
}
|
|
22815
22885
|
}
|
|
22816
|
-
function
|
|
22886
|
+
function failure3(action, result) {
|
|
22817
22887
|
return {
|
|
22818
22888
|
success: false,
|
|
22819
22889
|
message: `${action} ${result?.failure === "timed_out" ? "timed out" : "did not complete"}. Retry OMA preparation or follow ${DOCUMENTATION_URL}.`
|
|
@@ -22835,7 +22905,7 @@ async function prepareOma(workspaceRoot, overrides = {}) {
|
|
|
22835
22905
|
env: { ...deps.env, OMA_INSTALL_NO_RUN: "1" }
|
|
22836
22906
|
});
|
|
22837
22907
|
if (!bootstrap.success)
|
|
22838
|
-
return bootstrap.stage === "prerequisites" ? { success: false, message: `Install curl and bash, then retry OMA preparation. ${DOCUMENTATION_URL}` } :
|
|
22908
|
+
return bootstrap.stage === "prerequisites" ? { success: false, message: `Install curl and bash, then retry OMA preparation. ${DOCUMENTATION_URL}` } : failure3("OMA prerequisite preparation", bootstrap);
|
|
22839
22909
|
const bun = deps.resolveBinary("bun");
|
|
22840
22910
|
if (!bun)
|
|
22841
22911
|
return {
|
|
@@ -22854,9 +22924,9 @@ async function prepareOma(workspaceRoot, overrides = {}) {
|
|
|
22854
22924
|
const request = { command: bun, env: environment, cwd: root, timeoutMs: 300000 };
|
|
22855
22925
|
const latest = await deps.runCommand({ ...request, args: ["install", "--global", LATEST_PACKAGE] });
|
|
22856
22926
|
if (!latest.success)
|
|
22857
|
-
return
|
|
22927
|
+
return failure3("OMA CLI update", latest);
|
|
22858
22928
|
const agents = join47(root, ".agents");
|
|
22859
|
-
const existing = await
|
|
22929
|
+
const existing = await installedVersion2(join47(agents, "skills")) !== null || await directory2(join47(agents, "skills")) && (await present(join47(agents, "oma-config.yaml")) || await present(join47(agents, "mcp.json")) || await directory2(join47(agents, "workflows")));
|
|
22860
22930
|
const custom = await snapshotConfig(agents);
|
|
22861
22931
|
const args = existing ? ["update", "--yes", "--with-new-skills", "--all"] : ["install"];
|
|
22862
22932
|
let installed;
|
|
@@ -22867,7 +22937,7 @@ async function prepareOma(workspaceRoot, overrides = {}) {
|
|
|
22867
22937
|
await restoreConfig(agents, custom);
|
|
22868
22938
|
}
|
|
22869
22939
|
if (!installed.success)
|
|
22870
|
-
return
|
|
22940
|
+
return failure3(existing ? "OMA skill update" : "OMA skill installation", installed);
|
|
22871
22941
|
const inspection = await inspectOma(root, deps);
|
|
22872
22942
|
if (!inspection.success)
|
|
22873
22943
|
return {
|
|
@@ -22880,7 +22950,7 @@ async function prepareOma(workspaceRoot, overrides = {}) {
|
|
|
22880
22950
|
message: `Latest official OMA preparation completed. ${inspection.message.split(" Prepare ")[0]}`
|
|
22881
22951
|
};
|
|
22882
22952
|
} catch {
|
|
22883
|
-
return
|
|
22953
|
+
return failure3("OMA preparation");
|
|
22884
22954
|
}
|
|
22885
22955
|
}
|
|
22886
22956
|
var INSTALLER_URL = "https://raw.githubusercontent.com/first-fluke/oh-my-agent/main/cli/install.sh", DOCUMENTATION_URL = "https://github.com/first-fluke/oh-my-agent", LATEST_PACKAGE = "oh-my-agent@latest", CUSTOM_CONFIG_NAMES;
|
|
@@ -22898,7 +22968,7 @@ var init_oma_provisioning = __esm(() => {
|
|
|
22898
22968
|
});
|
|
22899
22969
|
|
|
22900
22970
|
// src/setup/noninteractive-runtime.ts
|
|
22901
|
-
import { spawn as
|
|
22971
|
+
import { spawn as spawn18 } from "node:child_process";
|
|
22902
22972
|
function noninteractiveSetupDefaults() {
|
|
22903
22973
|
const env = { ...process.env, CI: "true" };
|
|
22904
22974
|
const runCommand = (request) => runTerminalCommand(request, quietSpawn);
|
|
@@ -22925,7 +22995,7 @@ function currentRuntimeIdentity(env) {
|
|
|
22925
22995
|
throw new Error("Current runtime identity is ambiguous. Rerun av setup --yes --actor <current-vendor> --model <current-model-or-empty>; do not use OMA defaults to identify the caller.");
|
|
22926
22996
|
return identities[0];
|
|
22927
22997
|
}
|
|
22928
|
-
var quietSpawn = (command, args, options) =>
|
|
22998
|
+
var quietSpawn = (command, args, options) => spawn18(command, args, { ...options, stdio: "ignore" });
|
|
22929
22999
|
var init_noninteractive_runtime = __esm(() => {
|
|
22930
23000
|
init_yaml_loader();
|
|
22931
23001
|
init_agent_discovery();
|
|
@@ -24399,7 +24469,7 @@ var init_workspace_step = __esm(() => {
|
|
|
24399
24469
|
|
|
24400
24470
|
// src/setup/noninteractive-config.ts
|
|
24401
24471
|
import { lstat as lstat20, realpath as realpath26 } from "node:fs/promises";
|
|
24402
|
-
import { isAbsolute as isAbsolute17, join as join48, parse as parsePath, resolve as
|
|
24472
|
+
import { isAbsolute as isAbsolute17, join as join48, parse as parsePath, resolve as resolve29 } from "node:path";
|
|
24403
24473
|
function validateNoninteractiveOptions(options) {
|
|
24404
24474
|
if (!options.yes || options.edit || options.mode !== undefined && options.mode !== "order")
|
|
24405
24475
|
throw new Error("Use av setup --yes only for local order setup; --edit and --mode tracker require interactive setup.");
|
|
@@ -24480,13 +24550,13 @@ async function prepareNoninteractiveConfig(options, deps) {
|
|
|
24480
24550
|
validateNoninteractiveOptions(options);
|
|
24481
24551
|
let projectRoot;
|
|
24482
24552
|
try {
|
|
24483
|
-
projectRoot = await realpath26(
|
|
24553
|
+
projectRoot = await realpath26(resolve29(deps.projectRoot));
|
|
24484
24554
|
if (!(await lstat20(projectRoot)).isDirectory())
|
|
24485
24555
|
throw new Error("not a directory");
|
|
24486
24556
|
} catch {
|
|
24487
24557
|
throw new Error(`AV configuration directory ${deps.projectRoot} does not exist. Run av setup from an existing directory.`);
|
|
24488
24558
|
}
|
|
24489
|
-
const globalPath =
|
|
24559
|
+
const globalPath = resolve29(deps.globalConfigPath);
|
|
24490
24560
|
const projectPath = join48(projectRoot, "av.yaml");
|
|
24491
24561
|
const project = await configFile(projectPath, projectConfigSchema);
|
|
24492
24562
|
const global2 = await configFile(globalPath, globalConfigSchema);
|
|
@@ -24504,7 +24574,7 @@ async function prepareNoninteractiveConfig(options, deps) {
|
|
|
24504
24574
|
}
|
|
24505
24575
|
const savedWorkspace = project.raw.workspace?.root;
|
|
24506
24576
|
const selectedWorkspace = options.workspace ?? savedWorkspace ?? projectRoot;
|
|
24507
|
-
const workspacePath = isAbsolute17(selectedWorkspace) ? selectedWorkspace :
|
|
24577
|
+
const workspacePath = isAbsolute17(selectedWorkspace) ? selectedWorkspace : resolve29(projectRoot, selectedWorkspace);
|
|
24508
24578
|
const workspaceError = await validateOrderWorkspace(workspacePath);
|
|
24509
24579
|
if (workspaceError)
|
|
24510
24580
|
throw new Error(workspaceError);
|
|
@@ -24539,7 +24609,7 @@ var init_noninteractive_config = __esm(() => {
|
|
|
24539
24609
|
});
|
|
24540
24610
|
|
|
24541
24611
|
// src/setup/noninteractive.ts
|
|
24542
|
-
import { join as join49, parse as parsePath2, resolve as
|
|
24612
|
+
import { join as join49, parse as parsePath2, resolve as resolve30 } from "node:path";
|
|
24543
24613
|
function rerunCommand(result, options) {
|
|
24544
24614
|
const quote = (value) => `'${value.replace(/'/g, "'\\''")}'`;
|
|
24545
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`;
|
|
@@ -24550,11 +24620,11 @@ async function setupNoninteractive(options, overrides = {}) {
|
|
|
24550
24620
|
version: 1,
|
|
24551
24621
|
status: "failed",
|
|
24552
24622
|
exitCode: 1,
|
|
24553
|
-
projectRoot:
|
|
24623
|
+
projectRoot: resolve30(deps.projectRoot),
|
|
24554
24624
|
workspace: null,
|
|
24555
24625
|
config: {
|
|
24556
|
-
project: join49(
|
|
24557
|
-
global:
|
|
24626
|
+
project: join49(resolve30(deps.projectRoot), "av.yaml"),
|
|
24627
|
+
global: resolve30(deps.globalConfigPath),
|
|
24558
24628
|
saved: false
|
|
24559
24629
|
},
|
|
24560
24630
|
chief: {
|
|
@@ -24668,7 +24738,7 @@ var init_noninteractive = __esm(() => {
|
|
|
24668
24738
|
});
|
|
24669
24739
|
|
|
24670
24740
|
// src/invite.ts
|
|
24671
|
-
import { spawn as
|
|
24741
|
+
import { spawn as spawn19 } from "node:child_process";
|
|
24672
24742
|
function encodeInvite(data) {
|
|
24673
24743
|
const json = JSON.stringify(data);
|
|
24674
24744
|
const b64 = Buffer.from(json).toString("base64url");
|
|
@@ -24694,7 +24764,7 @@ async function readClipboard() {
|
|
|
24694
24764
|
try {
|
|
24695
24765
|
const cmd = process.platform === "darwin" ? "pbpaste" : "xclip -selection clipboard -o";
|
|
24696
24766
|
const parts = cmd.split(" ");
|
|
24697
|
-
const proc =
|
|
24767
|
+
const proc = spawn19(parts[0], parts.slice(1), { stdio: ["pipe", "pipe", "pipe"] });
|
|
24698
24768
|
const { text, exitCode } = await new Promise((resolve, reject) => {
|
|
24699
24769
|
const chunks = [];
|
|
24700
24770
|
proc.stdout.on("data", (chunk) => chunks.push(chunk));
|
|
@@ -24711,7 +24781,7 @@ async function writeClipboard(text) {
|
|
|
24711
24781
|
try {
|
|
24712
24782
|
const cmd = process.platform === "darwin" ? "pbcopy" : "xclip -selection clipboard";
|
|
24713
24783
|
const parts = cmd.split(" ");
|
|
24714
|
-
const proc =
|
|
24784
|
+
const proc = spawn19(parts[0], parts.slice(1), { stdio: ["pipe", "pipe", "pipe"] });
|
|
24715
24785
|
proc.stdin.write(text);
|
|
24716
24786
|
proc.stdin.end();
|
|
24717
24787
|
const exitCode = await new Promise((resolve, reject) => {
|
|
@@ -25127,18 +25197,18 @@ async function stepMetrics(ctx) {
|
|
|
25127
25197
|
draft.file = file;
|
|
25128
25198
|
}
|
|
25129
25199
|
for (const field of ["value_path", "timestamp_path", "unit_path"]) {
|
|
25130
|
-
const value = await text12(`JSON ${field}`, old?.[field] ?? field.replace("_path", ""),
|
|
25200
|
+
const value = await text12(`JSON ${field}`, old?.[field] ?? field.replace("_path", ""), path4);
|
|
25131
25201
|
if (navigated2(value))
|
|
25132
25202
|
return value;
|
|
25133
25203
|
draft[field] = value;
|
|
25134
25204
|
}
|
|
25135
|
-
const start = await text12("JSON measurement window start path (optional; blank omits window)", old?.window_start_path ?? "", (value) => value ?
|
|
25205
|
+
const start = await text12("JSON measurement window start path (optional; blank omits window)", old?.window_start_path ?? "", (value) => value ? path4(value) : undefined);
|
|
25136
25206
|
if (navigated2(start))
|
|
25137
25207
|
return start;
|
|
25138
25208
|
delete draft.window_start_path;
|
|
25139
25209
|
delete draft.window_end_path;
|
|
25140
25210
|
if (start) {
|
|
25141
|
-
const end = await text12("JSON measurement window end path", old?.window_end_path ?? "window.end",
|
|
25211
|
+
const end = await text12("JSON measurement window end path", old?.window_end_path ?? "window.end", path4);
|
|
25142
25212
|
if (navigated2(end))
|
|
25143
25213
|
return end;
|
|
25144
25214
|
draft.window_start_path = start;
|
|
@@ -25184,7 +25254,7 @@ async function stepMetrics(ctx) {
|
|
|
25184
25254
|
ctx.chiefChanged = true;
|
|
25185
25255
|
log2.info("Metric settings are saved after confirmation. Measurements are collected at mission runtime; setup does not contact the source. Set --duration or chief.execution.max_duration_sec long enough for work and the full measurement/observation windows. The default mission limit is 86400 seconds including waits; Stripe's default measurement window is also 86400 seconds.");
|
|
25186
25256
|
}
|
|
25187
|
-
var envName3 = (value) => /^[A-Za-z_][A-Za-z0-9_]*$/.test(value), navigated2 = (value) => typeof value !== "string", required2 = (limit) => (value) => value && value.length <= limit ? undefined : `Enter 1 to ${limit} characters.`, environment = (optional = false) => (value) => optional && !value || envName3(value) ? undefined : "Enter an environment variable name, never a token or URL.", number4 = (minimum, maximum) => (value) => value && Number.isInteger(Number(value)) && Number(value) >= minimum && Number(value) <= maximum ? undefined : `Enter a whole number from ${minimum} to ${maximum}.`,
|
|
25257
|
+
var envName3 = (value) => /^[A-Za-z_][A-Za-z0-9_]*$/.test(value), navigated2 = (value) => typeof value !== "string", required2 = (limit) => (value) => value && value.length <= limit ? undefined : `Enter 1 to ${limit} characters.`, environment = (optional = false) => (value) => optional && !value || envName3(value) ? undefined : "Enter an environment variable name, never a token or URL.", number4 = (minimum, maximum) => (value) => value && Number.isInteger(Number(value)) && Number(value) >= minimum && Number(value) <= maximum ? undefined : `Enter a whole number from ${minimum} to ${maximum}.`, path4 = (value) => {
|
|
25188
25258
|
const result = metricSourceSchema.shape.value_path.safeParse(value);
|
|
25189
25259
|
return result.success ? undefined : "Use dot-separated JSON keys or array indexes, without prototype keys.";
|
|
25190
25260
|
};
|
|
@@ -27130,7 +27200,7 @@ var init_breakdown_publish = __esm(() => {
|
|
|
27130
27200
|
});
|
|
27131
27201
|
|
|
27132
27202
|
// src/breakdown.ts
|
|
27133
|
-
import { spawn as
|
|
27203
|
+
import { spawn as spawn22 } from "node:child_process";
|
|
27134
27204
|
function parseBreakdownOutput(output) {
|
|
27135
27205
|
const parentTitleMatch = output.match(/^PARENT_TITLE:\s*(.+)$/m);
|
|
27136
27206
|
const parentDescStart = output.match(/^PARENT_DESCRIPTION:\s*\n/m);
|
|
@@ -27184,7 +27254,7 @@ function renderDagPreview(result) {
|
|
|
27184
27254
|
}
|
|
27185
27255
|
async function expandBreakdownWithClaude(rawInput) {
|
|
27186
27256
|
const output = await new Promise((resolve, reject) => {
|
|
27187
|
-
const proc =
|
|
27257
|
+
const proc = spawn22("claude", ["--print", "--no-session-persistence", "-p", `${BREAKDOWN_PROMPT}
|
|
27188
27258
|
|
|
27189
27259
|
Input: ${rawInput}`], { stdio: ["ignore", "pipe", "pipe"] });
|
|
27190
27260
|
const chunks = [];
|
|
@@ -27322,7 +27392,7 @@ async function createGithubIssue(config, input, fetchImpl = fetch) {
|
|
|
27322
27392
|
}
|
|
27323
27393
|
|
|
27324
27394
|
// src/issue.ts
|
|
27325
|
-
import { spawn as
|
|
27395
|
+
import { spawn as spawn23 } from "node:child_process";
|
|
27326
27396
|
function parseIssueInput(raw) {
|
|
27327
27397
|
const newlineIdx = raw.indexOf(`
|
|
27328
27398
|
`);
|
|
@@ -27362,7 +27432,7 @@ async function expandWithClaude(rawInput) {
|
|
|
27362
27432
|
const args = ["--print", "--no-session-persistence", "-p", `${EXPAND_PROMPT}
|
|
27363
27433
|
|
|
27364
27434
|
Input: ${rawInput}`];
|
|
27365
|
-
const proc =
|
|
27435
|
+
const proc = spawn23("claude", args, { stdio: ["pipe", "pipe", "pipe"] });
|
|
27366
27436
|
const { output, exitCode } = await new Promise((resolve, reject) => {
|
|
27367
27437
|
const chunks = [];
|
|
27368
27438
|
proc.stdout.on("data", (chunk) => chunks.push(chunk));
|
|
@@ -27760,9 +27830,9 @@ var init_login = __esm(() => {
|
|
|
27760
27830
|
// src/index.ts
|
|
27761
27831
|
init_project_config_path();
|
|
27762
27832
|
init_yaml_loader();
|
|
27763
|
-
import { spawn as
|
|
27833
|
+
import { spawn as spawn24, spawnSync as spawnSync5 } from "node:child_process";
|
|
27764
27834
|
import { existsSync as existsSync10, unlinkSync as unlinkSync2 } from "node:fs";
|
|
27765
|
-
import { resolve as
|
|
27835
|
+
import { resolve as resolve31 } from "node:path";
|
|
27766
27836
|
|
|
27767
27837
|
// ../../packages/core/src/version.ts
|
|
27768
27838
|
import { readFileSync as readFileSync2 } from "node:fs";
|
|
@@ -27872,7 +27942,7 @@ function humanReadableArgName(arg) {
|
|
|
27872
27942
|
// ../../node_modules/.bun/commander@15.0.0/node_modules/commander/lib/command.js
|
|
27873
27943
|
import { EventEmitter } from "node:events";
|
|
27874
27944
|
import childProcess from "node:child_process";
|
|
27875
|
-
import
|
|
27945
|
+
import path2 from "node:path";
|
|
27876
27946
|
import fs from "node:fs";
|
|
27877
27947
|
import process2 from "node:process";
|
|
27878
27948
|
import { stripVTControlCharacters as stripVTControlCharacters2 } from "node:util";
|
|
@@ -29016,10 +29086,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
29016
29086
|
args = args.slice();
|
|
29017
29087
|
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
29018
29088
|
function findFile(baseDir, baseName) {
|
|
29019
|
-
const localBin =
|
|
29089
|
+
const localBin = path2.resolve(baseDir, baseName);
|
|
29020
29090
|
if (fs.existsSync(localBin))
|
|
29021
29091
|
return localBin;
|
|
29022
|
-
if (sourceExt.includes(
|
|
29092
|
+
if (sourceExt.includes(path2.extname(baseName)))
|
|
29023
29093
|
return;
|
|
29024
29094
|
const foundExt = sourceExt.find((ext) => fs.existsSync(`${localBin}${ext}`));
|
|
29025
29095
|
if (foundExt)
|
|
@@ -29037,19 +29107,19 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
29037
29107
|
} catch {
|
|
29038
29108
|
resolvedScriptPath = this._scriptPath;
|
|
29039
29109
|
}
|
|
29040
|
-
executableDir =
|
|
29110
|
+
executableDir = path2.resolve(path2.dirname(resolvedScriptPath), executableDir);
|
|
29041
29111
|
}
|
|
29042
29112
|
if (executableDir) {
|
|
29043
29113
|
let localFile = findFile(executableDir, executableFile);
|
|
29044
29114
|
if (!localFile && !subcommand._executableFile && this._scriptPath) {
|
|
29045
|
-
const legacyName =
|
|
29115
|
+
const legacyName = path2.basename(this._scriptPath, path2.extname(this._scriptPath));
|
|
29046
29116
|
if (legacyName !== this._name) {
|
|
29047
29117
|
localFile = findFile(executableDir, `${legacyName}-${subcommand._name}`);
|
|
29048
29118
|
}
|
|
29049
29119
|
}
|
|
29050
29120
|
executableFile = localFile || executableFile;
|
|
29051
29121
|
}
|
|
29052
|
-
const launchWithNode = sourceExt.includes(
|
|
29122
|
+
const launchWithNode = sourceExt.includes(path2.extname(executableFile));
|
|
29053
29123
|
let proc;
|
|
29054
29124
|
if (process2.platform !== "win32") {
|
|
29055
29125
|
if (launchWithNode) {
|
|
@@ -29640,13 +29710,13 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
29640
29710
|
cmd.helpGroup(this._defaultCommandGroup);
|
|
29641
29711
|
}
|
|
29642
29712
|
nameFromFilename(filename) {
|
|
29643
|
-
this._name =
|
|
29713
|
+
this._name = path2.basename(filename, path2.extname(filename));
|
|
29644
29714
|
return this;
|
|
29645
29715
|
}
|
|
29646
|
-
executableDir(
|
|
29647
|
-
if (
|
|
29716
|
+
executableDir(path) {
|
|
29717
|
+
if (path === undefined)
|
|
29648
29718
|
return this._executableDir;
|
|
29649
|
-
this._executableDir =
|
|
29719
|
+
this._executableDir = path;
|
|
29650
29720
|
return this;
|
|
29651
29721
|
}
|
|
29652
29722
|
helpInformation(contextOptions) {
|
|
@@ -48938,7 +49008,7 @@ var sha256 = string2().regex(/^[a-f0-9]{64}$/);
|
|
|
48938
49008
|
function safeVerificationPath(path) {
|
|
48939
49009
|
return path.length > 0 && path.length <= 1024 && !isAbsolute2(path) && !/^[a-z]:/i.test(path) && !/[\\\0\r\n]/.test(path) && path.split("/").every((part) => part !== "" && part !== "." && part !== "..") && !/^(?:\.git(?:\/|$)|\.agent-valley(?:\/|$)|\.agents\/(?:state|results)(?:\/|$))/.test(path);
|
|
48940
49010
|
}
|
|
48941
|
-
var
|
|
49011
|
+
var path3 = string2().refine(safeVerificationPath, "Use a literal relative product path inside the worktree.");
|
|
48942
49012
|
var testPath = (name, nodeOnly = false) => safeVerificationPath(name) && !name.startsWith("-") && !/[*?{}]/.test(name) && !name.startsWith("node_modules/") && (nodeOnly ? /(?:\.test|\.spec)\.(?:js|mjs|cjs)$/ : /(?:\.test|\.spec)\.(?:[cm]?[jt]sx?)$/).test(name);
|
|
48943
49013
|
function verificationCommandTestPaths(program, args) {
|
|
48944
49014
|
if (program === "bun" && args[0] === "test")
|
|
@@ -48975,14 +49045,14 @@ function safeVerificationCommand(program, args) {
|
|
|
48975
49045
|
var goalVerificationCheckSchema = discriminatedUnion("kind", [
|
|
48976
49046
|
strictObject({
|
|
48977
49047
|
kind: literal("file"),
|
|
48978
|
-
path:
|
|
49048
|
+
path: path3,
|
|
48979
49049
|
minBytes: number2().int().min(1).max(4194304).default(1),
|
|
48980
49050
|
contains: array(text4).min(1).max(10).optional(),
|
|
48981
49051
|
sha256: sha256.optional()
|
|
48982
49052
|
}),
|
|
48983
49053
|
strictObject({
|
|
48984
49054
|
kind: literal("json"),
|
|
48985
|
-
path:
|
|
49055
|
+
path: path3,
|
|
48986
49056
|
pointer: string2().max(1024).refine((value) => value === "" || /^(?:\/(?:[^~]|~[01])*)+$/.test(value), {
|
|
48987
49057
|
message: "Use an RFC 6901 JSON pointer such as /engines/node."
|
|
48988
49058
|
}),
|
|
@@ -49444,16 +49514,29 @@ function routeEvidence(mission) {
|
|
|
49444
49514
|
function price2(candidate) {
|
|
49445
49515
|
return candidate.inputPerMillionUsd !== undefined && candidate.outputPerMillionUsd !== undefined ? candidate.inputPerMillionUsd + candidate.outputPerMillionUsd : Number.POSITIVE_INFINITY;
|
|
49446
49516
|
}
|
|
49447
|
-
function
|
|
49517
|
+
function workActorCandidates(mission, actor, preserveExplicit = false) {
|
|
49518
|
+
const routing = mission.operatingPolicy?.routing;
|
|
49519
|
+
if (!routing || actor.id === mission.chiefId || !mission.availableAgents && (actor.model || preserveExplicit))
|
|
49520
|
+
return [{ actorType: actor.agentType, model: actor.model }];
|
|
49521
|
+
const ready = mission.operatingPolicy?.readyActors ?? mission.availableAgents ?? [];
|
|
49522
|
+
return routing.candidates.filter((candidate) => ready.includes(candidate.actorType));
|
|
49523
|
+
}
|
|
49524
|
+
function selectWorkActor(mission, actor, taskId, compatibleRoutes) {
|
|
49448
49525
|
const routing = mission.operatingPolicy?.routing;
|
|
49449
|
-
if (!routing || actor.id === mission.chiefId || !mission.availableAgents && actor.model)
|
|
49526
|
+
if (!routing || actor.id === mission.chiefId || !mission.availableAgents && (actor.model || compatibleRoutes)) {
|
|
49527
|
+
if (compatibleRoutes && !compatibleRoutes.has(routeKey({ actorType: actor.agentType, model: actor.model })))
|
|
49528
|
+
throw new Error("Skill compatibility required: the configured Actor/model has no current passing evidence. Refresh oma.skill_compatibility.report_path in av.yaml; explicit Actors are not rerouted.");
|
|
49450
49529
|
return { actor, reason: "Preserved the configured Actor and explicit model." };
|
|
49530
|
+
}
|
|
49451
49531
|
const ready = mission.operatingPolicy?.readyActors ?? mission.availableAgents ?? [];
|
|
49452
49532
|
const candidates = routing.candidates.filter((candidate) => ready.includes(candidate.actorType));
|
|
49453
49533
|
if (!candidates.length)
|
|
49454
49534
|
throw new Error("No configured work routing candidate is ready. Install/login a candidate CLI or update chief.routing.candidates in av.yaml.");
|
|
49535
|
+
const compatible = compatibleRoutes ? candidates.filter((candidate) => compatibleRoutes.has(routeKey(candidate))) : candidates;
|
|
49536
|
+
if (!compatible.length)
|
|
49537
|
+
throw new Error("Skill compatibility required: no ready work candidate has current passing installed evidence. Refresh oma.skill_compatibility.report_path in av.yaml with explicit models before retrying.");
|
|
49455
49538
|
const evidence = routeEvidence(mission);
|
|
49456
|
-
const eligible =
|
|
49539
|
+
const eligible = compatible.filter((candidate) => {
|
|
49457
49540
|
const observed = evidence.find((item) => routeKey(item) === routeKey(candidate));
|
|
49458
49541
|
return !observed || observed.samples < routing.minSamples || observed.successes / observed.samples >= routing.minSuccessRate;
|
|
49459
49542
|
});
|
|
@@ -49515,6 +49598,10 @@ function operationsEvidence(mission) {
|
|
|
49515
49598
|
pricingBasis: "Estimates from configured input/output prices and actual adapter-reported tokens; excludes unreported cache/reasoning/subagent usage and subscription billing.",
|
|
49516
49599
|
routeQuality: routeEvidence(mission).slice(0, 20),
|
|
49517
49600
|
reviewPolicy: mission.operatingPolicy?.reviewVendor ?? "legacy independent Actor",
|
|
49601
|
+
skillCompatibility: mission.operatingPolicy?.skillCompatibility ? {
|
|
49602
|
+
mode: mission.operatingPolicy.skillCompatibility.mode,
|
|
49603
|
+
recentChecks: mission.history.filter((entry) => entry.stage === "skill-compatibility").slice(-10)
|
|
49604
|
+
} : undefined,
|
|
49518
49605
|
recentRuns: runs.slice(-20),
|
|
49519
49606
|
crossVendorReviews: mission.operations?.reviewDecisions.slice(-20) ?? [],
|
|
49520
49607
|
organizationContext: mission.organizationContext,
|
|
@@ -49530,6 +49617,10 @@ function operationsReportLines(mission) {
|
|
|
49530
49617
|
`기록된 token·설정 단가 기반 부분 비용 추정 USD ${evidence.knownEstimatedCostUsd.toFixed(6)} / 비용 미확인 ${evidence.unknownCostRuns}회 / 전체 추정 ${evidence.totalEstimatedCostUsd === null ? "미확인" : `USD ${evidence.totalEstimatedCostUsd.toFixed(6)}`}`,
|
|
49531
49618
|
`최근 독립 리뷰 배정: 다른 vendor ${evidence.crossVendorReviews.filter((review) => review.crossVendor).length}회 / 동일 vendor fallback ${evidence.crossVendorReviews.filter((review) => !review.crossVendor).length}회 / 실제 리뷰 통과 ${evidence.crossVendorReviews.filter((review) => review.outcome === "passed").length}회`,
|
|
49532
49619
|
`vendor 리뷰 정책: ${evidence.reviewPolicy}`,
|
|
49620
|
+
...evidence.skillCompatibility ? [
|
|
49621
|
+
`OMA 스킬 읽기·참조 정책: ${evidence.skillCompatibility.mode}; AV 실행 환경 또는 작업 품질 인증이 아닙니다.`,
|
|
49622
|
+
...evidence.skillCompatibility.recentChecks.map((entry) => `${entry.at}: ${entry.message}`)
|
|
49623
|
+
] : [],
|
|
49533
49624
|
...mission.organizationContext ? [
|
|
49534
49625
|
`계획·리뷰에 제공한 조직 근거: 승인 memory ${mission.organizationContext.memories.length}개 / 과거 outcome ${mission.organizationContext.outcomes.length}개 / 기록된 metric sample ${mission.organizationContext.metrics.length}개`
|
|
49535
49626
|
] : [],
|
|
@@ -49557,15 +49648,15 @@ var chiefReportSchema = strictObject({
|
|
|
49557
49648
|
checks: entries,
|
|
49558
49649
|
remaining: entries
|
|
49559
49650
|
});
|
|
49560
|
-
function
|
|
49651
|
+
function bounded2(value, limit = 500) {
|
|
49561
49652
|
const content = value.trim();
|
|
49562
49653
|
return content.length <= limit ? content : `${content.slice(0, limit - 8)}… [생략]`;
|
|
49563
49654
|
}
|
|
49564
49655
|
function compact(values, limit = 20) {
|
|
49565
49656
|
if (values.length <= limit)
|
|
49566
|
-
return values.map((value) =>
|
|
49657
|
+
return values.map((value) => bounded2(value)).filter(Boolean);
|
|
49567
49658
|
return [
|
|
49568
|
-
...values.slice(0, limit - 1).map((value) =>
|
|
49659
|
+
...values.slice(0, limit - 1).map((value) => bounded2(value)).filter(Boolean),
|
|
49569
49660
|
`${values.length - limit + 1}개 항목 생략`
|
|
49570
49661
|
];
|
|
49571
49662
|
}
|
|
@@ -49580,7 +49671,7 @@ function criteria(mission) {
|
|
|
49580
49671
|
function incompleteReasons(mission) {
|
|
49581
49672
|
const reasons = [];
|
|
49582
49673
|
if (mission.error)
|
|
49583
|
-
reasons.push(`${["waiting", "paused"].includes(mission.status) ? "대기·중단 이유" : "실패 원인"}: ${
|
|
49674
|
+
reasons.push(`${["waiting", "paused"].includes(mission.status) ? "대기·중단 이유" : "실패 원인"}: ${bounded2(mission.error, 450)}`);
|
|
49584
49675
|
if (mission.status !== "completed")
|
|
49585
49676
|
reasons.push(`미션 상태: ${mission.status}. 완료 판정이 없습니다.`);
|
|
49586
49677
|
if (!mission.verification)
|
|
@@ -49633,33 +49724,33 @@ function incompleteReasons(mission) {
|
|
|
49633
49724
|
}
|
|
49634
49725
|
function decisionEvidence(mission) {
|
|
49635
49726
|
const actions = { repair: "수정", reassign: "담당 교체", replan: "재계획", wait: "대기", stop: "중단" };
|
|
49636
|
-
return (mission.supervision?.decisions ?? []).slice(-20).map((decision) =>
|
|
49727
|
+
return (mission.supervision?.decisions ?? []).slice(-20).map((decision) => bounded2(`${decision.round}차 ${actions[decision.action]}${decision.taskId ? ` / 작업 ${decision.taskId}` : ""}${decision.personaId ? ` / 담당 ${decision.personaId}` : ""}: ${decision.reason}`));
|
|
49637
49728
|
}
|
|
49638
49729
|
function reviewEvidence(review) {
|
|
49639
49730
|
return review ? {
|
|
49640
49731
|
passed: review.passed,
|
|
49641
|
-
summary:
|
|
49732
|
+
summary: bounded2(review.summary),
|
|
49642
49733
|
findings: compact(review.findings),
|
|
49643
49734
|
criteria: review.criteria?.slice(0, 20).map((item) => ({
|
|
49644
|
-
criterion:
|
|
49735
|
+
criterion: bounded2(item.criterion),
|
|
49645
49736
|
passed: item.passed,
|
|
49646
|
-
evidence:
|
|
49737
|
+
evidence: bounded2(item.evidence)
|
|
49647
49738
|
}))
|
|
49648
49739
|
} : undefined;
|
|
49649
49740
|
}
|
|
49650
49741
|
function verificationEvidence(verification) {
|
|
49651
49742
|
return verification ? {
|
|
49652
49743
|
ok: verification.ok,
|
|
49653
|
-
output: verification.output ?
|
|
49654
|
-
fingerprint:
|
|
49744
|
+
output: verification.output ? bounded2(verification.output, 3000) : undefined,
|
|
49745
|
+
fingerprint: bounded2(verification.fingerprint, 128)
|
|
49655
49746
|
} : undefined;
|
|
49656
49747
|
}
|
|
49657
49748
|
function advisoryEvidence(kind, advisory) {
|
|
49658
49749
|
return advisory ? {
|
|
49659
49750
|
kind: `upfront ${kind} advice; historical snapshot; not current approval`,
|
|
49660
|
-
planKey:
|
|
49751
|
+
planKey: bounded2(advisory.planKey, 128),
|
|
49661
49752
|
reviewerId: advisory.reviewerId,
|
|
49662
|
-
fingerprint:
|
|
49753
|
+
fingerprint: bounded2(advisory.fingerprint, 128),
|
|
49663
49754
|
review: reviewEvidence(advisory.review)
|
|
49664
49755
|
} : undefined;
|
|
49665
49756
|
}
|
|
@@ -49669,24 +49760,24 @@ function historicalEvidence(mission) {
|
|
|
49669
49760
|
const verification = decision.evidence?.verification;
|
|
49670
49761
|
const review = decision.evidence?.finalReview;
|
|
49671
49762
|
if (verification)
|
|
49672
|
-
lines.push(
|
|
49763
|
+
lines.push(bounded2(`${decision.round}차 판단 당시 검증: ${verification.ok ? "통과" : "실패"} / 파일 상태 ${bounded2(verification.fingerprint, 128)}${verification.output ? ` / ${bounded2(verification.output, 250)}` : ""}`));
|
|
49673
49764
|
if (review) {
|
|
49674
|
-
lines.push(
|
|
49675
|
-
lines.push(...compact(review.findings, 3).map((finding) =>
|
|
49765
|
+
lines.push(bounded2(`${decision.round}차 판단 당시 최종 리뷰: ${review.passed ? "통과" : "실패"} / ${bounded2(review.summary, 350)}`));
|
|
49766
|
+
lines.push(...compact(review.findings, 3).map((finding) => bounded2(`${decision.round}차 판단 당시 지적: ${finding}`)));
|
|
49676
49767
|
}
|
|
49677
49768
|
return lines;
|
|
49678
49769
|
});
|
|
49679
49770
|
}
|
|
49680
49771
|
function checkEvidence(mission) {
|
|
49681
49772
|
return compact([
|
|
49682
|
-
`운영자 검증: ${mission.verification ? mission.verification.ok ? "통과" : "실패" : "미실행"} / 명령: ${
|
|
49773
|
+
`운영자 검증: ${mission.verification ? mission.verification.ok ? "통과" : "실패" : "미실행"} / 명령: ${bounded2(mission.supervision?.operatorVerifyCommand ?? mission.verifyCommand, 350)}`,
|
|
49683
49774
|
...mission.verification?.output ? [`검증 출력: ${mission.verification.output}`] : [],
|
|
49684
49775
|
`Chief Director 최종 리뷰: ${mission.finalReview ? mission.finalReview.passed && mission.finalReview.findings.length === 0 ? "통과" : "실패" : "미실행"}${mission.finalReview ? ` / ${mission.finalReview.summary}` : ""}`,
|
|
49685
49776
|
...mission.tasks.map((task) => `${task.id}: 상태 ${task.status}, 시도 ${task.attempts}회, 독립 리뷰 ${task.review ? task.review.passed && task.review.findings.length === 0 ? "통과" : "실패" : "미실행"} / 리뷰어 ${task.reviewerId}`)
|
|
49686
49777
|
]);
|
|
49687
49778
|
}
|
|
49688
49779
|
function criterionEvidence(mission) {
|
|
49689
|
-
return (mission.finalReview?.criteria ?? []).map((item) =>
|
|
49780
|
+
return (mission.finalReview?.criteria ?? []).map((item) => bounded2(`${bounded2(item.criterion, 200)}: ${item.passed ? "통과" : "실패"} / 근거: ${bounded2(item.evidence, 250)}`));
|
|
49690
49781
|
}
|
|
49691
49782
|
function reportPrompt(mission) {
|
|
49692
49783
|
const goal = mission.supervision?.operatorGoal ?? mission.goal;
|
|
@@ -49714,8 +49805,8 @@ function reportPrompt(mission) {
|
|
|
49714
49805
|
'{"summary":"result","eli5":"plain-language result and user impact","goalAssessment":"criteria and actual verdict","assumptions":[],"decisions":[],"deliverables":[],"checks":[],"remaining":[]}',
|
|
49715
49806
|
`Report evidence (JSON data):
|
|
49716
49807
|
${JSON.stringify({
|
|
49717
|
-
operatorGoal:
|
|
49718
|
-
interpretation: mission.goalBrief ?
|
|
49808
|
+
operatorGoal: bounded2(goal, 4000),
|
|
49809
|
+
interpretation: mission.goalBrief ? bounded2(mission.goalBrief.interpretation, 2000) : undefined,
|
|
49719
49810
|
assumptions: compact(mission.goalBrief?.assumptions ?? []),
|
|
49720
49811
|
successCriteria: compact(criteria(mission)),
|
|
49721
49812
|
status: mission.status,
|
|
@@ -49724,9 +49815,9 @@ ${JSON.stringify({
|
|
|
49724
49815
|
containerObservation: mission.containerObservation,
|
|
49725
49816
|
verdict: incompleteReasons(mission).length === 0 ? "completed" : "incomplete",
|
|
49726
49817
|
incompleteReasons: incompleteReasons(mission),
|
|
49727
|
-
error: mission.error ?
|
|
49728
|
-
workspace:
|
|
49729
|
-
branch:
|
|
49818
|
+
error: mission.error ? bounded2(mission.error, 2000) : undefined,
|
|
49819
|
+
workspace: bounded2(mission.workspace.path, 2000),
|
|
49820
|
+
branch: bounded2(mission.workspace.branch),
|
|
49730
49821
|
chiefId: mission.chiefId,
|
|
49731
49822
|
technicalLeadId: mission.technicalLeadId,
|
|
49732
49823
|
technicalAdvice: advisoryEvidence("technical", mission.technicalReview),
|
|
@@ -49736,10 +49827,10 @@ ${JSON.stringify({
|
|
|
49736
49827
|
marketingAdvice: advisoryEvidence("marketing", mission.marketingReview),
|
|
49737
49828
|
actors: mission.personas.slice(0, 20).map((persona) => ({
|
|
49738
49829
|
id: persona.id,
|
|
49739
|
-
name:
|
|
49740
|
-
role:
|
|
49741
|
-
cli:
|
|
49742
|
-
model: persona.model ?
|
|
49830
|
+
name: bounded2(persona.name),
|
|
49831
|
+
role: bounded2(persona.role),
|
|
49832
|
+
cli: bounded2(persona.agentType),
|
|
49833
|
+
model: persona.model ? bounded2(persona.model) : "native default (actual model not recorded)",
|
|
49743
49834
|
selectedSkills: persona.skills.slice(0, 30)
|
|
49744
49835
|
})),
|
|
49745
49836
|
decisions: decisions.map((decision) => ({
|
|
@@ -49747,8 +49838,8 @@ ${JSON.stringify({
|
|
|
49747
49838
|
action: decision.action,
|
|
49748
49839
|
taskId: decision.taskId,
|
|
49749
49840
|
actorId: decision.personaId,
|
|
49750
|
-
reason:
|
|
49751
|
-
instructions: decision.instructions ?
|
|
49841
|
+
reason: bounded2(decision.reason),
|
|
49842
|
+
instructions: decision.instructions ? bounded2(decision.instructions) : undefined,
|
|
49752
49843
|
historicalEvidence: decision.evidence && snapshotDecisions.has(decision) ? {
|
|
49753
49844
|
kind: "evidence at the recovery decision; not current approval",
|
|
49754
49845
|
finalReview: reviewEvidence(decision.evidence.finalReview),
|
|
@@ -49757,25 +49848,25 @@ ${JSON.stringify({
|
|
|
49757
49848
|
})),
|
|
49758
49849
|
tasks: mission.tasks.slice(0, 12).map((state) => ({
|
|
49759
49850
|
id: state.id,
|
|
49760
|
-
title:
|
|
49851
|
+
title: bounded2(mission.plan?.tasks.find((task) => task.id === state.id)?.title ?? state.id),
|
|
49761
49852
|
actorId: mission.plan?.tasks.find((task) => task.id === state.id)?.personaId,
|
|
49762
49853
|
reviewerId: state.reviewerId,
|
|
49763
49854
|
status: state.status,
|
|
49764
49855
|
attempts: state.attempts,
|
|
49765
|
-
actorClaim: state.output ?
|
|
49856
|
+
actorClaim: state.output ? bounded2(state.output, 3000) : undefined,
|
|
49766
49857
|
review: reviewEvidence(state.review)
|
|
49767
49858
|
})),
|
|
49768
|
-
verifyCommand:
|
|
49859
|
+
verifyCommand: bounded2(mission.supervision?.operatorVerifyCommand ?? mission.verifyCommand, 1200),
|
|
49769
49860
|
verification: verificationEvidence(mission.verification),
|
|
49770
49861
|
goalVerification: mission.goalVerification,
|
|
49771
49862
|
execution: mission.execution,
|
|
49772
49863
|
executionPolicy: mission.executionPolicy,
|
|
49773
49864
|
finalReview: reviewEvidence(mission.finalReview),
|
|
49774
49865
|
history: mission.history.slice(-30).map((event) => ({
|
|
49775
|
-
at:
|
|
49776
|
-
stage:
|
|
49866
|
+
at: bounded2(event.at),
|
|
49867
|
+
stage: bounded2(event.stage),
|
|
49777
49868
|
taskId: event.taskId,
|
|
49778
|
-
message:
|
|
49869
|
+
message: bounded2(event.message)
|
|
49779
49870
|
}))
|
|
49780
49871
|
})}`
|
|
49781
49872
|
].join(`
|
|
@@ -49797,10 +49888,10 @@ function parseReport(source) {
|
|
|
49797
49888
|
function fallbackReport(mission) {
|
|
49798
49889
|
const reasons = incompleteReasons(mission);
|
|
49799
49890
|
const complete = reasons.length === 0;
|
|
49800
|
-
const goal =
|
|
49891
|
+
const goal = bounded2(mission.supervision?.operatorGoal ?? mission.goal, 350);
|
|
49801
49892
|
return {
|
|
49802
49893
|
summary: complete ? "작업, 독립 리뷰, 운영자 검증과 Chief Director 최종 리뷰를 통과했습니다." : "목표는 미완료입니다. 확인된 미해결 조건과 보관된 실행 기록을 보고합니다.",
|
|
49803
|
-
eli5: complete ? `“${goal}”을 위한 결과물을 만들고, 다른 담당자의 점검과 지정한 확인 절차를 마쳤습니다. 결과물은 아래 작업 경로에 보관되어 있어 직접 확인할 수 있습니다.` : `“${goal}”을 위해 작업했지만, 아직 모든 확인 절차를 통과한 결과는 아닙니다. ${
|
|
49894
|
+
eli5: complete ? `“${goal}”을 위한 결과물을 만들고, 다른 담당자의 점검과 지정한 확인 절차를 마쳤습니다. 결과물은 아래 작업 경로에 보관되어 있어 직접 확인할 수 있습니다.` : `“${goal}”을 위해 작업했지만, 아직 모든 확인 절차를 통과한 결과는 아닙니다. ${bounded2(reasons[0] ?? "완료 증거가 없습니다.", 350)} 이미 만든 작업은 보관되어 있습니다. Chief Director가 기록한 판단과 다음 관측·재개 시각, 아직 충족되지 않은 조건을 아래에서 보고합니다.`,
|
|
49804
49895
|
goalAssessment: complete ? "기록된 성공 기준에 대해 작업별 독립 리뷰와 운영자 검증이 통과했고, Chief Director가 최종 승인했습니다." : "성공 기준 전체의 충족을 확인하지 못했습니다. 일부 작업이나 검증이 통과했더라도 목표 달성으로 표시하지 않습니다.",
|
|
49805
49896
|
assumptions: compact(mission.goalBrief?.assumptions ?? []),
|
|
49806
49897
|
decisions: decisionEvidence(mission),
|
|
@@ -49818,7 +49909,7 @@ function fallbackReport(mission) {
|
|
|
49818
49909
|
};
|
|
49819
49910
|
}
|
|
49820
49911
|
function markdown(value, limit = 1200) {
|
|
49821
|
-
return
|
|
49912
|
+
return bounded2(value, limit).replace(/[\p{Cc}\p{Cf}]/gu, " ").replace(/\s+/g, " ").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/[\\`*_{}[\]()#+.!|~-]/g, "\\$&");
|
|
49822
49913
|
}
|
|
49823
49914
|
function list(values) {
|
|
49824
49915
|
return values.length ? compact(values).map((value) => `- ${markdown(value)}`).join(`
|
|
@@ -50333,12 +50424,12 @@ async function assertMissionWorkspace(mission) {
|
|
|
50333
50424
|
}
|
|
50334
50425
|
|
|
50335
50426
|
// ../../packages/core/src/chief/parallel-workspace.ts
|
|
50336
|
-
var
|
|
50427
|
+
var hash2 = (value) => createHash10("sha256").update(value).digest("hex");
|
|
50337
50428
|
var same = (a, b) => JSON.stringify(a) === JSON.stringify(b);
|
|
50338
50429
|
function identity3(missionId, taskId, attempt) {
|
|
50339
50430
|
if (!taskId || taskId.length > 200 || !Number.isSafeInteger(attempt) || attempt < 1)
|
|
50340
50431
|
throw new Error("Use a valid task ID and positive attempt number for each parallel Actor.");
|
|
50341
|
-
return `${
|
|
50432
|
+
return `${hash2(missionId).slice(0, 16)}-${hash2(taskId).slice(0, 16)}-${attempt}`;
|
|
50342
50433
|
}
|
|
50343
50434
|
async function paths(source, missionId, taskId, attempt) {
|
|
50344
50435
|
const root = await parallelRoot(source);
|
|
@@ -50482,7 +50573,7 @@ async function collectTaskDelivery(mission, workspace) {
|
|
|
50482
50573
|
version: 1,
|
|
50483
50574
|
workspace,
|
|
50484
50575
|
patchPath: location.patch,
|
|
50485
|
-
patchSha256:
|
|
50576
|
+
patchSha256: hash2(patch),
|
|
50486
50577
|
deliveryTree: final.tree,
|
|
50487
50578
|
changes,
|
|
50488
50579
|
status: "prepared"
|
|
@@ -50498,7 +50589,7 @@ async function integrateTaskDelivery(mission, input) {
|
|
|
50498
50589
|
if (delivery.workspace.missionId !== mission.id || !same(delivery.workspace, input.workspace) || delivery.patchSha256 !== input.patchSha256 || delivery.patchPath !== location.patch)
|
|
50499
50590
|
throw new Error("Parallel delivery does not match its persisted task identity and patch. Inspect the saved artifacts before recovery.");
|
|
50500
50591
|
const patch = await readFile4(location.patch);
|
|
50501
|
-
if (
|
|
50592
|
+
if (hash2(patch) !== delivery.patchSha256)
|
|
50502
50593
|
throw new Error("Parallel delivery patch changed. Restore its saved SHA256 before integration.");
|
|
50503
50594
|
const current = await captureParallelBaseline(mission.workspace.path);
|
|
50504
50595
|
const images = await parallelTreeImages(mission.workspace.path, current.tree);
|
|
@@ -66141,7 +66232,11 @@ ${details}` : ""}`);
|
|
|
66141
66232
|
timeoutSec,
|
|
66142
66233
|
maxRepairs,
|
|
66143
66234
|
maxRounds,
|
|
66144
|
-
operatingPolicy: chiefOperatingPolicy(chiefConfig, readyActors, !profile
|
|
66235
|
+
operatingPolicy: chiefOperatingPolicy(chiefConfig, readyActors, !profile, project?.oma?.skill_compatibility ? {
|
|
66236
|
+
reportPath: resolve11(root, project.oma.skill_compatibility.report_path),
|
|
66237
|
+
maxAgeHours: project.oma.skill_compatibility.max_age_hours,
|
|
66238
|
+
mode: project.oma.skill_compatibility.mode
|
|
66239
|
+
} : undefined),
|
|
66145
66240
|
capturePolicy: chiefCapturePolicy(chiefConfig),
|
|
66146
66241
|
executionPolicy,
|
|
66147
66242
|
metricSourcePolicy: chiefConfig.metric_sources,
|
|
@@ -66676,7 +66771,7 @@ class ContinuousOperationStore {
|
|
|
66676
66771
|
}
|
|
66677
66772
|
|
|
66678
66773
|
// src/chief-continuous.ts
|
|
66679
|
-
import { execFile as
|
|
66774
|
+
import { execFile as execFile5 } from "node:child_process";
|
|
66680
66775
|
import { randomUUID as randomUUID15 } from "node:crypto";
|
|
66681
66776
|
import { mkdir as mkdir17, realpath as realpath19, rename as rename7, unlink as unlink7, writeFile as writeFile13 } from "node:fs/promises";
|
|
66682
66777
|
import { join as join35, resolve as resolve19 } from "node:path";
|
|
@@ -67963,11 +68058,141 @@ function getCachedTriggerTable(rootDir = process.cwd()) {
|
|
|
67963
68058
|
return table;
|
|
67964
68059
|
}
|
|
67965
68060
|
|
|
68061
|
+
// ../../packages/core/src/oma/latest-cli.ts
|
|
68062
|
+
import { spawn as spawn7 } from "node:child_process";
|
|
68063
|
+
var VERSION_TIMEOUT_MS = 1e4;
|
|
68064
|
+
var REGISTRY_TIMEOUT_MS = 60000;
|
|
68065
|
+
var INSTALL_TIMEOUT_MS = 300000;
|
|
68066
|
+
var MAX_OUTPUT_BYTES2 = 1048576;
|
|
68067
|
+
var INSTALL_HINT = "Run npm install --global --ignore-scripts oh-my-agent@latest, confirm oma --version, then retry.";
|
|
68068
|
+
var VERSION = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(?:\+[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*)?$/;
|
|
68069
|
+
function parseOmaCliVersion(value) {
|
|
68070
|
+
const trimmed = value.trim();
|
|
68071
|
+
if (trimmed.length > 128)
|
|
68072
|
+
return null;
|
|
68073
|
+
const version = trimmed.startsWith("v") ? trimmed.slice(1) : trimmed;
|
|
68074
|
+
return VERSION.test(version) ? version : null;
|
|
68075
|
+
}
|
|
68076
|
+
|
|
68077
|
+
class CommandFailure extends Error {
|
|
68078
|
+
kind;
|
|
68079
|
+
constructor(kind) {
|
|
68080
|
+
super(kind);
|
|
68081
|
+
this.kind = kind;
|
|
68082
|
+
}
|
|
68083
|
+
}
|
|
68084
|
+
var defaultIO = {
|
|
68085
|
+
run: (command, args, { timeoutMs, maxOutputBytes }) => new Promise((resolve, reject) => {
|
|
68086
|
+
let settled = false;
|
|
68087
|
+
let stdout = "";
|
|
68088
|
+
let stderr = "";
|
|
68089
|
+
let outputBytes = 0;
|
|
68090
|
+
let timer;
|
|
68091
|
+
const finish = (error, exitCode = null) => {
|
|
68092
|
+
if (settled)
|
|
68093
|
+
return;
|
|
68094
|
+
settled = true;
|
|
68095
|
+
clearTimeout(timer);
|
|
68096
|
+
if (error)
|
|
68097
|
+
reject(error);
|
|
68098
|
+
else
|
|
68099
|
+
resolve({ exitCode, stdout, stderr });
|
|
68100
|
+
};
|
|
68101
|
+
try {
|
|
68102
|
+
const child = spawn7(command, args, { stdio: ["ignore", "pipe", "pipe"], windowsHide: true });
|
|
68103
|
+
const append = (chunk, destination) => {
|
|
68104
|
+
if (settled)
|
|
68105
|
+
return;
|
|
68106
|
+
outputBytes += Buffer.byteLength(chunk);
|
|
68107
|
+
if (outputBytes > maxOutputBytes) {
|
|
68108
|
+
child.kill("SIGKILL");
|
|
68109
|
+
finish(new CommandFailure("output"));
|
|
68110
|
+
} else if (destination === "stdout")
|
|
68111
|
+
stdout += chunk.toString();
|
|
68112
|
+
else
|
|
68113
|
+
stderr += chunk.toString();
|
|
68114
|
+
};
|
|
68115
|
+
child.stdout?.on("data", (chunk) => append(chunk, "stdout"));
|
|
68116
|
+
child.stderr?.on("data", (chunk) => append(chunk, "stderr"));
|
|
68117
|
+
child.once("error", () => finish(new CommandFailure("spawn")));
|
|
68118
|
+
child.once("close", (code) => finish(undefined, code));
|
|
68119
|
+
timer = setTimeout(() => {
|
|
68120
|
+
child.kill("SIGKILL");
|
|
68121
|
+
finish(new CommandFailure("timeout"));
|
|
68122
|
+
}, timeoutMs);
|
|
68123
|
+
} catch {
|
|
68124
|
+
finish(new CommandFailure("spawn"));
|
|
68125
|
+
}
|
|
68126
|
+
})
|
|
68127
|
+
};
|
|
68128
|
+
function failure2(stage, error) {
|
|
68129
|
+
const detail = error instanceof CommandFailure ? error.kind === "timeout" ? "request timed out" : error.kind === "output" ? "command output exceeded the limit" : "command could not start" : "command failed";
|
|
68130
|
+
return new Error(`Latest OMA CLI ${stage}: ${detail}. ${INSTALL_HINT}`);
|
|
68131
|
+
}
|
|
68132
|
+
async function installedVersion(io) {
|
|
68133
|
+
try {
|
|
68134
|
+
const result = await io.run("oma", ["--version"], {
|
|
68135
|
+
timeoutMs: VERSION_TIMEOUT_MS,
|
|
68136
|
+
maxOutputBytes: MAX_OUTPUT_BYTES2
|
|
68137
|
+
});
|
|
68138
|
+
return result.exitCode === 0 ? parseOmaCliVersion(result.stdout) : null;
|
|
68139
|
+
} catch {
|
|
68140
|
+
return null;
|
|
68141
|
+
}
|
|
68142
|
+
}
|
|
68143
|
+
async function prepare(io) {
|
|
68144
|
+
const installed = await installedVersion(io);
|
|
68145
|
+
let latest;
|
|
68146
|
+
try {
|
|
68147
|
+
const result = await io.run("npm", ["view", "oh-my-agent@latest", "version", "--json", "--prefer-online"], {
|
|
68148
|
+
timeoutMs: REGISTRY_TIMEOUT_MS,
|
|
68149
|
+
maxOutputBytes: MAX_OUTPUT_BYTES2
|
|
68150
|
+
});
|
|
68151
|
+
if (result.exitCode !== 0)
|
|
68152
|
+
throw failure2("registry lookup");
|
|
68153
|
+
const value = JSON.parse(result.stdout);
|
|
68154
|
+
latest = typeof value === "string" ? parseOmaCliVersion(value) : null;
|
|
68155
|
+
} catch (error) {
|
|
68156
|
+
throw failure2("registry lookup", error);
|
|
68157
|
+
}
|
|
68158
|
+
if (!latest)
|
|
68159
|
+
throw new Error(`Latest OMA CLI registry returned invalid version metadata. ${INSTALL_HINT}`);
|
|
68160
|
+
if (installed === latest)
|
|
68161
|
+
return { version: latest, installed: false };
|
|
68162
|
+
try {
|
|
68163
|
+
const result = await io.run("npm", ["install", "--global", "--ignore-scripts", "oh-my-agent@latest"], {
|
|
68164
|
+
timeoutMs: INSTALL_TIMEOUT_MS,
|
|
68165
|
+
maxOutputBytes: MAX_OUTPUT_BYTES2
|
|
68166
|
+
});
|
|
68167
|
+
if (result.exitCode !== 0)
|
|
68168
|
+
throw failure2("installation");
|
|
68169
|
+
} catch (error) {
|
|
68170
|
+
throw failure2("installation", error);
|
|
68171
|
+
}
|
|
68172
|
+
const confirmed = await installedVersion(io);
|
|
68173
|
+
if (confirmed !== latest)
|
|
68174
|
+
throw new Error(`Latest OMA CLI verification expected ${latest}, but oma --version reported ${confirmed ?? "unavailable"}. Check PATH for another OMA executable. ${INSTALL_HINT}`);
|
|
68175
|
+
return { version: latest, installed: true };
|
|
68176
|
+
}
|
|
68177
|
+
var preparing = new WeakMap;
|
|
68178
|
+
function ensureLatestOmaCli(options = {}) {
|
|
68179
|
+
const io = options.io ?? defaultIO;
|
|
68180
|
+
const current = preparing.get(io);
|
|
68181
|
+
if (current)
|
|
68182
|
+
return current;
|
|
68183
|
+
const pending = prepare(io).finally(() => {
|
|
68184
|
+
if (preparing.get(io) === pending)
|
|
68185
|
+
preparing.delete(io);
|
|
68186
|
+
});
|
|
68187
|
+
preparing.set(io, pending);
|
|
68188
|
+
return pending;
|
|
68189
|
+
}
|
|
68190
|
+
|
|
67966
68191
|
// ../../packages/core/src/oma/receipt-adapter.ts
|
|
67967
|
-
var
|
|
68192
|
+
var OMA_RECEIPT_SCHEMA_VERSION = 1;
|
|
67968
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;
|
|
67969
68194
|
var HASH = /^[a-f0-9]{64}$/;
|
|
67970
|
-
var
|
|
68195
|
+
var defaultIO2 = {
|
|
67971
68196
|
listRunFiles: (workspacePath) => {
|
|
67972
68197
|
const dir = join25(workspacePath, ".agents", "state", "agent-runs");
|
|
67973
68198
|
return readdirSync(dir).filter((name) => RUN_ID.test(name.slice(0, -5)) && name.endsWith(".json"));
|
|
@@ -67996,7 +68221,7 @@ function stringArray(value) {
|
|
|
67996
68221
|
function shellQuote(value) {
|
|
67997
68222
|
return `'${value.replaceAll("'", "'\\''")}'`;
|
|
67998
68223
|
}
|
|
67999
|
-
async function prepareOmaAttempt(request) {
|
|
68224
|
+
async function prepareOmaAttempt(request, dependencies = {}) {
|
|
68000
68225
|
if (!request.verifyCommand.trim()) {
|
|
68001
68226
|
throw new Error("oma.mode: strict requires verify.command in av.yaml or a routing verify_command");
|
|
68002
68227
|
}
|
|
@@ -68011,6 +68236,7 @@ ${request.issue.description ?? ""}`, table);
|
|
|
68011
68236
|
if (!existsSync4(file))
|
|
68012
68237
|
throw new Error(`OMA workflow file missing in target worktree: ${file}`);
|
|
68013
68238
|
}
|
|
68239
|
+
await ensureLatestOmaCli({ io: dependencies.latestCliIO });
|
|
68014
68240
|
const path = join25(request.workspace.path, ".agents", "results", `plan-${request.attempt.id}.json`);
|
|
68015
68241
|
const plan = {
|
|
68016
68242
|
session_id: request.attempt.id,
|
|
@@ -68064,14 +68290,16 @@ function buildOmaGuidance(request) {
|
|
|
68064
68290
|
].join(`
|
|
68065
68291
|
`);
|
|
68066
68292
|
}
|
|
68067
|
-
function validateOmaEvidence(request, io =
|
|
68293
|
+
function validateOmaEvidence(request, io = defaultIO2) {
|
|
68068
68294
|
const root = resolve14(request.workspace.path);
|
|
68069
68295
|
if (!request.verifyCommand.trim())
|
|
68070
68296
|
return fail("Strict OMA mode has no configured verify command");
|
|
68297
|
+
let cliVersion;
|
|
68071
68298
|
try {
|
|
68072
68299
|
const version = io.runCli(["--version"], root);
|
|
68073
|
-
|
|
68074
|
-
|
|
68300
|
+
cliVersion = parseOmaCliVersion(version.stdout);
|
|
68301
|
+
if (version.exitCode !== 0 || !cliVersion) {
|
|
68302
|
+
return fail("OMA CLI is unavailable or returned a malformed version. Run npm install -g oh-my-agent@latest, then confirm oma --version and rerun the receipt verification.");
|
|
68075
68303
|
}
|
|
68076
68304
|
} catch (err) {
|
|
68077
68305
|
return fail(`OMA CLI unavailable: ${String(err)}`);
|
|
@@ -68093,8 +68321,11 @@ function validateOmaEvidence(request, io = defaultIO) {
|
|
|
68093
68321
|
const run = forAttempt.at(-1);
|
|
68094
68322
|
if (!run)
|
|
68095
68323
|
return fail("No OMA receipt is bound to this Valley attempt");
|
|
68096
|
-
if (run.schemaVersion !==
|
|
68097
|
-
return fail(
|
|
68324
|
+
if (run.schemaVersion !== OMA_RECEIPT_SCHEMA_VERSION) {
|
|
68325
|
+
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
|
+
}
|
|
68327
|
+
if (run.taskId !== request.attempt.id || !RUN_ID.test(String(run.runId))) {
|
|
68328
|
+
return fail("OMA receipt task identity is incompatible");
|
|
68098
68329
|
}
|
|
68099
68330
|
if (run.workspace !== root || run.artifactRoot !== root || run.status !== "completed" || run.exitCode !== 0) {
|
|
68100
68331
|
return fail("OMA receipt has the wrong workspace or did not complete");
|
|
@@ -68161,6 +68392,8 @@ function validateOmaEvidence(request, io = defaultIO) {
|
|
|
68161
68392
|
try {
|
|
68162
68393
|
const status = io.runCli(["agent", "status", request.attempt.id, request.agentId, "--project-root", root], root);
|
|
68163
68394
|
if (status.exitCode !== 0 || status.stdout.trim() !== `${request.agentId}:completed`) {
|
|
68395
|
+
if (status.stdout.trim() !== `${request.agentId}:stale`)
|
|
68396
|
+
return fail(`OMA CLI ${cliVersion} did not provide the required native <agent>:completed status proof. Update AV and OMA (npm install -g oh-my-agent@latest), then rerun verification; unknown status output cannot establish completion.`);
|
|
68164
68397
|
return fail("OMA CLI did not confirm current completed evidence");
|
|
68165
68398
|
}
|
|
68166
68399
|
} catch (err) {
|
|
@@ -68169,6 +68402,214 @@ function validateOmaEvidence(request, io = defaultIO) {
|
|
|
68169
68402
|
return { ok: true, runId: String(run.runId) };
|
|
68170
68403
|
}
|
|
68171
68404
|
|
|
68405
|
+
// ../../packages/core/src/oma/skill-matrix-adapter.ts
|
|
68406
|
+
import { posix } from "node:path";
|
|
68407
|
+
|
|
68408
|
+
// ../../packages/core/src/oma/skill-matrix-io.ts
|
|
68409
|
+
init_skill_matrix_schema();
|
|
68410
|
+
import { execFile as execFile4 } from "node:child_process";
|
|
68411
|
+
import { constants as constants5 } from "node:fs";
|
|
68412
|
+
import { open as open7 } from "node:fs/promises";
|
|
68413
|
+
var MAX_BYTES = 4 * 1024 * 1024;
|
|
68414
|
+
async function command(binary, args, signal) {
|
|
68415
|
+
return new Promise((resolve, reject) => {
|
|
68416
|
+
execFile4(binary, args, {
|
|
68417
|
+
encoding: "utf8",
|
|
68418
|
+
timeout: 1e4,
|
|
68419
|
+
maxBuffer: MAX_BYTES,
|
|
68420
|
+
signal,
|
|
68421
|
+
...binary === "oma" ? { env: { ...process.env, OMA_SKIP_VERSION_CHECK: "1" } } : {}
|
|
68422
|
+
}, (error, stdout) => {
|
|
68423
|
+
if (error)
|
|
68424
|
+
reject(new Error(`${binary} local diagnostic command failed. Check its installation/version and retry.`));
|
|
68425
|
+
else
|
|
68426
|
+
resolve(stdout);
|
|
68427
|
+
});
|
|
68428
|
+
});
|
|
68429
|
+
}
|
|
68430
|
+
async function readReport(path) {
|
|
68431
|
+
const file = await open7(path, constants5.O_RDONLY | constants5.O_NOFOLLOW | constants5.O_NONBLOCK);
|
|
68432
|
+
try {
|
|
68433
|
+
const info = await file.stat();
|
|
68434
|
+
if (!info.isFile() || info.size > MAX_BYTES)
|
|
68435
|
+
throw new Error("Matrix report must be a regular file at most 4 MiB.");
|
|
68436
|
+
const bytes = Buffer.alloc(info.size + 1);
|
|
68437
|
+
let length = 0;
|
|
68438
|
+
while (length < bytes.length) {
|
|
68439
|
+
const result = await file.read(bytes, length, bytes.length - length, length);
|
|
68440
|
+
if (!result.bytesRead)
|
|
68441
|
+
break;
|
|
68442
|
+
length += result.bytesRead;
|
|
68443
|
+
}
|
|
68444
|
+
if (length !== info.size)
|
|
68445
|
+
throw new Error("Matrix report changed during the read. Retry after its writer finishes.");
|
|
68446
|
+
return JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes.subarray(0, length)));
|
|
68447
|
+
} finally {
|
|
68448
|
+
await file.close();
|
|
68449
|
+
}
|
|
68450
|
+
}
|
|
68451
|
+
var defaultSkillMatrixDeps = {
|
|
68452
|
+
now: Date.now,
|
|
68453
|
+
platform: process.platform,
|
|
68454
|
+
arch: process.arch,
|
|
68455
|
+
readReport,
|
|
68456
|
+
plan: async (workspace, skills, signal) => JSON.parse(await command("oma", [
|
|
68457
|
+
"skills",
|
|
68458
|
+
"matrix",
|
|
68459
|
+
"--project-root",
|
|
68460
|
+
workspace,
|
|
68461
|
+
"--skills",
|
|
68462
|
+
skills.join(","),
|
|
68463
|
+
"--delivery",
|
|
68464
|
+
"injected",
|
|
68465
|
+
"--vendors",
|
|
68466
|
+
"claude,codex",
|
|
68467
|
+
"--json"
|
|
68468
|
+
], signal)),
|
|
68469
|
+
cliVersion: async (vendor, signal) => {
|
|
68470
|
+
const version = (await command(vendor, ["--version"], signal)).trim();
|
|
68471
|
+
return /^[\w .()+/-]{1,160}$/.test(version) ? version : null;
|
|
68472
|
+
}
|
|
68473
|
+
};
|
|
68474
|
+
function parseSkillMatrix(value) {
|
|
68475
|
+
const parsed = matrixReportSchema.safeParse(value);
|
|
68476
|
+
if (!parsed.success)
|
|
68477
|
+
throw new Error("Matrix report uses an unsupported or malformed evidence contract. Regenerate it with the current OMA CLI.");
|
|
68478
|
+
const report = parsed.data;
|
|
68479
|
+
const unique = (values) => new Set(values).size === values.length;
|
|
68480
|
+
if (!unique(report.cases.map((entry) => entry.id)) || !unique(report.cells.map((entry) => `${entry.vendor}\x00${entry.caseId}`)) || report.bundle && (!unique(report.bundle.skills.map((entry) => entry.name)) || !unique(report.bundle.skills.map((entry) => entry.caseId))) || report.cells.some((cell) => !unique(cell.checks.map((check) => check.id))))
|
|
68481
|
+
throw new Error("Matrix report repeats a skill, case or vendor cell. Regenerate an unambiguous report.");
|
|
68482
|
+
return report;
|
|
68483
|
+
}
|
|
68484
|
+
|
|
68485
|
+
// ../../packages/core/src/oma/skill-matrix-adapter.ts
|
|
68486
|
+
var scope = "installed injected read-reference audit; not AV runtime or task-quality certification";
|
|
68487
|
+
var safeNames = /^[a-z0-9][a-z0-9-]{0,127}$/;
|
|
68488
|
+
var remediation = "Regenerate the installed injected matrix with explicit models, then set oma.skill_compatibility.report_path in av.yaml.";
|
|
68489
|
+
var matrixRouteKey = (route) => `${route.actorType}\x00${route.model ?? ""}`;
|
|
68490
|
+
function sourceProblem(report) {
|
|
68491
|
+
if (report.sourceKind !== "installed" || report.delivery !== "injected" || report.auditScope !== "read-reference" || !report.bundle)
|
|
68492
|
+
return "Evidence is not an installed, injected, read-reference audit. Synthetic probes cannot authorize installed skills.";
|
|
68493
|
+
return;
|
|
68494
|
+
}
|
|
68495
|
+
function sameCoverage(a, b) {
|
|
68496
|
+
const sorted = (items) => JSON.stringify([...items].sort());
|
|
68497
|
+
return a.hash === b.hash && a.caseId === b.caseId && sorted(a.requiredFiles) === sorted(b.requiredFiles) && sorted(a.missingFiles) === sorted(b.missingFiles) && JSON.stringify(a.excludedReferences) === JSON.stringify(b.excludedReferences);
|
|
68498
|
+
}
|
|
68499
|
+
function assessRoute(report, plan, skills, route, version) {
|
|
68500
|
+
const result = (status, reason) => ({
|
|
68501
|
+
...route,
|
|
68502
|
+
status,
|
|
68503
|
+
reason
|
|
68504
|
+
});
|
|
68505
|
+
if (route.actorType !== "claude" && route.actorType !== "codex")
|
|
68506
|
+
return result("unknown", "This matrix protocol measures only Claude and Codex.");
|
|
68507
|
+
if (!route.model)
|
|
68508
|
+
return result("unknown", "The candidate uses an unpinned native model default; it cannot match a measured model.");
|
|
68509
|
+
if (!version)
|
|
68510
|
+
return result("unknown", "The current native CLI version could not be verified.");
|
|
68511
|
+
for (const name of skills) {
|
|
68512
|
+
const current = plan.bundle?.skills.find((entry) => entry.name === name);
|
|
68513
|
+
const saved = report.bundle?.skills.find((entry) => entry.name === name);
|
|
68514
|
+
if (!current || !saved)
|
|
68515
|
+
return result("unknown", `Skill ${name} has no complete installed audit coverage.`);
|
|
68516
|
+
if (!sameCoverage(current, saved))
|
|
68517
|
+
return result("unknown", `Skill ${name} content or reference coverage changed after the audit.`);
|
|
68518
|
+
if (current.missingFiles.length || current.excludedReferences.length || saved.missingFiles.length || saved.excludedReferences.length)
|
|
68519
|
+
return result("unknown", `Skill ${name} has missing or excluded references; complete its audit coverage first.`);
|
|
68520
|
+
if (!report.cases.some((entry) => entry.id === saved.caseId && entry.skill === name))
|
|
68521
|
+
return result("unknown", `Skill ${name} required case is absent from the measured selection.`);
|
|
68522
|
+
const cell = report.cells.find((entry) => entry.caseId === saved.caseId && entry.vendor === route.actorType);
|
|
68523
|
+
if (!cell || cell.skill !== name || cell.contentHash !== current.hash)
|
|
68524
|
+
return result("unknown", `Skill ${name} lacks a matching measured vendor cell.`);
|
|
68525
|
+
if (cell.cliVersion !== version)
|
|
68526
|
+
return result("unknown", `Skill ${name} was measured with a different or unknown native CLI version.`);
|
|
68527
|
+
if (cell.model !== route.model)
|
|
68528
|
+
return result("unknown", `Skill ${name} was measured with a different or unknown reported model.`);
|
|
68529
|
+
if (cell.status !== "pass" || !cell.checks.length || cell.checks.some((check) => check.status !== "pass"))
|
|
68530
|
+
return result(cell.status === "fail" ? "fail" : "unknown", `Skill ${name} audit is ${cell.status}; passing read-reference evidence is required.`);
|
|
68531
|
+
const entry = `${name}/SKILL.md`;
|
|
68532
|
+
if (!current.requiredFiles.includes(entry))
|
|
68533
|
+
return result("unknown", `Skill ${name} audit omits its installed SKILL.md.`);
|
|
68534
|
+
const required = [
|
|
68535
|
+
"process",
|
|
68536
|
+
"output",
|
|
68537
|
+
"content",
|
|
68538
|
+
"integrity",
|
|
68539
|
+
"reference-coverage",
|
|
68540
|
+
...current.requiredFiles.filter((file) => file !== entry).map((file) => `reference:${posix.relative(name, file)}`)
|
|
68541
|
+
];
|
|
68542
|
+
if (required.some((id) => !cell.checks.some((check) => check.id === id && check.status === "pass" && (id === "content" || id.startsWith("reference:") ? check.proof === "read" : true))))
|
|
68543
|
+
return result("unknown", `Skill ${name} audit lacks a mandatory successful read-reference check.`);
|
|
68544
|
+
}
|
|
68545
|
+
return result("pass", "All selected skills have current passing installed injected read-reference evidence.");
|
|
68546
|
+
}
|
|
68547
|
+
async function inspectSkillCompatibility(policy, workspace, selectedSkills, routes, deps = defaultSkillMatrixDeps, signal) {
|
|
68548
|
+
const unknown = (reason) => ({
|
|
68549
|
+
scope,
|
|
68550
|
+
routes: routes.map((route) => ({ ...route, status: "unknown", reason }))
|
|
68551
|
+
});
|
|
68552
|
+
if (selectedSkills?.length === 0)
|
|
68553
|
+
return {
|
|
68554
|
+
scope,
|
|
68555
|
+
routes: routes.map((route) => ({
|
|
68556
|
+
...route,
|
|
68557
|
+
status: "pass",
|
|
68558
|
+
reason: "No skills selected; no compatibility claim is required."
|
|
68559
|
+
}))
|
|
68560
|
+
};
|
|
68561
|
+
try {
|
|
68562
|
+
if (signal?.aborted)
|
|
68563
|
+
throw new Error("Interrupted");
|
|
68564
|
+
const report = parseSkillMatrix(await deps.readReport(policy.reportPath));
|
|
68565
|
+
const source = sourceProblem(report);
|
|
68566
|
+
if (source)
|
|
68567
|
+
return unknown(source);
|
|
68568
|
+
if (report.mode !== "live" || report.status !== "completed")
|
|
68569
|
+
return unknown("The report is not a completed live measurement; a plan is unmeasured.");
|
|
68570
|
+
const age = deps.now() - Date.parse(report.createdAt);
|
|
68571
|
+
if (age < -60000 || age > policy.maxAgeHours * 3600000)
|
|
68572
|
+
return unknown("The cached matrix is stale or has a future timestamp.");
|
|
68573
|
+
if (report.host.platform !== deps.platform || report.host.arch !== deps.arch)
|
|
68574
|
+
return unknown("The matrix host platform or architecture differs from this runtime.");
|
|
68575
|
+
const skills = [...new Set(selectedSkills ?? report.bundle?.skills.map((entry) => entry.name) ?? [])];
|
|
68576
|
+
if (!skills.length || skills.length > 100 || skills.some((name) => !safeNames.test(name)))
|
|
68577
|
+
return unknown("Select a bounded list of valid installed skill names.");
|
|
68578
|
+
const plan = parseSkillMatrix(await deps.plan(workspace, skills, signal));
|
|
68579
|
+
if (sourceProblem(plan) || plan.mode !== "plan" || plan.status !== "planned")
|
|
68580
|
+
return unknown("OMA did not return a supported installed injected plan.");
|
|
68581
|
+
if (plan.omaVersion !== report.omaVersion)
|
|
68582
|
+
return unknown("The OMA version changed after measurement; refresh the cached matrix.");
|
|
68583
|
+
if (plan.host.platform !== deps.platform || plan.host.arch !== deps.arch)
|
|
68584
|
+
return unknown("The current OMA plan host does not match this runtime.");
|
|
68585
|
+
const versions = new Map;
|
|
68586
|
+
for (const route of routes) {
|
|
68587
|
+
if (versions.has(route.actorType) || route.actorType !== "claude" && route.actorType !== "codex")
|
|
68588
|
+
continue;
|
|
68589
|
+
try {
|
|
68590
|
+
versions.set(route.actorType, await deps.cliVersion(route.actorType, signal));
|
|
68591
|
+
} catch {
|
|
68592
|
+
versions.set(route.actorType, null);
|
|
68593
|
+
}
|
|
68594
|
+
}
|
|
68595
|
+
if (signal?.aborted)
|
|
68596
|
+
throw new Error("Interrupted");
|
|
68597
|
+
return {
|
|
68598
|
+
scope,
|
|
68599
|
+
routes: routes.map((route) => assessRoute(report, plan, skills, route, versions.get(route.actorType) ?? null))
|
|
68600
|
+
};
|
|
68601
|
+
} catch {
|
|
68602
|
+
if (signal?.aborted)
|
|
68603
|
+
throw new Error("Skill compatibility inspection interrupted before Actor launch.");
|
|
68604
|
+
return unknown(`The cached report or local OMA plan could not be validated. ${remediation}`);
|
|
68605
|
+
}
|
|
68606
|
+
}
|
|
68607
|
+
function assertCompatibleRoute(route, inspection) {
|
|
68608
|
+
const result = inspection.routes.find((entry) => matrixRouteKey(entry) === matrixRouteKey(route));
|
|
68609
|
+
if (result?.status !== "pass")
|
|
68610
|
+
throw new Error(`Skill compatibility required for ${route.actorType}/${route.model ?? "native default"}: ${result?.reason ?? "no matching evidence"} ${remediation}`);
|
|
68611
|
+
}
|
|
68612
|
+
|
|
68172
68613
|
// ../../packages/core/src/orchestrator/agent-runner.ts
|
|
68173
68614
|
init_logger();
|
|
68174
68615
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
@@ -68510,7 +68951,7 @@ class AgentRunnerService {
|
|
|
68510
68951
|
// ../../packages/core/src/orchestrator/verification-gate.ts
|
|
68511
68952
|
init_logger();
|
|
68512
68953
|
init_process_tree();
|
|
68513
|
-
import { spawn as
|
|
68954
|
+
import { spawn as spawn15 } from "node:child_process";
|
|
68514
68955
|
var MAX_OUTPUT_LENGTH = 10240;
|
|
68515
68956
|
var DEFAULT_TIMEOUT_SEC = 600;
|
|
68516
68957
|
var defaultVerifyExec = (command, cwd, timeoutMs, signal, onSpawned) => new Promise((resolve) => {
|
|
@@ -68518,7 +68959,7 @@ var defaultVerifyExec = (command, cwd, timeoutMs, signal, onSpawned) => new Prom
|
|
|
68518
68959
|
resolve({ exitCode: -1, output: "Verification cancelled.", timedOut: false, aborted: true });
|
|
68519
68960
|
return;
|
|
68520
68961
|
}
|
|
68521
|
-
const proc =
|
|
68962
|
+
const proc = spawn15(command, {
|
|
68522
68963
|
cwd,
|
|
68523
68964
|
shell: true,
|
|
68524
68965
|
detached: process.platform !== "win32",
|
|
@@ -68660,8 +69101,8 @@ async function withMissionDeadline(mission, parent, run) {
|
|
|
68660
69101
|
|
|
68661
69102
|
// ../../packages/core/src/chief/skills.ts
|
|
68662
69103
|
init_dist();
|
|
68663
|
-
import { constants as
|
|
68664
|
-
import { lstat as lstat11, mkdir as mkdir13, open as
|
|
69104
|
+
import { constants as constants6 } from "node:fs";
|
|
69105
|
+
import { lstat as lstat11, mkdir as mkdir13, open as open8, readdir as readdir6, realpath as realpath14, stat, writeFile as writeFile10 } from "node:fs/promises";
|
|
68665
69106
|
import { isAbsolute as isAbsolute8, join as join26, relative as relative8, sep as sep10 } from "node:path";
|
|
68666
69107
|
var MAX_SKILL_BYTES = 256000;
|
|
68667
69108
|
var MAX_METADATA_BYTES = 16384;
|
|
@@ -68742,7 +69183,7 @@ async function prepareMissionSkills(sourceRepositoryPath, workspacePath) {
|
|
|
68742
69183
|
const parent = await realpath14(targetDirectory);
|
|
68743
69184
|
if (parent !== destinationRoot && !inside(destinationRoot, parent))
|
|
68744
69185
|
throw new Error("A target skill resource escapes the mission worktree. Fix its symlink before creating this order.");
|
|
68745
|
-
const file = await
|
|
69186
|
+
const file = await open8(from, constants6.O_RDONLY | constants6.O_NOFOLLOW | constants6.O_NONBLOCK);
|
|
68746
69187
|
try {
|
|
68747
69188
|
const current = await file.stat();
|
|
68748
69189
|
if (!current.isFile())
|
|
@@ -68803,7 +69244,7 @@ async function skillPath(root, name) {
|
|
|
68803
69244
|
return path;
|
|
68804
69245
|
}
|
|
68805
69246
|
async function readSkill(path, metadataOnly) {
|
|
68806
|
-
const file = await
|
|
69247
|
+
const file = await open8(path, constants6.O_RDONLY | constants6.O_NOFOLLOW | constants6.O_NONBLOCK);
|
|
68807
69248
|
try {
|
|
68808
69249
|
const info = await file.stat();
|
|
68809
69250
|
if (!info.isFile())
|
|
@@ -69031,11 +69472,13 @@ class ChiefRuntime {
|
|
|
69031
69472
|
store;
|
|
69032
69473
|
signal;
|
|
69033
69474
|
onStage;
|
|
69475
|
+
skillMatrixDeps;
|
|
69034
69476
|
runners = new Set;
|
|
69035
|
-
constructor(store, signal, onStage = () => {}) {
|
|
69477
|
+
constructor(store, signal, onStage = () => {}, skillMatrixDeps) {
|
|
69036
69478
|
this.store = store;
|
|
69037
69479
|
this.signal = signal;
|
|
69038
69480
|
this.onStage = onStage;
|
|
69481
|
+
this.skillMatrixDeps = skillMatrixDeps;
|
|
69039
69482
|
}
|
|
69040
69483
|
ports() {
|
|
69041
69484
|
return {
|
|
@@ -69111,8 +69554,22 @@ class ChiefRuntime {
|
|
|
69111
69554
|
};
|
|
69112
69555
|
if (signal?.aborted)
|
|
69113
69556
|
throw new Error("Order interrupted. Resume it with av order --resume followed by its mission ID.");
|
|
69114
|
-
const
|
|
69557
|
+
const compatibilityPolicy = mission.operatingPolicy?.skillCompatibility;
|
|
69558
|
+
const compatibility = stage === "work" && compatibilityPolicy ? await inspectSkillCompatibility(compatibilityPolicy, workspace.path, persona.skills, workActorCandidates(mission, persona, compatibilityPolicy.mode === "require"), this.skillMatrixDeps, signal) : undefined;
|
|
69559
|
+
const compatibleRoutes = compatibilityPolicy?.mode === "require" && compatibility ? new Set(compatibility.routes.filter((entry) => entry.status === "pass").map(matrixRouteKey)) : undefined;
|
|
69560
|
+
if (compatibility && compatibilityPolicy)
|
|
69561
|
+
mission.history.push({
|
|
69562
|
+
at: new Date().toISOString(),
|
|
69563
|
+
stage: "skill-compatibility",
|
|
69564
|
+
message: `${compatibilityPolicy.mode}: ${compatibility.routes.map((entry) => `${entry.actorType}/${entry.model ?? "native default"} ${entry.status}: ${entry.reason}`).join("; ")} Scope: ${compatibility.scope}.`,
|
|
69565
|
+
...context?.taskId ? { taskId: context.taskId } : {}
|
|
69566
|
+
});
|
|
69567
|
+
const route = stage === "work" ? selectWorkActor(mission, persona, context?.taskId, compatibleRoutes) : undefined;
|
|
69115
69568
|
persona = route?.actor ?? persona;
|
|
69569
|
+
if (compatibility && compatibilityPolicy) {
|
|
69570
|
+
if (compatibilityPolicy.mode === "require")
|
|
69571
|
+
assertCompatibleRoute({ actorType: persona.agentType, model: persona.model }, compatibility);
|
|
69572
|
+
}
|
|
69116
69573
|
this.onStage(stage, persona);
|
|
69117
69574
|
const attempt = {
|
|
69118
69575
|
id: randomUUID11(),
|
|
@@ -69321,7 +69778,7 @@ function continuousDirectorAdvice(mission) {
|
|
|
69321
69778
|
init_execution();
|
|
69322
69779
|
|
|
69323
69780
|
// src/chief-supervisor.ts
|
|
69324
|
-
import { spawn as
|
|
69781
|
+
import { spawn as spawn16 } from "node:child_process";
|
|
69325
69782
|
import { randomUUID as randomUUID13 } from "node:crypto";
|
|
69326
69783
|
import { join as join31 } from "node:path";
|
|
69327
69784
|
init_execution();
|
|
@@ -69714,19 +70171,19 @@ init_report_delivery_contract();
|
|
|
69714
70171
|
init_zod();
|
|
69715
70172
|
init_report_delivery_contract();
|
|
69716
70173
|
import { createHash as createHash16, randomUUID as randomUUID12 } from "node:crypto";
|
|
69717
|
-
import { constants as
|
|
69718
|
-
import { mkdir as mkdir14, open as
|
|
70174
|
+
import { constants as constants7 } from "node:fs";
|
|
70175
|
+
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";
|
|
69719
70176
|
import { isAbsolute as isAbsolute9, join as join28, relative as relative9, resolve as resolve16 } from "node:path";
|
|
69720
|
-
var
|
|
70177
|
+
var hash3 = string2().regex(/^[a-f0-9]{64}$/);
|
|
69721
70178
|
var outboxRecordSchema = strictObject({
|
|
69722
70179
|
version: literal(1),
|
|
69723
|
-
id:
|
|
70180
|
+
id: hash3,
|
|
69724
70181
|
missionId: string2().regex(/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/),
|
|
69725
70182
|
missionStatus: _enum(["completed", "failed"]),
|
|
69726
70183
|
destinationId: string2().regex(/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/),
|
|
69727
70184
|
channel: string2().regex(/^[a-z][a-z0-9-]{0,63}$/),
|
|
69728
|
-
reportHash:
|
|
69729
|
-
destinationHash:
|
|
70185
|
+
reportHash: hash3,
|
|
70186
|
+
destinationHash: hash3.optional(),
|
|
69730
70187
|
goal: string2().max(32000),
|
|
69731
70188
|
markdown: string2().max(256000),
|
|
69732
70189
|
reportPath: string2().max(4096),
|
|
@@ -69761,7 +70218,7 @@ class ReportOutbox {
|
|
|
69761
70218
|
this.directory = join28(stateDir, "report-outbox");
|
|
69762
70219
|
}
|
|
69763
70220
|
path(id) {
|
|
69764
|
-
if (!
|
|
70221
|
+
if (!hash3.safeParse(id).success)
|
|
69765
70222
|
throw new Error("Invalid report receipt ID. Use av reports to find a receipt.");
|
|
69766
70223
|
return join28(this.directory, `${id}.json`);
|
|
69767
70224
|
}
|
|
@@ -69824,7 +70281,7 @@ async function verifiedAttachment(attachment, artifactRoot, readBytes) {
|
|
|
69824
70281
|
throw failure;
|
|
69825
70282
|
if (resolve16(attachment.path) !== attachment.path)
|
|
69826
70283
|
throw failure;
|
|
69827
|
-
const file = await
|
|
70284
|
+
const file = await open9(attachment.path, constants7.O_RDONLY | constants7.O_NOFOLLOW);
|
|
69828
70285
|
try {
|
|
69829
70286
|
const stat = await file.stat();
|
|
69830
70287
|
if (!stat.isFile() || stat.size !== attachment.sizeBytes)
|
|
@@ -70162,7 +70619,7 @@ function runWorker(args, root, signal) {
|
|
|
70162
70619
|
reject(new Error("CLI entry point is unavailable. Run av order from the installed CLI."));
|
|
70163
70620
|
return;
|
|
70164
70621
|
}
|
|
70165
|
-
const child =
|
|
70622
|
+
const child = spawn16(process.execPath, [entry, ...args], { cwd: root, stdio: "inherit" });
|
|
70166
70623
|
const interrupt = () => child.kill("SIGTERM");
|
|
70167
70624
|
signal.addEventListener("abort", interrupt, { once: true });
|
|
70168
70625
|
if (signal.aborted)
|
|
@@ -70359,8 +70816,8 @@ Return one valid JSON object under the original charter and pinned evidence.` :
|
|
|
70359
70816
|
|
|
70360
70817
|
// ../../packages/core/src/chief/metric-source-adapters.ts
|
|
70361
70818
|
init_metric_source_policy();
|
|
70362
|
-
import { constants as
|
|
70363
|
-
import { lstat as lstat12, open as
|
|
70819
|
+
import { constants as constants8 } from "node:fs";
|
|
70820
|
+
import { lstat as lstat12, open as open10, realpath as realpath16 } from "node:fs/promises";
|
|
70364
70821
|
import { isAbsolute as isAbsolute10, relative as relative10, resolve as resolve17, sep as sep11 } from "node:path";
|
|
70365
70822
|
var MAX_METRIC_RESPONSE_BYTES = 2000000;
|
|
70366
70823
|
function metricSourceEnvironment(request, name) {
|
|
@@ -70458,7 +70915,7 @@ var jsonFileMetricAdapter = {
|
|
|
70458
70915
|
if ((await lstat12(current)).isSymbolicLink())
|
|
70459
70916
|
throw new MetricSourceError("Metric file and parent directories must not be symlinks. Choose a regular JSON file inside the source repository.");
|
|
70460
70917
|
}
|
|
70461
|
-
const file = await
|
|
70918
|
+
const file = await open10(path, constants8.O_RDONLY | constants8.O_NOFOLLOW);
|
|
70462
70919
|
try {
|
|
70463
70920
|
const stat = await file.stat();
|
|
70464
70921
|
if (!stat.isFile() || stat.size > MAX_METRIC_RESPONSE_BYTES || await realpath16(path) !== path)
|
|
@@ -70859,8 +71316,8 @@ function createMissionMetricPorts(repository, mission, dependencies = {}) {
|
|
|
70859
71316
|
|
|
70860
71317
|
// src/chief-tool-config.ts
|
|
70861
71318
|
import { randomUUID as randomUUID14 } from "node:crypto";
|
|
70862
|
-
import { constants as
|
|
70863
|
-
import { link as link2, lstat as lstat13, mkdir as mkdir16, open as
|
|
71319
|
+
import { constants as constants9 } from "node:fs";
|
|
71320
|
+
import { link as link2, lstat as lstat13, mkdir as mkdir16, open as open11, realpath as realpath17, unlink as unlink6 } from "node:fs/promises";
|
|
70864
71321
|
import { join as join32 } from "node:path";
|
|
70865
71322
|
init_dist2();
|
|
70866
71323
|
init_client_toml();
|
|
@@ -70894,7 +71351,7 @@ async function assertLocalPath(root, local) {
|
|
|
70894
71351
|
return true;
|
|
70895
71352
|
}
|
|
70896
71353
|
async function readPrivateFile(path) {
|
|
70897
|
-
const file = await
|
|
71354
|
+
const file = await open11(path, constants9.O_RDONLY | constants9.O_NOFOLLOW);
|
|
70898
71355
|
try {
|
|
70899
71356
|
const stats = await file.stat();
|
|
70900
71357
|
if (!stats.isFile() || stats.size > maximumBytes)
|
|
@@ -70957,7 +71414,7 @@ async function privateExclude(original, target, paths) {
|
|
|
70957
71414
|
const patterns = paths.flatMap((local) => [`/${local}`, `/${local}.av-mcp-*.tmp`]).filter((pattern) => !lines.has(pattern));
|
|
70958
71415
|
if (!patterns.length)
|
|
70959
71416
|
return;
|
|
70960
|
-
const file = await
|
|
71417
|
+
const file = await open11(path, constants9.O_WRONLY | constants9.O_APPEND | constants9.O_CREAT | constants9.O_NOFOLLOW, 384);
|
|
70961
71418
|
try {
|
|
70962
71419
|
await file.writeFile(`${content && !content.endsWith(`
|
|
70963
71420
|
`) ? `
|
|
@@ -71002,7 +71459,7 @@ async function prepareToolConfig(originalRepository, targetWorkspace) {
|
|
|
71002
71459
|
continue;
|
|
71003
71460
|
const path = join32(target, config.path);
|
|
71004
71461
|
const temporary = `${path}.av-mcp-${randomUUID14()}.tmp`;
|
|
71005
|
-
const file = await
|
|
71462
|
+
const file = await open11(temporary, "wx", 384);
|
|
71006
71463
|
try {
|
|
71007
71464
|
await file.writeFile(config.content);
|
|
71008
71465
|
} finally {
|
|
@@ -71031,7 +71488,7 @@ async function prepareChiefToolConfig(originalRepository, targetWorkspace) {
|
|
|
71031
71488
|
|
|
71032
71489
|
// src/tool-discovery.ts
|
|
71033
71490
|
init_client_toml();
|
|
71034
|
-
import { constants as
|
|
71491
|
+
import { constants as constants10 } from "node:fs";
|
|
71035
71492
|
import { access, lstat as lstat14, readFile as readFile12, realpath as realpath18 } from "node:fs/promises";
|
|
71036
71493
|
import { homedir as homedir6 } from "node:os";
|
|
71037
71494
|
import { delimiter as delimiter2, isAbsolute as isAbsolute11, join as join33, resolve as resolve18 } from "node:path";
|
|
@@ -71053,7 +71510,7 @@ async function executable(name, env) {
|
|
|
71053
71510
|
for (const directory of (env.PATH ?? "").split(delimiter2).filter(isAbsolute11)) {
|
|
71054
71511
|
try {
|
|
71055
71512
|
const path = join33(directory, name);
|
|
71056
|
-
await access(path,
|
|
71513
|
+
await access(path, constants10.X_OK);
|
|
71057
71514
|
if ((await lstat14(await realpath18(path))).isFile())
|
|
71058
71515
|
return true;
|
|
71059
71516
|
} catch {}
|
|
@@ -71308,7 +71765,7 @@ async function decideContinuousGoal(operation, decisionId, root, dependencies =
|
|
|
71308
71765
|
}
|
|
71309
71766
|
|
|
71310
71767
|
// src/chief-continuous.ts
|
|
71311
|
-
var execute = promisify2(
|
|
71768
|
+
var execute = promisify2(execFile5);
|
|
71312
71769
|
var orderKeys = [
|
|
71313
71770
|
"workspace",
|
|
71314
71771
|
"verify",
|
|
@@ -72997,7 +73454,7 @@ function selectTaskReviewer(mission, task, state) {
|
|
|
72997
73454
|
}
|
|
72998
73455
|
|
|
72999
73456
|
// ../../packages/core/src/chief/coordinator.ts
|
|
73000
|
-
var
|
|
73457
|
+
var bounded3 = (value) => value.slice(-32000);
|
|
73001
73458
|
async function coordinate(mission, ports) {
|
|
73002
73459
|
Object.assign(mission, validateMission(mission));
|
|
73003
73460
|
const operatorGoal = mission.goal;
|
|
@@ -73061,7 +73518,7 @@ async function coordinate(mission, ports) {
|
|
|
73061
73518
|
if (task.effectScope === "external" && state.effectState === "unknown")
|
|
73062
73519
|
throw new MissionPause(`External effect ${task.id} has no established destination outcome and will not be repeated.`, "unknown-effect");
|
|
73063
73520
|
if (task.effectScope !== "external" || state.effectState !== "completed") {
|
|
73064
|
-
state.output =
|
|
73521
|
+
state.output = bounded3(await run(persona(task.personaId), workPrompt(mission, task, state, persona(task.personaId)), "work", task.id));
|
|
73065
73522
|
if (task.effectScope === "external")
|
|
73066
73523
|
state.effectState = "completed";
|
|
73067
73524
|
}
|
|
@@ -73235,7 +73692,7 @@ async function coordinate(mission, ports) {
|
|
|
73235
73692
|
mission.fingerprint = await ports.fingerprint(mission);
|
|
73236
73693
|
mission.verification = {
|
|
73237
73694
|
ok: result.ok,
|
|
73238
|
-
output: result.output ?
|
|
73695
|
+
output: result.output ? bounded3(result.output) : undefined,
|
|
73239
73696
|
fingerprint: mission.fingerprint
|
|
73240
73697
|
};
|
|
73241
73698
|
if (mission.verificationMode === "chief" && !mission.goalVerification?.ok) {
|
|
@@ -73334,7 +73791,7 @@ async function coordinate(mission, ports) {
|
|
|
73334
73791
|
return mission;
|
|
73335
73792
|
}
|
|
73336
73793
|
mission.status = "failed";
|
|
73337
|
-
mission.error =
|
|
73794
|
+
mission.error = bounded3(error instanceof Error ? error.message : String(error));
|
|
73338
73795
|
if (error instanceof ReadOnlyViolation || error instanceof ContractViolation || error instanceof CheckpointError)
|
|
73339
73796
|
executionState(mission).failureKind = "integrity";
|
|
73340
73797
|
if (error instanceof ReadOnlyViolation)
|
|
@@ -73351,7 +73808,7 @@ async function coordinate(mission, ports) {
|
|
|
73351
73808
|
if (reportError instanceof ReadOnlyViolation) {
|
|
73352
73809
|
executionState(mission).failureKind = "integrity";
|
|
73353
73810
|
invalidate();
|
|
73354
|
-
mission.error =
|
|
73811
|
+
mission.error = bounded3(`${mission.error}
|
|
73355
73812
|
${reportError.message}`);
|
|
73356
73813
|
mission.report = fallbackReport(mission);
|
|
73357
73814
|
}
|
|
@@ -74418,21 +74875,21 @@ function checkOma(project, deps) {
|
|
|
74418
74875
|
let version = null;
|
|
74419
74876
|
if (omaPath) {
|
|
74420
74877
|
try {
|
|
74421
|
-
version = deps.getOmaVersion?.() ?? null;
|
|
74878
|
+
version = parseOmaCliVersion(deps.getOmaVersion?.() ?? "") ?? null;
|
|
74422
74879
|
} catch {}
|
|
74423
74880
|
}
|
|
74424
|
-
results.push(version
|
|
74881
|
+
results.push(version !== null ? {
|
|
74425
74882
|
id: "oma.cli",
|
|
74426
|
-
name: "OMA CLI
|
|
74883
|
+
name: "OMA CLI availability",
|
|
74427
74884
|
status: "pass",
|
|
74428
|
-
message: `${omaPath} (${version})`,
|
|
74885
|
+
message: `${omaPath} (${version}); receipt schema v${OMA_RECEIPT_SCHEMA_VERSION} and current evidence are checked for each task`,
|
|
74429
74886
|
critical: false
|
|
74430
74887
|
} : {
|
|
74431
74888
|
id: "oma.cli",
|
|
74432
|
-
name: "OMA CLI
|
|
74889
|
+
name: "OMA CLI availability",
|
|
74433
74890
|
status: "fail",
|
|
74434
|
-
message: omaPath ?
|
|
74435
|
-
fix:
|
|
74891
|
+
message: omaPath ? "OMA CLI did not return a valid version" : "oma not found on PATH",
|
|
74892
|
+
fix: "Run npm install -g oh-my-agent@latest, verify with oma --version, then rerun av doctor.",
|
|
74436
74893
|
critical: true
|
|
74437
74894
|
});
|
|
74438
74895
|
const command = project?.verify?.command?.trim();
|
|
@@ -74485,6 +74942,37 @@ function checkOma(project, deps) {
|
|
|
74485
74942
|
return results;
|
|
74486
74943
|
}
|
|
74487
74944
|
|
|
74945
|
+
// src/doctor-skill-matrix-checks.ts
|
|
74946
|
+
import { resolve as resolve26 } from "node:path";
|
|
74947
|
+
async function checkSkillMatrix(project, global2, deps) {
|
|
74948
|
+
const config = project?.oma?.skill_compatibility;
|
|
74949
|
+
if (!config)
|
|
74950
|
+
return [];
|
|
74951
|
+
const projectActor = project?.actor ?? project?.agent;
|
|
74952
|
+
const globalActor = global2?.actor ?? global2?.agent;
|
|
74953
|
+
const actorType = projectActor?.type ?? globalActor?.type ?? "claude";
|
|
74954
|
+
const model = projectActor?.model ?? (globalActor?.type === actorType ? globalActor.model : undefined);
|
|
74955
|
+
const inspection = await inspectSkillCompatibility({
|
|
74956
|
+
reportPath: resolve26(deps.cwd, config.report_path),
|
|
74957
|
+
maxAgeHours: config.max_age_hours,
|
|
74958
|
+
mode: config.mode
|
|
74959
|
+
}, resolve26(deps.cwd, project?.workspace?.root ?? "."), undefined, [{ actorType, model }], deps.skillMatrix);
|
|
74960
|
+
const route = inspection.routes[0];
|
|
74961
|
+
const status = route?.status ?? "unknown";
|
|
74962
|
+
return [
|
|
74963
|
+
{
|
|
74964
|
+
id: "oma.skill-compatibility",
|
|
74965
|
+
name: "OMA skill read-reference compatibility",
|
|
74966
|
+
status,
|
|
74967
|
+
message: `${config.mode}: ${actorType}/${model ?? "native default"}: ${route?.reason ?? "Evidence unavailable."} Scope: ${inspection.scope}. Work dispatch rechecks its own selected skills and candidates.`,
|
|
74968
|
+
...status !== "pass" ? {
|
|
74969
|
+
fix: "Generate a completed installed injected matrix with explicit models and set oma.skill_compatibility.report_path in av.yaml. av doctor never runs a live matrix."
|
|
74970
|
+
} : {},
|
|
74971
|
+
critical: config.mode === "require"
|
|
74972
|
+
}
|
|
74973
|
+
];
|
|
74974
|
+
}
|
|
74975
|
+
|
|
74488
74976
|
// src/doctor-config-checks.ts
|
|
74489
74977
|
function checkTunnel(project, deps) {
|
|
74490
74978
|
const provider = project?.tunnel?.provider ?? "ngrok";
|
|
@@ -74739,10 +75227,11 @@ async function runDoctorChecks(deps, options = {}) {
|
|
|
74739
75227
|
results.push(checkTunnel(project, deps));
|
|
74740
75228
|
results.push(checkWebhookSecret(project));
|
|
74741
75229
|
results.push(...checkOma(project, deps));
|
|
75230
|
+
results.push(...await checkSkillMatrix(project, global2, deps));
|
|
74742
75231
|
return results;
|
|
74743
75232
|
}
|
|
74744
75233
|
function computeExitCode(results) {
|
|
74745
|
-
return results.some((r) => r.critical && r.status === "fail") ? 1 : 0;
|
|
75234
|
+
return results.some((r) => r.critical && (r.status === "fail" || r.status === "unknown")) ? 1 : 0;
|
|
74746
75235
|
}
|
|
74747
75236
|
function summarize(results) {
|
|
74748
75237
|
return { passed: results.filter((r) => r.status === "pass").length, total: results.length };
|
|
@@ -74817,7 +75306,7 @@ async function registerLinearWebhook(root, tunnelUrl) {
|
|
|
74817
75306
|
init_yaml_loader();
|
|
74818
75307
|
import { existsSync as existsSync5, readFileSync as readFileSync10, writeFileSync as writeFileSync2 } from "node:fs";
|
|
74819
75308
|
import { createServer as createServer3 } from "node:net";
|
|
74820
|
-
import { resolve as
|
|
75309
|
+
import { resolve as resolve27 } from "node:path";
|
|
74821
75310
|
import { setTimeout as delay } from "node:timers/promises";
|
|
74822
75311
|
|
|
74823
75312
|
// src/webhook-proxy.ts
|
|
@@ -74932,12 +75421,12 @@ function resolveServerPort(root, runningPort) {
|
|
|
74932
75421
|
return String(port);
|
|
74933
75422
|
}
|
|
74934
75423
|
function resolveRuntimePaths(root, cliDir) {
|
|
74935
|
-
const dashboardCwd =
|
|
74936
|
-
if (!existsSync5(
|
|
75424
|
+
const dashboardCwd = resolve27(root, "apps/dashboard");
|
|
75425
|
+
if (!existsSync5(resolve27(dashboardCwd, "package.json"))) {
|
|
74937
75426
|
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.`);
|
|
74938
75427
|
}
|
|
74939
|
-
const bundled =
|
|
74940
|
-
const supervisorScript = existsSync5(bundled) ? bundled :
|
|
75428
|
+
const bundled = resolve27(cliDir, "supervisor.js");
|
|
75429
|
+
const supervisorScript = existsSync5(bundled) ? bundled : resolve27(cliDir, "supervisor.ts");
|
|
74941
75430
|
if (!existsSync5(supervisorScript)) {
|
|
74942
75431
|
throw new Error(`Supervisor is missing at ${supervisorScript}. Run bun av up from an intact Agent Valley checkout.`);
|
|
74943
75432
|
}
|
|
@@ -75012,7 +75501,7 @@ async function readStatus(port) {
|
|
|
75012
75501
|
}
|
|
75013
75502
|
|
|
75014
75503
|
// src/tunnel/cloudflare.ts
|
|
75015
|
-
import { spawn as
|
|
75504
|
+
import { spawn as spawn20, spawnSync as spawnSync3 } from "node:child_process";
|
|
75016
75505
|
|
|
75017
75506
|
// src/tunnel/types.ts
|
|
75018
75507
|
function nullTunnelHandle() {
|
|
@@ -75038,7 +75527,7 @@ function spawnCloudflare(cfg, input) {
|
|
|
75038
75527
|
return spawnQuick(port, logger);
|
|
75039
75528
|
}
|
|
75040
75529
|
function spawnQuick(port, logger) {
|
|
75041
|
-
const proc =
|
|
75530
|
+
const proc = spawn20("cloudflared", ["tunnel", "--url", `http://localhost:${port}`, "--logformat", "json", "--no-autoupdate"], {
|
|
75042
75531
|
stdio: ["ignore", "pipe", "pipe"],
|
|
75043
75532
|
detached: true
|
|
75044
75533
|
});
|
|
@@ -75055,7 +75544,7 @@ function spawnNamed(cfg, logger) {
|
|
|
75055
75544
|
logger.dim(" Fix: add tunnel.cloudflare.name: <tunnel-name> or switch mode to 'quick'.");
|
|
75056
75545
|
return nullTunnelHandle();
|
|
75057
75546
|
}
|
|
75058
|
-
const proc =
|
|
75547
|
+
const proc = spawn20("cloudflared", ["tunnel", "run", cfg.name, "--no-autoupdate"], {
|
|
75059
75548
|
stdio: ["ignore", "pipe", "pipe"],
|
|
75060
75549
|
detached: true
|
|
75061
75550
|
});
|
|
@@ -75124,7 +75613,7 @@ function emitMissingBinaryWarning(logger) {
|
|
|
75124
75613
|
}
|
|
75125
75614
|
|
|
75126
75615
|
// src/tunnel/ngrok.ts
|
|
75127
|
-
import { spawn as
|
|
75616
|
+
import { spawn as spawn21, spawnSync as spawnSync4 } from "node:child_process";
|
|
75128
75617
|
function spawnNgrok(input) {
|
|
75129
75618
|
const { port, logger } = input;
|
|
75130
75619
|
const which = spawnSync4("which", ["ngrok"]);
|
|
@@ -75132,7 +75621,7 @@ function spawnNgrok(input) {
|
|
|
75132
75621
|
emitMissingBinaryWarning2(logger);
|
|
75133
75622
|
return nullTunnelHandle();
|
|
75134
75623
|
}
|
|
75135
|
-
const proc =
|
|
75624
|
+
const proc = spawn21("ngrok", ["http", port, "--log", "stdout", "--log-format", "json"], {
|
|
75136
75625
|
stdio: ["ignore", "pipe", "pipe"],
|
|
75137
75626
|
detached: true
|
|
75138
75627
|
});
|
|
@@ -75216,8 +75705,8 @@ function spawnTunnel(config, input) {
|
|
|
75216
75705
|
|
|
75217
75706
|
// src/index.ts
|
|
75218
75707
|
var ROOT = process.cwd();
|
|
75219
|
-
var PID_FILE =
|
|
75220
|
-
var LOG_FILE =
|
|
75708
|
+
var PID_FILE = resolve31(ROOT, ".av.pid");
|
|
75709
|
+
var LOG_FILE = resolve31(ROOT, ".av.log");
|
|
75221
75710
|
function ensureConfig() {
|
|
75222
75711
|
if (!existsSync10(resolveProjectConfigPath(ROOT))) {
|
|
75223
75712
|
console.log(import_picocolors15.default.red("No av.yaml found. Run `av setup` first."));
|
|
@@ -75263,7 +75752,7 @@ program.command("up").description("Start dashboard + orchestrator + configured t
|
|
|
75263
75752
|
else
|
|
75264
75753
|
mode = "start";
|
|
75265
75754
|
}
|
|
75266
|
-
const dashProc =
|
|
75755
|
+
const dashProc = spawn24("bun", [supervisorScript, dashboardCwd, port, mode], {
|
|
75267
75756
|
cwd: ROOT,
|
|
75268
75757
|
stdio: "ignore",
|
|
75269
75758
|
detached: true
|
|
@@ -75344,7 +75833,7 @@ program.command("dev").description("Start in foreground (with file watching + au
|
|
|
75344
75833
|
const startDashboard = () => {
|
|
75345
75834
|
if (shuttingDown)
|
|
75346
75835
|
return;
|
|
75347
|
-
const child =
|
|
75836
|
+
const child = spawn24("bun", ["next", "dev", "--turbopack", "-p", port, "-H", listenHost], {
|
|
75348
75837
|
cwd: dashboardCwd,
|
|
75349
75838
|
stdio: "inherit",
|
|
75350
75839
|
env: { ...process.env, HOSTNAME: listenHost }
|
|
@@ -75433,7 +75922,7 @@ program.command("logs").description("Tail dashboard + orchestrator logs").option
|
|
|
75433
75922
|
console.log(import_picocolors15.default.yellow("No logs found. Start with: av up"));
|
|
75434
75923
|
return;
|
|
75435
75924
|
}
|
|
75436
|
-
const tail =
|
|
75925
|
+
const tail = spawn24("tail", ["-n", opts.lines, "-f", LOG_FILE], { stdio: "inherit" });
|
|
75437
75926
|
process.on("SIGINT", () => {
|
|
75438
75927
|
tail.kill();
|
|
75439
75928
|
process.exit(0);
|