oh-my-opencode 5.1.3 → 5.1.5
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 +599 -191
- package/dist/cli-node/index.js +599 -191
- package/dist/config/prune-plugin-view.d.ts +18 -0
- package/dist/config/validate.d.ts +3 -1
- package/dist/index.js +12044 -11657
- package/dist/plugin-config/omo-config-chain.d.ts +4 -6
- package/dist/skills/browser/runtime/omowright/manifest.json +1 -1
- package/dist/tui.js +683 -280
- package/package.json +14 -14
- package/packages/lsp-core/src/lsp/outside-context-workspace.ts +1 -1
- package/packages/lsp-core/src/missing-dependency-result.test.ts +32 -2
- package/packages/lsp-core/src/missing-dependency-result.ts +3 -0
- package/packages/lsp-core/src/post-edit/file-location.ts +50 -0
- package/packages/lsp-core/src/post-edit/index.ts +2 -0
- package/packages/lsp-core/src/post-edit/not-installed-guidance.ts +36 -0
- package/packages/lsp-core/src/post-edit/not-installed.test.ts +199 -0
- package/packages/lsp-core/src/post-edit/orchestration.ts +26 -5
- package/packages/lsp-daemon/dist/cli.js +2 -1
- package/packages/lsp-daemon/dist/client.js +2 -1
- package/packages/lsp-daemon/dist/index.js +2 -1
- package/packages/lsp-tools-mcp/dist/cli.js +2 -1
- package/packages/lsp-tools-mcp/dist/mcp.js +2 -1
- package/packages/lsp-tools-mcp/dist/tools.js +2 -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 +4 -4
- package/packages/omo-codex/plugin/components/lsp/dist/cli.js +141 -107
- package/packages/omo-codex/plugin/components/lsp/dist/lsp-session-state.js +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/lsp/src/lsp-session-state.ts +2 -2
- 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/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/package.json +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/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/scripts/install-dist/install-local.mjs +311 -135
- package/packages/shared-skills/skills/browser/runtime/omowright/manifest.json +1 -1
package/dist/tui.js
CHANGED
|
@@ -3502,6 +3502,8 @@ var init_category_model_requirements = __esm(() => {
|
|
|
3502
3502
|
},
|
|
3503
3503
|
"deep-low": {
|
|
3504
3504
|
fallbackChain: [
|
|
3505
|
+
{ providers: ["openai", "chatgpt-subscription"], model: "gpt-6.1-sol", variant: "medium" },
|
|
3506
|
+
{ providers: ["openai", "chatgpt-subscription"], model: "gpt-6.1-sol-fast", variant: "medium" },
|
|
3505
3507
|
{
|
|
3506
3508
|
providers: ["openai", "chatgpt-subscription", "github-copilot", "opencode"],
|
|
3507
3509
|
model: "gpt-5.6-sol",
|
|
@@ -3554,7 +3556,9 @@ var init_category_model_requirements = __esm(() => {
|
|
|
3554
3556
|
providers: ["anthropic", "anthropic-api", "github-copilot"],
|
|
3555
3557
|
model: "claude-haiku-4-5",
|
|
3556
3558
|
variant: "off"
|
|
3557
|
-
}
|
|
3559
|
+
},
|
|
3560
|
+
{ providers: ["zai-coding-plan"], model: "glm-5.3-flash", variant: "low" },
|
|
3561
|
+
{ providers: ["xiaomi"], model: "mimo-v2.6-flash", variant: "low" }
|
|
3558
3562
|
]
|
|
3559
3563
|
},
|
|
3560
3564
|
"unspecified-low": {
|
|
@@ -3700,7 +3704,7 @@ var init_model_capability_aliases = __esm(() => {
|
|
|
3700
3704
|
description: "Normalizes OpenCode's OpenAI GPT fast service-tier IDs to canonical snapshot IDs.",
|
|
3701
3705
|
providerIDs: ["openai"],
|
|
3702
3706
|
allowedSubproviderHosts: ["vercel"],
|
|
3703
|
-
match: (normalizedModelID) => /^(?:gpt-5\.6-(?:sol|terra|luna)|gpt-6-(?:astra|sol|luna))-fast$/.test(normalizedModelID),
|
|
3707
|
+
match: (normalizedModelID) => /^(?:gpt-5\.6-(?:sol|terra|luna)|gpt-6-(?:astra|sol|luna)|gpt-6\.1-sol)-fast$/.test(normalizedModelID),
|
|
3704
3708
|
canonicalize: (normalizedModelID) => normalizedModelID.slice(0, -"-fast".length)
|
|
3705
3709
|
},
|
|
3706
3710
|
{
|
|
@@ -3836,6 +3840,14 @@ var init_model_capability_heuristics = __esm(() => {
|
|
|
3836
3840
|
reasoningEffortAliases: { none: "low", minimal: "low" },
|
|
3837
3841
|
supportsTemperature: false
|
|
3838
3842
|
},
|
|
3843
|
+
{
|
|
3844
|
+
family: "gpt-6.1-sol",
|
|
3845
|
+
pattern: /gpt-6-1-sol/,
|
|
3846
|
+
variants: ["low", "medium", "high", "xhigh", "max"],
|
|
3847
|
+
reasoningEfforts: ["low", "medium", "high", "xhigh", "max"],
|
|
3848
|
+
reasoningEffortAliases: { none: "low", minimal: "low" },
|
|
3849
|
+
supportsTemperature: false
|
|
3850
|
+
},
|
|
3839
3851
|
{
|
|
3840
3852
|
family: "gpt-6",
|
|
3841
3853
|
includes: ["gpt-6"],
|
|
@@ -4076,6 +4088,36 @@ var init_supplemental_entries = __esm(() => {
|
|
|
4076
4088
|
output: 128000
|
|
4077
4089
|
}
|
|
4078
4090
|
},
|
|
4091
|
+
"gpt-6.1-sol": {
|
|
4092
|
+
id: "gpt-6.1-sol",
|
|
4093
|
+
family: "gpt",
|
|
4094
|
+
reasoning: true,
|
|
4095
|
+
temperature: false,
|
|
4096
|
+
toolCall: true,
|
|
4097
|
+
modalities: {
|
|
4098
|
+
input: ["text", "image"],
|
|
4099
|
+
output: ["text"]
|
|
4100
|
+
},
|
|
4101
|
+
limit: {
|
|
4102
|
+
context: 400000,
|
|
4103
|
+
output: 128000
|
|
4104
|
+
}
|
|
4105
|
+
},
|
|
4106
|
+
"gpt-6.1-sol-fast": {
|
|
4107
|
+
id: "gpt-6.1-sol-fast",
|
|
4108
|
+
family: "gpt",
|
|
4109
|
+
reasoning: true,
|
|
4110
|
+
temperature: false,
|
|
4111
|
+
toolCall: true,
|
|
4112
|
+
modalities: {
|
|
4113
|
+
input: ["text", "image"],
|
|
4114
|
+
output: ["text"]
|
|
4115
|
+
},
|
|
4116
|
+
limit: {
|
|
4117
|
+
context: 400000,
|
|
4118
|
+
output: 128000
|
|
4119
|
+
}
|
|
4120
|
+
},
|
|
4079
4121
|
"gpt-6-luna": {
|
|
4080
4122
|
id: "gpt-6-luna",
|
|
4081
4123
|
family: "gpt-nano",
|
|
@@ -5257,7 +5299,7 @@ You are working on tasks that don't fit specific categories but require substant
|
|
|
5257
5299
|
</Category_Context>`, UNSPECIFIED_HIGH_CATEGORY_CALLER_GUIDANCE = `<Selection_Gate>Use only when no specialist category fits and substantial effort spans systems/modules with broad impact. Use unspecified-low for contained moderate work.</Selection_Gate>`, DEEP_LOW_CATEGORY_CALLER_GUIDANCE = `<Selection_Gate>Route here when one subsystem plus its callers holds the mechanism and the evidence, once read, leaves one right answer. Wide but mechanical work belongs here or in a quick batch. When unsure, choose deep-low: a misrouted child returns \`ESCALATE: deep-high\` after one cheap attempt; re-spawn the same brief as deep-high with its findings.</Selection_Gate>`, DEEP_HIGH_CATEGORY_CALLER_GUIDANCE = `<Selection_Gate>Route here only when you can name the decision evidence cannot settle: a trade-off with no single right answer, a contract change crossing a package or process boundary, a mechanism with no in-repo pattern to copy, or correctness argued from invariants rather than observed in a test. Wide scope with easy decisions is deep-low or unspecified-high; reasoning as the deliverable is ultrabrain.</Selection_Gate>`, DEEP_LOW_GATE_MODELS, DEEP_HIGH_GATE_MODEL = "gpt-6-astra", OPENAI_CATEGORIES;
|
|
5258
5300
|
var init_openai_categories = __esm(() => {
|
|
5259
5301
|
init_types();
|
|
5260
|
-
DEEP_LOW_GATE_MODELS = ["gpt-5.6-sol-fast", "gpt-5.6-sol"];
|
|
5302
|
+
DEEP_LOW_GATE_MODELS = ["gpt-6.1-sol", "gpt-6.1-sol-fast", "gpt-5.6-sol-fast", "gpt-5.6-sol"];
|
|
5261
5303
|
OPENAI_CATEGORIES = [
|
|
5262
5304
|
{
|
|
5263
5305
|
name: "ultrabrain",
|
|
@@ -5268,7 +5310,7 @@ var init_openai_categories = __esm(() => {
|
|
|
5268
5310
|
},
|
|
5269
5311
|
{
|
|
5270
5312
|
name: "deep-low",
|
|
5271
|
-
config: { model: "openai/gpt-
|
|
5313
|
+
config: { model: "openai/gpt-6.1-sol", variant: "medium" },
|
|
5272
5314
|
description: "Default deep lane: one goal, one deliverable, decisions the child can settle from what it reads. **3D graphics, computer/browser use, CAPTCHA, multimodal, backend, logic, and algorithm work is routed here.** Multiple goals fan out as parallel calls.",
|
|
5273
5315
|
callerGuidance: DEEP_LOW_CATEGORY_CALLER_GUIDANCE,
|
|
5274
5316
|
promptAppend: DEEP_LOW_CATEGORY_PROMPT_APPEND,
|
|
@@ -60328,6 +60370,94 @@ var init_model_capabilities_generated = __esm(() => {
|
|
|
60328
60370
|
context: 1e6,
|
|
60329
60371
|
output: 128000
|
|
60330
60372
|
}
|
|
60373
|
+
},
|
|
60374
|
+
"glm-5.3-flash": {
|
|
60375
|
+
id: "glm-5.3-flash",
|
|
60376
|
+
family: "glm-flash",
|
|
60377
|
+
reasoning: true,
|
|
60378
|
+
temperature: true,
|
|
60379
|
+
toolCall: true,
|
|
60380
|
+
modalities: {
|
|
60381
|
+
input: [
|
|
60382
|
+
"text",
|
|
60383
|
+
"image",
|
|
60384
|
+
"video"
|
|
60385
|
+
],
|
|
60386
|
+
output: [
|
|
60387
|
+
"text"
|
|
60388
|
+
]
|
|
60389
|
+
},
|
|
60390
|
+
limit: {
|
|
60391
|
+
context: 1048576,
|
|
60392
|
+
output: 1048576
|
|
60393
|
+
}
|
|
60394
|
+
},
|
|
60395
|
+
"zai/glm-5.3-flash": {
|
|
60396
|
+
id: "zai/glm-5.3-flash",
|
|
60397
|
+
family: "glm-flash",
|
|
60398
|
+
reasoning: true,
|
|
60399
|
+
temperature: true,
|
|
60400
|
+
toolCall: true,
|
|
60401
|
+
modalities: {
|
|
60402
|
+
input: [
|
|
60403
|
+
"text",
|
|
60404
|
+
"image",
|
|
60405
|
+
"video",
|
|
60406
|
+
"pdf"
|
|
60407
|
+
],
|
|
60408
|
+
output: [
|
|
60409
|
+
"text"
|
|
60410
|
+
]
|
|
60411
|
+
},
|
|
60412
|
+
limit: {
|
|
60413
|
+
context: 1e6,
|
|
60414
|
+
output: 131072
|
|
60415
|
+
}
|
|
60416
|
+
},
|
|
60417
|
+
"mimo-v2.6-flash": {
|
|
60418
|
+
id: "mimo-v2.6-flash",
|
|
60419
|
+
family: "mimo",
|
|
60420
|
+
reasoning: true,
|
|
60421
|
+
temperature: true,
|
|
60422
|
+
toolCall: true,
|
|
60423
|
+
modalities: {
|
|
60424
|
+
input: [
|
|
60425
|
+
"text",
|
|
60426
|
+
"image",
|
|
60427
|
+
"audio",
|
|
60428
|
+
"video"
|
|
60429
|
+
],
|
|
60430
|
+
output: [
|
|
60431
|
+
"text"
|
|
60432
|
+
]
|
|
60433
|
+
},
|
|
60434
|
+
limit: {
|
|
60435
|
+
context: 1048576,
|
|
60436
|
+
output: 131072
|
|
60437
|
+
}
|
|
60438
|
+
},
|
|
60439
|
+
"xiaomi/mimo-v2.6-flash": {
|
|
60440
|
+
id: "xiaomi/mimo-v2.6-flash",
|
|
60441
|
+
family: "mimo",
|
|
60442
|
+
reasoning: true,
|
|
60443
|
+
temperature: true,
|
|
60444
|
+
toolCall: true,
|
|
60445
|
+
modalities: {
|
|
60446
|
+
input: [
|
|
60447
|
+
"text",
|
|
60448
|
+
"image",
|
|
60449
|
+
"audio",
|
|
60450
|
+
"video"
|
|
60451
|
+
],
|
|
60452
|
+
output: [
|
|
60453
|
+
"text"
|
|
60454
|
+
]
|
|
60455
|
+
},
|
|
60456
|
+
limit: {
|
|
60457
|
+
context: 1048576,
|
|
60458
|
+
input: 1048576,
|
|
60459
|
+
output: 131072
|
|
60460
|
+
}
|
|
60331
60461
|
}
|
|
60332
60462
|
}
|
|
60333
60463
|
};
|
|
@@ -69481,97 +69611,6 @@ var init_zod = __esm(() => {
|
|
|
69481
69611
|
init_external();
|
|
69482
69612
|
});
|
|
69483
69613
|
|
|
69484
|
-
// packages/omo-opencode/src/shared/disabled-providers.ts
|
|
69485
|
-
function getModelProvider(model) {
|
|
69486
|
-
const slash = model.indexOf("/");
|
|
69487
|
-
if (slash <= 0)
|
|
69488
|
-
return;
|
|
69489
|
-
const provider = model.slice(0, slash).trim();
|
|
69490
|
-
return provider || undefined;
|
|
69491
|
-
}
|
|
69492
|
-
function isProviderDisabled(model, disabled) {
|
|
69493
|
-
if (!model || disabled.length === 0)
|
|
69494
|
-
return false;
|
|
69495
|
-
const provider = getModelProvider(model);
|
|
69496
|
-
if (provider === undefined)
|
|
69497
|
-
return false;
|
|
69498
|
-
const providerLower = provider.toLowerCase();
|
|
69499
|
-
return disabled.some((entry) => entry.trim().toLowerCase() === providerLower);
|
|
69500
|
-
}
|
|
69501
|
-
function filterDisabledProviderModels(models, disabled) {
|
|
69502
|
-
if (disabled.length === 0)
|
|
69503
|
-
return [...models];
|
|
69504
|
-
return models.filter((entry) => {
|
|
69505
|
-
const model = typeof entry === "string" ? entry : entry.model;
|
|
69506
|
-
return !isProviderDisabled(model, disabled);
|
|
69507
|
-
});
|
|
69508
|
-
}
|
|
69509
|
-
function findFirstAllowedReplacement(chain, disabled) {
|
|
69510
|
-
if (!chain)
|
|
69511
|
-
return;
|
|
69512
|
-
for (const entry of chain) {
|
|
69513
|
-
const model = typeof entry === "string" ? entry : entry.model;
|
|
69514
|
-
if (!isProviderDisabled(model, disabled))
|
|
69515
|
-
return model;
|
|
69516
|
-
}
|
|
69517
|
-
return;
|
|
69518
|
-
}
|
|
69519
|
-
function applyToHolder(label, holder, disabled) {
|
|
69520
|
-
const normalizedChain = normalizeFallbackModels(holder.fallback_models);
|
|
69521
|
-
if (normalizedChain) {
|
|
69522
|
-
const filteredChain = filterDisabledProviderModels(normalizedChain, disabled);
|
|
69523
|
-
if (filteredChain.length !== normalizedChain.length) {
|
|
69524
|
-
log2(`[${HOOK_NAME}] Filtered disabled-provider entries from fallback chain`, {
|
|
69525
|
-
label,
|
|
69526
|
-
removed: normalizedChain.length - filteredChain.length,
|
|
69527
|
-
remaining: filteredChain.length
|
|
69528
|
-
});
|
|
69529
|
-
}
|
|
69530
|
-
holder.fallback_models = filteredChain.length === 0 ? undefined : filteredChain;
|
|
69531
|
-
}
|
|
69532
|
-
if (typeof holder.model === "string" && isProviderDisabled(holder.model, disabled)) {
|
|
69533
|
-
const replacement = findFirstAllowedReplacement(normalizeFallbackModels(holder.fallback_models), disabled);
|
|
69534
|
-
if (replacement) {
|
|
69535
|
-
log2(`[${HOOK_NAME}] Substituted primary model from fallback chain`, {
|
|
69536
|
-
label,
|
|
69537
|
-
from: holder.model,
|
|
69538
|
-
to: replacement
|
|
69539
|
-
});
|
|
69540
|
-
holder.model = replacement;
|
|
69541
|
-
} else {
|
|
69542
|
-
const message = `${label} primary model "${holder.model}" uses a disabled provider and no allowed entry is available in fallback_models. ` + `Either remove the provider from disabled_providers or add an allowed entry to fallback_models.`;
|
|
69543
|
-
addConfigLoadError({ path: `disabled_providers:${label}`, error: message });
|
|
69544
|
-
log2(`[${HOOK_NAME}] ${message}`, { label, primary: holder.model });
|
|
69545
|
-
}
|
|
69546
|
-
}
|
|
69547
|
-
}
|
|
69548
|
-
function applyDisabledProviders(config) {
|
|
69549
|
-
const disabled = config.disabled_providers ?? [];
|
|
69550
|
-
if (disabled.length === 0)
|
|
69551
|
-
return config;
|
|
69552
|
-
if (config.agents) {
|
|
69553
|
-
for (const [name, agentConfig] of Object.entries(config.agents)) {
|
|
69554
|
-
if (agentConfig && typeof agentConfig === "object") {
|
|
69555
|
-
applyToHolder(`agents.${name}`, agentConfig, disabled);
|
|
69556
|
-
}
|
|
69557
|
-
}
|
|
69558
|
-
}
|
|
69559
|
-
if (config.categories) {
|
|
69560
|
-
for (const [name, categoryConfig] of Object.entries(config.categories)) {
|
|
69561
|
-
if (categoryConfig && typeof categoryConfig === "object") {
|
|
69562
|
-
applyToHolder(`categories.${name}`, categoryConfig, disabled);
|
|
69563
|
-
}
|
|
69564
|
-
}
|
|
69565
|
-
}
|
|
69566
|
-
return config;
|
|
69567
|
-
}
|
|
69568
|
-
var HOOK_NAME = "disabled-providers";
|
|
69569
|
-
var init_disabled_providers = __esm(() => {
|
|
69570
|
-
init_config_errors();
|
|
69571
|
-
init_logger2();
|
|
69572
|
-
init_model_resolver2();
|
|
69573
|
-
});
|
|
69574
|
-
|
|
69575
69614
|
// packages/omo-config-core/src/schema/reasoning-vocabulary.ts
|
|
69576
69615
|
function isReasoningLevel(value) {
|
|
69577
69616
|
return REASONING_LEVEL_SET2.has(value);
|
|
@@ -69663,7 +69702,6 @@ function normalizeLegacyModelFields(entry) {
|
|
|
69663
69702
|
delete normalized["reasoningEffort"];
|
|
69664
69703
|
delete normalized["thinking"];
|
|
69665
69704
|
delete normalized["textVerbosity"];
|
|
69666
|
-
delete normalized["maxTokens"];
|
|
69667
69705
|
delete normalized["providerOptions"];
|
|
69668
69706
|
if (typeof entry["model"] === "string")
|
|
69669
69707
|
normalized["model"] = canonicalModelString(entry["model"]);
|
|
@@ -69681,10 +69719,15 @@ function normalizeLegacyModelFields(entry) {
|
|
|
69681
69719
|
providerOptions["textVerbosity"] = entry["textVerbosity"];
|
|
69682
69720
|
if (Object.keys(providerOptions).length > 0)
|
|
69683
69721
|
normalized["provider_options"] = providerOptions;
|
|
69684
|
-
if (entry["max_tokens"] !== undefined)
|
|
69722
|
+
if (entry["max_tokens"] !== undefined) {
|
|
69685
69723
|
normalized["max_tokens"] = entry["max_tokens"];
|
|
69686
|
-
|
|
69724
|
+
if (entry["maxTokens"] === undefined || typeof entry["maxTokens"] === "number") {
|
|
69725
|
+
delete normalized["maxTokens"];
|
|
69726
|
+
}
|
|
69727
|
+
} else if (typeof entry["maxTokens"] === "number") {
|
|
69687
69728
|
normalized["max_tokens"] = entry["maxTokens"];
|
|
69729
|
+
delete normalized["maxTokens"];
|
|
69730
|
+
}
|
|
69688
69731
|
return normalized;
|
|
69689
69732
|
}
|
|
69690
69733
|
var OmoThinkingConfigSchema, OmoReasoningEffortSchema, OmoLegacyFallbackModelObjectInputSchema, OmoFallbackModelObjectSchema, OmoFallbackModelsSchema;
|
|
@@ -69724,12 +69767,25 @@ var init_fallback_models = __esm(() => {
|
|
|
69724
69767
|
function isRecord5(value) {
|
|
69725
69768
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
69726
69769
|
}
|
|
69727
|
-
var OmoAgentModelEntrySchema, OmoAgentDefInputSchema, OmoAgentDefSchema, OmoAgentsConfigSchema;
|
|
69770
|
+
var OmoAgentModelEntrySchema, PermissionValueSchema, BashPermissionSchema, OmoAgentPermissionSchema, OmoAgentDefInputSchema, OmoAgentDefSchema, OmoAgentsConfigSchema;
|
|
69728
69771
|
var init_agent = __esm(() => {
|
|
69729
69772
|
init_zod();
|
|
69730
69773
|
init_fallback_models();
|
|
69731
69774
|
init_model_ref();
|
|
69732
69775
|
OmoAgentModelEntrySchema = union([string2(), OmoFallbackModelObjectSchema]);
|
|
69776
|
+
PermissionValueSchema = _enum(["ask", "allow", "deny"]);
|
|
69777
|
+
BashPermissionSchema = union([
|
|
69778
|
+
PermissionValueSchema,
|
|
69779
|
+
record(string2(), PermissionValueSchema)
|
|
69780
|
+
]);
|
|
69781
|
+
OmoAgentPermissionSchema = object({
|
|
69782
|
+
edit: PermissionValueSchema.optional(),
|
|
69783
|
+
bash: BashPermissionSchema.optional(),
|
|
69784
|
+
webfetch: PermissionValueSchema.optional(),
|
|
69785
|
+
task: PermissionValueSchema.optional(),
|
|
69786
|
+
doom_loop: PermissionValueSchema.optional(),
|
|
69787
|
+
external_directory: PermissionValueSchema.optional()
|
|
69788
|
+
}).catchall(PermissionValueSchema.optional());
|
|
69733
69789
|
OmoAgentDefInputSchema = object({
|
|
69734
69790
|
description: string2().optional(),
|
|
69735
69791
|
prompt: string2().optional(),
|
|
@@ -69746,7 +69802,9 @@ var init_agent = __esm(() => {
|
|
|
69746
69802
|
disallowed_tools: array(string2()).optional(),
|
|
69747
69803
|
max_turns: number2().int().nonnegative().optional(),
|
|
69748
69804
|
temperature: number2().min(0).max(2).optional(),
|
|
69749
|
-
disable: boolean2().optional()
|
|
69805
|
+
disable: boolean2().optional(),
|
|
69806
|
+
permission: OmoAgentPermissionSchema.optional(),
|
|
69807
|
+
prompt_append: string2().optional()
|
|
69750
69808
|
}).strict();
|
|
69751
69809
|
OmoAgentDefSchema = preprocess((value) => isRecord5(value) ? normalizeLegacyModelFields(value) : value, OmoAgentDefInputSchema);
|
|
69752
69810
|
OmoAgentsConfigSchema = record(string2(), OmoAgentDefSchema);
|
|
@@ -70526,6 +70584,64 @@ var init_schema = __esm(() => {
|
|
|
70526
70584
|
init_computer();
|
|
70527
70585
|
});
|
|
70528
70586
|
|
|
70587
|
+
// packages/omo-config-core/src/loader/types.ts
|
|
70588
|
+
import { existsSync as existsSync6, lstatSync, readFileSync as readFileSync6, realpathSync as realpathSync4 } from "fs";
|
|
70589
|
+
var MERGED_OMO_CONFIG_PATH = "(merged omo config)", DEFAULT_READ_FILE_SYSTEM;
|
|
70590
|
+
var init_types3 = __esm(() => {
|
|
70591
|
+
DEFAULT_READ_FILE_SYSTEM = {
|
|
70592
|
+
existsSync: existsSync6,
|
|
70593
|
+
lstatSync,
|
|
70594
|
+
readFileSync: readFileSync6,
|
|
70595
|
+
realpathSync: realpathSync4
|
|
70596
|
+
};
|
|
70597
|
+
});
|
|
70598
|
+
|
|
70599
|
+
// packages/omo-config-core/src/loader/diagnostic-lines.ts
|
|
70600
|
+
function displayOmoConfigPath(path, homeDir) {
|
|
70601
|
+
if (path === MERGED_OMO_CONFIG_PATH)
|
|
70602
|
+
return "merged config";
|
|
70603
|
+
if (homeDir === undefined || homeDir.length === 0)
|
|
70604
|
+
return path;
|
|
70605
|
+
const slashed = (value) => value.replaceAll("\\", "/");
|
|
70606
|
+
const home = slashed(homeDir).replace(/\/+$/, "");
|
|
70607
|
+
const file = slashed(path);
|
|
70608
|
+
const fold = (value) => /^[A-Za-z]:\//.test(home) ? value.toLowerCase() : value;
|
|
70609
|
+
if (fold(file) === fold(home))
|
|
70610
|
+
return "~";
|
|
70611
|
+
return fold(file).startsWith(`${fold(home)}/`) ? `~${file.slice(home.length)}` : path;
|
|
70612
|
+
}
|
|
70613
|
+
function notLoadedReason(diagnostic) {
|
|
70614
|
+
switch (diagnostic.kind) {
|
|
70615
|
+
case "parse":
|
|
70616
|
+
return "JSONC parse error";
|
|
70617
|
+
case "read":
|
|
70618
|
+
return "unreadable";
|
|
70619
|
+
default:
|
|
70620
|
+
return diagnostic.issuePaths === undefined || diagnostic.issuePaths.length === 0 ? "invalid config" : `invalid: ${diagnostic.issuePaths.join(", ")}`;
|
|
70621
|
+
}
|
|
70622
|
+
}
|
|
70623
|
+
function omoConfigDiagnosticLines(diagnostics, options = {}) {
|
|
70624
|
+
return diagnostics.flatMap((diagnostic) => {
|
|
70625
|
+
const file = displayOmoConfigPath(diagnostic.path, options.homeDir);
|
|
70626
|
+
switch (diagnostic.kind) {
|
|
70627
|
+
case "invalid-value":
|
|
70628
|
+
return (diagnostic.issuePaths ?? []).map((key) => `config: ${file}: ${key} ignored (invalid value)`);
|
|
70629
|
+
case "unknown-keys":
|
|
70630
|
+
return (diagnostic.issuePaths ?? []).map((key) => `config: ${file}: ${key} ignored (unknown key)`);
|
|
70631
|
+
case "parse":
|
|
70632
|
+
case "read":
|
|
70633
|
+
case "validation":
|
|
70634
|
+
return diagnostic.path === MERGED_OMO_CONFIG_PATH ? [`config: ${file}: reset to defaults (${notLoadedReason(diagnostic)})`] : [`config: ${file}: not loaded (${notLoadedReason(diagnostic)})`];
|
|
70635
|
+
case "deprecated-keys":
|
|
70636
|
+
case "profile":
|
|
70637
|
+
return [];
|
|
70638
|
+
}
|
|
70639
|
+
});
|
|
70640
|
+
}
|
|
70641
|
+
var init_diagnostic_lines = __esm(() => {
|
|
70642
|
+
init_types3();
|
|
70643
|
+
});
|
|
70644
|
+
|
|
70529
70645
|
// packages/omo-config-core/src/loader/disabled-skills.ts
|
|
70530
70646
|
var init_disabled_skills = () => {};
|
|
70531
70647
|
|
|
@@ -70565,24 +70681,265 @@ var init_merge = __esm(() => {
|
|
|
70565
70681
|
DANGEROUS_KEYS2 = new Set(["__proto__", "constructor", "prototype"]);
|
|
70566
70682
|
});
|
|
70567
70683
|
|
|
70684
|
+
// packages/omo-config-core/src/loader/prune-invalid-leaves.ts
|
|
70685
|
+
function isContainer(value) {
|
|
70686
|
+
return typeof value === "object" && value !== null;
|
|
70687
|
+
}
|
|
70688
|
+
function childOf(container, segment) {
|
|
70689
|
+
return Array.isArray(container) ? container[Number(segment)] : container[String(segment)];
|
|
70690
|
+
}
|
|
70691
|
+
function hasChild(container, segment) {
|
|
70692
|
+
if (Array.isArray(container)) {
|
|
70693
|
+
const index = Number(segment);
|
|
70694
|
+
return Number.isInteger(index) && index >= 0 && index < container.length;
|
|
70695
|
+
}
|
|
70696
|
+
return Object.hasOwn(container, String(segment));
|
|
70697
|
+
}
|
|
70698
|
+
function segmentsOf(path) {
|
|
70699
|
+
return path.map((segment) => typeof segment === "number" ? segment : String(segment));
|
|
70700
|
+
}
|
|
70701
|
+
function targetPaths(root, issue) {
|
|
70702
|
+
const base = segmentsOf(issue.path);
|
|
70703
|
+
if (issue.code === "unrecognized_keys")
|
|
70704
|
+
return issue.keys.map((key) => [...base, key]);
|
|
70705
|
+
let node = root;
|
|
70706
|
+
let depth = 0;
|
|
70707
|
+
for (const segment of base) {
|
|
70708
|
+
if (!isContainer(node) || !hasChild(node, segment))
|
|
70709
|
+
break;
|
|
70710
|
+
node = childOf(node, segment);
|
|
70711
|
+
depth += 1;
|
|
70712
|
+
}
|
|
70713
|
+
return [base.slice(0, depth)];
|
|
70714
|
+
}
|
|
70715
|
+
function isAncestor(ancestor, path) {
|
|
70716
|
+
return ancestor.length < path.length && ancestor.every((segment, index) => segment === path[index]);
|
|
70717
|
+
}
|
|
70718
|
+
function compareDescending(left, right) {
|
|
70719
|
+
const length = Math.min(left.length, right.length);
|
|
70720
|
+
for (let index = 0;index < length; index += 1) {
|
|
70721
|
+
const a = left[index];
|
|
70722
|
+
const b = right[index];
|
|
70723
|
+
if (a === b)
|
|
70724
|
+
continue;
|
|
70725
|
+
if (typeof a === "number" && typeof b === "number")
|
|
70726
|
+
return b - a;
|
|
70727
|
+
return String(b).localeCompare(String(a));
|
|
70728
|
+
}
|
|
70729
|
+
return right.length - left.length;
|
|
70730
|
+
}
|
|
70731
|
+
function removeChild(container, segment) {
|
|
70732
|
+
if (Array.isArray(container))
|
|
70733
|
+
container.splice(Number(segment), 1);
|
|
70734
|
+
else
|
|
70735
|
+
delete container[String(segment)];
|
|
70736
|
+
}
|
|
70737
|
+
function isEmpty(container) {
|
|
70738
|
+
return Array.isArray(container) ? container.length === 0 : Object.keys(container).length === 0;
|
|
70739
|
+
}
|
|
70740
|
+
function removePathAndEmptiedAncestors(root, path) {
|
|
70741
|
+
const chain = [root];
|
|
70742
|
+
for (const segment of path.slice(0, -1)) {
|
|
70743
|
+
const current = chain[chain.length - 1];
|
|
70744
|
+
if (current === undefined)
|
|
70745
|
+
return;
|
|
70746
|
+
const next = childOf(current, segment);
|
|
70747
|
+
if (!isContainer(next))
|
|
70748
|
+
return;
|
|
70749
|
+
chain.push(next);
|
|
70750
|
+
}
|
|
70751
|
+
for (let depth = path.length - 1;depth >= 0; depth -= 1) {
|
|
70752
|
+
const container = chain[depth];
|
|
70753
|
+
const segment = path[depth];
|
|
70754
|
+
if (container === undefined || segment === undefined)
|
|
70755
|
+
return;
|
|
70756
|
+
removeChild(container, segment);
|
|
70757
|
+
if (depth === 0 || !isEmpty(container))
|
|
70758
|
+
return;
|
|
70759
|
+
}
|
|
70760
|
+
}
|
|
70761
|
+
function prunePass(root, issues) {
|
|
70762
|
+
const byKey = new Map;
|
|
70763
|
+
for (const issue of issues) {
|
|
70764
|
+
for (const path of targetPaths(root, issue)) {
|
|
70765
|
+
if (path.length === 0)
|
|
70766
|
+
return null;
|
|
70767
|
+
const key = path.map((segment) => String(segment)).join(".");
|
|
70768
|
+
if (!byKey.has(key))
|
|
70769
|
+
byKey.set(key, { key, message: issue.message, path });
|
|
70770
|
+
}
|
|
70771
|
+
}
|
|
70772
|
+
const targets = [...byKey.values()];
|
|
70773
|
+
const outermost = targets.filter((target) => !targets.some((other) => isAncestor(other.path, target.path))).sort((left, right) => compareDescending(left.path, right.path));
|
|
70774
|
+
const next = structuredClone(root);
|
|
70775
|
+
for (const target of outermost)
|
|
70776
|
+
removePathAndEmptiedAncestors(next, target.path);
|
|
70777
|
+
return { dropped: outermost, next };
|
|
70778
|
+
}
|
|
70779
|
+
function pruneInvalidConfigPaths(config, issues, validate, maxPasses = MAX_PRUNE_PASSES) {
|
|
70780
|
+
const dropped = [];
|
|
70781
|
+
let current = config;
|
|
70782
|
+
let pending = issues;
|
|
70783
|
+
for (let pass = 0;pass < maxPasses; pass += 1) {
|
|
70784
|
+
const step = prunePass(current, pending);
|
|
70785
|
+
if (step === null || step.dropped.length === 0)
|
|
70786
|
+
return { ok: false, dropped };
|
|
70787
|
+
dropped.push(...step.dropped);
|
|
70788
|
+
current = step.next;
|
|
70789
|
+
if (Object.keys(current).length === 0)
|
|
70790
|
+
return { ok: false, dropped };
|
|
70791
|
+
const validation = validate(current);
|
|
70792
|
+
if (validation.success)
|
|
70793
|
+
return { ok: true, config: current, dropped };
|
|
70794
|
+
pending = validation.issues;
|
|
70795
|
+
}
|
|
70796
|
+
return { ok: false, dropped };
|
|
70797
|
+
}
|
|
70798
|
+
var MAX_PRUNE_PASSES = 32;
|
|
70799
|
+
|
|
70800
|
+
// packages/omo-config-core/src/loader/layer-validation.ts
|
|
70801
|
+
function validationDiagnostic(path, issues) {
|
|
70802
|
+
const issuePaths = issues.map((issue) => issue.path.map((segment) => String(segment)).join("."));
|
|
70803
|
+
return {
|
|
70804
|
+
kind: "validation",
|
|
70805
|
+
message: `Invalid omo config at ${path}: ${issuePaths.join(", ")}`,
|
|
70806
|
+
path,
|
|
70807
|
+
issuePaths
|
|
70808
|
+
};
|
|
70809
|
+
}
|
|
70810
|
+
function invalidValueDiagnostics(path, dropped) {
|
|
70811
|
+
return dropped.map((entry) => ({
|
|
70812
|
+
kind: "invalid-value",
|
|
70813
|
+
message: `Ignored invalid value in ${path}: ${entry.key}: ${entry.message}`,
|
|
70814
|
+
path,
|
|
70815
|
+
issuePaths: [entry.key]
|
|
70816
|
+
}));
|
|
70817
|
+
}
|
|
70818
|
+
function unrecognizedKeyIssues(issues) {
|
|
70819
|
+
return issues.flatMap((issue) => issue.code === "unrecognized_keys" ? [{ keys: issue.keys, path: issue.path.map((segment) => String(segment)) }] : []);
|
|
70820
|
+
}
|
|
70821
|
+
function isRecord11(value) {
|
|
70822
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
70823
|
+
}
|
|
70824
|
+
function sanitizeUnsafeKeys(value, path = []) {
|
|
70825
|
+
if (Array.isArray(value)) {
|
|
70826
|
+
const issues = [];
|
|
70827
|
+
const sanitized = value.map((entry, index) => {
|
|
70828
|
+
const nested = sanitizeUnsafeKeys(entry, [...path, String(index)]);
|
|
70829
|
+
issues.push(...nested.issues);
|
|
70830
|
+
return nested.value;
|
|
70831
|
+
});
|
|
70832
|
+
return { issues, value: sanitized };
|
|
70833
|
+
}
|
|
70834
|
+
if (!isRecord11(value))
|
|
70835
|
+
return { issues: [], value };
|
|
70836
|
+
const issues = [];
|
|
70837
|
+
if (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) {
|
|
70838
|
+
issues.push({ keys: ["__proto__"], path });
|
|
70839
|
+
}
|
|
70840
|
+
const sanitized = {};
|
|
70841
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
70842
|
+
if (isUnsafeObjectKey2(key)) {
|
|
70843
|
+
issues.push({ keys: [key], path });
|
|
70844
|
+
continue;
|
|
70845
|
+
}
|
|
70846
|
+
const nested = sanitizeUnsafeKeys(entry, [...path, key]);
|
|
70847
|
+
issues.push(...nested.issues);
|
|
70848
|
+
sanitized[key] = nested.value;
|
|
70849
|
+
}
|
|
70850
|
+
return { issues, value: sanitized };
|
|
70851
|
+
}
|
|
70852
|
+
function containerAt(record, path) {
|
|
70853
|
+
let node = record;
|
|
70854
|
+
for (const segment of path) {
|
|
70855
|
+
if (Array.isArray(node)) {
|
|
70856
|
+
const index = Number(segment);
|
|
70857
|
+
if (!Number.isInteger(index) || index < 0 || index >= node.length)
|
|
70858
|
+
return null;
|
|
70859
|
+
node = node[index];
|
|
70860
|
+
} else if (isRecord11(node) && Object.hasOwn(node, segment)) {
|
|
70861
|
+
node = node[segment];
|
|
70862
|
+
} else {
|
|
70863
|
+
return null;
|
|
70864
|
+
}
|
|
70865
|
+
}
|
|
70866
|
+
return isRecord11(node) ? node : null;
|
|
70867
|
+
}
|
|
70868
|
+
function stripUnrecognizedKeys(record, issues) {
|
|
70869
|
+
const stripped = structuredClone(record);
|
|
70870
|
+
const issuePaths = [];
|
|
70871
|
+
for (const issue of issues) {
|
|
70872
|
+
const container = containerAt(stripped, issue.path);
|
|
70873
|
+
if (container === null)
|
|
70874
|
+
continue;
|
|
70875
|
+
for (const key of issue.keys) {
|
|
70876
|
+
delete container[key];
|
|
70877
|
+
issuePaths.push([...issue.path, key].join("."));
|
|
70878
|
+
}
|
|
70879
|
+
}
|
|
70880
|
+
return { issuePaths, stripped };
|
|
70881
|
+
}
|
|
70882
|
+
function toRecord(value) {
|
|
70883
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
70884
|
+
return null;
|
|
70885
|
+
const record = {};
|
|
70886
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
70887
|
+
record[key] = entry;
|
|
70888
|
+
}
|
|
70889
|
+
return record;
|
|
70890
|
+
}
|
|
70891
|
+
function validateConfigLayer(path, data) {
|
|
70892
|
+
const sanitized = sanitizeUnsafeKeys(data);
|
|
70893
|
+
const record = toRecord(sanitized.value);
|
|
70894
|
+
const unsafeIssuePaths = sanitized.issues.flatMap((issue) => issue.keys.map((key) => [...issue.path, key].join(".")));
|
|
70895
|
+
const unsafeDiagnostics = unsafeIssuePaths.length === 0 ? [] : [{ kind: "unknown-keys", message: `Ignored unknown keys in ${path}: ${unsafeIssuePaths.join(", ")}`, path, issuePaths: unsafeIssuePaths }];
|
|
70896
|
+
const validation = OmoConfigLayerSchema.safeParse(sanitized.value);
|
|
70897
|
+
if (validation.success) {
|
|
70898
|
+
if (record !== null)
|
|
70899
|
+
return { loaded: true, diagnostics: unsafeDiagnostics, value: record };
|
|
70900
|
+
return {
|
|
70901
|
+
loaded: false,
|
|
70902
|
+
diagnostics: [{ kind: "validation", message: `Invalid omo config at ${path}: root must be an object`, path }]
|
|
70903
|
+
};
|
|
70904
|
+
}
|
|
70905
|
+
const rejected = { loaded: false, diagnostics: [validationDiagnostic(path, validation.error.issues)] };
|
|
70906
|
+
const unknownIssues = unrecognizedKeyIssues(validation.error.issues);
|
|
70907
|
+
if (record === null)
|
|
70908
|
+
return rejected;
|
|
70909
|
+
let candidate = record;
|
|
70910
|
+
let issues = validation.error.issues;
|
|
70911
|
+
const diagnostics = [...unsafeDiagnostics];
|
|
70912
|
+
if (unknownIssues.length > 0) {
|
|
70913
|
+
const { issuePaths, stripped } = stripUnrecognizedKeys(record, unknownIssues);
|
|
70914
|
+
if (issuePaths.length > 0) {
|
|
70915
|
+
diagnostics.push({ kind: "unknown-keys", message: `Ignored unknown keys in ${path}: ${issuePaths.join(", ")}`, path, issuePaths });
|
|
70916
|
+
}
|
|
70917
|
+
const strippedValidation = validateLayerRecord(stripped);
|
|
70918
|
+
if (strippedValidation.success)
|
|
70919
|
+
return { loaded: true, diagnostics, value: stripped };
|
|
70920
|
+
candidate = stripped;
|
|
70921
|
+
issues = strippedValidation.issues;
|
|
70922
|
+
}
|
|
70923
|
+
const pruned = pruneInvalidConfigPaths(candidate, issues, validateLayerRecord);
|
|
70924
|
+
if (!pruned.ok)
|
|
70925
|
+
return rejected;
|
|
70926
|
+
return { loaded: true, diagnostics: [...diagnostics, ...invalidValueDiagnostics(path, pruned.dropped)], value: pruned.config };
|
|
70927
|
+
}
|
|
70928
|
+
var validateLayerRecord = (record) => {
|
|
70929
|
+
const parsed = OmoConfigLayerSchema.safeParse(record);
|
|
70930
|
+
return parsed.success ? { success: true } : { success: false, issues: parsed.error.issues };
|
|
70931
|
+
};
|
|
70932
|
+
var init_layer_validation = __esm(() => {
|
|
70933
|
+
init_schema();
|
|
70934
|
+
init_merge();
|
|
70935
|
+
});
|
|
70936
|
+
|
|
70568
70937
|
// packages/omo-config-core/src/internal/posix-path.ts
|
|
70569
70938
|
function toPosixPath(path) {
|
|
70570
70939
|
return path.split("\\").join("/");
|
|
70571
70940
|
}
|
|
70572
70941
|
var init_posix_path = () => {};
|
|
70573
70942
|
|
|
70574
|
-
// packages/omo-config-core/src/loader/types.ts
|
|
70575
|
-
import { existsSync as existsSync6, lstatSync, readFileSync as readFileSync6, realpathSync as realpathSync4 } from "fs";
|
|
70576
|
-
var DEFAULT_READ_FILE_SYSTEM;
|
|
70577
|
-
var init_types3 = __esm(() => {
|
|
70578
|
-
DEFAULT_READ_FILE_SYSTEM = {
|
|
70579
|
-
existsSync: existsSync6,
|
|
70580
|
-
lstatSync,
|
|
70581
|
-
readFileSync: readFileSync6,
|
|
70582
|
-
realpathSync: realpathSync4
|
|
70583
|
-
};
|
|
70584
|
-
});
|
|
70585
|
-
|
|
70586
70943
|
// packages/omo-config-core/src/loader/paths.ts
|
|
70587
70944
|
import { userInfo } from "os";
|
|
70588
70945
|
import { dirname as dirname4, join as join12, posix as posix2, resolve as resolve4 } from "path";
|
|
@@ -70683,7 +71040,7 @@ function resolveOmoProfileName(options = {}) {
|
|
|
70683
71040
|
const env = options.env ?? process.env;
|
|
70684
71041
|
return profileName(options.profile) ?? profileName(env["OMO_PROFILE"]) ?? profileName(env["OCX_PROFILE"]) ?? profileNameFromOpenCodeConfigDir(env["OPENCODE_CONFIG_DIR"]);
|
|
70685
71042
|
}
|
|
70686
|
-
function
|
|
71043
|
+
function toRecord2(value) {
|
|
70687
71044
|
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
70688
71045
|
return;
|
|
70689
71046
|
return Object.fromEntries(Object.entries(value));
|
|
@@ -70704,13 +71061,13 @@ function harnessLayer(config, harness) {
|
|
|
70704
71061
|
const legacyKeys = Object.entries(OMO_CONFIG_LEGACY_HARNESS_ALIASES).filter(([, target]) => target === canonical).map(([legacy]) => harnessBlockKey(legacy));
|
|
70705
71062
|
let layer = {};
|
|
70706
71063
|
for (const key of [...legacyKeys, harnessBlockKey(canonical)]) {
|
|
70707
|
-
layer = mergeOmoConfigRecords(layer,
|
|
71064
|
+
layer = mergeOmoConfigRecords(layer, toRecord2(config[key]) ?? {});
|
|
70708
71065
|
}
|
|
70709
71066
|
return layer;
|
|
70710
71067
|
}
|
|
70711
71068
|
function resolveOmoConfigView(options) {
|
|
70712
|
-
const profiles =
|
|
70713
|
-
const profile = options.profile === undefined ? undefined :
|
|
71069
|
+
const profiles = toRecord2(options.config["profiles"]);
|
|
71070
|
+
const profile = options.profile === undefined ? undefined : toRecord2(profiles?.[options.profile]);
|
|
70714
71071
|
const diagnostics = profile === undefined && options.profile !== undefined ? [{
|
|
70715
71072
|
kind: "profile",
|
|
70716
71073
|
message: `Activated omo profile "${options.profile}" does not exist; using the base configuration`,
|
|
@@ -70765,70 +71122,9 @@ function stripResolutionControlKeys(config) {
|
|
|
70765
71122
|
} = config;
|
|
70766
71123
|
return resolved;
|
|
70767
71124
|
}
|
|
70768
|
-
function validationDiagnostic(path, issues) {
|
|
70769
|
-
const issuePaths = issues.map((issue) => issue.path.map((segment) => String(segment)).join("."));
|
|
70770
|
-
return {
|
|
70771
|
-
kind: "validation",
|
|
70772
|
-
message: `Invalid omo config at ${path}: ${issuePaths.join(", ")}`,
|
|
70773
|
-
path,
|
|
70774
|
-
issuePaths
|
|
70775
|
-
};
|
|
70776
|
-
}
|
|
70777
|
-
function unrecognizedKeyIssues(issues) {
|
|
70778
|
-
return issues.flatMap((issue) => issue.code === "unrecognized_keys" ? [{ keys: issue.keys, path: issue.path.map((segment) => String(segment)) }] : []);
|
|
70779
|
-
}
|
|
70780
|
-
function hasUnsafeUnrecognizedKey(issues) {
|
|
70781
|
-
return issues.some((issue) => issue.keys.some((key) => isUnsafeObjectKey2(key)));
|
|
70782
|
-
}
|
|
70783
|
-
function hasTamperedPrototype(value) {
|
|
70784
|
-
if (Array.isArray(value))
|
|
70785
|
-
return value.some((entry) => hasTamperedPrototype(entry));
|
|
70786
|
-
if (!isRecord11(value))
|
|
70787
|
-
return false;
|
|
70788
|
-
const prototype = Object.getPrototypeOf(value);
|
|
70789
|
-
if (prototype !== Object.prototype && prototype !== null)
|
|
70790
|
-
return true;
|
|
70791
|
-
return Object.values(value).some((entry) => hasTamperedPrototype(entry));
|
|
70792
|
-
}
|
|
70793
|
-
function isRecord11(value) {
|
|
70794
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
70795
|
-
}
|
|
70796
|
-
function containerAt(record, path) {
|
|
70797
|
-
let container = record;
|
|
70798
|
-
for (const segment of path) {
|
|
70799
|
-
const next = container[segment];
|
|
70800
|
-
if (!isRecord11(next))
|
|
70801
|
-
return null;
|
|
70802
|
-
container = next;
|
|
70803
|
-
}
|
|
70804
|
-
return container;
|
|
70805
|
-
}
|
|
70806
|
-
function stripUnrecognizedKeys(record, issues) {
|
|
70807
|
-
const stripped = structuredClone(record);
|
|
70808
|
-
const issuePaths = [];
|
|
70809
|
-
for (const issue of issues) {
|
|
70810
|
-
const container = containerAt(stripped, issue.path);
|
|
70811
|
-
if (container === null)
|
|
70812
|
-
continue;
|
|
70813
|
-
for (const key of issue.keys) {
|
|
70814
|
-
delete container[key];
|
|
70815
|
-
issuePaths.push([...issue.path, key].join("."));
|
|
70816
|
-
}
|
|
70817
|
-
}
|
|
70818
|
-
return { issuePaths, stripped };
|
|
70819
|
-
}
|
|
70820
|
-
function toRecord2(value) {
|
|
70821
|
-
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
70822
|
-
return null;
|
|
70823
|
-
const record = {};
|
|
70824
|
-
for (const [key, entry] of Object.entries(value)) {
|
|
70825
|
-
record[key] = entry;
|
|
70826
|
-
}
|
|
70827
|
-
return record;
|
|
70828
|
-
}
|
|
70829
71125
|
function readConfigSource(path, scope, fileSystem) {
|
|
70830
71126
|
if (!fileSystem.existsSync(path)) {
|
|
70831
|
-
return { source: { exists: false, loaded: false, path, scope } };
|
|
71127
|
+
return { diagnostics: [], source: { exists: false, loaded: false, path, scope } };
|
|
70832
71128
|
}
|
|
70833
71129
|
let content;
|
|
70834
71130
|
try {
|
|
@@ -70836,68 +71132,23 @@ function readConfigSource(path, scope, fileSystem) {
|
|
|
70836
71132
|
} catch (error) {
|
|
70837
71133
|
const message = error instanceof Error ? error.message : String(error);
|
|
70838
71134
|
return {
|
|
70839
|
-
|
|
71135
|
+
diagnostics: [{ kind: "read", message: `Failed to read ${path}: ${message}`, path }],
|
|
70840
71136
|
source: { exists: true, loaded: false, path, scope }
|
|
70841
71137
|
};
|
|
70842
71138
|
}
|
|
70843
71139
|
const parsed = parseJsoncSafe2(content);
|
|
70844
71140
|
if (parsed.errors.length > 0) {
|
|
70845
71141
|
return {
|
|
70846
|
-
|
|
71142
|
+
diagnostics: [{
|
|
70847
71143
|
kind: "parse",
|
|
70848
71144
|
message: `JSONC parse error in ${path}: ${parsed.errors.map((error) => error.message).join(", ")}`,
|
|
70849
71145
|
path
|
|
70850
|
-
},
|
|
70851
|
-
source: { exists: true, loaded: false, path, scope }
|
|
70852
|
-
};
|
|
70853
|
-
}
|
|
70854
|
-
if (hasTamperedPrototype(parsed.data)) {
|
|
70855
|
-
return {
|
|
70856
|
-
diagnostic: { kind: "validation", message: `Invalid omo config at ${path}: "__proto__" member is not allowed`, path },
|
|
70857
|
-
source: { exists: true, loaded: false, path, scope }
|
|
70858
|
-
};
|
|
70859
|
-
}
|
|
70860
|
-
const parsedRecord = toRecord2(parsed.data);
|
|
70861
|
-
const validation = OmoConfigLayerSchema.safeParse(parsed.data);
|
|
70862
|
-
if (!validation.success) {
|
|
70863
|
-
const unrecognized = unrecognizedKeyIssues(validation.error.issues);
|
|
70864
|
-
if (hasUnsafeUnrecognizedKey(unrecognized)) {
|
|
70865
|
-
return {
|
|
70866
|
-
diagnostic: validationDiagnostic(path, validation.error.issues),
|
|
70867
|
-
source: { exists: true, loaded: false, path, scope }
|
|
70868
|
-
};
|
|
70869
|
-
}
|
|
70870
|
-
const rejected = {
|
|
70871
|
-
diagnostic: validationDiagnostic(path, validation.error.issues),
|
|
71146
|
+
}],
|
|
70872
71147
|
source: { exists: true, loaded: false, path, scope }
|
|
70873
71148
|
};
|
|
70874
|
-
const unknownIssues = unrecognizedKeyIssues(validation.error.issues);
|
|
70875
|
-
if (parsedRecord === null || unknownIssues.length === 0)
|
|
70876
|
-
return rejected;
|
|
70877
|
-
const { issuePaths, stripped } = stripUnrecognizedKeys(parsedRecord, unknownIssues);
|
|
70878
|
-
if (!OmoConfigLayerSchema.safeParse(stripped).success)
|
|
70879
|
-
return rejected;
|
|
70880
|
-
return {
|
|
70881
|
-
diagnostic: {
|
|
70882
|
-
kind: "unknown-keys",
|
|
70883
|
-
message: `Ignored unknown keys in ${path}: ${issuePaths.join(", ")}`,
|
|
70884
|
-
path,
|
|
70885
|
-
issuePaths
|
|
70886
|
-
},
|
|
70887
|
-
source: { exists: true, loaded: true, path, scope },
|
|
70888
|
-
value: stripped
|
|
70889
|
-
};
|
|
70890
71149
|
}
|
|
70891
|
-
|
|
70892
|
-
|
|
70893
|
-
diagnostic: { kind: "validation", message: `Invalid omo config at ${path}: root must be an object`, path },
|
|
70894
|
-
source: { exists: true, loaded: false, path, scope }
|
|
70895
|
-
};
|
|
70896
|
-
}
|
|
70897
|
-
return {
|
|
70898
|
-
source: { exists: true, loaded: true, path, scope },
|
|
70899
|
-
value: parsedRecord
|
|
70900
|
-
};
|
|
71150
|
+
const layer = validateConfigLayer(path, parsed.data);
|
|
71151
|
+
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 } };
|
|
70901
71152
|
}
|
|
70902
71153
|
function legacyCategoryDiagnostic(path, renames) {
|
|
70903
71154
|
const detail = renames.map((rename) => rename.dropped ? `${rename.path} ignored because ${rename.canonical} is also configured` : `${rename.path} renamed to ${rename.canonical}`).join(", ");
|
|
@@ -70932,8 +71183,7 @@ function loadOmoConfig(options = {}) {
|
|
|
70932
71183
|
})) {
|
|
70933
71184
|
const loaded = readConfigSource(candidate.path, candidate.scope, fileSystem);
|
|
70934
71185
|
sources.push(loaded.source);
|
|
70935
|
-
|
|
70936
|
-
diagnostics.push(loaded.diagnostic);
|
|
71186
|
+
diagnostics.push(...loaded.diagnostics);
|
|
70937
71187
|
if (loaded.value !== undefined) {
|
|
70938
71188
|
const canonicalized = canonicalizeLegacyCategoryNames(loaded.value);
|
|
70939
71189
|
if (canonicalized.renames.length > 0) {
|
|
@@ -70956,7 +71206,8 @@ function loadOmoConfig(options = {}) {
|
|
|
70956
71206
|
...options.harness === undefined ? {} : { harness: options.harness },
|
|
70957
71207
|
...requestedProfile === undefined ? {} : { profile: requestedProfile }
|
|
70958
71208
|
});
|
|
70959
|
-
const
|
|
71209
|
+
const finalInput = mergeOmoConfigRecords(DEFAULT_RAW_CONFIG, resolved.config);
|
|
71210
|
+
const finalConfig = OmoConfigSchema.safeParse(finalInput);
|
|
70960
71211
|
if (finalConfig.success) {
|
|
70961
71212
|
return {
|
|
70962
71213
|
config: stripResolutionControlKeys(finalConfig.data),
|
|
@@ -70966,9 +71217,22 @@ function loadOmoConfig(options = {}) {
|
|
|
70966
71217
|
sources
|
|
70967
71218
|
};
|
|
70968
71219
|
}
|
|
71220
|
+
const pruned = pruneInvalidConfigPaths(finalInput, finalConfig.error.issues, (record) => {
|
|
71221
|
+
const parsed = OmoConfigSchema.safeParse(record);
|
|
71222
|
+
return parsed.success ? { success: true } : { success: false, issues: parsed.error.issues };
|
|
71223
|
+
});
|
|
71224
|
+
if (pruned.ok) {
|
|
71225
|
+
return {
|
|
71226
|
+
config: stripResolutionControlKeys(OmoConfigSchema.parse(pruned.config)),
|
|
71227
|
+
diagnostics: [...diagnostics, ...resolved.diagnostics, ...invalidValueDiagnostics(MERGED_OMO_CONFIG_PATH, pruned.dropped)],
|
|
71228
|
+
layers,
|
|
71229
|
+
...resolved.profile === undefined ? {} : { profile: resolved.profile },
|
|
71230
|
+
sources
|
|
71231
|
+
};
|
|
71232
|
+
}
|
|
70969
71233
|
return {
|
|
70970
71234
|
config: stripResolutionControlKeys(OmoConfigSchema.parse(DEFAULT_RAW_CONFIG)),
|
|
70971
|
-
diagnostics: [...diagnostics, ...resolved.diagnostics, validationDiagnostic(
|
|
71235
|
+
diagnostics: [...diagnostics, ...resolved.diagnostics, validationDiagnostic(MERGED_OMO_CONFIG_PATH, finalConfig.error.issues)],
|
|
70972
71236
|
layers,
|
|
70973
71237
|
...resolved.profile === undefined ? {} : { profile: resolved.profile },
|
|
70974
71238
|
sources
|
|
@@ -70978,6 +71242,7 @@ var DEFAULT_RAW_CONFIG;
|
|
|
70978
71242
|
var init_loader2 = __esm(() => {
|
|
70979
71243
|
init_main();
|
|
70980
71244
|
init_schema();
|
|
71245
|
+
init_layer_validation();
|
|
70981
71246
|
init_merge();
|
|
70982
71247
|
init_paths();
|
|
70983
71248
|
init_resolution();
|
|
@@ -70992,6 +71257,7 @@ var init_loader2 = __esm(() => {
|
|
|
70992
71257
|
|
|
70993
71258
|
// packages/omo-config-core/src/loader/index.ts
|
|
70994
71259
|
var init_loader3 = __esm(() => {
|
|
71260
|
+
init_diagnostic_lines();
|
|
70995
71261
|
init_disabled_skills();
|
|
70996
71262
|
init_loader2();
|
|
70997
71263
|
init_merge();
|
|
@@ -71285,6 +71551,97 @@ var init_src4 = __esm(() => {
|
|
|
71285
71551
|
init_migration3();
|
|
71286
71552
|
});
|
|
71287
71553
|
|
|
71554
|
+
// packages/omo-opencode/src/shared/disabled-providers.ts
|
|
71555
|
+
function getModelProvider(model) {
|
|
71556
|
+
const slash = model.indexOf("/");
|
|
71557
|
+
if (slash <= 0)
|
|
71558
|
+
return;
|
|
71559
|
+
const provider = model.slice(0, slash).trim();
|
|
71560
|
+
return provider || undefined;
|
|
71561
|
+
}
|
|
71562
|
+
function isProviderDisabled(model, disabled) {
|
|
71563
|
+
if (!model || disabled.length === 0)
|
|
71564
|
+
return false;
|
|
71565
|
+
const provider = getModelProvider(model);
|
|
71566
|
+
if (provider === undefined)
|
|
71567
|
+
return false;
|
|
71568
|
+
const providerLower = provider.toLowerCase();
|
|
71569
|
+
return disabled.some((entry) => entry.trim().toLowerCase() === providerLower);
|
|
71570
|
+
}
|
|
71571
|
+
function filterDisabledProviderModels(models, disabled) {
|
|
71572
|
+
if (disabled.length === 0)
|
|
71573
|
+
return [...models];
|
|
71574
|
+
return models.filter((entry) => {
|
|
71575
|
+
const model = typeof entry === "string" ? entry : entry.model;
|
|
71576
|
+
return !isProviderDisabled(model, disabled);
|
|
71577
|
+
});
|
|
71578
|
+
}
|
|
71579
|
+
function findFirstAllowedReplacement(chain, disabled) {
|
|
71580
|
+
if (!chain)
|
|
71581
|
+
return;
|
|
71582
|
+
for (const entry of chain) {
|
|
71583
|
+
const model = typeof entry === "string" ? entry : entry.model;
|
|
71584
|
+
if (!isProviderDisabled(model, disabled))
|
|
71585
|
+
return model;
|
|
71586
|
+
}
|
|
71587
|
+
return;
|
|
71588
|
+
}
|
|
71589
|
+
function applyToHolder(label, holder, disabled) {
|
|
71590
|
+
const normalizedChain = normalizeFallbackModels(holder.fallback_models);
|
|
71591
|
+
if (normalizedChain) {
|
|
71592
|
+
const filteredChain = filterDisabledProviderModels(normalizedChain, disabled);
|
|
71593
|
+
if (filteredChain.length !== normalizedChain.length) {
|
|
71594
|
+
log2(`[${HOOK_NAME}] Filtered disabled-provider entries from fallback chain`, {
|
|
71595
|
+
label,
|
|
71596
|
+
removed: normalizedChain.length - filteredChain.length,
|
|
71597
|
+
remaining: filteredChain.length
|
|
71598
|
+
});
|
|
71599
|
+
}
|
|
71600
|
+
holder.fallback_models = filteredChain.length === 0 ? undefined : filteredChain;
|
|
71601
|
+
}
|
|
71602
|
+
if (typeof holder.model === "string" && isProviderDisabled(holder.model, disabled)) {
|
|
71603
|
+
const replacement = findFirstAllowedReplacement(normalizeFallbackModels(holder.fallback_models), disabled);
|
|
71604
|
+
if (replacement) {
|
|
71605
|
+
log2(`[${HOOK_NAME}] Substituted primary model from fallback chain`, {
|
|
71606
|
+
label,
|
|
71607
|
+
from: holder.model,
|
|
71608
|
+
to: replacement
|
|
71609
|
+
});
|
|
71610
|
+
holder.model = replacement;
|
|
71611
|
+
} else {
|
|
71612
|
+
const message = `${label} primary model "${holder.model}" uses a disabled provider and no allowed entry is available in fallback_models. ` + `Either remove the provider from disabled_providers or add an allowed entry to fallback_models.`;
|
|
71613
|
+
addConfigLoadError({ path: `disabled_providers:${label}`, error: message });
|
|
71614
|
+
log2(`[${HOOK_NAME}] ${message}`, { label, primary: holder.model });
|
|
71615
|
+
}
|
|
71616
|
+
}
|
|
71617
|
+
}
|
|
71618
|
+
function applyDisabledProviders(config) {
|
|
71619
|
+
const disabled = config.disabled_providers ?? [];
|
|
71620
|
+
if (disabled.length === 0)
|
|
71621
|
+
return config;
|
|
71622
|
+
if (config.agents) {
|
|
71623
|
+
for (const [name, agentConfig] of Object.entries(config.agents)) {
|
|
71624
|
+
if (agentConfig && typeof agentConfig === "object") {
|
|
71625
|
+
applyToHolder(`agents.${name}`, agentConfig, disabled);
|
|
71626
|
+
}
|
|
71627
|
+
}
|
|
71628
|
+
}
|
|
71629
|
+
if (config.categories) {
|
|
71630
|
+
for (const [name, categoryConfig] of Object.entries(config.categories)) {
|
|
71631
|
+
if (categoryConfig && typeof categoryConfig === "object") {
|
|
71632
|
+
applyToHolder(`categories.${name}`, categoryConfig, disabled);
|
|
71633
|
+
}
|
|
71634
|
+
}
|
|
71635
|
+
}
|
|
71636
|
+
return config;
|
|
71637
|
+
}
|
|
71638
|
+
var HOOK_NAME = "disabled-providers";
|
|
71639
|
+
var init_disabled_providers = __esm(() => {
|
|
71640
|
+
init_config_errors();
|
|
71641
|
+
init_logger2();
|
|
71642
|
+
init_model_resolver2();
|
|
71643
|
+
});
|
|
71644
|
+
|
|
71288
71645
|
// packages/omo-opencode/src/plugin-config/omo-config-chain.ts
|
|
71289
71646
|
function block(config) {
|
|
71290
71647
|
const value = config["[opencode]"];
|
|
@@ -71308,11 +71665,11 @@ function baseView(config) {
|
|
|
71308
71665
|
}
|
|
71309
71666
|
return result;
|
|
71310
71667
|
}
|
|
71311
|
-
function appendViews(views, layers, select) {
|
|
71668
|
+
function appendViews(views, layers, select, keyPrefix) {
|
|
71312
71669
|
for (const layer of layers) {
|
|
71313
71670
|
const config = select(layer.config);
|
|
71314
71671
|
if (Object.keys(config).length > 0)
|
|
71315
|
-
views.push({ config, path: layer.source.path });
|
|
71672
|
+
views.push({ config, keyPrefix, path: layer.source.path });
|
|
71316
71673
|
}
|
|
71317
71674
|
}
|
|
71318
71675
|
function recordFields(value, fields) {
|
|
@@ -71341,10 +71698,21 @@ function modelInput(view) {
|
|
|
71341
71698
|
};
|
|
71342
71699
|
}
|
|
71343
71700
|
function modelView(view) {
|
|
71344
|
-
const
|
|
71345
|
-
|
|
71701
|
+
const input = modelInput(view);
|
|
71702
|
+
const parsed = OmoConfigSchema.safeParse(input);
|
|
71703
|
+
const modelConfig = parsed.success ? parsed.data : (() => {
|
|
71704
|
+
const pruned = pruneInvalidConfigPaths(input, parsed.error.issues, (record) => {
|
|
71705
|
+
const validation = OmoConfigSchema.safeParse(record);
|
|
71706
|
+
return validation.success ? { success: true } : { success: false, issues: validation.error.issues };
|
|
71707
|
+
});
|
|
71708
|
+
if (!pruned.ok)
|
|
71709
|
+
return;
|
|
71710
|
+
const validation = OmoConfigSchema.safeParse(pruned.config);
|
|
71711
|
+
return validation.success ? validation.data : undefined;
|
|
71712
|
+
})();
|
|
71713
|
+
if (modelConfig === undefined)
|
|
71346
71714
|
return { config: {}, diagnostics: [] };
|
|
71347
|
-
const resolved = resolveModelReferences(
|
|
71715
|
+
const resolved = resolveModelReferences(modelConfig);
|
|
71348
71716
|
return {
|
|
71349
71717
|
config: {
|
|
71350
71718
|
...resolved.view.agents === undefined ? {} : { agents: resolved.view.agents },
|
|
@@ -71363,14 +71731,15 @@ function loadOmoOpenCodeConfigChain(directory, environment = process.env) {
|
|
|
71363
71731
|
});
|
|
71364
71732
|
const views = [];
|
|
71365
71733
|
const selectedProfile = loaded.profile;
|
|
71366
|
-
|
|
71367
|
-
appendViews(views, loaded.layers,
|
|
71368
|
-
appendViews(views, loaded.layers,
|
|
71369
|
-
appendViews(views, loaded.layers, (config) =>
|
|
71734
|
+
const profilePrefix = selectedProfile === undefined ? "" : `profiles.${selectedProfile}.`;
|
|
71735
|
+
appendViews(views, loaded.layers, baseView, "");
|
|
71736
|
+
appendViews(views, loaded.layers, block, "[opencode].");
|
|
71737
|
+
appendViews(views, loaded.layers, (config) => baseView(profile(config, selectedProfile)), profilePrefix);
|
|
71738
|
+
appendViews(views, loaded.layers, (config) => block(profile(config, selectedProfile)), `${profilePrefix}[opencode].`);
|
|
71370
71739
|
const resolvedModels = modelView(resolved.config);
|
|
71371
71740
|
if (Object.keys(resolvedModels.config).length > 0) {
|
|
71372
71741
|
const source = loaded.layers[0]?.source.path ?? directory;
|
|
71373
|
-
views.push({ config: resolvedModels.config, path: source });
|
|
71742
|
+
views.push({ config: resolvedModels.config, keyPrefix: "", path: source });
|
|
71374
71743
|
}
|
|
71375
71744
|
let protectedUserView = {};
|
|
71376
71745
|
for (const layer of loaded.layers) {
|
|
@@ -71465,7 +71834,7 @@ function unknownPaths(schema, value, path) {
|
|
|
71465
71834
|
if (def.type === "object" && isPlainRecord2(value) && def.shape !== undefined) {
|
|
71466
71835
|
const catchall = def.catchall !== undefined && definition(def.catchall).type !== "never" ? def.catchall : undefined;
|
|
71467
71836
|
return Object.entries(value).flatMap(([key, entry]) => {
|
|
71468
|
-
const propertySchema = def.shape
|
|
71837
|
+
const propertySchema = def.shape !== undefined && Object.hasOwn(def.shape, key) ? def.shape[key] : undefined;
|
|
71469
71838
|
if (propertySchema !== undefined)
|
|
71470
71839
|
return unknownPaths(propertySchema, entry, [...path, key]);
|
|
71471
71840
|
if (catchall !== undefined)
|
|
@@ -71582,22 +71951,22 @@ var init_fallback_models2 = __esm(() => {
|
|
|
71582
71951
|
});
|
|
71583
71952
|
|
|
71584
71953
|
// packages/omo-opencode/src/config/schema/internal/permission.ts
|
|
71585
|
-
var
|
|
71954
|
+
var PermissionValueSchema2, BashPermissionSchema2, AgentPermissionSchema;
|
|
71586
71955
|
var init_permission = __esm(() => {
|
|
71587
71956
|
init_zod();
|
|
71588
|
-
|
|
71589
|
-
|
|
71590
|
-
|
|
71591
|
-
record(string2(),
|
|
71957
|
+
PermissionValueSchema2 = _enum(["ask", "allow", "deny"]);
|
|
71958
|
+
BashPermissionSchema2 = union([
|
|
71959
|
+
PermissionValueSchema2,
|
|
71960
|
+
record(string2(), PermissionValueSchema2)
|
|
71592
71961
|
]);
|
|
71593
71962
|
AgentPermissionSchema = object({
|
|
71594
|
-
edit:
|
|
71595
|
-
bash:
|
|
71596
|
-
webfetch:
|
|
71597
|
-
task:
|
|
71598
|
-
doom_loop:
|
|
71599
|
-
external_directory:
|
|
71600
|
-
}).catchall(
|
|
71963
|
+
edit: PermissionValueSchema2.optional(),
|
|
71964
|
+
bash: BashPermissionSchema2.optional(),
|
|
71965
|
+
webfetch: PermissionValueSchema2.optional(),
|
|
71966
|
+
task: PermissionValueSchema2.optional(),
|
|
71967
|
+
doom_loop: PermissionValueSchema2.optional(),
|
|
71968
|
+
external_directory: PermissionValueSchema2.optional()
|
|
71969
|
+
}).catchall(PermissionValueSchema2.optional());
|
|
71601
71970
|
});
|
|
71602
71971
|
|
|
71603
71972
|
// packages/omo-opencode/src/config/schema/agent-overrides.ts
|
|
@@ -72361,6 +72730,30 @@ var init_schema2 = __esm(() => {
|
|
|
72361
72730
|
init_websearch();
|
|
72362
72731
|
});
|
|
72363
72732
|
|
|
72733
|
+
// packages/omo-opencode/src/config/prune-plugin-view.ts
|
|
72734
|
+
function prunePluginView(input) {
|
|
72735
|
+
const validation = OhMyOpenCodeConfigSchema.safeParse(input.config);
|
|
72736
|
+
if (validation.success)
|
|
72737
|
+
return { config: input.config, issues: [], warnings: [] };
|
|
72738
|
+
const pruned = pruneInvalidConfigPaths(input.config, validation.error.issues, validatePluginRecord);
|
|
72739
|
+
if (!pruned.ok)
|
|
72740
|
+
return { config: input.config, issues: validation.error.issues, warnings: [] };
|
|
72741
|
+
const file = displayOmoConfigPath(input.path, input.homeDir);
|
|
72742
|
+
return {
|
|
72743
|
+
config: pruned.config,
|
|
72744
|
+
issues: [],
|
|
72745
|
+
warnings: pruned.dropped.map((entry) => `config: ${file}: ${input.keyPrefix}${entry.key} ignored (invalid value)`)
|
|
72746
|
+
};
|
|
72747
|
+
}
|
|
72748
|
+
var validatePluginRecord = (record) => {
|
|
72749
|
+
const parsed = OhMyOpenCodeConfigSchema.safeParse(record);
|
|
72750
|
+
return parsed.success ? { success: true } : { success: false, issues: parsed.error.issues };
|
|
72751
|
+
};
|
|
72752
|
+
var init_prune_plugin_view = __esm(() => {
|
|
72753
|
+
init_src4();
|
|
72754
|
+
init_schema2();
|
|
72755
|
+
});
|
|
72756
|
+
|
|
72364
72757
|
// packages/omo-opencode/src/config/validate.ts
|
|
72365
72758
|
import { relative } from "path";
|
|
72366
72759
|
function shortPath(configPath) {
|
|
@@ -72371,9 +72764,8 @@ function formatIssuePath(path) {
|
|
|
72371
72764
|
const formatted = path.map((segment) => String(segment)).join(".");
|
|
72372
72765
|
return formatted.length > 0 ? formatted : "<root>";
|
|
72373
72766
|
}
|
|
72374
|
-
function schemaMessages(configPath, rawConfig) {
|
|
72375
|
-
const
|
|
72376
|
-
const validationMessages = result.success ? [] : result.error.issues.map((issue) => `${shortPath(configPath)}: ${formatIssuePath(issue.path)}: ${issue.message}`);
|
|
72767
|
+
function schemaMessages(configPath, rawConfig, issues) {
|
|
72768
|
+
const validationMessages = issues.map((issue) => `${shortPath(configPath)}: ${formatIssuePath(issue.path)}: ${issue.message}`);
|
|
72377
72769
|
const unknownKeyMessages = findUnknownKeyPaths(OhMyOpenCodeConfigSchema, rawConfig).map((path) => `${shortPath(configPath)}: Unknown config key: ${formatIssuePath(path)}`);
|
|
72378
72770
|
return [...validationMessages, ...unknownKeyMessages];
|
|
72379
72771
|
}
|
|
@@ -72389,11 +72781,13 @@ function parseConfig(rawConfig) {
|
|
|
72389
72781
|
}
|
|
72390
72782
|
return config;
|
|
72391
72783
|
}
|
|
72392
|
-
function parseConfigView(
|
|
72784
|
+
function parseConfigView(view, homeDir) {
|
|
72785
|
+
const pruned = prunePluginView({ config: view.config, homeDir, keyPrefix: view.keyPrefix, path: view.path });
|
|
72393
72786
|
return {
|
|
72394
|
-
config: parseConfig(
|
|
72395
|
-
messages: schemaMessages(path,
|
|
72396
|
-
path
|
|
72787
|
+
config: parseConfig(pruned.config),
|
|
72788
|
+
messages: schemaMessages(view.path, view.config, pruned.issues),
|
|
72789
|
+
path: view.path,
|
|
72790
|
+
warnings: pruned.warnings
|
|
72397
72791
|
};
|
|
72398
72792
|
}
|
|
72399
72793
|
function mergeViews(views) {
|
|
@@ -72483,27 +72877,36 @@ function migrateRalphLoopConfig(config) {
|
|
|
72483
72877
|
}
|
|
72484
72878
|
function validatePluginConfig(directory, environment = process.env) {
|
|
72485
72879
|
const chain = loadOmoOpenCodeConfigChain(directory, environment);
|
|
72486
|
-
const
|
|
72487
|
-
const
|
|
72880
|
+
const homeDir = environment.HOME ?? environment.USERPROFILE;
|
|
72881
|
+
const views = chain.views.map((view) => parseConfigView(view, homeDir));
|
|
72882
|
+
const failing = chain.diagnostics.filter((diagnostic) => diagnostic.kind !== "deprecated-keys" && diagnostic.kind !== "invalid-value");
|
|
72883
|
+
const chainMessages = failing.map((diagnostic) => `${shortPath(diagnostic.path)}: ${diagnostic.message}`);
|
|
72488
72884
|
const messages = [...chainMessages, ...views.flatMap((view) => view.messages)];
|
|
72885
|
+
const warnings = [
|
|
72886
|
+
...omoConfigDiagnosticLines(chain.diagnostics.flatMap((diagnostic) => diagnostic.kind === "invalid-value" ? [diagnostic] : []), { homeDir }),
|
|
72887
|
+
...views.flatMap((view) => view.warnings)
|
|
72888
|
+
];
|
|
72489
72889
|
const firstFailingView = views.find((view) => view.messages.length > 0);
|
|
72490
72890
|
const firstView = views[0];
|
|
72491
|
-
const userConfig = parseConfig(chain.protectedUserView);
|
|
72891
|
+
const userConfig = parseConfig(prunePluginView({ config: chain.protectedUserView, homeDir, keyPrefix: "", path: "" }).config);
|
|
72492
72892
|
const config = applyDisabledProviders(materializeAgentModelChains(protectUserFields(mergeViews(views), userConfig)));
|
|
72493
72893
|
warnLegacyUlwExecuteKey(chain.views);
|
|
72494
72894
|
return {
|
|
72495
72895
|
valid: messages.length === 0,
|
|
72496
72896
|
messages,
|
|
72497
|
-
|
|
72897
|
+
warnings,
|
|
72898
|
+
path: failing[0]?.path ?? firstFailingView?.path ?? firstView?.path ?? null,
|
|
72498
72899
|
config: migrateRalphLoopConfig(migrateLegacyUlwExecuteKey(config))
|
|
72499
72900
|
};
|
|
72500
72901
|
}
|
|
72501
72902
|
var START_WORK_DEPRECATION_MESSAGE = 'config key "start_work" is deprecated, rename to "ulw_execute" - will be removed next release', deprecationWarningSink;
|
|
72502
72903
|
var init_validate = __esm(() => {
|
|
72904
|
+
init_src4();
|
|
72503
72905
|
init_disabled_providers();
|
|
72504
72906
|
init_logger2();
|
|
72505
72907
|
init_omo_config_chain();
|
|
72506
72908
|
init_config_merger();
|
|
72909
|
+
init_prune_plugin_view();
|
|
72507
72910
|
init_schema2();
|
|
72508
72911
|
deprecationWarningSink = log2;
|
|
72509
72912
|
});
|
|
@@ -74214,7 +74617,7 @@ init_shared();
|
|
|
74214
74617
|
// package.json
|
|
74215
74618
|
var package_default = {
|
|
74216
74619
|
name: "oh-my-opencode",
|
|
74217
|
-
version: "5.1.
|
|
74620
|
+
version: "5.1.5",
|
|
74218
74621
|
description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
|
|
74219
74622
|
main: "./dist/index.js",
|
|
74220
74623
|
types: "dist/index.d.ts",
|
|
@@ -74391,7 +74794,7 @@ var package_default = {
|
|
|
74391
74794
|
},
|
|
74392
74795
|
devDependencies: {
|
|
74393
74796
|
"@clack/prompts": "^1.8.1",
|
|
74394
|
-
"@code-yeongyu/senpi": "2026.9.29-
|
|
74797
|
+
"@code-yeongyu/senpi": "2026.9.29-5",
|
|
74395
74798
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
74396
74799
|
"@oh-my-opencode/agents-md-core": "workspace:*",
|
|
74397
74800
|
"@oh-my-opencode/ast-grep-mcp": "workspace:*",
|
|
@@ -74449,18 +74852,18 @@ var package_default = {
|
|
|
74449
74852
|
typescript: "^7.0.2"
|
|
74450
74853
|
},
|
|
74451
74854
|
optionalDependencies: {
|
|
74452
|
-
"oh-my-opencode-darwin-arm64": "5.1.
|
|
74453
|
-
"oh-my-opencode-darwin-x64": "5.1.
|
|
74454
|
-
"oh-my-opencode-darwin-x64-baseline": "5.1.
|
|
74455
|
-
"oh-my-opencode-linux-arm64": "5.1.
|
|
74456
|
-
"oh-my-opencode-linux-arm64-musl": "5.1.
|
|
74457
|
-
"oh-my-opencode-linux-x64": "5.1.
|
|
74458
|
-
"oh-my-opencode-linux-x64-baseline": "5.1.
|
|
74459
|
-
"oh-my-opencode-linux-x64-musl": "5.1.
|
|
74460
|
-
"oh-my-opencode-linux-x64-musl-baseline": "5.1.
|
|
74461
|
-
"oh-my-opencode-windows-arm64": "5.1.
|
|
74462
|
-
"oh-my-opencode-windows-x64": "5.1.
|
|
74463
|
-
"oh-my-opencode-windows-x64-baseline": "5.1.
|
|
74855
|
+
"oh-my-opencode-darwin-arm64": "5.1.5",
|
|
74856
|
+
"oh-my-opencode-darwin-x64": "5.1.5",
|
|
74857
|
+
"oh-my-opencode-darwin-x64-baseline": "5.1.5",
|
|
74858
|
+
"oh-my-opencode-linux-arm64": "5.1.5",
|
|
74859
|
+
"oh-my-opencode-linux-arm64-musl": "5.1.5",
|
|
74860
|
+
"oh-my-opencode-linux-x64": "5.1.5",
|
|
74861
|
+
"oh-my-opencode-linux-x64-baseline": "5.1.5",
|
|
74862
|
+
"oh-my-opencode-linux-x64-musl": "5.1.5",
|
|
74863
|
+
"oh-my-opencode-linux-x64-musl-baseline": "5.1.5",
|
|
74864
|
+
"oh-my-opencode-windows-arm64": "5.1.5",
|
|
74865
|
+
"oh-my-opencode-windows-x64": "5.1.5",
|
|
74866
|
+
"oh-my-opencode-windows-x64-baseline": "5.1.5"
|
|
74464
74867
|
},
|
|
74465
74868
|
overrides: {
|
|
74466
74869
|
hono: "^4.13.8",
|