lazycodex-ai 5.1.4 → 5.1.6
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/cli/index.js +465 -187
- package/dist/cli-node/index.js +465 -187
- package/package.json +1 -1
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +309 -133
- package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
- package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
- package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/rules/package.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +25 -18
- package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/src/directive-content.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/directive.md +25 -18
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +5 -5
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/package-lock.json +12 -12
- package/packages/omo-codex/plugin/package.json +1 -1
- package/packages/omo-codex/plugin/skills/browser/runtime/omowright/manifest.json +1 -1
- package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +25 -18
- package/packages/omo-codex/plugin/skills/ulw-execute/SKILL.md +1 -1
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +311 -135
- package/packages/prompts-core/prompts/ultrawork/codex.md +25 -18
- package/packages/shared-skills/skills/browser/runtime/omowright/manifest.json +1 -1
- package/packages/shared-skills/skills/ulw-execute/SKILL.md +1 -1
package/dist/cli-node/index.js
CHANGED
|
@@ -65,7 +65,7 @@ var package_default;
|
|
|
65
65
|
var init_package = __esm(() => {
|
|
66
66
|
package_default = {
|
|
67
67
|
name: "oh-my-opencode",
|
|
68
|
-
version: "5.1.
|
|
68
|
+
version: "5.1.6",
|
|
69
69
|
description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
|
|
70
70
|
main: "./dist/index.js",
|
|
71
71
|
types: "dist/index.d.ts",
|
|
@@ -242,7 +242,7 @@ var init_package = __esm(() => {
|
|
|
242
242
|
},
|
|
243
243
|
devDependencies: {
|
|
244
244
|
"@clack/prompts": "^1.8.1",
|
|
245
|
-
"@code-yeongyu/senpi": "2026.9.
|
|
245
|
+
"@code-yeongyu/senpi": "2026.9.30",
|
|
246
246
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
247
247
|
"@oh-my-opencode/agents-md-core": "workspace:*",
|
|
248
248
|
"@oh-my-opencode/ast-grep-mcp": "workspace:*",
|
|
@@ -300,18 +300,18 @@ var init_package = __esm(() => {
|
|
|
300
300
|
typescript: "^7.0.2"
|
|
301
301
|
},
|
|
302
302
|
optionalDependencies: {
|
|
303
|
-
"oh-my-opencode-darwin-arm64": "5.1.
|
|
304
|
-
"oh-my-opencode-darwin-x64": "5.1.
|
|
305
|
-
"oh-my-opencode-darwin-x64-baseline": "5.1.
|
|
306
|
-
"oh-my-opencode-linux-arm64": "5.1.
|
|
307
|
-
"oh-my-opencode-linux-arm64-musl": "5.1.
|
|
308
|
-
"oh-my-opencode-linux-x64": "5.1.
|
|
309
|
-
"oh-my-opencode-linux-x64-baseline": "5.1.
|
|
310
|
-
"oh-my-opencode-linux-x64-musl": "5.1.
|
|
311
|
-
"oh-my-opencode-linux-x64-musl-baseline": "5.1.
|
|
312
|
-
"oh-my-opencode-windows-arm64": "5.1.
|
|
313
|
-
"oh-my-opencode-windows-x64": "5.1.
|
|
314
|
-
"oh-my-opencode-windows-x64-baseline": "5.1.
|
|
303
|
+
"oh-my-opencode-darwin-arm64": "5.1.6",
|
|
304
|
+
"oh-my-opencode-darwin-x64": "5.1.6",
|
|
305
|
+
"oh-my-opencode-darwin-x64-baseline": "5.1.6",
|
|
306
|
+
"oh-my-opencode-linux-arm64": "5.1.6",
|
|
307
|
+
"oh-my-opencode-linux-arm64-musl": "5.1.6",
|
|
308
|
+
"oh-my-opencode-linux-x64": "5.1.6",
|
|
309
|
+
"oh-my-opencode-linux-x64-baseline": "5.1.6",
|
|
310
|
+
"oh-my-opencode-linux-x64-musl": "5.1.6",
|
|
311
|
+
"oh-my-opencode-linux-x64-musl-baseline": "5.1.6",
|
|
312
|
+
"oh-my-opencode-windows-arm64": "5.1.6",
|
|
313
|
+
"oh-my-opencode-windows-x64": "5.1.6",
|
|
314
|
+
"oh-my-opencode-windows-x64-baseline": "5.1.6"
|
|
315
315
|
},
|
|
316
316
|
overrides: {
|
|
317
317
|
hono: "^4.13.8",
|
|
@@ -74458,7 +74458,6 @@ function normalizeLegacyModelFields(entry) {
|
|
|
74458
74458
|
delete normalized["reasoningEffort"];
|
|
74459
74459
|
delete normalized["thinking"];
|
|
74460
74460
|
delete normalized["textVerbosity"];
|
|
74461
|
-
delete normalized["maxTokens"];
|
|
74462
74461
|
delete normalized["providerOptions"];
|
|
74463
74462
|
if (typeof entry["model"] === "string")
|
|
74464
74463
|
normalized["model"] = canonicalModelString(entry["model"]);
|
|
@@ -74476,10 +74475,15 @@ function normalizeLegacyModelFields(entry) {
|
|
|
74476
74475
|
providerOptions["textVerbosity"] = entry["textVerbosity"];
|
|
74477
74476
|
if (Object.keys(providerOptions).length > 0)
|
|
74478
74477
|
normalized["provider_options"] = providerOptions;
|
|
74479
|
-
if (entry["max_tokens"] !== undefined)
|
|
74478
|
+
if (entry["max_tokens"] !== undefined) {
|
|
74480
74479
|
normalized["max_tokens"] = entry["max_tokens"];
|
|
74481
|
-
|
|
74480
|
+
if (entry["maxTokens"] === undefined || typeof entry["maxTokens"] === "number") {
|
|
74481
|
+
delete normalized["maxTokens"];
|
|
74482
|
+
}
|
|
74483
|
+
} else if (typeof entry["maxTokens"] === "number") {
|
|
74482
74484
|
normalized["max_tokens"] = entry["maxTokens"];
|
|
74485
|
+
delete normalized["maxTokens"];
|
|
74486
|
+
}
|
|
74483
74487
|
return normalized;
|
|
74484
74488
|
}
|
|
74485
74489
|
function normalizeLegacyModelEntry(entry) {
|
|
@@ -74522,12 +74526,25 @@ var init_fallback_models = __esm(() => {
|
|
|
74522
74526
|
function isRecord5(value) {
|
|
74523
74527
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
74524
74528
|
}
|
|
74525
|
-
var OmoAgentModelEntrySchema, OmoAgentDefInputSchema, OmoAgentDefSchema, OmoAgentsConfigSchema;
|
|
74529
|
+
var OmoAgentModelEntrySchema, PermissionValueSchema, BashPermissionSchema, OmoAgentPermissionSchema, OmoAgentDefInputSchema, OmoAgentDefSchema, OmoAgentsConfigSchema;
|
|
74526
74530
|
var init_agent = __esm(() => {
|
|
74527
74531
|
init_zod();
|
|
74528
74532
|
init_fallback_models();
|
|
74529
74533
|
init_model_ref();
|
|
74530
74534
|
OmoAgentModelEntrySchema = union([string2(), OmoFallbackModelObjectSchema]);
|
|
74535
|
+
PermissionValueSchema = _enum(["ask", "allow", "deny"]);
|
|
74536
|
+
BashPermissionSchema = union([
|
|
74537
|
+
PermissionValueSchema,
|
|
74538
|
+
record(string2(), PermissionValueSchema)
|
|
74539
|
+
]);
|
|
74540
|
+
OmoAgentPermissionSchema = object({
|
|
74541
|
+
edit: PermissionValueSchema.optional(),
|
|
74542
|
+
bash: BashPermissionSchema.optional(),
|
|
74543
|
+
webfetch: PermissionValueSchema.optional(),
|
|
74544
|
+
task: PermissionValueSchema.optional(),
|
|
74545
|
+
doom_loop: PermissionValueSchema.optional(),
|
|
74546
|
+
external_directory: PermissionValueSchema.optional()
|
|
74547
|
+
}).catchall(PermissionValueSchema.optional());
|
|
74531
74548
|
OmoAgentDefInputSchema = object({
|
|
74532
74549
|
description: string2().optional(),
|
|
74533
74550
|
prompt: string2().optional(),
|
|
@@ -74544,7 +74561,9 @@ var init_agent = __esm(() => {
|
|
|
74544
74561
|
disallowed_tools: array(string2()).optional(),
|
|
74545
74562
|
max_turns: number2().int().nonnegative().optional(),
|
|
74546
74563
|
temperature: number2().min(0).max(2).optional(),
|
|
74547
|
-
disable: boolean2().optional()
|
|
74564
|
+
disable: boolean2().optional(),
|
|
74565
|
+
permission: OmoAgentPermissionSchema.optional(),
|
|
74566
|
+
prompt_append: string2().optional()
|
|
74548
74567
|
}).strict();
|
|
74549
74568
|
OmoAgentDefSchema = preprocess((value) => isRecord5(value) ? normalizeLegacyModelFields(value) : value, OmoAgentDefInputSchema);
|
|
74550
74569
|
OmoAgentsConfigSchema = record(string2(), OmoAgentDefSchema);
|
|
@@ -75330,6 +75349,64 @@ var init_schema = __esm(() => {
|
|
|
75330
75349
|
init_computer();
|
|
75331
75350
|
});
|
|
75332
75351
|
|
|
75352
|
+
// packages/omo-config-core/src/loader/types.ts
|
|
75353
|
+
import { existsSync as existsSync13, lstatSync as lstatSync2, readFileSync as readFileSync5, realpathSync as realpathSync5 } from "node:fs";
|
|
75354
|
+
var MERGED_OMO_CONFIG_PATH = "(merged omo config)", DEFAULT_READ_FILE_SYSTEM;
|
|
75355
|
+
var init_types3 = __esm(() => {
|
|
75356
|
+
DEFAULT_READ_FILE_SYSTEM = {
|
|
75357
|
+
existsSync: existsSync13,
|
|
75358
|
+
lstatSync: lstatSync2,
|
|
75359
|
+
readFileSync: readFileSync5,
|
|
75360
|
+
realpathSync: realpathSync5
|
|
75361
|
+
};
|
|
75362
|
+
});
|
|
75363
|
+
|
|
75364
|
+
// packages/omo-config-core/src/loader/diagnostic-lines.ts
|
|
75365
|
+
function displayOmoConfigPath(path, homeDir) {
|
|
75366
|
+
if (path === MERGED_OMO_CONFIG_PATH)
|
|
75367
|
+
return "merged config";
|
|
75368
|
+
if (homeDir === undefined || homeDir.length === 0)
|
|
75369
|
+
return path;
|
|
75370
|
+
const slashed = (value) => value.replaceAll("\\", "/");
|
|
75371
|
+
const home = slashed(homeDir).replace(/\/+$/, "");
|
|
75372
|
+
const file = slashed(path);
|
|
75373
|
+
const fold = (value) => /^[A-Za-z]:\//.test(home) ? value.toLowerCase() : value;
|
|
75374
|
+
if (fold(file) === fold(home))
|
|
75375
|
+
return "~";
|
|
75376
|
+
return fold(file).startsWith(`${fold(home)}/`) ? `~${file.slice(home.length)}` : path;
|
|
75377
|
+
}
|
|
75378
|
+
function notLoadedReason(diagnostic) {
|
|
75379
|
+
switch (diagnostic.kind) {
|
|
75380
|
+
case "parse":
|
|
75381
|
+
return "JSONC parse error";
|
|
75382
|
+
case "read":
|
|
75383
|
+
return "unreadable";
|
|
75384
|
+
default:
|
|
75385
|
+
return diagnostic.issuePaths === undefined || diagnostic.issuePaths.length === 0 ? "invalid config" : `invalid: ${diagnostic.issuePaths.join(", ")}`;
|
|
75386
|
+
}
|
|
75387
|
+
}
|
|
75388
|
+
function omoConfigDiagnosticLines(diagnostics, options = {}) {
|
|
75389
|
+
return diagnostics.flatMap((diagnostic) => {
|
|
75390
|
+
const file = displayOmoConfigPath(diagnostic.path, options.homeDir);
|
|
75391
|
+
switch (diagnostic.kind) {
|
|
75392
|
+
case "invalid-value":
|
|
75393
|
+
return (diagnostic.issuePaths ?? []).map((key) => `config: ${file}: ${key} ignored (invalid value)`);
|
|
75394
|
+
case "unknown-keys":
|
|
75395
|
+
return (diagnostic.issuePaths ?? []).map((key) => `config: ${file}: ${key} ignored (unknown key)`);
|
|
75396
|
+
case "parse":
|
|
75397
|
+
case "read":
|
|
75398
|
+
case "validation":
|
|
75399
|
+
return diagnostic.path === MERGED_OMO_CONFIG_PATH ? [`config: ${file}: reset to defaults (${notLoadedReason(diagnostic)})`] : [`config: ${file}: not loaded (${notLoadedReason(diagnostic)})`];
|
|
75400
|
+
case "deprecated-keys":
|
|
75401
|
+
case "profile":
|
|
75402
|
+
return [];
|
|
75403
|
+
}
|
|
75404
|
+
});
|
|
75405
|
+
}
|
|
75406
|
+
var init_diagnostic_lines = __esm(() => {
|
|
75407
|
+
init_types3();
|
|
75408
|
+
});
|
|
75409
|
+
|
|
75333
75410
|
// packages/omo-config-core/src/loader/disabled-skills.ts
|
|
75334
75411
|
var init_disabled_skills = () => {};
|
|
75335
75412
|
|
|
@@ -75369,24 +75446,265 @@ var init_merge = __esm(() => {
|
|
|
75369
75446
|
DANGEROUS_KEYS2 = new Set(["__proto__", "constructor", "prototype"]);
|
|
75370
75447
|
});
|
|
75371
75448
|
|
|
75449
|
+
// packages/omo-config-core/src/loader/prune-invalid-leaves.ts
|
|
75450
|
+
function isContainer(value) {
|
|
75451
|
+
return typeof value === "object" && value !== null;
|
|
75452
|
+
}
|
|
75453
|
+
function childOf(container, segment) {
|
|
75454
|
+
return Array.isArray(container) ? container[Number(segment)] : container[String(segment)];
|
|
75455
|
+
}
|
|
75456
|
+
function hasChild(container, segment) {
|
|
75457
|
+
if (Array.isArray(container)) {
|
|
75458
|
+
const index = Number(segment);
|
|
75459
|
+
return Number.isInteger(index) && index >= 0 && index < container.length;
|
|
75460
|
+
}
|
|
75461
|
+
return Object.hasOwn(container, String(segment));
|
|
75462
|
+
}
|
|
75463
|
+
function segmentsOf(path) {
|
|
75464
|
+
return path.map((segment) => typeof segment === "number" ? segment : String(segment));
|
|
75465
|
+
}
|
|
75466
|
+
function targetPaths(root, issue) {
|
|
75467
|
+
const base = segmentsOf(issue.path);
|
|
75468
|
+
if (issue.code === "unrecognized_keys")
|
|
75469
|
+
return issue.keys.map((key) => [...base, key]);
|
|
75470
|
+
let node = root;
|
|
75471
|
+
let depth = 0;
|
|
75472
|
+
for (const segment of base) {
|
|
75473
|
+
if (!isContainer(node) || !hasChild(node, segment))
|
|
75474
|
+
break;
|
|
75475
|
+
node = childOf(node, segment);
|
|
75476
|
+
depth += 1;
|
|
75477
|
+
}
|
|
75478
|
+
return [base.slice(0, depth)];
|
|
75479
|
+
}
|
|
75480
|
+
function isAncestor(ancestor, path) {
|
|
75481
|
+
return ancestor.length < path.length && ancestor.every((segment, index) => segment === path[index]);
|
|
75482
|
+
}
|
|
75483
|
+
function compareDescending(left, right) {
|
|
75484
|
+
const length = Math.min(left.length, right.length);
|
|
75485
|
+
for (let index = 0;index < length; index += 1) {
|
|
75486
|
+
const a = left[index];
|
|
75487
|
+
const b = right[index];
|
|
75488
|
+
if (a === b)
|
|
75489
|
+
continue;
|
|
75490
|
+
if (typeof a === "number" && typeof b === "number")
|
|
75491
|
+
return b - a;
|
|
75492
|
+
return String(b).localeCompare(String(a));
|
|
75493
|
+
}
|
|
75494
|
+
return right.length - left.length;
|
|
75495
|
+
}
|
|
75496
|
+
function removeChild(container, segment) {
|
|
75497
|
+
if (Array.isArray(container))
|
|
75498
|
+
container.splice(Number(segment), 1);
|
|
75499
|
+
else
|
|
75500
|
+
delete container[String(segment)];
|
|
75501
|
+
}
|
|
75502
|
+
function isEmpty(container) {
|
|
75503
|
+
return Array.isArray(container) ? container.length === 0 : Object.keys(container).length === 0;
|
|
75504
|
+
}
|
|
75505
|
+
function removePathAndEmptiedAncestors(root, path) {
|
|
75506
|
+
const chain = [root];
|
|
75507
|
+
for (const segment of path.slice(0, -1)) {
|
|
75508
|
+
const current = chain[chain.length - 1];
|
|
75509
|
+
if (current === undefined)
|
|
75510
|
+
return;
|
|
75511
|
+
const next = childOf(current, segment);
|
|
75512
|
+
if (!isContainer(next))
|
|
75513
|
+
return;
|
|
75514
|
+
chain.push(next);
|
|
75515
|
+
}
|
|
75516
|
+
for (let depth = path.length - 1;depth >= 0; depth -= 1) {
|
|
75517
|
+
const container = chain[depth];
|
|
75518
|
+
const segment = path[depth];
|
|
75519
|
+
if (container === undefined || segment === undefined)
|
|
75520
|
+
return;
|
|
75521
|
+
removeChild(container, segment);
|
|
75522
|
+
if (depth === 0 || !isEmpty(container))
|
|
75523
|
+
return;
|
|
75524
|
+
}
|
|
75525
|
+
}
|
|
75526
|
+
function prunePass(root, issues) {
|
|
75527
|
+
const byKey = new Map;
|
|
75528
|
+
for (const issue of issues) {
|
|
75529
|
+
for (const path of targetPaths(root, issue)) {
|
|
75530
|
+
if (path.length === 0)
|
|
75531
|
+
return null;
|
|
75532
|
+
const key = path.map((segment) => String(segment)).join(".");
|
|
75533
|
+
if (!byKey.has(key))
|
|
75534
|
+
byKey.set(key, { key, message: issue.message, path });
|
|
75535
|
+
}
|
|
75536
|
+
}
|
|
75537
|
+
const targets = [...byKey.values()];
|
|
75538
|
+
const outermost = targets.filter((target) => !targets.some((other) => isAncestor(other.path, target.path))).sort((left, right) => compareDescending(left.path, right.path));
|
|
75539
|
+
const next = structuredClone(root);
|
|
75540
|
+
for (const target of outermost)
|
|
75541
|
+
removePathAndEmptiedAncestors(next, target.path);
|
|
75542
|
+
return { dropped: outermost, next };
|
|
75543
|
+
}
|
|
75544
|
+
function pruneInvalidConfigPaths(config, issues, validate, maxPasses = MAX_PRUNE_PASSES) {
|
|
75545
|
+
const dropped = [];
|
|
75546
|
+
let current = config;
|
|
75547
|
+
let pending = issues;
|
|
75548
|
+
for (let pass = 0;pass < maxPasses; pass += 1) {
|
|
75549
|
+
const step = prunePass(current, pending);
|
|
75550
|
+
if (step === null || step.dropped.length === 0)
|
|
75551
|
+
return { ok: false, dropped };
|
|
75552
|
+
dropped.push(...step.dropped);
|
|
75553
|
+
current = step.next;
|
|
75554
|
+
if (Object.keys(current).length === 0)
|
|
75555
|
+
return { ok: false, dropped };
|
|
75556
|
+
const validation = validate(current);
|
|
75557
|
+
if (validation.success)
|
|
75558
|
+
return { ok: true, config: current, dropped };
|
|
75559
|
+
pending = validation.issues;
|
|
75560
|
+
}
|
|
75561
|
+
return { ok: false, dropped };
|
|
75562
|
+
}
|
|
75563
|
+
var MAX_PRUNE_PASSES = 32;
|
|
75564
|
+
|
|
75565
|
+
// packages/omo-config-core/src/loader/layer-validation.ts
|
|
75566
|
+
function validationDiagnostic(path, issues) {
|
|
75567
|
+
const issuePaths = issues.map((issue) => issue.path.map((segment) => String(segment)).join("."));
|
|
75568
|
+
return {
|
|
75569
|
+
kind: "validation",
|
|
75570
|
+
message: `Invalid omo config at ${path}: ${issuePaths.join(", ")}`,
|
|
75571
|
+
path,
|
|
75572
|
+
issuePaths
|
|
75573
|
+
};
|
|
75574
|
+
}
|
|
75575
|
+
function invalidValueDiagnostics(path, dropped) {
|
|
75576
|
+
return dropped.map((entry) => ({
|
|
75577
|
+
kind: "invalid-value",
|
|
75578
|
+
message: `Ignored invalid value in ${path}: ${entry.key}: ${entry.message}`,
|
|
75579
|
+
path,
|
|
75580
|
+
issuePaths: [entry.key]
|
|
75581
|
+
}));
|
|
75582
|
+
}
|
|
75583
|
+
function unrecognizedKeyIssues(issues) {
|
|
75584
|
+
return issues.flatMap((issue) => issue.code === "unrecognized_keys" ? [{ keys: issue.keys, path: issue.path.map((segment) => String(segment)) }] : []);
|
|
75585
|
+
}
|
|
75586
|
+
function isRecord11(value) {
|
|
75587
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
75588
|
+
}
|
|
75589
|
+
function sanitizeUnsafeKeys(value, path = []) {
|
|
75590
|
+
if (Array.isArray(value)) {
|
|
75591
|
+
const issues = [];
|
|
75592
|
+
const sanitized = value.map((entry, index) => {
|
|
75593
|
+
const nested = sanitizeUnsafeKeys(entry, [...path, String(index)]);
|
|
75594
|
+
issues.push(...nested.issues);
|
|
75595
|
+
return nested.value;
|
|
75596
|
+
});
|
|
75597
|
+
return { issues, value: sanitized };
|
|
75598
|
+
}
|
|
75599
|
+
if (!isRecord11(value))
|
|
75600
|
+
return { issues: [], value };
|
|
75601
|
+
const issues = [];
|
|
75602
|
+
if (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) {
|
|
75603
|
+
issues.push({ keys: ["__proto__"], path });
|
|
75604
|
+
}
|
|
75605
|
+
const sanitized = {};
|
|
75606
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
75607
|
+
if (isUnsafeObjectKey2(key)) {
|
|
75608
|
+
issues.push({ keys: [key], path });
|
|
75609
|
+
continue;
|
|
75610
|
+
}
|
|
75611
|
+
const nested = sanitizeUnsafeKeys(entry, [...path, key]);
|
|
75612
|
+
issues.push(...nested.issues);
|
|
75613
|
+
sanitized[key] = nested.value;
|
|
75614
|
+
}
|
|
75615
|
+
return { issues, value: sanitized };
|
|
75616
|
+
}
|
|
75617
|
+
function containerAt(record, path) {
|
|
75618
|
+
let node = record;
|
|
75619
|
+
for (const segment of path) {
|
|
75620
|
+
if (Array.isArray(node)) {
|
|
75621
|
+
const index = Number(segment);
|
|
75622
|
+
if (!Number.isInteger(index) || index < 0 || index >= node.length)
|
|
75623
|
+
return null;
|
|
75624
|
+
node = node[index];
|
|
75625
|
+
} else if (isRecord11(node) && Object.hasOwn(node, segment)) {
|
|
75626
|
+
node = node[segment];
|
|
75627
|
+
} else {
|
|
75628
|
+
return null;
|
|
75629
|
+
}
|
|
75630
|
+
}
|
|
75631
|
+
return isRecord11(node) ? node : null;
|
|
75632
|
+
}
|
|
75633
|
+
function stripUnrecognizedKeys(record, issues) {
|
|
75634
|
+
const stripped = structuredClone(record);
|
|
75635
|
+
const issuePaths = [];
|
|
75636
|
+
for (const issue of issues) {
|
|
75637
|
+
const container = containerAt(stripped, issue.path);
|
|
75638
|
+
if (container === null)
|
|
75639
|
+
continue;
|
|
75640
|
+
for (const key of issue.keys) {
|
|
75641
|
+
delete container[key];
|
|
75642
|
+
issuePaths.push([...issue.path, key].join("."));
|
|
75643
|
+
}
|
|
75644
|
+
}
|
|
75645
|
+
return { issuePaths, stripped };
|
|
75646
|
+
}
|
|
75647
|
+
function toRecord(value) {
|
|
75648
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
75649
|
+
return null;
|
|
75650
|
+
const record = {};
|
|
75651
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
75652
|
+
record[key] = entry;
|
|
75653
|
+
}
|
|
75654
|
+
return record;
|
|
75655
|
+
}
|
|
75656
|
+
function validateConfigLayer(path, data) {
|
|
75657
|
+
const sanitized = sanitizeUnsafeKeys(data);
|
|
75658
|
+
const record = toRecord(sanitized.value);
|
|
75659
|
+
const unsafeIssuePaths = sanitized.issues.flatMap((issue) => issue.keys.map((key) => [...issue.path, key].join(".")));
|
|
75660
|
+
const unsafeDiagnostics = unsafeIssuePaths.length === 0 ? [] : [{ kind: "unknown-keys", message: `Ignored unknown keys in ${path}: ${unsafeIssuePaths.join(", ")}`, path, issuePaths: unsafeIssuePaths }];
|
|
75661
|
+
const validation = OmoConfigLayerSchema.safeParse(sanitized.value);
|
|
75662
|
+
if (validation.success) {
|
|
75663
|
+
if (record !== null)
|
|
75664
|
+
return { loaded: true, diagnostics: unsafeDiagnostics, value: record };
|
|
75665
|
+
return {
|
|
75666
|
+
loaded: false,
|
|
75667
|
+
diagnostics: [{ kind: "validation", message: `Invalid omo config at ${path}: root must be an object`, path }]
|
|
75668
|
+
};
|
|
75669
|
+
}
|
|
75670
|
+
const rejected = { loaded: false, diagnostics: [validationDiagnostic(path, validation.error.issues)] };
|
|
75671
|
+
const unknownIssues = unrecognizedKeyIssues(validation.error.issues);
|
|
75672
|
+
if (record === null)
|
|
75673
|
+
return rejected;
|
|
75674
|
+
let candidate = record;
|
|
75675
|
+
let issues = validation.error.issues;
|
|
75676
|
+
const diagnostics = [...unsafeDiagnostics];
|
|
75677
|
+
if (unknownIssues.length > 0) {
|
|
75678
|
+
const { issuePaths, stripped } = stripUnrecognizedKeys(record, unknownIssues);
|
|
75679
|
+
if (issuePaths.length > 0) {
|
|
75680
|
+
diagnostics.push({ kind: "unknown-keys", message: `Ignored unknown keys in ${path}: ${issuePaths.join(", ")}`, path, issuePaths });
|
|
75681
|
+
}
|
|
75682
|
+
const strippedValidation = validateLayerRecord(stripped);
|
|
75683
|
+
if (strippedValidation.success)
|
|
75684
|
+
return { loaded: true, diagnostics, value: stripped };
|
|
75685
|
+
candidate = stripped;
|
|
75686
|
+
issues = strippedValidation.issues;
|
|
75687
|
+
}
|
|
75688
|
+
const pruned = pruneInvalidConfigPaths(candidate, issues, validateLayerRecord);
|
|
75689
|
+
if (!pruned.ok)
|
|
75690
|
+
return rejected;
|
|
75691
|
+
return { loaded: true, diagnostics: [...diagnostics, ...invalidValueDiagnostics(path, pruned.dropped)], value: pruned.config };
|
|
75692
|
+
}
|
|
75693
|
+
var validateLayerRecord = (record) => {
|
|
75694
|
+
const parsed = OmoConfigLayerSchema.safeParse(record);
|
|
75695
|
+
return parsed.success ? { success: true } : { success: false, issues: parsed.error.issues };
|
|
75696
|
+
};
|
|
75697
|
+
var init_layer_validation = __esm(() => {
|
|
75698
|
+
init_schema();
|
|
75699
|
+
init_merge();
|
|
75700
|
+
});
|
|
75701
|
+
|
|
75372
75702
|
// packages/omo-config-core/src/internal/posix-path.ts
|
|
75373
75703
|
function toPosixPath(path) {
|
|
75374
75704
|
return path.split("\\").join("/");
|
|
75375
75705
|
}
|
|
75376
75706
|
var init_posix_path = () => {};
|
|
75377
75707
|
|
|
75378
|
-
// packages/omo-config-core/src/loader/types.ts
|
|
75379
|
-
import { existsSync as existsSync13, lstatSync as lstatSync2, readFileSync as readFileSync5, realpathSync as realpathSync5 } from "node:fs";
|
|
75380
|
-
var DEFAULT_READ_FILE_SYSTEM;
|
|
75381
|
-
var init_types3 = __esm(() => {
|
|
75382
|
-
DEFAULT_READ_FILE_SYSTEM = {
|
|
75383
|
-
existsSync: existsSync13,
|
|
75384
|
-
lstatSync: lstatSync2,
|
|
75385
|
-
readFileSync: readFileSync5,
|
|
75386
|
-
realpathSync: realpathSync5
|
|
75387
|
-
};
|
|
75388
|
-
});
|
|
75389
|
-
|
|
75390
75708
|
// packages/omo-config-core/src/loader/paths.ts
|
|
75391
75709
|
import { userInfo } from "node:os";
|
|
75392
75710
|
import { dirname as dirname4, join as join15, posix as posix2, resolve as resolve3 } from "node:path";
|
|
@@ -75490,7 +75808,7 @@ function resolveOmoProfileName(options = {}) {
|
|
|
75490
75808
|
const env = options.env ?? process.env;
|
|
75491
75809
|
return profileName(options.profile) ?? profileName(env["OMO_PROFILE"]) ?? profileName(env["OCX_PROFILE"]) ?? profileNameFromOpenCodeConfigDir(env["OPENCODE_CONFIG_DIR"]);
|
|
75492
75810
|
}
|
|
75493
|
-
function
|
|
75811
|
+
function toRecord2(value) {
|
|
75494
75812
|
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
75495
75813
|
return;
|
|
75496
75814
|
return Object.fromEntries(Object.entries(value));
|
|
@@ -75511,13 +75829,13 @@ function harnessLayer(config, harness) {
|
|
|
75511
75829
|
const legacyKeys = Object.entries(OMO_CONFIG_LEGACY_HARNESS_ALIASES).filter(([, target]) => target === canonical).map(([legacy]) => harnessBlockKey(legacy));
|
|
75512
75830
|
let layer = {};
|
|
75513
75831
|
for (const key of [...legacyKeys, harnessBlockKey(canonical)]) {
|
|
75514
|
-
layer = mergeOmoConfigRecords(layer,
|
|
75832
|
+
layer = mergeOmoConfigRecords(layer, toRecord2(config[key]) ?? {});
|
|
75515
75833
|
}
|
|
75516
75834
|
return layer;
|
|
75517
75835
|
}
|
|
75518
75836
|
function resolveOmoConfigView(options) {
|
|
75519
|
-
const profiles =
|
|
75520
|
-
const profile = options.profile === undefined ? undefined :
|
|
75837
|
+
const profiles = toRecord2(options.config["profiles"]);
|
|
75838
|
+
const profile = options.profile === undefined ? undefined : toRecord2(profiles?.[options.profile]);
|
|
75521
75839
|
const diagnostics = profile === undefined && options.profile !== undefined ? [{
|
|
75522
75840
|
kind: "profile",
|
|
75523
75841
|
message: `Activated omo profile "${options.profile}" does not exist; using the base configuration`,
|
|
@@ -75572,70 +75890,9 @@ function stripResolutionControlKeys(config) {
|
|
|
75572
75890
|
} = config;
|
|
75573
75891
|
return resolved;
|
|
75574
75892
|
}
|
|
75575
|
-
function validationDiagnostic(path, issues) {
|
|
75576
|
-
const issuePaths = issues.map((issue) => issue.path.map((segment) => String(segment)).join("."));
|
|
75577
|
-
return {
|
|
75578
|
-
kind: "validation",
|
|
75579
|
-
message: `Invalid omo config at ${path}: ${issuePaths.join(", ")}`,
|
|
75580
|
-
path,
|
|
75581
|
-
issuePaths
|
|
75582
|
-
};
|
|
75583
|
-
}
|
|
75584
|
-
function unrecognizedKeyIssues(issues) {
|
|
75585
|
-
return issues.flatMap((issue) => issue.code === "unrecognized_keys" ? [{ keys: issue.keys, path: issue.path.map((segment) => String(segment)) }] : []);
|
|
75586
|
-
}
|
|
75587
|
-
function hasUnsafeUnrecognizedKey(issues) {
|
|
75588
|
-
return issues.some((issue) => issue.keys.some((key) => isUnsafeObjectKey2(key)));
|
|
75589
|
-
}
|
|
75590
|
-
function hasTamperedPrototype(value) {
|
|
75591
|
-
if (Array.isArray(value))
|
|
75592
|
-
return value.some((entry) => hasTamperedPrototype(entry));
|
|
75593
|
-
if (!isRecord11(value))
|
|
75594
|
-
return false;
|
|
75595
|
-
const prototype = Object.getPrototypeOf(value);
|
|
75596
|
-
if (prototype !== Object.prototype && prototype !== null)
|
|
75597
|
-
return true;
|
|
75598
|
-
return Object.values(value).some((entry) => hasTamperedPrototype(entry));
|
|
75599
|
-
}
|
|
75600
|
-
function isRecord11(value) {
|
|
75601
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
75602
|
-
}
|
|
75603
|
-
function containerAt(record, path) {
|
|
75604
|
-
let container = record;
|
|
75605
|
-
for (const segment of path) {
|
|
75606
|
-
const next = container[segment];
|
|
75607
|
-
if (!isRecord11(next))
|
|
75608
|
-
return null;
|
|
75609
|
-
container = next;
|
|
75610
|
-
}
|
|
75611
|
-
return container;
|
|
75612
|
-
}
|
|
75613
|
-
function stripUnrecognizedKeys(record, issues) {
|
|
75614
|
-
const stripped = structuredClone(record);
|
|
75615
|
-
const issuePaths = [];
|
|
75616
|
-
for (const issue of issues) {
|
|
75617
|
-
const container = containerAt(stripped, issue.path);
|
|
75618
|
-
if (container === null)
|
|
75619
|
-
continue;
|
|
75620
|
-
for (const key of issue.keys) {
|
|
75621
|
-
delete container[key];
|
|
75622
|
-
issuePaths.push([...issue.path, key].join("."));
|
|
75623
|
-
}
|
|
75624
|
-
}
|
|
75625
|
-
return { issuePaths, stripped };
|
|
75626
|
-
}
|
|
75627
|
-
function toRecord2(value) {
|
|
75628
|
-
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
75629
|
-
return null;
|
|
75630
|
-
const record = {};
|
|
75631
|
-
for (const [key, entry] of Object.entries(value)) {
|
|
75632
|
-
record[key] = entry;
|
|
75633
|
-
}
|
|
75634
|
-
return record;
|
|
75635
|
-
}
|
|
75636
75893
|
function readConfigSource(path, scope, fileSystem) {
|
|
75637
75894
|
if (!fileSystem.existsSync(path)) {
|
|
75638
|
-
return { source: { exists: false, loaded: false, path, scope } };
|
|
75895
|
+
return { diagnostics: [], source: { exists: false, loaded: false, path, scope } };
|
|
75639
75896
|
}
|
|
75640
75897
|
let content;
|
|
75641
75898
|
try {
|
|
@@ -75643,68 +75900,23 @@ function readConfigSource(path, scope, fileSystem) {
|
|
|
75643
75900
|
} catch (error) {
|
|
75644
75901
|
const message = error instanceof Error ? error.message : String(error);
|
|
75645
75902
|
return {
|
|
75646
|
-
|
|
75903
|
+
diagnostics: [{ kind: "read", message: `Failed to read ${path}: ${message}`, path }],
|
|
75647
75904
|
source: { exists: true, loaded: false, path, scope }
|
|
75648
75905
|
};
|
|
75649
75906
|
}
|
|
75650
75907
|
const parsed = parseJsoncSafe2(content);
|
|
75651
75908
|
if (parsed.errors.length > 0) {
|
|
75652
75909
|
return {
|
|
75653
|
-
|
|
75910
|
+
diagnostics: [{
|
|
75654
75911
|
kind: "parse",
|
|
75655
75912
|
message: `JSONC parse error in ${path}: ${parsed.errors.map((error) => error.message).join(", ")}`,
|
|
75656
75913
|
path
|
|
75657
|
-
},
|
|
75658
|
-
source: { exists: true, loaded: false, path, scope }
|
|
75659
|
-
};
|
|
75660
|
-
}
|
|
75661
|
-
if (hasTamperedPrototype(parsed.data)) {
|
|
75662
|
-
return {
|
|
75663
|
-
diagnostic: { kind: "validation", message: `Invalid omo config at ${path}: "__proto__" member is not allowed`, path },
|
|
75664
|
-
source: { exists: true, loaded: false, path, scope }
|
|
75665
|
-
};
|
|
75666
|
-
}
|
|
75667
|
-
const parsedRecord = toRecord2(parsed.data);
|
|
75668
|
-
const validation = OmoConfigLayerSchema.safeParse(parsed.data);
|
|
75669
|
-
if (!validation.success) {
|
|
75670
|
-
const unrecognized = unrecognizedKeyIssues(validation.error.issues);
|
|
75671
|
-
if (hasUnsafeUnrecognizedKey(unrecognized)) {
|
|
75672
|
-
return {
|
|
75673
|
-
diagnostic: validationDiagnostic(path, validation.error.issues),
|
|
75674
|
-
source: { exists: true, loaded: false, path, scope }
|
|
75675
|
-
};
|
|
75676
|
-
}
|
|
75677
|
-
const rejected = {
|
|
75678
|
-
diagnostic: validationDiagnostic(path, validation.error.issues),
|
|
75914
|
+
}],
|
|
75679
75915
|
source: { exists: true, loaded: false, path, scope }
|
|
75680
75916
|
};
|
|
75681
|
-
const unknownIssues = unrecognizedKeyIssues(validation.error.issues);
|
|
75682
|
-
if (parsedRecord === null || unknownIssues.length === 0)
|
|
75683
|
-
return rejected;
|
|
75684
|
-
const { issuePaths, stripped } = stripUnrecognizedKeys(parsedRecord, unknownIssues);
|
|
75685
|
-
if (!OmoConfigLayerSchema.safeParse(stripped).success)
|
|
75686
|
-
return rejected;
|
|
75687
|
-
return {
|
|
75688
|
-
diagnostic: {
|
|
75689
|
-
kind: "unknown-keys",
|
|
75690
|
-
message: `Ignored unknown keys in ${path}: ${issuePaths.join(", ")}`,
|
|
75691
|
-
path,
|
|
75692
|
-
issuePaths
|
|
75693
|
-
},
|
|
75694
|
-
source: { exists: true, loaded: true, path, scope },
|
|
75695
|
-
value: stripped
|
|
75696
|
-
};
|
|
75697
75917
|
}
|
|
75698
|
-
|
|
75699
|
-
|
|
75700
|
-
diagnostic: { kind: "validation", message: `Invalid omo config at ${path}: root must be an object`, path },
|
|
75701
|
-
source: { exists: true, loaded: false, path, scope }
|
|
75702
|
-
};
|
|
75703
|
-
}
|
|
75704
|
-
return {
|
|
75705
|
-
source: { exists: true, loaded: true, path, scope },
|
|
75706
|
-
value: parsedRecord
|
|
75707
|
-
};
|
|
75918
|
+
const layer = validateConfigLayer(path, parsed.data);
|
|
75919
|
+
return layer.loaded ? { diagnostics: layer.diagnostics, source: { exists: true, loaded: true, path, scope }, value: layer.value } : { diagnostics: layer.diagnostics, source: { exists: true, loaded: false, path, scope } };
|
|
75708
75920
|
}
|
|
75709
75921
|
function legacyCategoryDiagnostic(path, renames) {
|
|
75710
75922
|
const detail = renames.map((rename) => rename.dropped ? `${rename.path} ignored because ${rename.canonical} is also configured` : `${rename.path} renamed to ${rename.canonical}`).join(", ");
|
|
@@ -75739,8 +75951,7 @@ function loadOmoConfig(options = {}) {
|
|
|
75739
75951
|
})) {
|
|
75740
75952
|
const loaded = readConfigSource(candidate.path, candidate.scope, fileSystem);
|
|
75741
75953
|
sources.push(loaded.source);
|
|
75742
|
-
|
|
75743
|
-
diagnostics.push(loaded.diagnostic);
|
|
75954
|
+
diagnostics.push(...loaded.diagnostics);
|
|
75744
75955
|
if (loaded.value !== undefined) {
|
|
75745
75956
|
const canonicalized = canonicalizeLegacyCategoryNames(loaded.value);
|
|
75746
75957
|
if (canonicalized.renames.length > 0) {
|
|
@@ -75763,7 +75974,8 @@ function loadOmoConfig(options = {}) {
|
|
|
75763
75974
|
...options.harness === undefined ? {} : { harness: options.harness },
|
|
75764
75975
|
...requestedProfile === undefined ? {} : { profile: requestedProfile }
|
|
75765
75976
|
});
|
|
75766
|
-
const
|
|
75977
|
+
const finalInput = mergeOmoConfigRecords(DEFAULT_RAW_CONFIG, resolved.config);
|
|
75978
|
+
const finalConfig = OmoConfigSchema.safeParse(finalInput);
|
|
75767
75979
|
if (finalConfig.success) {
|
|
75768
75980
|
return {
|
|
75769
75981
|
config: stripResolutionControlKeys(finalConfig.data),
|
|
@@ -75773,9 +75985,22 @@ function loadOmoConfig(options = {}) {
|
|
|
75773
75985
|
sources
|
|
75774
75986
|
};
|
|
75775
75987
|
}
|
|
75988
|
+
const pruned = pruneInvalidConfigPaths(finalInput, finalConfig.error.issues, (record) => {
|
|
75989
|
+
const parsed = OmoConfigSchema.safeParse(record);
|
|
75990
|
+
return parsed.success ? { success: true } : { success: false, issues: parsed.error.issues };
|
|
75991
|
+
});
|
|
75992
|
+
if (pruned.ok) {
|
|
75993
|
+
return {
|
|
75994
|
+
config: stripResolutionControlKeys(OmoConfigSchema.parse(pruned.config)),
|
|
75995
|
+
diagnostics: [...diagnostics, ...resolved.diagnostics, ...invalidValueDiagnostics(MERGED_OMO_CONFIG_PATH, pruned.dropped)],
|
|
75996
|
+
layers,
|
|
75997
|
+
...resolved.profile === undefined ? {} : { profile: resolved.profile },
|
|
75998
|
+
sources
|
|
75999
|
+
};
|
|
76000
|
+
}
|
|
75776
76001
|
return {
|
|
75777
76002
|
config: stripResolutionControlKeys(OmoConfigSchema.parse(DEFAULT_RAW_CONFIG)),
|
|
75778
|
-
diagnostics: [...diagnostics, ...resolved.diagnostics, validationDiagnostic(
|
|
76003
|
+
diagnostics: [...diagnostics, ...resolved.diagnostics, validationDiagnostic(MERGED_OMO_CONFIG_PATH, finalConfig.error.issues)],
|
|
75779
76004
|
layers,
|
|
75780
76005
|
...resolved.profile === undefined ? {} : { profile: resolved.profile },
|
|
75781
76006
|
sources
|
|
@@ -75785,6 +76010,7 @@ var DEFAULT_RAW_CONFIG;
|
|
|
75785
76010
|
var init_loader2 = __esm(() => {
|
|
75786
76011
|
init_main();
|
|
75787
76012
|
init_schema();
|
|
76013
|
+
init_layer_validation();
|
|
75788
76014
|
init_merge();
|
|
75789
76015
|
init_paths();
|
|
75790
76016
|
init_resolution();
|
|
@@ -75799,6 +76025,7 @@ var init_loader2 = __esm(() => {
|
|
|
75799
76025
|
|
|
75800
76026
|
// packages/omo-config-core/src/loader/index.ts
|
|
75801
76027
|
var init_loader3 = __esm(() => {
|
|
76028
|
+
init_diagnostic_lines();
|
|
75802
76029
|
init_disabled_skills();
|
|
75803
76030
|
init_loader2();
|
|
75804
76031
|
init_merge();
|
|
@@ -89229,7 +89456,7 @@ var package_default2;
|
|
|
89229
89456
|
var init_package2 = __esm(() => {
|
|
89230
89457
|
package_default2 = {
|
|
89231
89458
|
name: "@oh-my-opencode/omo-codex",
|
|
89232
|
-
version: "5.1.
|
|
89459
|
+
version: "5.1.6",
|
|
89233
89460
|
type: "module",
|
|
89234
89461
|
private: true,
|
|
89235
89462
|
description: "Codex harness adapter for oh-my-openagent. Vendored Codex plugin namespace (omo) + TypeScript installer + telemetry.",
|
|
@@ -102230,6 +102457,7 @@ async function processEvents(ctx, stream, state) {
|
|
|
102230
102457
|
}
|
|
102231
102458
|
}
|
|
102232
102459
|
// packages/omo-opencode/src/config/validate.ts
|
|
102460
|
+
init_src4();
|
|
102233
102461
|
import { relative as relative7 } from "node:path";
|
|
102234
102462
|
|
|
102235
102463
|
// packages/omo-opencode/src/shared/disabled-providers.ts
|
|
@@ -102350,11 +102578,11 @@ function baseView(config) {
|
|
|
102350
102578
|
}
|
|
102351
102579
|
return result;
|
|
102352
102580
|
}
|
|
102353
|
-
function appendViews(views, layers, select) {
|
|
102581
|
+
function appendViews(views, layers, select, keyPrefix) {
|
|
102354
102582
|
for (const layer of layers) {
|
|
102355
102583
|
const config = select(layer.config);
|
|
102356
102584
|
if (Object.keys(config).length > 0)
|
|
102357
|
-
views.push({ config, path: layer.source.path });
|
|
102585
|
+
views.push({ config, keyPrefix, path: layer.source.path });
|
|
102358
102586
|
}
|
|
102359
102587
|
}
|
|
102360
102588
|
function recordFields(value, fields) {
|
|
@@ -102383,10 +102611,21 @@ function modelInput(view) {
|
|
|
102383
102611
|
};
|
|
102384
102612
|
}
|
|
102385
102613
|
function modelView(view) {
|
|
102386
|
-
const
|
|
102387
|
-
|
|
102614
|
+
const input = modelInput(view);
|
|
102615
|
+
const parsed = OmoConfigSchema.safeParse(input);
|
|
102616
|
+
const modelConfig = parsed.success ? parsed.data : (() => {
|
|
102617
|
+
const pruned = pruneInvalidConfigPaths(input, parsed.error.issues, (record) => {
|
|
102618
|
+
const validation = OmoConfigSchema.safeParse(record);
|
|
102619
|
+
return validation.success ? { success: true } : { success: false, issues: validation.error.issues };
|
|
102620
|
+
});
|
|
102621
|
+
if (!pruned.ok)
|
|
102622
|
+
return;
|
|
102623
|
+
const validation = OmoConfigSchema.safeParse(pruned.config);
|
|
102624
|
+
return validation.success ? validation.data : undefined;
|
|
102625
|
+
})();
|
|
102626
|
+
if (modelConfig === undefined)
|
|
102388
102627
|
return { config: {}, diagnostics: [] };
|
|
102389
|
-
const resolved = resolveModelReferences(
|
|
102628
|
+
const resolved = resolveModelReferences(modelConfig);
|
|
102390
102629
|
return {
|
|
102391
102630
|
config: {
|
|
102392
102631
|
...resolved.view.agents === undefined ? {} : { agents: resolved.view.agents },
|
|
@@ -102405,14 +102644,15 @@ function loadOmoOpenCodeConfigChain(directory, environment = process.env) {
|
|
|
102405
102644
|
});
|
|
102406
102645
|
const views = [];
|
|
102407
102646
|
const selectedProfile = loaded.profile;
|
|
102408
|
-
|
|
102409
|
-
appendViews(views, loaded.layers,
|
|
102410
|
-
appendViews(views, loaded.layers,
|
|
102411
|
-
appendViews(views, loaded.layers, (config) =>
|
|
102647
|
+
const profilePrefix = selectedProfile === undefined ? "" : `profiles.${selectedProfile}.`;
|
|
102648
|
+
appendViews(views, loaded.layers, baseView, "");
|
|
102649
|
+
appendViews(views, loaded.layers, block2, "[opencode].");
|
|
102650
|
+
appendViews(views, loaded.layers, (config) => baseView(profile(config, selectedProfile)), profilePrefix);
|
|
102651
|
+
appendViews(views, loaded.layers, (config) => block2(profile(config, selectedProfile)), `${profilePrefix}[opencode].`);
|
|
102412
102652
|
const resolvedModels = modelView(resolved.config);
|
|
102413
102653
|
if (Object.keys(resolvedModels.config).length > 0) {
|
|
102414
102654
|
const source = loaded.layers[0]?.source.path ?? directory;
|
|
102415
|
-
views.push({ config: resolvedModels.config, path: source });
|
|
102655
|
+
views.push({ config: resolvedModels.config, keyPrefix: "", path: source });
|
|
102416
102656
|
}
|
|
102417
102657
|
let protectedUserView = {};
|
|
102418
102658
|
for (const layer of loaded.layers) {
|
|
@@ -102499,7 +102739,7 @@ function unknownPaths(schema, value, path) {
|
|
|
102499
102739
|
if (def.type === "object" && isPlainRecord5(value) && def.shape !== undefined) {
|
|
102500
102740
|
const catchall = def.catchall !== undefined && definition(def.catchall).type !== "never" ? def.catchall : undefined;
|
|
102501
102741
|
return Object.entries(value).flatMap(([key, entry]) => {
|
|
102502
|
-
const propertySchema = def.shape
|
|
102742
|
+
const propertySchema = def.shape !== undefined && Object.hasOwn(def.shape, key) ? def.shape[key] : undefined;
|
|
102503
102743
|
if (propertySchema !== undefined)
|
|
102504
102744
|
return unknownPaths(propertySchema, entry, [...path, key]);
|
|
102505
102745
|
if (catchall !== undefined)
|
|
@@ -102537,6 +102777,9 @@ function findUnknownKeyPaths(schema, value) {
|
|
|
102537
102777
|
return unknownPaths(schema, value, []);
|
|
102538
102778
|
}
|
|
102539
102779
|
|
|
102780
|
+
// packages/omo-opencode/src/config/prune-plugin-view.ts
|
|
102781
|
+
init_src4();
|
|
102782
|
+
|
|
102540
102783
|
// packages/omo-opencode/src/config/schema/agent-names.ts
|
|
102541
102784
|
init_zod();
|
|
102542
102785
|
var BuiltinAgentNameSchema = _enum([
|
|
@@ -102614,19 +102857,19 @@ var FallbackModelsSchema = union([
|
|
|
102614
102857
|
|
|
102615
102858
|
// packages/omo-opencode/src/config/schema/internal/permission.ts
|
|
102616
102859
|
init_zod();
|
|
102617
|
-
var
|
|
102618
|
-
var
|
|
102619
|
-
|
|
102620
|
-
record(string2(),
|
|
102860
|
+
var PermissionValueSchema2 = _enum(["ask", "allow", "deny"]);
|
|
102861
|
+
var BashPermissionSchema2 = union([
|
|
102862
|
+
PermissionValueSchema2,
|
|
102863
|
+
record(string2(), PermissionValueSchema2)
|
|
102621
102864
|
]);
|
|
102622
102865
|
var AgentPermissionSchema = object({
|
|
102623
|
-
edit:
|
|
102624
|
-
bash:
|
|
102625
|
-
webfetch:
|
|
102626
|
-
task:
|
|
102627
|
-
doom_loop:
|
|
102628
|
-
external_directory:
|
|
102629
|
-
}).catchall(
|
|
102866
|
+
edit: PermissionValueSchema2.optional(),
|
|
102867
|
+
bash: BashPermissionSchema2.optional(),
|
|
102868
|
+
webfetch: PermissionValueSchema2.optional(),
|
|
102869
|
+
task: PermissionValueSchema2.optional(),
|
|
102870
|
+
doom_loop: PermissionValueSchema2.optional(),
|
|
102871
|
+
external_directory: PermissionValueSchema2.optional()
|
|
102872
|
+
}).catchall(PermissionValueSchema2.optional());
|
|
102630
102873
|
|
|
102631
102874
|
// packages/omo-opencode/src/config/schema/agent-overrides.ts
|
|
102632
102875
|
var AgentOverrideConfigSchema = object({
|
|
@@ -103191,6 +103434,26 @@ var OhMyOpenCodeConfigSchema = object({
|
|
|
103191
103434
|
default_mode: DefaultModeConfigSchema.optional(),
|
|
103192
103435
|
_migrations: array(string2()).optional()
|
|
103193
103436
|
});
|
|
103437
|
+
// packages/omo-opencode/src/config/prune-plugin-view.ts
|
|
103438
|
+
var validatePluginRecord = (record) => {
|
|
103439
|
+
const parsed = OhMyOpenCodeConfigSchema.safeParse(record);
|
|
103440
|
+
return parsed.success ? { success: true } : { success: false, issues: parsed.error.issues };
|
|
103441
|
+
};
|
|
103442
|
+
function prunePluginView(input) {
|
|
103443
|
+
const validation = OhMyOpenCodeConfigSchema.safeParse(input.config);
|
|
103444
|
+
if (validation.success)
|
|
103445
|
+
return { config: input.config, issues: [], warnings: [] };
|
|
103446
|
+
const pruned = pruneInvalidConfigPaths(input.config, validation.error.issues, validatePluginRecord);
|
|
103447
|
+
if (!pruned.ok)
|
|
103448
|
+
return { config: input.config, issues: validation.error.issues, warnings: [] };
|
|
103449
|
+
const file = displayOmoConfigPath(input.path, input.homeDir);
|
|
103450
|
+
return {
|
|
103451
|
+
config: pruned.config,
|
|
103452
|
+
issues: [],
|
|
103453
|
+
warnings: pruned.dropped.map((entry) => `config: ${file}: ${input.keyPrefix}${entry.key} ignored (invalid value)`)
|
|
103454
|
+
};
|
|
103455
|
+
}
|
|
103456
|
+
|
|
103194
103457
|
// packages/omo-opencode/src/config/validate.ts
|
|
103195
103458
|
function shortPath(configPath) {
|
|
103196
103459
|
const candidate = relative7(process.cwd(), configPath);
|
|
@@ -103200,9 +103463,8 @@ function formatIssuePath(path) {
|
|
|
103200
103463
|
const formatted = path.map((segment) => String(segment)).join(".");
|
|
103201
103464
|
return formatted.length > 0 ? formatted : "<root>";
|
|
103202
103465
|
}
|
|
103203
|
-
function schemaMessages(configPath, rawConfig) {
|
|
103204
|
-
const
|
|
103205
|
-
const validationMessages = result.success ? [] : result.error.issues.map((issue) => `${shortPath(configPath)}: ${formatIssuePath(issue.path)}: ${issue.message}`);
|
|
103466
|
+
function schemaMessages(configPath, rawConfig, issues) {
|
|
103467
|
+
const validationMessages = issues.map((issue) => `${shortPath(configPath)}: ${formatIssuePath(issue.path)}: ${issue.message}`);
|
|
103206
103468
|
const unknownKeyMessages = findUnknownKeyPaths(OhMyOpenCodeConfigSchema, rawConfig).map((path) => `${shortPath(configPath)}: Unknown config key: ${formatIssuePath(path)}`);
|
|
103207
103469
|
return [...validationMessages, ...unknownKeyMessages];
|
|
103208
103470
|
}
|
|
@@ -103218,11 +103480,13 @@ function parseConfig(rawConfig) {
|
|
|
103218
103480
|
}
|
|
103219
103481
|
return config;
|
|
103220
103482
|
}
|
|
103221
|
-
function parseConfigView(
|
|
103483
|
+
function parseConfigView(view, homeDir) {
|
|
103484
|
+
const pruned = prunePluginView({ config: view.config, homeDir, keyPrefix: view.keyPrefix, path: view.path });
|
|
103222
103485
|
return {
|
|
103223
|
-
config: parseConfig(
|
|
103224
|
-
messages: schemaMessages(path,
|
|
103225
|
-
path
|
|
103486
|
+
config: parseConfig(pruned.config),
|
|
103487
|
+
messages: schemaMessages(view.path, view.config, pruned.issues),
|
|
103488
|
+
path: view.path,
|
|
103489
|
+
warnings: pruned.warnings
|
|
103226
103490
|
};
|
|
103227
103491
|
}
|
|
103228
103492
|
function mergeViews(views) {
|
|
@@ -103314,18 +103578,25 @@ function migrateRalphLoopConfig(config) {
|
|
|
103314
103578
|
}
|
|
103315
103579
|
function validatePluginConfig(directory, environment = process.env) {
|
|
103316
103580
|
const chain = loadOmoOpenCodeConfigChain(directory, environment);
|
|
103317
|
-
const
|
|
103318
|
-
const
|
|
103581
|
+
const homeDir = environment.HOME ?? environment.USERPROFILE;
|
|
103582
|
+
const views = chain.views.map((view) => parseConfigView(view, homeDir));
|
|
103583
|
+
const failing = chain.diagnostics.filter((diagnostic) => diagnostic.kind !== "deprecated-keys" && diagnostic.kind !== "invalid-value");
|
|
103584
|
+
const chainMessages = failing.map((diagnostic) => `${shortPath(diagnostic.path)}: ${diagnostic.message}`);
|
|
103319
103585
|
const messages = [...chainMessages, ...views.flatMap((view) => view.messages)];
|
|
103586
|
+
const warnings = [
|
|
103587
|
+
...omoConfigDiagnosticLines(chain.diagnostics.flatMap((diagnostic) => diagnostic.kind === "invalid-value" ? [diagnostic] : []), { homeDir }),
|
|
103588
|
+
...views.flatMap((view) => view.warnings)
|
|
103589
|
+
];
|
|
103320
103590
|
const firstFailingView = views.find((view) => view.messages.length > 0);
|
|
103321
103591
|
const firstView = views[0];
|
|
103322
|
-
const userConfig = parseConfig(chain.protectedUserView);
|
|
103592
|
+
const userConfig = parseConfig(prunePluginView({ config: chain.protectedUserView, homeDir, keyPrefix: "", path: "" }).config);
|
|
103323
103593
|
const config = applyDisabledProviders(materializeAgentModelChains(protectUserFields(mergeViews(views), userConfig)));
|
|
103324
103594
|
warnLegacyUlwExecuteKey(chain.views);
|
|
103325
103595
|
return {
|
|
103326
103596
|
valid: messages.length === 0,
|
|
103327
103597
|
messages,
|
|
103328
|
-
|
|
103598
|
+
warnings,
|
|
103599
|
+
path: failing[0]?.path ?? firstFailingView?.path ?? firstView?.path ?? null,
|
|
103329
103600
|
config: migrateRalphLoopConfig(migrateLegacyUlwExecuteKey(config))
|
|
103330
103601
|
};
|
|
103331
103602
|
}
|
|
@@ -106449,14 +106720,15 @@ function toOmoConfig(config) {
|
|
|
106449
106720
|
function validateConfig() {
|
|
106450
106721
|
const validation = validatePluginConfig(process.cwd());
|
|
106451
106722
|
if (!validation.path) {
|
|
106452
|
-
return { exists: false, path: null, valid: true, config: null, errors: [] };
|
|
106723
|
+
return { exists: false, path: null, valid: true, config: null, errors: [], warnings: validation.warnings };
|
|
106453
106724
|
}
|
|
106454
106725
|
return {
|
|
106455
106726
|
exists: true,
|
|
106456
106727
|
path: validation.path,
|
|
106457
106728
|
valid: validation.valid,
|
|
106458
106729
|
config: toOmoConfig(validation.config),
|
|
106459
|
-
errors: [...validation.messages]
|
|
106730
|
+
errors: [...validation.messages],
|
|
106731
|
+
warnings: validation.warnings
|
|
106460
106732
|
};
|
|
106461
106733
|
}
|
|
106462
106734
|
function collectModelResolutionIssues(config) {
|
|
@@ -106509,6 +106781,12 @@ async function checkConfig() {
|
|
|
106509
106781
|
}));
|
|
106510
106782
|
if (legacyWarning !== undefined)
|
|
106511
106783
|
issues.push(legacyWarning);
|
|
106784
|
+
issues.push(...validation.warnings.map((warning) => ({
|
|
106785
|
+
title: warning,
|
|
106786
|
+
description: "The rest of that file still applies; fix or remove this value to use it.",
|
|
106787
|
+
severity: "warning",
|
|
106788
|
+
affects: ["configuration"]
|
|
106789
|
+
})));
|
|
106512
106790
|
if (!validation.exists) {
|
|
106513
106791
|
return {
|
|
106514
106792
|
name: CHECK_NAMES[CHECK_IDS.CONFIG],
|