oh-my-openagent 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/dist/config/prune-plugin-view.d.ts +18 -0
- package/dist/config/validate.d.ts +3 -1
- package/dist/index.js +11196 -10939
- package/dist/plugin-config/omo-config-chain.d.ts +4 -6
- package/dist/skills/browser/runtime/omowright/manifest.json +1 -1
- package/dist/skills/ulw-execute/SKILL.md +1 -1
- package/dist/tui.js +549 -276
- package/package.json +14 -14
- 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/index.js
CHANGED
|
@@ -64,7 +64,7 @@ var package_default;
|
|
|
64
64
|
var init_package = __esm(() => {
|
|
65
65
|
package_default = {
|
|
66
66
|
name: "oh-my-opencode",
|
|
67
|
-
version: "5.1.
|
|
67
|
+
version: "5.1.6",
|
|
68
68
|
description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
|
|
69
69
|
main: "./dist/index.js",
|
|
70
70
|
types: "dist/index.d.ts",
|
|
@@ -241,7 +241,7 @@ var init_package = __esm(() => {
|
|
|
241
241
|
},
|
|
242
242
|
devDependencies: {
|
|
243
243
|
"@clack/prompts": "^1.8.1",
|
|
244
|
-
"@code-yeongyu/senpi": "2026.9.
|
|
244
|
+
"@code-yeongyu/senpi": "2026.9.30",
|
|
245
245
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
246
246
|
"@oh-my-opencode/agents-md-core": "workspace:*",
|
|
247
247
|
"@oh-my-opencode/ast-grep-mcp": "workspace:*",
|
|
@@ -299,18 +299,18 @@ var init_package = __esm(() => {
|
|
|
299
299
|
typescript: "^7.0.2"
|
|
300
300
|
},
|
|
301
301
|
optionalDependencies: {
|
|
302
|
-
"oh-my-opencode-darwin-arm64": "5.1.
|
|
303
|
-
"oh-my-opencode-darwin-x64": "5.1.
|
|
304
|
-
"oh-my-opencode-darwin-x64-baseline": "5.1.
|
|
305
|
-
"oh-my-opencode-linux-arm64": "5.1.
|
|
306
|
-
"oh-my-opencode-linux-arm64-musl": "5.1.
|
|
307
|
-
"oh-my-opencode-linux-x64": "5.1.
|
|
308
|
-
"oh-my-opencode-linux-x64-baseline": "5.1.
|
|
309
|
-
"oh-my-opencode-linux-x64-musl": "5.1.
|
|
310
|
-
"oh-my-opencode-linux-x64-musl-baseline": "5.1.
|
|
311
|
-
"oh-my-opencode-windows-arm64": "5.1.
|
|
312
|
-
"oh-my-opencode-windows-x64": "5.1.
|
|
313
|
-
"oh-my-opencode-windows-x64-baseline": "5.1.
|
|
302
|
+
"oh-my-opencode-darwin-arm64": "5.1.6",
|
|
303
|
+
"oh-my-opencode-darwin-x64": "5.1.6",
|
|
304
|
+
"oh-my-opencode-darwin-x64-baseline": "5.1.6",
|
|
305
|
+
"oh-my-opencode-linux-arm64": "5.1.6",
|
|
306
|
+
"oh-my-opencode-linux-arm64-musl": "5.1.6",
|
|
307
|
+
"oh-my-opencode-linux-x64": "5.1.6",
|
|
308
|
+
"oh-my-opencode-linux-x64-baseline": "5.1.6",
|
|
309
|
+
"oh-my-opencode-linux-x64-musl": "5.1.6",
|
|
310
|
+
"oh-my-opencode-linux-x64-musl-baseline": "5.1.6",
|
|
311
|
+
"oh-my-opencode-windows-arm64": "5.1.6",
|
|
312
|
+
"oh-my-opencode-windows-x64": "5.1.6",
|
|
313
|
+
"oh-my-opencode-windows-x64-baseline": "5.1.6"
|
|
314
314
|
},
|
|
315
315
|
overrides: {
|
|
316
316
|
hono: "^4.13.8",
|
|
@@ -74379,7 +74379,6 @@ function normalizeLegacyModelFields(entry) {
|
|
|
74379
74379
|
delete normalized["reasoningEffort"];
|
|
74380
74380
|
delete normalized["thinking"];
|
|
74381
74381
|
delete normalized["textVerbosity"];
|
|
74382
|
-
delete normalized["maxTokens"];
|
|
74383
74382
|
delete normalized["providerOptions"];
|
|
74384
74383
|
if (typeof entry["model"] === "string")
|
|
74385
74384
|
normalized["model"] = canonicalModelString(entry["model"]);
|
|
@@ -74397,10 +74396,15 @@ function normalizeLegacyModelFields(entry) {
|
|
|
74397
74396
|
providerOptions["textVerbosity"] = entry["textVerbosity"];
|
|
74398
74397
|
if (Object.keys(providerOptions).length > 0)
|
|
74399
74398
|
normalized["provider_options"] = providerOptions;
|
|
74400
|
-
if (entry["max_tokens"] !== undefined)
|
|
74399
|
+
if (entry["max_tokens"] !== undefined) {
|
|
74401
74400
|
normalized["max_tokens"] = entry["max_tokens"];
|
|
74402
|
-
|
|
74401
|
+
if (entry["maxTokens"] === undefined || typeof entry["maxTokens"] === "number") {
|
|
74402
|
+
delete normalized["maxTokens"];
|
|
74403
|
+
}
|
|
74404
|
+
} else if (typeof entry["maxTokens"] === "number") {
|
|
74403
74405
|
normalized["max_tokens"] = entry["maxTokens"];
|
|
74406
|
+
delete normalized["maxTokens"];
|
|
74407
|
+
}
|
|
74404
74408
|
return normalized;
|
|
74405
74409
|
}
|
|
74406
74410
|
function normalizeLegacyModelEntry(entry) {
|
|
@@ -74443,12 +74447,25 @@ var init_fallback_models = __esm(() => {
|
|
|
74443
74447
|
function isRecord5(value) {
|
|
74444
74448
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
74445
74449
|
}
|
|
74446
|
-
var OmoAgentModelEntrySchema, OmoAgentDefInputSchema, OmoAgentDefSchema, OmoAgentsConfigSchema;
|
|
74450
|
+
var OmoAgentModelEntrySchema, PermissionValueSchema, BashPermissionSchema, OmoAgentPermissionSchema, OmoAgentDefInputSchema, OmoAgentDefSchema, OmoAgentsConfigSchema;
|
|
74447
74451
|
var init_agent = __esm(() => {
|
|
74448
74452
|
init_zod();
|
|
74449
74453
|
init_fallback_models();
|
|
74450
74454
|
init_model_ref();
|
|
74451
74455
|
OmoAgentModelEntrySchema = union([string2(), OmoFallbackModelObjectSchema]);
|
|
74456
|
+
PermissionValueSchema = _enum(["ask", "allow", "deny"]);
|
|
74457
|
+
BashPermissionSchema = union([
|
|
74458
|
+
PermissionValueSchema,
|
|
74459
|
+
record(string2(), PermissionValueSchema)
|
|
74460
|
+
]);
|
|
74461
|
+
OmoAgentPermissionSchema = object({
|
|
74462
|
+
edit: PermissionValueSchema.optional(),
|
|
74463
|
+
bash: BashPermissionSchema.optional(),
|
|
74464
|
+
webfetch: PermissionValueSchema.optional(),
|
|
74465
|
+
task: PermissionValueSchema.optional(),
|
|
74466
|
+
doom_loop: PermissionValueSchema.optional(),
|
|
74467
|
+
external_directory: PermissionValueSchema.optional()
|
|
74468
|
+
}).catchall(PermissionValueSchema.optional());
|
|
74452
74469
|
OmoAgentDefInputSchema = object({
|
|
74453
74470
|
description: string2().optional(),
|
|
74454
74471
|
prompt: string2().optional(),
|
|
@@ -74465,7 +74482,9 @@ var init_agent = __esm(() => {
|
|
|
74465
74482
|
disallowed_tools: array(string2()).optional(),
|
|
74466
74483
|
max_turns: number2().int().nonnegative().optional(),
|
|
74467
74484
|
temperature: number2().min(0).max(2).optional(),
|
|
74468
|
-
disable: boolean2().optional()
|
|
74485
|
+
disable: boolean2().optional(),
|
|
74486
|
+
permission: OmoAgentPermissionSchema.optional(),
|
|
74487
|
+
prompt_append: string2().optional()
|
|
74469
74488
|
}).strict();
|
|
74470
74489
|
OmoAgentDefSchema = preprocess((value) => isRecord5(value) ? normalizeLegacyModelFields(value) : value, OmoAgentDefInputSchema);
|
|
74471
74490
|
OmoAgentsConfigSchema = record(string2(), OmoAgentDefSchema);
|
|
@@ -75251,6 +75270,64 @@ var init_schema = __esm(() => {
|
|
|
75251
75270
|
init_computer();
|
|
75252
75271
|
});
|
|
75253
75272
|
|
|
75273
|
+
// packages/omo-config-core/src/loader/types.ts
|
|
75274
|
+
import { existsSync as existsSync13, lstatSync as lstatSync2, readFileSync as readFileSync5, realpathSync as realpathSync5 } from "fs";
|
|
75275
|
+
var MERGED_OMO_CONFIG_PATH = "(merged omo config)", DEFAULT_READ_FILE_SYSTEM;
|
|
75276
|
+
var init_types3 = __esm(() => {
|
|
75277
|
+
DEFAULT_READ_FILE_SYSTEM = {
|
|
75278
|
+
existsSync: existsSync13,
|
|
75279
|
+
lstatSync: lstatSync2,
|
|
75280
|
+
readFileSync: readFileSync5,
|
|
75281
|
+
realpathSync: realpathSync5
|
|
75282
|
+
};
|
|
75283
|
+
});
|
|
75284
|
+
|
|
75285
|
+
// packages/omo-config-core/src/loader/diagnostic-lines.ts
|
|
75286
|
+
function displayOmoConfigPath(path, homeDir) {
|
|
75287
|
+
if (path === MERGED_OMO_CONFIG_PATH)
|
|
75288
|
+
return "merged config";
|
|
75289
|
+
if (homeDir === undefined || homeDir.length === 0)
|
|
75290
|
+
return path;
|
|
75291
|
+
const slashed = (value) => value.replaceAll("\\", "/");
|
|
75292
|
+
const home = slashed(homeDir).replace(/\/+$/, "");
|
|
75293
|
+
const file = slashed(path);
|
|
75294
|
+
const fold = (value) => /^[A-Za-z]:\//.test(home) ? value.toLowerCase() : value;
|
|
75295
|
+
if (fold(file) === fold(home))
|
|
75296
|
+
return "~";
|
|
75297
|
+
return fold(file).startsWith(`${fold(home)}/`) ? `~${file.slice(home.length)}` : path;
|
|
75298
|
+
}
|
|
75299
|
+
function notLoadedReason(diagnostic) {
|
|
75300
|
+
switch (diagnostic.kind) {
|
|
75301
|
+
case "parse":
|
|
75302
|
+
return "JSONC parse error";
|
|
75303
|
+
case "read":
|
|
75304
|
+
return "unreadable";
|
|
75305
|
+
default:
|
|
75306
|
+
return diagnostic.issuePaths === undefined || diagnostic.issuePaths.length === 0 ? "invalid config" : `invalid: ${diagnostic.issuePaths.join(", ")}`;
|
|
75307
|
+
}
|
|
75308
|
+
}
|
|
75309
|
+
function omoConfigDiagnosticLines(diagnostics, options = {}) {
|
|
75310
|
+
return diagnostics.flatMap((diagnostic) => {
|
|
75311
|
+
const file = displayOmoConfigPath(diagnostic.path, options.homeDir);
|
|
75312
|
+
switch (diagnostic.kind) {
|
|
75313
|
+
case "invalid-value":
|
|
75314
|
+
return (diagnostic.issuePaths ?? []).map((key) => `config: ${file}: ${key} ignored (invalid value)`);
|
|
75315
|
+
case "unknown-keys":
|
|
75316
|
+
return (diagnostic.issuePaths ?? []).map((key) => `config: ${file}: ${key} ignored (unknown key)`);
|
|
75317
|
+
case "parse":
|
|
75318
|
+
case "read":
|
|
75319
|
+
case "validation":
|
|
75320
|
+
return diagnostic.path === MERGED_OMO_CONFIG_PATH ? [`config: ${file}: reset to defaults (${notLoadedReason(diagnostic)})`] : [`config: ${file}: not loaded (${notLoadedReason(diagnostic)})`];
|
|
75321
|
+
case "deprecated-keys":
|
|
75322
|
+
case "profile":
|
|
75323
|
+
return [];
|
|
75324
|
+
}
|
|
75325
|
+
});
|
|
75326
|
+
}
|
|
75327
|
+
var init_diagnostic_lines = __esm(() => {
|
|
75328
|
+
init_types3();
|
|
75329
|
+
});
|
|
75330
|
+
|
|
75254
75331
|
// packages/omo-config-core/src/loader/disabled-skills.ts
|
|
75255
75332
|
var init_disabled_skills = () => {};
|
|
75256
75333
|
|
|
@@ -75290,24 +75367,265 @@ var init_merge = __esm(() => {
|
|
|
75290
75367
|
DANGEROUS_KEYS2 = new Set(["__proto__", "constructor", "prototype"]);
|
|
75291
75368
|
});
|
|
75292
75369
|
|
|
75370
|
+
// packages/omo-config-core/src/loader/prune-invalid-leaves.ts
|
|
75371
|
+
function isContainer(value) {
|
|
75372
|
+
return typeof value === "object" && value !== null;
|
|
75373
|
+
}
|
|
75374
|
+
function childOf(container, segment) {
|
|
75375
|
+
return Array.isArray(container) ? container[Number(segment)] : container[String(segment)];
|
|
75376
|
+
}
|
|
75377
|
+
function hasChild(container, segment) {
|
|
75378
|
+
if (Array.isArray(container)) {
|
|
75379
|
+
const index = Number(segment);
|
|
75380
|
+
return Number.isInteger(index) && index >= 0 && index < container.length;
|
|
75381
|
+
}
|
|
75382
|
+
return Object.hasOwn(container, String(segment));
|
|
75383
|
+
}
|
|
75384
|
+
function segmentsOf(path) {
|
|
75385
|
+
return path.map((segment) => typeof segment === "number" ? segment : String(segment));
|
|
75386
|
+
}
|
|
75387
|
+
function targetPaths(root, issue) {
|
|
75388
|
+
const base = segmentsOf(issue.path);
|
|
75389
|
+
if (issue.code === "unrecognized_keys")
|
|
75390
|
+
return issue.keys.map((key) => [...base, key]);
|
|
75391
|
+
let node = root;
|
|
75392
|
+
let depth = 0;
|
|
75393
|
+
for (const segment of base) {
|
|
75394
|
+
if (!isContainer(node) || !hasChild(node, segment))
|
|
75395
|
+
break;
|
|
75396
|
+
node = childOf(node, segment);
|
|
75397
|
+
depth += 1;
|
|
75398
|
+
}
|
|
75399
|
+
return [base.slice(0, depth)];
|
|
75400
|
+
}
|
|
75401
|
+
function isAncestor(ancestor, path) {
|
|
75402
|
+
return ancestor.length < path.length && ancestor.every((segment, index) => segment === path[index]);
|
|
75403
|
+
}
|
|
75404
|
+
function compareDescending(left, right) {
|
|
75405
|
+
const length = Math.min(left.length, right.length);
|
|
75406
|
+
for (let index = 0;index < length; index += 1) {
|
|
75407
|
+
const a = left[index];
|
|
75408
|
+
const b = right[index];
|
|
75409
|
+
if (a === b)
|
|
75410
|
+
continue;
|
|
75411
|
+
if (typeof a === "number" && typeof b === "number")
|
|
75412
|
+
return b - a;
|
|
75413
|
+
return String(b).localeCompare(String(a));
|
|
75414
|
+
}
|
|
75415
|
+
return right.length - left.length;
|
|
75416
|
+
}
|
|
75417
|
+
function removeChild(container, segment) {
|
|
75418
|
+
if (Array.isArray(container))
|
|
75419
|
+
container.splice(Number(segment), 1);
|
|
75420
|
+
else
|
|
75421
|
+
delete container[String(segment)];
|
|
75422
|
+
}
|
|
75423
|
+
function isEmpty(container) {
|
|
75424
|
+
return Array.isArray(container) ? container.length === 0 : Object.keys(container).length === 0;
|
|
75425
|
+
}
|
|
75426
|
+
function removePathAndEmptiedAncestors(root, path) {
|
|
75427
|
+
const chain = [root];
|
|
75428
|
+
for (const segment of path.slice(0, -1)) {
|
|
75429
|
+
const current = chain[chain.length - 1];
|
|
75430
|
+
if (current === undefined)
|
|
75431
|
+
return;
|
|
75432
|
+
const next = childOf(current, segment);
|
|
75433
|
+
if (!isContainer(next))
|
|
75434
|
+
return;
|
|
75435
|
+
chain.push(next);
|
|
75436
|
+
}
|
|
75437
|
+
for (let depth = path.length - 1;depth >= 0; depth -= 1) {
|
|
75438
|
+
const container = chain[depth];
|
|
75439
|
+
const segment = path[depth];
|
|
75440
|
+
if (container === undefined || segment === undefined)
|
|
75441
|
+
return;
|
|
75442
|
+
removeChild(container, segment);
|
|
75443
|
+
if (depth === 0 || !isEmpty(container))
|
|
75444
|
+
return;
|
|
75445
|
+
}
|
|
75446
|
+
}
|
|
75447
|
+
function prunePass(root, issues) {
|
|
75448
|
+
const byKey = new Map;
|
|
75449
|
+
for (const issue of issues) {
|
|
75450
|
+
for (const path of targetPaths(root, issue)) {
|
|
75451
|
+
if (path.length === 0)
|
|
75452
|
+
return null;
|
|
75453
|
+
const key = path.map((segment) => String(segment)).join(".");
|
|
75454
|
+
if (!byKey.has(key))
|
|
75455
|
+
byKey.set(key, { key, message: issue.message, path });
|
|
75456
|
+
}
|
|
75457
|
+
}
|
|
75458
|
+
const targets = [...byKey.values()];
|
|
75459
|
+
const outermost = targets.filter((target) => !targets.some((other) => isAncestor(other.path, target.path))).sort((left, right) => compareDescending(left.path, right.path));
|
|
75460
|
+
const next = structuredClone(root);
|
|
75461
|
+
for (const target of outermost)
|
|
75462
|
+
removePathAndEmptiedAncestors(next, target.path);
|
|
75463
|
+
return { dropped: outermost, next };
|
|
75464
|
+
}
|
|
75465
|
+
function pruneInvalidConfigPaths(config, issues, validate, maxPasses = MAX_PRUNE_PASSES) {
|
|
75466
|
+
const dropped = [];
|
|
75467
|
+
let current = config;
|
|
75468
|
+
let pending = issues;
|
|
75469
|
+
for (let pass = 0;pass < maxPasses; pass += 1) {
|
|
75470
|
+
const step = prunePass(current, pending);
|
|
75471
|
+
if (step === null || step.dropped.length === 0)
|
|
75472
|
+
return { ok: false, dropped };
|
|
75473
|
+
dropped.push(...step.dropped);
|
|
75474
|
+
current = step.next;
|
|
75475
|
+
if (Object.keys(current).length === 0)
|
|
75476
|
+
return { ok: false, dropped };
|
|
75477
|
+
const validation = validate(current);
|
|
75478
|
+
if (validation.success)
|
|
75479
|
+
return { ok: true, config: current, dropped };
|
|
75480
|
+
pending = validation.issues;
|
|
75481
|
+
}
|
|
75482
|
+
return { ok: false, dropped };
|
|
75483
|
+
}
|
|
75484
|
+
var MAX_PRUNE_PASSES = 32;
|
|
75485
|
+
|
|
75486
|
+
// packages/omo-config-core/src/loader/layer-validation.ts
|
|
75487
|
+
function validationDiagnostic(path, issues) {
|
|
75488
|
+
const issuePaths = issues.map((issue) => issue.path.map((segment) => String(segment)).join("."));
|
|
75489
|
+
return {
|
|
75490
|
+
kind: "validation",
|
|
75491
|
+
message: `Invalid omo config at ${path}: ${issuePaths.join(", ")}`,
|
|
75492
|
+
path,
|
|
75493
|
+
issuePaths
|
|
75494
|
+
};
|
|
75495
|
+
}
|
|
75496
|
+
function invalidValueDiagnostics(path, dropped) {
|
|
75497
|
+
return dropped.map((entry) => ({
|
|
75498
|
+
kind: "invalid-value",
|
|
75499
|
+
message: `Ignored invalid value in ${path}: ${entry.key}: ${entry.message}`,
|
|
75500
|
+
path,
|
|
75501
|
+
issuePaths: [entry.key]
|
|
75502
|
+
}));
|
|
75503
|
+
}
|
|
75504
|
+
function unrecognizedKeyIssues(issues) {
|
|
75505
|
+
return issues.flatMap((issue) => issue.code === "unrecognized_keys" ? [{ keys: issue.keys, path: issue.path.map((segment) => String(segment)) }] : []);
|
|
75506
|
+
}
|
|
75507
|
+
function isRecord11(value) {
|
|
75508
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
75509
|
+
}
|
|
75510
|
+
function sanitizeUnsafeKeys(value, path = []) {
|
|
75511
|
+
if (Array.isArray(value)) {
|
|
75512
|
+
const issues = [];
|
|
75513
|
+
const sanitized = value.map((entry, index) => {
|
|
75514
|
+
const nested = sanitizeUnsafeKeys(entry, [...path, String(index)]);
|
|
75515
|
+
issues.push(...nested.issues);
|
|
75516
|
+
return nested.value;
|
|
75517
|
+
});
|
|
75518
|
+
return { issues, value: sanitized };
|
|
75519
|
+
}
|
|
75520
|
+
if (!isRecord11(value))
|
|
75521
|
+
return { issues: [], value };
|
|
75522
|
+
const issues = [];
|
|
75523
|
+
if (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) {
|
|
75524
|
+
issues.push({ keys: ["__proto__"], path });
|
|
75525
|
+
}
|
|
75526
|
+
const sanitized = {};
|
|
75527
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
75528
|
+
if (isUnsafeObjectKey2(key)) {
|
|
75529
|
+
issues.push({ keys: [key], path });
|
|
75530
|
+
continue;
|
|
75531
|
+
}
|
|
75532
|
+
const nested = sanitizeUnsafeKeys(entry, [...path, key]);
|
|
75533
|
+
issues.push(...nested.issues);
|
|
75534
|
+
sanitized[key] = nested.value;
|
|
75535
|
+
}
|
|
75536
|
+
return { issues, value: sanitized };
|
|
75537
|
+
}
|
|
75538
|
+
function containerAt(record, path) {
|
|
75539
|
+
let node = record;
|
|
75540
|
+
for (const segment of path) {
|
|
75541
|
+
if (Array.isArray(node)) {
|
|
75542
|
+
const index = Number(segment);
|
|
75543
|
+
if (!Number.isInteger(index) || index < 0 || index >= node.length)
|
|
75544
|
+
return null;
|
|
75545
|
+
node = node[index];
|
|
75546
|
+
} else if (isRecord11(node) && Object.hasOwn(node, segment)) {
|
|
75547
|
+
node = node[segment];
|
|
75548
|
+
} else {
|
|
75549
|
+
return null;
|
|
75550
|
+
}
|
|
75551
|
+
}
|
|
75552
|
+
return isRecord11(node) ? node : null;
|
|
75553
|
+
}
|
|
75554
|
+
function stripUnrecognizedKeys(record, issues) {
|
|
75555
|
+
const stripped = structuredClone(record);
|
|
75556
|
+
const issuePaths = [];
|
|
75557
|
+
for (const issue of issues) {
|
|
75558
|
+
const container = containerAt(stripped, issue.path);
|
|
75559
|
+
if (container === null)
|
|
75560
|
+
continue;
|
|
75561
|
+
for (const key of issue.keys) {
|
|
75562
|
+
delete container[key];
|
|
75563
|
+
issuePaths.push([...issue.path, key].join("."));
|
|
75564
|
+
}
|
|
75565
|
+
}
|
|
75566
|
+
return { issuePaths, stripped };
|
|
75567
|
+
}
|
|
75568
|
+
function toRecord(value) {
|
|
75569
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
75570
|
+
return null;
|
|
75571
|
+
const record = {};
|
|
75572
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
75573
|
+
record[key] = entry;
|
|
75574
|
+
}
|
|
75575
|
+
return record;
|
|
75576
|
+
}
|
|
75577
|
+
function validateConfigLayer(path, data) {
|
|
75578
|
+
const sanitized = sanitizeUnsafeKeys(data);
|
|
75579
|
+
const record = toRecord(sanitized.value);
|
|
75580
|
+
const unsafeIssuePaths = sanitized.issues.flatMap((issue) => issue.keys.map((key) => [...issue.path, key].join(".")));
|
|
75581
|
+
const unsafeDiagnostics = unsafeIssuePaths.length === 0 ? [] : [{ kind: "unknown-keys", message: `Ignored unknown keys in ${path}: ${unsafeIssuePaths.join(", ")}`, path, issuePaths: unsafeIssuePaths }];
|
|
75582
|
+
const validation = OmoConfigLayerSchema.safeParse(sanitized.value);
|
|
75583
|
+
if (validation.success) {
|
|
75584
|
+
if (record !== null)
|
|
75585
|
+
return { loaded: true, diagnostics: unsafeDiagnostics, value: record };
|
|
75586
|
+
return {
|
|
75587
|
+
loaded: false,
|
|
75588
|
+
diagnostics: [{ kind: "validation", message: `Invalid omo config at ${path}: root must be an object`, path }]
|
|
75589
|
+
};
|
|
75590
|
+
}
|
|
75591
|
+
const rejected = { loaded: false, diagnostics: [validationDiagnostic(path, validation.error.issues)] };
|
|
75592
|
+
const unknownIssues = unrecognizedKeyIssues(validation.error.issues);
|
|
75593
|
+
if (record === null)
|
|
75594
|
+
return rejected;
|
|
75595
|
+
let candidate = record;
|
|
75596
|
+
let issues = validation.error.issues;
|
|
75597
|
+
const diagnostics = [...unsafeDiagnostics];
|
|
75598
|
+
if (unknownIssues.length > 0) {
|
|
75599
|
+
const { issuePaths, stripped } = stripUnrecognizedKeys(record, unknownIssues);
|
|
75600
|
+
if (issuePaths.length > 0) {
|
|
75601
|
+
diagnostics.push({ kind: "unknown-keys", message: `Ignored unknown keys in ${path}: ${issuePaths.join(", ")}`, path, issuePaths });
|
|
75602
|
+
}
|
|
75603
|
+
const strippedValidation = validateLayerRecord(stripped);
|
|
75604
|
+
if (strippedValidation.success)
|
|
75605
|
+
return { loaded: true, diagnostics, value: stripped };
|
|
75606
|
+
candidate = stripped;
|
|
75607
|
+
issues = strippedValidation.issues;
|
|
75608
|
+
}
|
|
75609
|
+
const pruned = pruneInvalidConfigPaths(candidate, issues, validateLayerRecord);
|
|
75610
|
+
if (!pruned.ok)
|
|
75611
|
+
return rejected;
|
|
75612
|
+
return { loaded: true, diagnostics: [...diagnostics, ...invalidValueDiagnostics(path, pruned.dropped)], value: pruned.config };
|
|
75613
|
+
}
|
|
75614
|
+
var validateLayerRecord = (record) => {
|
|
75615
|
+
const parsed = OmoConfigLayerSchema.safeParse(record);
|
|
75616
|
+
return parsed.success ? { success: true } : { success: false, issues: parsed.error.issues };
|
|
75617
|
+
};
|
|
75618
|
+
var init_layer_validation = __esm(() => {
|
|
75619
|
+
init_schema();
|
|
75620
|
+
init_merge();
|
|
75621
|
+
});
|
|
75622
|
+
|
|
75293
75623
|
// packages/omo-config-core/src/internal/posix-path.ts
|
|
75294
75624
|
function toPosixPath(path) {
|
|
75295
75625
|
return path.split("\\").join("/");
|
|
75296
75626
|
}
|
|
75297
75627
|
var init_posix_path = () => {};
|
|
75298
75628
|
|
|
75299
|
-
// packages/omo-config-core/src/loader/types.ts
|
|
75300
|
-
import { existsSync as existsSync13, lstatSync as lstatSync2, readFileSync as readFileSync5, realpathSync as realpathSync5 } from "fs";
|
|
75301
|
-
var DEFAULT_READ_FILE_SYSTEM;
|
|
75302
|
-
var init_types3 = __esm(() => {
|
|
75303
|
-
DEFAULT_READ_FILE_SYSTEM = {
|
|
75304
|
-
existsSync: existsSync13,
|
|
75305
|
-
lstatSync: lstatSync2,
|
|
75306
|
-
readFileSync: readFileSync5,
|
|
75307
|
-
realpathSync: realpathSync5
|
|
75308
|
-
};
|
|
75309
|
-
});
|
|
75310
|
-
|
|
75311
75629
|
// packages/omo-config-core/src/loader/paths.ts
|
|
75312
75630
|
import { userInfo } from "os";
|
|
75313
75631
|
import { dirname as dirname4, join as join15, posix as posix2, resolve as resolve3 } from "path";
|
|
@@ -75411,7 +75729,7 @@ function resolveOmoProfileName(options = {}) {
|
|
|
75411
75729
|
const env = options.env ?? process.env;
|
|
75412
75730
|
return profileName(options.profile) ?? profileName(env["OMO_PROFILE"]) ?? profileName(env["OCX_PROFILE"]) ?? profileNameFromOpenCodeConfigDir(env["OPENCODE_CONFIG_DIR"]);
|
|
75413
75731
|
}
|
|
75414
|
-
function
|
|
75732
|
+
function toRecord2(value) {
|
|
75415
75733
|
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
75416
75734
|
return;
|
|
75417
75735
|
return Object.fromEntries(Object.entries(value));
|
|
@@ -75432,13 +75750,13 @@ function harnessLayer(config, harness) {
|
|
|
75432
75750
|
const legacyKeys = Object.entries(OMO_CONFIG_LEGACY_HARNESS_ALIASES).filter(([, target]) => target === canonical).map(([legacy]) => harnessBlockKey(legacy));
|
|
75433
75751
|
let layer = {};
|
|
75434
75752
|
for (const key of [...legacyKeys, harnessBlockKey(canonical)]) {
|
|
75435
|
-
layer = mergeOmoConfigRecords(layer,
|
|
75753
|
+
layer = mergeOmoConfigRecords(layer, toRecord2(config[key]) ?? {});
|
|
75436
75754
|
}
|
|
75437
75755
|
return layer;
|
|
75438
75756
|
}
|
|
75439
75757
|
function resolveOmoConfigView(options) {
|
|
75440
|
-
const profiles =
|
|
75441
|
-
const profile = options.profile === undefined ? undefined :
|
|
75758
|
+
const profiles = toRecord2(options.config["profiles"]);
|
|
75759
|
+
const profile = options.profile === undefined ? undefined : toRecord2(profiles?.[options.profile]);
|
|
75442
75760
|
const diagnostics = profile === undefined && options.profile !== undefined ? [{
|
|
75443
75761
|
kind: "profile",
|
|
75444
75762
|
message: `Activated omo profile "${options.profile}" does not exist; using the base configuration`,
|
|
@@ -75493,70 +75811,9 @@ function stripResolutionControlKeys(config) {
|
|
|
75493
75811
|
} = config;
|
|
75494
75812
|
return resolved;
|
|
75495
75813
|
}
|
|
75496
|
-
function validationDiagnostic(path, issues) {
|
|
75497
|
-
const issuePaths = issues.map((issue) => issue.path.map((segment) => String(segment)).join("."));
|
|
75498
|
-
return {
|
|
75499
|
-
kind: "validation",
|
|
75500
|
-
message: `Invalid omo config at ${path}: ${issuePaths.join(", ")}`,
|
|
75501
|
-
path,
|
|
75502
|
-
issuePaths
|
|
75503
|
-
};
|
|
75504
|
-
}
|
|
75505
|
-
function unrecognizedKeyIssues(issues) {
|
|
75506
|
-
return issues.flatMap((issue) => issue.code === "unrecognized_keys" ? [{ keys: issue.keys, path: issue.path.map((segment) => String(segment)) }] : []);
|
|
75507
|
-
}
|
|
75508
|
-
function hasUnsafeUnrecognizedKey(issues) {
|
|
75509
|
-
return issues.some((issue) => issue.keys.some((key) => isUnsafeObjectKey2(key)));
|
|
75510
|
-
}
|
|
75511
|
-
function hasTamperedPrototype(value) {
|
|
75512
|
-
if (Array.isArray(value))
|
|
75513
|
-
return value.some((entry) => hasTamperedPrototype(entry));
|
|
75514
|
-
if (!isRecord11(value))
|
|
75515
|
-
return false;
|
|
75516
|
-
const prototype = Object.getPrototypeOf(value);
|
|
75517
|
-
if (prototype !== Object.prototype && prototype !== null)
|
|
75518
|
-
return true;
|
|
75519
|
-
return Object.values(value).some((entry) => hasTamperedPrototype(entry));
|
|
75520
|
-
}
|
|
75521
|
-
function isRecord11(value) {
|
|
75522
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
75523
|
-
}
|
|
75524
|
-
function containerAt(record, path) {
|
|
75525
|
-
let container = record;
|
|
75526
|
-
for (const segment of path) {
|
|
75527
|
-
const next = container[segment];
|
|
75528
|
-
if (!isRecord11(next))
|
|
75529
|
-
return null;
|
|
75530
|
-
container = next;
|
|
75531
|
-
}
|
|
75532
|
-
return container;
|
|
75533
|
-
}
|
|
75534
|
-
function stripUnrecognizedKeys(record, issues) {
|
|
75535
|
-
const stripped = structuredClone(record);
|
|
75536
|
-
const issuePaths = [];
|
|
75537
|
-
for (const issue of issues) {
|
|
75538
|
-
const container = containerAt(stripped, issue.path);
|
|
75539
|
-
if (container === null)
|
|
75540
|
-
continue;
|
|
75541
|
-
for (const key of issue.keys) {
|
|
75542
|
-
delete container[key];
|
|
75543
|
-
issuePaths.push([...issue.path, key].join("."));
|
|
75544
|
-
}
|
|
75545
|
-
}
|
|
75546
|
-
return { issuePaths, stripped };
|
|
75547
|
-
}
|
|
75548
|
-
function toRecord2(value) {
|
|
75549
|
-
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
75550
|
-
return null;
|
|
75551
|
-
const record = {};
|
|
75552
|
-
for (const [key, entry] of Object.entries(value)) {
|
|
75553
|
-
record[key] = entry;
|
|
75554
|
-
}
|
|
75555
|
-
return record;
|
|
75556
|
-
}
|
|
75557
75814
|
function readConfigSource(path, scope, fileSystem) {
|
|
75558
75815
|
if (!fileSystem.existsSync(path)) {
|
|
75559
|
-
return { source: { exists: false, loaded: false, path, scope } };
|
|
75816
|
+
return { diagnostics: [], source: { exists: false, loaded: false, path, scope } };
|
|
75560
75817
|
}
|
|
75561
75818
|
let content;
|
|
75562
75819
|
try {
|
|
@@ -75564,68 +75821,23 @@ function readConfigSource(path, scope, fileSystem) {
|
|
|
75564
75821
|
} catch (error) {
|
|
75565
75822
|
const message = error instanceof Error ? error.message : String(error);
|
|
75566
75823
|
return {
|
|
75567
|
-
|
|
75824
|
+
diagnostics: [{ kind: "read", message: `Failed to read ${path}: ${message}`, path }],
|
|
75568
75825
|
source: { exists: true, loaded: false, path, scope }
|
|
75569
75826
|
};
|
|
75570
75827
|
}
|
|
75571
75828
|
const parsed = parseJsoncSafe2(content);
|
|
75572
75829
|
if (parsed.errors.length > 0) {
|
|
75573
75830
|
return {
|
|
75574
|
-
|
|
75831
|
+
diagnostics: [{
|
|
75575
75832
|
kind: "parse",
|
|
75576
75833
|
message: `JSONC parse error in ${path}: ${parsed.errors.map((error) => error.message).join(", ")}`,
|
|
75577
75834
|
path
|
|
75578
|
-
},
|
|
75579
|
-
source: { exists: true, loaded: false, path, scope }
|
|
75580
|
-
};
|
|
75581
|
-
}
|
|
75582
|
-
if (hasTamperedPrototype(parsed.data)) {
|
|
75583
|
-
return {
|
|
75584
|
-
diagnostic: { kind: "validation", message: `Invalid omo config at ${path}: "__proto__" member is not allowed`, path },
|
|
75585
|
-
source: { exists: true, loaded: false, path, scope }
|
|
75586
|
-
};
|
|
75587
|
-
}
|
|
75588
|
-
const parsedRecord = toRecord2(parsed.data);
|
|
75589
|
-
const validation = OmoConfigLayerSchema.safeParse(parsed.data);
|
|
75590
|
-
if (!validation.success) {
|
|
75591
|
-
const unrecognized = unrecognizedKeyIssues(validation.error.issues);
|
|
75592
|
-
if (hasUnsafeUnrecognizedKey(unrecognized)) {
|
|
75593
|
-
return {
|
|
75594
|
-
diagnostic: validationDiagnostic(path, validation.error.issues),
|
|
75595
|
-
source: { exists: true, loaded: false, path, scope }
|
|
75596
|
-
};
|
|
75597
|
-
}
|
|
75598
|
-
const rejected = {
|
|
75599
|
-
diagnostic: validationDiagnostic(path, validation.error.issues),
|
|
75835
|
+
}],
|
|
75600
75836
|
source: { exists: true, loaded: false, path, scope }
|
|
75601
75837
|
};
|
|
75602
|
-
const unknownIssues = unrecognizedKeyIssues(validation.error.issues);
|
|
75603
|
-
if (parsedRecord === null || unknownIssues.length === 0)
|
|
75604
|
-
return rejected;
|
|
75605
|
-
const { issuePaths, stripped } = stripUnrecognizedKeys(parsedRecord, unknownIssues);
|
|
75606
|
-
if (!OmoConfigLayerSchema.safeParse(stripped).success)
|
|
75607
|
-
return rejected;
|
|
75608
|
-
return {
|
|
75609
|
-
diagnostic: {
|
|
75610
|
-
kind: "unknown-keys",
|
|
75611
|
-
message: `Ignored unknown keys in ${path}: ${issuePaths.join(", ")}`,
|
|
75612
|
-
path,
|
|
75613
|
-
issuePaths
|
|
75614
|
-
},
|
|
75615
|
-
source: { exists: true, loaded: true, path, scope },
|
|
75616
|
-
value: stripped
|
|
75617
|
-
};
|
|
75618
75838
|
}
|
|
75619
|
-
|
|
75620
|
-
|
|
75621
|
-
diagnostic: { kind: "validation", message: `Invalid omo config at ${path}: root must be an object`, path },
|
|
75622
|
-
source: { exists: true, loaded: false, path, scope }
|
|
75623
|
-
};
|
|
75624
|
-
}
|
|
75625
|
-
return {
|
|
75626
|
-
source: { exists: true, loaded: true, path, scope },
|
|
75627
|
-
value: parsedRecord
|
|
75628
|
-
};
|
|
75839
|
+
const layer = validateConfigLayer(path, parsed.data);
|
|
75840
|
+
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 } };
|
|
75629
75841
|
}
|
|
75630
75842
|
function legacyCategoryDiagnostic(path, renames) {
|
|
75631
75843
|
const detail = renames.map((rename) => rename.dropped ? `${rename.path} ignored because ${rename.canonical} is also configured` : `${rename.path} renamed to ${rename.canonical}`).join(", ");
|
|
@@ -75660,8 +75872,7 @@ function loadOmoConfig(options = {}) {
|
|
|
75660
75872
|
})) {
|
|
75661
75873
|
const loaded = readConfigSource(candidate.path, candidate.scope, fileSystem);
|
|
75662
75874
|
sources.push(loaded.source);
|
|
75663
|
-
|
|
75664
|
-
diagnostics.push(loaded.diagnostic);
|
|
75875
|
+
diagnostics.push(...loaded.diagnostics);
|
|
75665
75876
|
if (loaded.value !== undefined) {
|
|
75666
75877
|
const canonicalized = canonicalizeLegacyCategoryNames(loaded.value);
|
|
75667
75878
|
if (canonicalized.renames.length > 0) {
|
|
@@ -75684,7 +75895,8 @@ function loadOmoConfig(options = {}) {
|
|
|
75684
75895
|
...options.harness === undefined ? {} : { harness: options.harness },
|
|
75685
75896
|
...requestedProfile === undefined ? {} : { profile: requestedProfile }
|
|
75686
75897
|
});
|
|
75687
|
-
const
|
|
75898
|
+
const finalInput = mergeOmoConfigRecords(DEFAULT_RAW_CONFIG, resolved.config);
|
|
75899
|
+
const finalConfig = OmoConfigSchema.safeParse(finalInput);
|
|
75688
75900
|
if (finalConfig.success) {
|
|
75689
75901
|
return {
|
|
75690
75902
|
config: stripResolutionControlKeys(finalConfig.data),
|
|
@@ -75694,9 +75906,22 @@ function loadOmoConfig(options = {}) {
|
|
|
75694
75906
|
sources
|
|
75695
75907
|
};
|
|
75696
75908
|
}
|
|
75909
|
+
const pruned = pruneInvalidConfigPaths(finalInput, finalConfig.error.issues, (record) => {
|
|
75910
|
+
const parsed = OmoConfigSchema.safeParse(record);
|
|
75911
|
+
return parsed.success ? { success: true } : { success: false, issues: parsed.error.issues };
|
|
75912
|
+
});
|
|
75913
|
+
if (pruned.ok) {
|
|
75914
|
+
return {
|
|
75915
|
+
config: stripResolutionControlKeys(OmoConfigSchema.parse(pruned.config)),
|
|
75916
|
+
diagnostics: [...diagnostics, ...resolved.diagnostics, ...invalidValueDiagnostics(MERGED_OMO_CONFIG_PATH, pruned.dropped)],
|
|
75917
|
+
layers,
|
|
75918
|
+
...resolved.profile === undefined ? {} : { profile: resolved.profile },
|
|
75919
|
+
sources
|
|
75920
|
+
};
|
|
75921
|
+
}
|
|
75697
75922
|
return {
|
|
75698
75923
|
config: stripResolutionControlKeys(OmoConfigSchema.parse(DEFAULT_RAW_CONFIG)),
|
|
75699
|
-
diagnostics: [...diagnostics, ...resolved.diagnostics, validationDiagnostic(
|
|
75924
|
+
diagnostics: [...diagnostics, ...resolved.diagnostics, validationDiagnostic(MERGED_OMO_CONFIG_PATH, finalConfig.error.issues)],
|
|
75700
75925
|
layers,
|
|
75701
75926
|
...resolved.profile === undefined ? {} : { profile: resolved.profile },
|
|
75702
75927
|
sources
|
|
@@ -75706,6 +75931,7 @@ var DEFAULT_RAW_CONFIG;
|
|
|
75706
75931
|
var init_loader2 = __esm(() => {
|
|
75707
75932
|
init_main();
|
|
75708
75933
|
init_schema();
|
|
75934
|
+
init_layer_validation();
|
|
75709
75935
|
init_merge();
|
|
75710
75936
|
init_paths();
|
|
75711
75937
|
init_resolution();
|
|
@@ -75720,6 +75946,7 @@ var init_loader2 = __esm(() => {
|
|
|
75720
75946
|
|
|
75721
75947
|
// packages/omo-config-core/src/loader/index.ts
|
|
75722
75948
|
var init_loader3 = __esm(() => {
|
|
75949
|
+
init_diagnostic_lines();
|
|
75723
75950
|
init_disabled_skills();
|
|
75724
75951
|
init_loader2();
|
|
75725
75952
|
init_merge();
|
|
@@ -89150,7 +89377,7 @@ var package_default2;
|
|
|
89150
89377
|
var init_package2 = __esm(() => {
|
|
89151
89378
|
package_default2 = {
|
|
89152
89379
|
name: "@oh-my-opencode/omo-codex",
|
|
89153
|
-
version: "5.1.
|
|
89380
|
+
version: "5.1.6",
|
|
89154
89381
|
type: "module",
|
|
89155
89382
|
private: true,
|
|
89156
89383
|
description: "Codex harness adapter for oh-my-openagent. Vendored Codex plugin namespace (omo) + TypeScript installer + telemetry.",
|
|
@@ -102151,6 +102378,7 @@ async function processEvents(ctx, stream, state) {
|
|
|
102151
102378
|
}
|
|
102152
102379
|
}
|
|
102153
102380
|
// packages/omo-opencode/src/config/validate.ts
|
|
102381
|
+
init_src4();
|
|
102154
102382
|
import { relative as relative7 } from "path";
|
|
102155
102383
|
|
|
102156
102384
|
// packages/omo-opencode/src/shared/disabled-providers.ts
|
|
@@ -102271,11 +102499,11 @@ function baseView(config) {
|
|
|
102271
102499
|
}
|
|
102272
102500
|
return result;
|
|
102273
102501
|
}
|
|
102274
|
-
function appendViews(views, layers, select) {
|
|
102502
|
+
function appendViews(views, layers, select, keyPrefix) {
|
|
102275
102503
|
for (const layer of layers) {
|
|
102276
102504
|
const config = select(layer.config);
|
|
102277
102505
|
if (Object.keys(config).length > 0)
|
|
102278
|
-
views.push({ config, path: layer.source.path });
|
|
102506
|
+
views.push({ config, keyPrefix, path: layer.source.path });
|
|
102279
102507
|
}
|
|
102280
102508
|
}
|
|
102281
102509
|
function recordFields(value, fields) {
|
|
@@ -102304,10 +102532,21 @@ function modelInput(view) {
|
|
|
102304
102532
|
};
|
|
102305
102533
|
}
|
|
102306
102534
|
function modelView(view) {
|
|
102307
|
-
const
|
|
102308
|
-
|
|
102535
|
+
const input = modelInput(view);
|
|
102536
|
+
const parsed = OmoConfigSchema.safeParse(input);
|
|
102537
|
+
const modelConfig = parsed.success ? parsed.data : (() => {
|
|
102538
|
+
const pruned = pruneInvalidConfigPaths(input, parsed.error.issues, (record) => {
|
|
102539
|
+
const validation = OmoConfigSchema.safeParse(record);
|
|
102540
|
+
return validation.success ? { success: true } : { success: false, issues: validation.error.issues };
|
|
102541
|
+
});
|
|
102542
|
+
if (!pruned.ok)
|
|
102543
|
+
return;
|
|
102544
|
+
const validation = OmoConfigSchema.safeParse(pruned.config);
|
|
102545
|
+
return validation.success ? validation.data : undefined;
|
|
102546
|
+
})();
|
|
102547
|
+
if (modelConfig === undefined)
|
|
102309
102548
|
return { config: {}, diagnostics: [] };
|
|
102310
|
-
const resolved = resolveModelReferences(
|
|
102549
|
+
const resolved = resolveModelReferences(modelConfig);
|
|
102311
102550
|
return {
|
|
102312
102551
|
config: {
|
|
102313
102552
|
...resolved.view.agents === undefined ? {} : { agents: resolved.view.agents },
|
|
@@ -102326,14 +102565,15 @@ function loadOmoOpenCodeConfigChain(directory, environment = process.env) {
|
|
|
102326
102565
|
});
|
|
102327
102566
|
const views = [];
|
|
102328
102567
|
const selectedProfile = loaded.profile;
|
|
102329
|
-
|
|
102330
|
-
appendViews(views, loaded.layers,
|
|
102331
|
-
appendViews(views, loaded.layers,
|
|
102332
|
-
appendViews(views, loaded.layers, (config) =>
|
|
102568
|
+
const profilePrefix = selectedProfile === undefined ? "" : `profiles.${selectedProfile}.`;
|
|
102569
|
+
appendViews(views, loaded.layers, baseView, "");
|
|
102570
|
+
appendViews(views, loaded.layers, block2, "[opencode].");
|
|
102571
|
+
appendViews(views, loaded.layers, (config) => baseView(profile(config, selectedProfile)), profilePrefix);
|
|
102572
|
+
appendViews(views, loaded.layers, (config) => block2(profile(config, selectedProfile)), `${profilePrefix}[opencode].`);
|
|
102333
102573
|
const resolvedModels = modelView(resolved.config);
|
|
102334
102574
|
if (Object.keys(resolvedModels.config).length > 0) {
|
|
102335
102575
|
const source = loaded.layers[0]?.source.path ?? directory;
|
|
102336
|
-
views.push({ config: resolvedModels.config, path: source });
|
|
102576
|
+
views.push({ config: resolvedModels.config, keyPrefix: "", path: source });
|
|
102337
102577
|
}
|
|
102338
102578
|
let protectedUserView = {};
|
|
102339
102579
|
for (const layer of loaded.layers) {
|
|
@@ -102420,7 +102660,7 @@ function unknownPaths(schema, value, path) {
|
|
|
102420
102660
|
if (def.type === "object" && isPlainRecord5(value) && def.shape !== undefined) {
|
|
102421
102661
|
const catchall = def.catchall !== undefined && definition(def.catchall).type !== "never" ? def.catchall : undefined;
|
|
102422
102662
|
return Object.entries(value).flatMap(([key, entry]) => {
|
|
102423
|
-
const propertySchema = def.shape
|
|
102663
|
+
const propertySchema = def.shape !== undefined && Object.hasOwn(def.shape, key) ? def.shape[key] : undefined;
|
|
102424
102664
|
if (propertySchema !== undefined)
|
|
102425
102665
|
return unknownPaths(propertySchema, entry, [...path, key]);
|
|
102426
102666
|
if (catchall !== undefined)
|
|
@@ -102458,6 +102698,9 @@ function findUnknownKeyPaths(schema, value) {
|
|
|
102458
102698
|
return unknownPaths(schema, value, []);
|
|
102459
102699
|
}
|
|
102460
102700
|
|
|
102701
|
+
// packages/omo-opencode/src/config/prune-plugin-view.ts
|
|
102702
|
+
init_src4();
|
|
102703
|
+
|
|
102461
102704
|
// packages/omo-opencode/src/config/schema/agent-names.ts
|
|
102462
102705
|
init_zod();
|
|
102463
102706
|
var BuiltinAgentNameSchema = _enum([
|
|
@@ -102535,19 +102778,19 @@ var FallbackModelsSchema = union([
|
|
|
102535
102778
|
|
|
102536
102779
|
// packages/omo-opencode/src/config/schema/internal/permission.ts
|
|
102537
102780
|
init_zod();
|
|
102538
|
-
var
|
|
102539
|
-
var
|
|
102540
|
-
|
|
102541
|
-
record(string2(),
|
|
102781
|
+
var PermissionValueSchema2 = _enum(["ask", "allow", "deny"]);
|
|
102782
|
+
var BashPermissionSchema2 = union([
|
|
102783
|
+
PermissionValueSchema2,
|
|
102784
|
+
record(string2(), PermissionValueSchema2)
|
|
102542
102785
|
]);
|
|
102543
102786
|
var AgentPermissionSchema = object({
|
|
102544
|
-
edit:
|
|
102545
|
-
bash:
|
|
102546
|
-
webfetch:
|
|
102547
|
-
task:
|
|
102548
|
-
doom_loop:
|
|
102549
|
-
external_directory:
|
|
102550
|
-
}).catchall(
|
|
102787
|
+
edit: PermissionValueSchema2.optional(),
|
|
102788
|
+
bash: BashPermissionSchema2.optional(),
|
|
102789
|
+
webfetch: PermissionValueSchema2.optional(),
|
|
102790
|
+
task: PermissionValueSchema2.optional(),
|
|
102791
|
+
doom_loop: PermissionValueSchema2.optional(),
|
|
102792
|
+
external_directory: PermissionValueSchema2.optional()
|
|
102793
|
+
}).catchall(PermissionValueSchema2.optional());
|
|
102551
102794
|
|
|
102552
102795
|
// packages/omo-opencode/src/config/schema/agent-overrides.ts
|
|
102553
102796
|
var AgentOverrideConfigSchema = object({
|
|
@@ -103112,6 +103355,26 @@ var OhMyOpenCodeConfigSchema = object({
|
|
|
103112
103355
|
default_mode: DefaultModeConfigSchema.optional(),
|
|
103113
103356
|
_migrations: array(string2()).optional()
|
|
103114
103357
|
});
|
|
103358
|
+
// packages/omo-opencode/src/config/prune-plugin-view.ts
|
|
103359
|
+
var validatePluginRecord = (record) => {
|
|
103360
|
+
const parsed = OhMyOpenCodeConfigSchema.safeParse(record);
|
|
103361
|
+
return parsed.success ? { success: true } : { success: false, issues: parsed.error.issues };
|
|
103362
|
+
};
|
|
103363
|
+
function prunePluginView(input) {
|
|
103364
|
+
const validation = OhMyOpenCodeConfigSchema.safeParse(input.config);
|
|
103365
|
+
if (validation.success)
|
|
103366
|
+
return { config: input.config, issues: [], warnings: [] };
|
|
103367
|
+
const pruned = pruneInvalidConfigPaths(input.config, validation.error.issues, validatePluginRecord);
|
|
103368
|
+
if (!pruned.ok)
|
|
103369
|
+
return { config: input.config, issues: validation.error.issues, warnings: [] };
|
|
103370
|
+
const file = displayOmoConfigPath(input.path, input.homeDir);
|
|
103371
|
+
return {
|
|
103372
|
+
config: pruned.config,
|
|
103373
|
+
issues: [],
|
|
103374
|
+
warnings: pruned.dropped.map((entry) => `config: ${file}: ${input.keyPrefix}${entry.key} ignored (invalid value)`)
|
|
103375
|
+
};
|
|
103376
|
+
}
|
|
103377
|
+
|
|
103115
103378
|
// packages/omo-opencode/src/config/validate.ts
|
|
103116
103379
|
function shortPath(configPath) {
|
|
103117
103380
|
const candidate = relative7(process.cwd(), configPath);
|
|
@@ -103121,9 +103384,8 @@ function formatIssuePath(path) {
|
|
|
103121
103384
|
const formatted = path.map((segment) => String(segment)).join(".");
|
|
103122
103385
|
return formatted.length > 0 ? formatted : "<root>";
|
|
103123
103386
|
}
|
|
103124
|
-
function schemaMessages(configPath, rawConfig) {
|
|
103125
|
-
const
|
|
103126
|
-
const validationMessages = result.success ? [] : result.error.issues.map((issue) => `${shortPath(configPath)}: ${formatIssuePath(issue.path)}: ${issue.message}`);
|
|
103387
|
+
function schemaMessages(configPath, rawConfig, issues) {
|
|
103388
|
+
const validationMessages = issues.map((issue) => `${shortPath(configPath)}: ${formatIssuePath(issue.path)}: ${issue.message}`);
|
|
103127
103389
|
const unknownKeyMessages = findUnknownKeyPaths(OhMyOpenCodeConfigSchema, rawConfig).map((path) => `${shortPath(configPath)}: Unknown config key: ${formatIssuePath(path)}`);
|
|
103128
103390
|
return [...validationMessages, ...unknownKeyMessages];
|
|
103129
103391
|
}
|
|
@@ -103139,11 +103401,13 @@ function parseConfig(rawConfig) {
|
|
|
103139
103401
|
}
|
|
103140
103402
|
return config;
|
|
103141
103403
|
}
|
|
103142
|
-
function parseConfigView(
|
|
103404
|
+
function parseConfigView(view, homeDir) {
|
|
103405
|
+
const pruned = prunePluginView({ config: view.config, homeDir, keyPrefix: view.keyPrefix, path: view.path });
|
|
103143
103406
|
return {
|
|
103144
|
-
config: parseConfig(
|
|
103145
|
-
messages: schemaMessages(path,
|
|
103146
|
-
path
|
|
103407
|
+
config: parseConfig(pruned.config),
|
|
103408
|
+
messages: schemaMessages(view.path, view.config, pruned.issues),
|
|
103409
|
+
path: view.path,
|
|
103410
|
+
warnings: pruned.warnings
|
|
103147
103411
|
};
|
|
103148
103412
|
}
|
|
103149
103413
|
function mergeViews(views) {
|
|
@@ -103235,18 +103499,25 @@ function migrateRalphLoopConfig(config) {
|
|
|
103235
103499
|
}
|
|
103236
103500
|
function validatePluginConfig(directory, environment = process.env) {
|
|
103237
103501
|
const chain = loadOmoOpenCodeConfigChain(directory, environment);
|
|
103238
|
-
const
|
|
103239
|
-
const
|
|
103502
|
+
const homeDir = environment.HOME ?? environment.USERPROFILE;
|
|
103503
|
+
const views = chain.views.map((view) => parseConfigView(view, homeDir));
|
|
103504
|
+
const failing = chain.diagnostics.filter((diagnostic) => diagnostic.kind !== "deprecated-keys" && diagnostic.kind !== "invalid-value");
|
|
103505
|
+
const chainMessages = failing.map((diagnostic) => `${shortPath(diagnostic.path)}: ${diagnostic.message}`);
|
|
103240
103506
|
const messages = [...chainMessages, ...views.flatMap((view) => view.messages)];
|
|
103507
|
+
const warnings = [
|
|
103508
|
+
...omoConfigDiagnosticLines(chain.diagnostics.flatMap((diagnostic) => diagnostic.kind === "invalid-value" ? [diagnostic] : []), { homeDir }),
|
|
103509
|
+
...views.flatMap((view) => view.warnings)
|
|
103510
|
+
];
|
|
103241
103511
|
const firstFailingView = views.find((view) => view.messages.length > 0);
|
|
103242
103512
|
const firstView = views[0];
|
|
103243
|
-
const userConfig = parseConfig(chain.protectedUserView);
|
|
103513
|
+
const userConfig = parseConfig(prunePluginView({ config: chain.protectedUserView, homeDir, keyPrefix: "", path: "" }).config);
|
|
103244
103514
|
const config = applyDisabledProviders(materializeAgentModelChains(protectUserFields(mergeViews(views), userConfig)));
|
|
103245
103515
|
warnLegacyUlwExecuteKey(chain.views);
|
|
103246
103516
|
return {
|
|
103247
103517
|
valid: messages.length === 0,
|
|
103248
103518
|
messages,
|
|
103249
|
-
|
|
103519
|
+
warnings,
|
|
103520
|
+
path: failing[0]?.path ?? firstFailingView?.path ?? firstView?.path ?? null,
|
|
103250
103521
|
config: migrateRalphLoopConfig(migrateLegacyUlwExecuteKey(config))
|
|
103251
103522
|
};
|
|
103252
103523
|
}
|
|
@@ -106370,14 +106641,15 @@ function toOmoConfig(config) {
|
|
|
106370
106641
|
function validateConfig() {
|
|
106371
106642
|
const validation = validatePluginConfig(process.cwd());
|
|
106372
106643
|
if (!validation.path) {
|
|
106373
|
-
return { exists: false, path: null, valid: true, config: null, errors: [] };
|
|
106644
|
+
return { exists: false, path: null, valid: true, config: null, errors: [], warnings: validation.warnings };
|
|
106374
106645
|
}
|
|
106375
106646
|
return {
|
|
106376
106647
|
exists: true,
|
|
106377
106648
|
path: validation.path,
|
|
106378
106649
|
valid: validation.valid,
|
|
106379
106650
|
config: toOmoConfig(validation.config),
|
|
106380
|
-
errors: [...validation.messages]
|
|
106651
|
+
errors: [...validation.messages],
|
|
106652
|
+
warnings: validation.warnings
|
|
106381
106653
|
};
|
|
106382
106654
|
}
|
|
106383
106655
|
function collectModelResolutionIssues(config) {
|
|
@@ -106430,6 +106702,12 @@ async function checkConfig() {
|
|
|
106430
106702
|
}));
|
|
106431
106703
|
if (legacyWarning !== undefined)
|
|
106432
106704
|
issues.push(legacyWarning);
|
|
106705
|
+
issues.push(...validation.warnings.map((warning) => ({
|
|
106706
|
+
title: warning,
|
|
106707
|
+
description: "The rest of that file still applies; fix or remove this value to use it.",
|
|
106708
|
+
severity: "warning",
|
|
106709
|
+
affects: ["configuration"]
|
|
106710
|
+
})));
|
|
106433
106711
|
if (!validation.exists) {
|
|
106434
106712
|
return {
|
|
106435
106713
|
name: CHECK_NAMES[CHECK_IDS.CONFIG],
|