oh-my-openagent 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/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.5",
|
|
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.29-
|
|
244
|
+
"@code-yeongyu/senpi": "2026.9.29-5",
|
|
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.5",
|
|
303
|
+
"oh-my-opencode-darwin-x64": "5.1.5",
|
|
304
|
+
"oh-my-opencode-darwin-x64-baseline": "5.1.5",
|
|
305
|
+
"oh-my-opencode-linux-arm64": "5.1.5",
|
|
306
|
+
"oh-my-opencode-linux-arm64-musl": "5.1.5",
|
|
307
|
+
"oh-my-opencode-linux-x64": "5.1.5",
|
|
308
|
+
"oh-my-opencode-linux-x64-baseline": "5.1.5",
|
|
309
|
+
"oh-my-opencode-linux-x64-musl": "5.1.5",
|
|
310
|
+
"oh-my-opencode-linux-x64-musl-baseline": "5.1.5",
|
|
311
|
+
"oh-my-opencode-windows-arm64": "5.1.5",
|
|
312
|
+
"oh-my-opencode-windows-x64": "5.1.5",
|
|
313
|
+
"oh-my-opencode-windows-x64-baseline": "5.1.5"
|
|
314
314
|
},
|
|
315
315
|
overrides: {
|
|
316
316
|
hono: "^4.13.8",
|
|
@@ -7392,6 +7392,8 @@ var init_category_model_requirements = __esm(() => {
|
|
|
7392
7392
|
},
|
|
7393
7393
|
"deep-low": {
|
|
7394
7394
|
fallbackChain: [
|
|
7395
|
+
{ providers: ["openai", "chatgpt-subscription"], model: "gpt-6.1-sol", variant: "medium" },
|
|
7396
|
+
{ providers: ["openai", "chatgpt-subscription"], model: "gpt-6.1-sol-fast", variant: "medium" },
|
|
7395
7397
|
{
|
|
7396
7398
|
providers: ["openai", "chatgpt-subscription", "github-copilot", "opencode"],
|
|
7397
7399
|
model: "gpt-5.6-sol",
|
|
@@ -7444,7 +7446,9 @@ var init_category_model_requirements = __esm(() => {
|
|
|
7444
7446
|
providers: ["anthropic", "anthropic-api", "github-copilot"],
|
|
7445
7447
|
model: "claude-haiku-4-5",
|
|
7446
7448
|
variant: "off"
|
|
7447
|
-
}
|
|
7449
|
+
},
|
|
7450
|
+
{ providers: ["zai-coding-plan"], model: "glm-5.3-flash", variant: "low" },
|
|
7451
|
+
{ providers: ["xiaomi"], model: "mimo-v2.6-flash", variant: "low" }
|
|
7448
7452
|
]
|
|
7449
7453
|
},
|
|
7450
7454
|
"unspecified-low": {
|
|
@@ -7609,7 +7613,7 @@ var init_model_capability_aliases = __esm(() => {
|
|
|
7609
7613
|
description: "Normalizes OpenCode's OpenAI GPT fast service-tier IDs to canonical snapshot IDs.",
|
|
7610
7614
|
providerIDs: ["openai"],
|
|
7611
7615
|
allowedSubproviderHosts: ["vercel"],
|
|
7612
|
-
match: (normalizedModelID) => /^(?:gpt-5\.6-(?:sol|terra|luna)|gpt-6-(?:astra|sol|luna))-fast$/.test(normalizedModelID),
|
|
7616
|
+
match: (normalizedModelID) => /^(?:gpt-5\.6-(?:sol|terra|luna)|gpt-6-(?:astra|sol|luna)|gpt-6\.1-sol)-fast$/.test(normalizedModelID),
|
|
7613
7617
|
canonicalize: (normalizedModelID) => normalizedModelID.slice(0, -"-fast".length)
|
|
7614
7618
|
},
|
|
7615
7619
|
{
|
|
@@ -7757,6 +7761,14 @@ var init_model_capability_heuristics = __esm(() => {
|
|
|
7757
7761
|
reasoningEffortAliases: { none: "low", minimal: "low" },
|
|
7758
7762
|
supportsTemperature: false
|
|
7759
7763
|
},
|
|
7764
|
+
{
|
|
7765
|
+
family: "gpt-6.1-sol",
|
|
7766
|
+
pattern: /gpt-6-1-sol/,
|
|
7767
|
+
variants: ["low", "medium", "high", "xhigh", "max"],
|
|
7768
|
+
reasoningEfforts: ["low", "medium", "high", "xhigh", "max"],
|
|
7769
|
+
reasoningEffortAliases: { none: "low", minimal: "low" },
|
|
7770
|
+
supportsTemperature: false
|
|
7771
|
+
},
|
|
7760
7772
|
{
|
|
7761
7773
|
family: "gpt-6",
|
|
7762
7774
|
includes: ["gpt-6"],
|
|
@@ -8188,6 +8200,36 @@ var init_supplemental_entries = __esm(() => {
|
|
|
8188
8200
|
output: 128000
|
|
8189
8201
|
}
|
|
8190
8202
|
},
|
|
8203
|
+
"gpt-6.1-sol": {
|
|
8204
|
+
id: "gpt-6.1-sol",
|
|
8205
|
+
family: "gpt",
|
|
8206
|
+
reasoning: true,
|
|
8207
|
+
temperature: false,
|
|
8208
|
+
toolCall: true,
|
|
8209
|
+
modalities: {
|
|
8210
|
+
input: ["text", "image"],
|
|
8211
|
+
output: ["text"]
|
|
8212
|
+
},
|
|
8213
|
+
limit: {
|
|
8214
|
+
context: 400000,
|
|
8215
|
+
output: 128000
|
|
8216
|
+
}
|
|
8217
|
+
},
|
|
8218
|
+
"gpt-6.1-sol-fast": {
|
|
8219
|
+
id: "gpt-6.1-sol-fast",
|
|
8220
|
+
family: "gpt",
|
|
8221
|
+
reasoning: true,
|
|
8222
|
+
temperature: false,
|
|
8223
|
+
toolCall: true,
|
|
8224
|
+
modalities: {
|
|
8225
|
+
input: ["text", "image"],
|
|
8226
|
+
output: ["text"]
|
|
8227
|
+
},
|
|
8228
|
+
limit: {
|
|
8229
|
+
context: 400000,
|
|
8230
|
+
output: 128000
|
|
8231
|
+
}
|
|
8232
|
+
},
|
|
8191
8233
|
"gpt-6-luna": {
|
|
8192
8234
|
id: "gpt-6-luna",
|
|
8193
8235
|
family: "gpt-nano",
|
|
@@ -9454,7 +9496,7 @@ You are working on tasks that don't fit specific categories but require substant
|
|
|
9454
9496
|
</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;
|
|
9455
9497
|
var init_openai_categories = __esm(() => {
|
|
9456
9498
|
init_types();
|
|
9457
|
-
DEEP_LOW_GATE_MODELS = ["gpt-5.6-sol-fast", "gpt-5.6-sol"];
|
|
9499
|
+
DEEP_LOW_GATE_MODELS = ["gpt-6.1-sol", "gpt-6.1-sol-fast", "gpt-5.6-sol-fast", "gpt-5.6-sol"];
|
|
9458
9500
|
OPENAI_CATEGORIES = [
|
|
9459
9501
|
{
|
|
9460
9502
|
name: "ultrabrain",
|
|
@@ -9465,7 +9507,7 @@ var init_openai_categories = __esm(() => {
|
|
|
9465
9507
|
},
|
|
9466
9508
|
{
|
|
9467
9509
|
name: "deep-low",
|
|
9468
|
-
config: { model: "openai/gpt-
|
|
9510
|
+
config: { model: "openai/gpt-6.1-sol", variant: "medium" },
|
|
9469
9511
|
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.",
|
|
9470
9512
|
callerGuidance: DEEP_LOW_CATEGORY_CALLER_GUIDANCE,
|
|
9471
9513
|
promptAppend: DEEP_LOW_CATEGORY_PROMPT_APPEND,
|
|
@@ -64779,6 +64821,94 @@ var init_model_capabilities_generated = __esm(() => {
|
|
|
64779
64821
|
context: 1e6,
|
|
64780
64822
|
output: 128000
|
|
64781
64823
|
}
|
|
64824
|
+
},
|
|
64825
|
+
"glm-5.3-flash": {
|
|
64826
|
+
id: "glm-5.3-flash",
|
|
64827
|
+
family: "glm-flash",
|
|
64828
|
+
reasoning: true,
|
|
64829
|
+
temperature: true,
|
|
64830
|
+
toolCall: true,
|
|
64831
|
+
modalities: {
|
|
64832
|
+
input: [
|
|
64833
|
+
"text",
|
|
64834
|
+
"image",
|
|
64835
|
+
"video"
|
|
64836
|
+
],
|
|
64837
|
+
output: [
|
|
64838
|
+
"text"
|
|
64839
|
+
]
|
|
64840
|
+
},
|
|
64841
|
+
limit: {
|
|
64842
|
+
context: 1048576,
|
|
64843
|
+
output: 1048576
|
|
64844
|
+
}
|
|
64845
|
+
},
|
|
64846
|
+
"zai/glm-5.3-flash": {
|
|
64847
|
+
id: "zai/glm-5.3-flash",
|
|
64848
|
+
family: "glm-flash",
|
|
64849
|
+
reasoning: true,
|
|
64850
|
+
temperature: true,
|
|
64851
|
+
toolCall: true,
|
|
64852
|
+
modalities: {
|
|
64853
|
+
input: [
|
|
64854
|
+
"text",
|
|
64855
|
+
"image",
|
|
64856
|
+
"video",
|
|
64857
|
+
"pdf"
|
|
64858
|
+
],
|
|
64859
|
+
output: [
|
|
64860
|
+
"text"
|
|
64861
|
+
]
|
|
64862
|
+
},
|
|
64863
|
+
limit: {
|
|
64864
|
+
context: 1e6,
|
|
64865
|
+
output: 131072
|
|
64866
|
+
}
|
|
64867
|
+
},
|
|
64868
|
+
"mimo-v2.6-flash": {
|
|
64869
|
+
id: "mimo-v2.6-flash",
|
|
64870
|
+
family: "mimo",
|
|
64871
|
+
reasoning: true,
|
|
64872
|
+
temperature: true,
|
|
64873
|
+
toolCall: true,
|
|
64874
|
+
modalities: {
|
|
64875
|
+
input: [
|
|
64876
|
+
"text",
|
|
64877
|
+
"image",
|
|
64878
|
+
"audio",
|
|
64879
|
+
"video"
|
|
64880
|
+
],
|
|
64881
|
+
output: [
|
|
64882
|
+
"text"
|
|
64883
|
+
]
|
|
64884
|
+
},
|
|
64885
|
+
limit: {
|
|
64886
|
+
context: 1048576,
|
|
64887
|
+
output: 131072
|
|
64888
|
+
}
|
|
64889
|
+
},
|
|
64890
|
+
"xiaomi/mimo-v2.6-flash": {
|
|
64891
|
+
id: "xiaomi/mimo-v2.6-flash",
|
|
64892
|
+
family: "mimo",
|
|
64893
|
+
reasoning: true,
|
|
64894
|
+
temperature: true,
|
|
64895
|
+
toolCall: true,
|
|
64896
|
+
modalities: {
|
|
64897
|
+
input: [
|
|
64898
|
+
"text",
|
|
64899
|
+
"image",
|
|
64900
|
+
"audio",
|
|
64901
|
+
"video"
|
|
64902
|
+
],
|
|
64903
|
+
output: [
|
|
64904
|
+
"text"
|
|
64905
|
+
]
|
|
64906
|
+
},
|
|
64907
|
+
limit: {
|
|
64908
|
+
context: 1048576,
|
|
64909
|
+
input: 1048576,
|
|
64910
|
+
output: 131072
|
|
64911
|
+
}
|
|
64782
64912
|
}
|
|
64783
64913
|
}
|
|
64784
64914
|
};
|
|
@@ -74249,7 +74379,6 @@ function normalizeLegacyModelFields(entry) {
|
|
|
74249
74379
|
delete normalized["reasoningEffort"];
|
|
74250
74380
|
delete normalized["thinking"];
|
|
74251
74381
|
delete normalized["textVerbosity"];
|
|
74252
|
-
delete normalized["maxTokens"];
|
|
74253
74382
|
delete normalized["providerOptions"];
|
|
74254
74383
|
if (typeof entry["model"] === "string")
|
|
74255
74384
|
normalized["model"] = canonicalModelString(entry["model"]);
|
|
@@ -74267,10 +74396,15 @@ function normalizeLegacyModelFields(entry) {
|
|
|
74267
74396
|
providerOptions["textVerbosity"] = entry["textVerbosity"];
|
|
74268
74397
|
if (Object.keys(providerOptions).length > 0)
|
|
74269
74398
|
normalized["provider_options"] = providerOptions;
|
|
74270
|
-
if (entry["max_tokens"] !== undefined)
|
|
74399
|
+
if (entry["max_tokens"] !== undefined) {
|
|
74271
74400
|
normalized["max_tokens"] = entry["max_tokens"];
|
|
74272
|
-
|
|
74401
|
+
if (entry["maxTokens"] === undefined || typeof entry["maxTokens"] === "number") {
|
|
74402
|
+
delete normalized["maxTokens"];
|
|
74403
|
+
}
|
|
74404
|
+
} else if (typeof entry["maxTokens"] === "number") {
|
|
74273
74405
|
normalized["max_tokens"] = entry["maxTokens"];
|
|
74406
|
+
delete normalized["maxTokens"];
|
|
74407
|
+
}
|
|
74274
74408
|
return normalized;
|
|
74275
74409
|
}
|
|
74276
74410
|
function normalizeLegacyModelEntry(entry) {
|
|
@@ -74313,12 +74447,25 @@ var init_fallback_models = __esm(() => {
|
|
|
74313
74447
|
function isRecord5(value) {
|
|
74314
74448
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
74315
74449
|
}
|
|
74316
|
-
var OmoAgentModelEntrySchema, OmoAgentDefInputSchema, OmoAgentDefSchema, OmoAgentsConfigSchema;
|
|
74450
|
+
var OmoAgentModelEntrySchema, PermissionValueSchema, BashPermissionSchema, OmoAgentPermissionSchema, OmoAgentDefInputSchema, OmoAgentDefSchema, OmoAgentsConfigSchema;
|
|
74317
74451
|
var init_agent = __esm(() => {
|
|
74318
74452
|
init_zod();
|
|
74319
74453
|
init_fallback_models();
|
|
74320
74454
|
init_model_ref();
|
|
74321
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());
|
|
74322
74469
|
OmoAgentDefInputSchema = object({
|
|
74323
74470
|
description: string2().optional(),
|
|
74324
74471
|
prompt: string2().optional(),
|
|
@@ -74335,7 +74482,9 @@ var init_agent = __esm(() => {
|
|
|
74335
74482
|
disallowed_tools: array(string2()).optional(),
|
|
74336
74483
|
max_turns: number2().int().nonnegative().optional(),
|
|
74337
74484
|
temperature: number2().min(0).max(2).optional(),
|
|
74338
|
-
disable: boolean2().optional()
|
|
74485
|
+
disable: boolean2().optional(),
|
|
74486
|
+
permission: OmoAgentPermissionSchema.optional(),
|
|
74487
|
+
prompt_append: string2().optional()
|
|
74339
74488
|
}).strict();
|
|
74340
74489
|
OmoAgentDefSchema = preprocess((value) => isRecord5(value) ? normalizeLegacyModelFields(value) : value, OmoAgentDefInputSchema);
|
|
74341
74490
|
OmoAgentsConfigSchema = record(string2(), OmoAgentDefSchema);
|
|
@@ -75121,6 +75270,64 @@ var init_schema = __esm(() => {
|
|
|
75121
75270
|
init_computer();
|
|
75122
75271
|
});
|
|
75123
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
|
+
|
|
75124
75331
|
// packages/omo-config-core/src/loader/disabled-skills.ts
|
|
75125
75332
|
var init_disabled_skills = () => {};
|
|
75126
75333
|
|
|
@@ -75160,24 +75367,265 @@ var init_merge = __esm(() => {
|
|
|
75160
75367
|
DANGEROUS_KEYS2 = new Set(["__proto__", "constructor", "prototype"]);
|
|
75161
75368
|
});
|
|
75162
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
|
+
|
|
75163
75623
|
// packages/omo-config-core/src/internal/posix-path.ts
|
|
75164
75624
|
function toPosixPath(path) {
|
|
75165
75625
|
return path.split("\\").join("/");
|
|
75166
75626
|
}
|
|
75167
75627
|
var init_posix_path = () => {};
|
|
75168
75628
|
|
|
75169
|
-
// packages/omo-config-core/src/loader/types.ts
|
|
75170
|
-
import { existsSync as existsSync13, lstatSync as lstatSync2, readFileSync as readFileSync5, realpathSync as realpathSync5 } from "fs";
|
|
75171
|
-
var DEFAULT_READ_FILE_SYSTEM;
|
|
75172
|
-
var init_types3 = __esm(() => {
|
|
75173
|
-
DEFAULT_READ_FILE_SYSTEM = {
|
|
75174
|
-
existsSync: existsSync13,
|
|
75175
|
-
lstatSync: lstatSync2,
|
|
75176
|
-
readFileSync: readFileSync5,
|
|
75177
|
-
realpathSync: realpathSync5
|
|
75178
|
-
};
|
|
75179
|
-
});
|
|
75180
|
-
|
|
75181
75629
|
// packages/omo-config-core/src/loader/paths.ts
|
|
75182
75630
|
import { userInfo } from "os";
|
|
75183
75631
|
import { dirname as dirname4, join as join15, posix as posix2, resolve as resolve3 } from "path";
|
|
@@ -75281,7 +75729,7 @@ function resolveOmoProfileName(options = {}) {
|
|
|
75281
75729
|
const env = options.env ?? process.env;
|
|
75282
75730
|
return profileName(options.profile) ?? profileName(env["OMO_PROFILE"]) ?? profileName(env["OCX_PROFILE"]) ?? profileNameFromOpenCodeConfigDir(env["OPENCODE_CONFIG_DIR"]);
|
|
75283
75731
|
}
|
|
75284
|
-
function
|
|
75732
|
+
function toRecord2(value) {
|
|
75285
75733
|
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
75286
75734
|
return;
|
|
75287
75735
|
return Object.fromEntries(Object.entries(value));
|
|
@@ -75302,13 +75750,13 @@ function harnessLayer(config, harness) {
|
|
|
75302
75750
|
const legacyKeys = Object.entries(OMO_CONFIG_LEGACY_HARNESS_ALIASES).filter(([, target]) => target === canonical).map(([legacy]) => harnessBlockKey(legacy));
|
|
75303
75751
|
let layer = {};
|
|
75304
75752
|
for (const key of [...legacyKeys, harnessBlockKey(canonical)]) {
|
|
75305
|
-
layer = mergeOmoConfigRecords(layer,
|
|
75753
|
+
layer = mergeOmoConfigRecords(layer, toRecord2(config[key]) ?? {});
|
|
75306
75754
|
}
|
|
75307
75755
|
return layer;
|
|
75308
75756
|
}
|
|
75309
75757
|
function resolveOmoConfigView(options) {
|
|
75310
|
-
const profiles =
|
|
75311
|
-
const profile = options.profile === undefined ? undefined :
|
|
75758
|
+
const profiles = toRecord2(options.config["profiles"]);
|
|
75759
|
+
const profile = options.profile === undefined ? undefined : toRecord2(profiles?.[options.profile]);
|
|
75312
75760
|
const diagnostics = profile === undefined && options.profile !== undefined ? [{
|
|
75313
75761
|
kind: "profile",
|
|
75314
75762
|
message: `Activated omo profile "${options.profile}" does not exist; using the base configuration`,
|
|
@@ -75363,70 +75811,9 @@ function stripResolutionControlKeys(config) {
|
|
|
75363
75811
|
} = config;
|
|
75364
75812
|
return resolved;
|
|
75365
75813
|
}
|
|
75366
|
-
function validationDiagnostic(path, issues) {
|
|
75367
|
-
const issuePaths = issues.map((issue) => issue.path.map((segment) => String(segment)).join("."));
|
|
75368
|
-
return {
|
|
75369
|
-
kind: "validation",
|
|
75370
|
-
message: `Invalid omo config at ${path}: ${issuePaths.join(", ")}`,
|
|
75371
|
-
path,
|
|
75372
|
-
issuePaths
|
|
75373
|
-
};
|
|
75374
|
-
}
|
|
75375
|
-
function unrecognizedKeyIssues(issues) {
|
|
75376
|
-
return issues.flatMap((issue) => issue.code === "unrecognized_keys" ? [{ keys: issue.keys, path: issue.path.map((segment) => String(segment)) }] : []);
|
|
75377
|
-
}
|
|
75378
|
-
function hasUnsafeUnrecognizedKey(issues) {
|
|
75379
|
-
return issues.some((issue) => issue.keys.some((key) => isUnsafeObjectKey2(key)));
|
|
75380
|
-
}
|
|
75381
|
-
function hasTamperedPrototype(value) {
|
|
75382
|
-
if (Array.isArray(value))
|
|
75383
|
-
return value.some((entry) => hasTamperedPrototype(entry));
|
|
75384
|
-
if (!isRecord11(value))
|
|
75385
|
-
return false;
|
|
75386
|
-
const prototype = Object.getPrototypeOf(value);
|
|
75387
|
-
if (prototype !== Object.prototype && prototype !== null)
|
|
75388
|
-
return true;
|
|
75389
|
-
return Object.values(value).some((entry) => hasTamperedPrototype(entry));
|
|
75390
|
-
}
|
|
75391
|
-
function isRecord11(value) {
|
|
75392
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
75393
|
-
}
|
|
75394
|
-
function containerAt(record, path) {
|
|
75395
|
-
let container = record;
|
|
75396
|
-
for (const segment of path) {
|
|
75397
|
-
const next = container[segment];
|
|
75398
|
-
if (!isRecord11(next))
|
|
75399
|
-
return null;
|
|
75400
|
-
container = next;
|
|
75401
|
-
}
|
|
75402
|
-
return container;
|
|
75403
|
-
}
|
|
75404
|
-
function stripUnrecognizedKeys(record, issues) {
|
|
75405
|
-
const stripped = structuredClone(record);
|
|
75406
|
-
const issuePaths = [];
|
|
75407
|
-
for (const issue of issues) {
|
|
75408
|
-
const container = containerAt(stripped, issue.path);
|
|
75409
|
-
if (container === null)
|
|
75410
|
-
continue;
|
|
75411
|
-
for (const key of issue.keys) {
|
|
75412
|
-
delete container[key];
|
|
75413
|
-
issuePaths.push([...issue.path, key].join("."));
|
|
75414
|
-
}
|
|
75415
|
-
}
|
|
75416
|
-
return { issuePaths, stripped };
|
|
75417
|
-
}
|
|
75418
|
-
function toRecord2(value) {
|
|
75419
|
-
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
75420
|
-
return null;
|
|
75421
|
-
const record = {};
|
|
75422
|
-
for (const [key, entry] of Object.entries(value)) {
|
|
75423
|
-
record[key] = entry;
|
|
75424
|
-
}
|
|
75425
|
-
return record;
|
|
75426
|
-
}
|
|
75427
75814
|
function readConfigSource(path, scope, fileSystem) {
|
|
75428
75815
|
if (!fileSystem.existsSync(path)) {
|
|
75429
|
-
return { source: { exists: false, loaded: false, path, scope } };
|
|
75816
|
+
return { diagnostics: [], source: { exists: false, loaded: false, path, scope } };
|
|
75430
75817
|
}
|
|
75431
75818
|
let content;
|
|
75432
75819
|
try {
|
|
@@ -75434,68 +75821,23 @@ function readConfigSource(path, scope, fileSystem) {
|
|
|
75434
75821
|
} catch (error) {
|
|
75435
75822
|
const message = error instanceof Error ? error.message : String(error);
|
|
75436
75823
|
return {
|
|
75437
|
-
|
|
75824
|
+
diagnostics: [{ kind: "read", message: `Failed to read ${path}: ${message}`, path }],
|
|
75438
75825
|
source: { exists: true, loaded: false, path, scope }
|
|
75439
75826
|
};
|
|
75440
75827
|
}
|
|
75441
75828
|
const parsed = parseJsoncSafe2(content);
|
|
75442
75829
|
if (parsed.errors.length > 0) {
|
|
75443
75830
|
return {
|
|
75444
|
-
|
|
75831
|
+
diagnostics: [{
|
|
75445
75832
|
kind: "parse",
|
|
75446
75833
|
message: `JSONC parse error in ${path}: ${parsed.errors.map((error) => error.message).join(", ")}`,
|
|
75447
75834
|
path
|
|
75448
|
-
},
|
|
75449
|
-
source: { exists: true, loaded: false, path, scope }
|
|
75450
|
-
};
|
|
75451
|
-
}
|
|
75452
|
-
if (hasTamperedPrototype(parsed.data)) {
|
|
75453
|
-
return {
|
|
75454
|
-
diagnostic: { kind: "validation", message: `Invalid omo config at ${path}: "__proto__" member is not allowed`, path },
|
|
75835
|
+
}],
|
|
75455
75836
|
source: { exists: true, loaded: false, path, scope }
|
|
75456
75837
|
};
|
|
75457
75838
|
}
|
|
75458
|
-
const
|
|
75459
|
-
|
|
75460
|
-
if (!validation.success) {
|
|
75461
|
-
const unrecognized = unrecognizedKeyIssues(validation.error.issues);
|
|
75462
|
-
if (hasUnsafeUnrecognizedKey(unrecognized)) {
|
|
75463
|
-
return {
|
|
75464
|
-
diagnostic: validationDiagnostic(path, validation.error.issues),
|
|
75465
|
-
source: { exists: true, loaded: false, path, scope }
|
|
75466
|
-
};
|
|
75467
|
-
}
|
|
75468
|
-
const rejected = {
|
|
75469
|
-
diagnostic: validationDiagnostic(path, validation.error.issues),
|
|
75470
|
-
source: { exists: true, loaded: false, path, scope }
|
|
75471
|
-
};
|
|
75472
|
-
const unknownIssues = unrecognizedKeyIssues(validation.error.issues);
|
|
75473
|
-
if (parsedRecord === null || unknownIssues.length === 0)
|
|
75474
|
-
return rejected;
|
|
75475
|
-
const { issuePaths, stripped } = stripUnrecognizedKeys(parsedRecord, unknownIssues);
|
|
75476
|
-
if (!OmoConfigLayerSchema.safeParse(stripped).success)
|
|
75477
|
-
return rejected;
|
|
75478
|
-
return {
|
|
75479
|
-
diagnostic: {
|
|
75480
|
-
kind: "unknown-keys",
|
|
75481
|
-
message: `Ignored unknown keys in ${path}: ${issuePaths.join(", ")}`,
|
|
75482
|
-
path,
|
|
75483
|
-
issuePaths
|
|
75484
|
-
},
|
|
75485
|
-
source: { exists: true, loaded: true, path, scope },
|
|
75486
|
-
value: stripped
|
|
75487
|
-
};
|
|
75488
|
-
}
|
|
75489
|
-
if (parsedRecord === null) {
|
|
75490
|
-
return {
|
|
75491
|
-
diagnostic: { kind: "validation", message: `Invalid omo config at ${path}: root must be an object`, path },
|
|
75492
|
-
source: { exists: true, loaded: false, path, scope }
|
|
75493
|
-
};
|
|
75494
|
-
}
|
|
75495
|
-
return {
|
|
75496
|
-
source: { exists: true, loaded: true, path, scope },
|
|
75497
|
-
value: parsedRecord
|
|
75498
|
-
};
|
|
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 } };
|
|
75499
75841
|
}
|
|
75500
75842
|
function legacyCategoryDiagnostic(path, renames) {
|
|
75501
75843
|
const detail = renames.map((rename) => rename.dropped ? `${rename.path} ignored because ${rename.canonical} is also configured` : `${rename.path} renamed to ${rename.canonical}`).join(", ");
|
|
@@ -75530,8 +75872,7 @@ function loadOmoConfig(options = {}) {
|
|
|
75530
75872
|
})) {
|
|
75531
75873
|
const loaded = readConfigSource(candidate.path, candidate.scope, fileSystem);
|
|
75532
75874
|
sources.push(loaded.source);
|
|
75533
|
-
|
|
75534
|
-
diagnostics.push(loaded.diagnostic);
|
|
75875
|
+
diagnostics.push(...loaded.diagnostics);
|
|
75535
75876
|
if (loaded.value !== undefined) {
|
|
75536
75877
|
const canonicalized = canonicalizeLegacyCategoryNames(loaded.value);
|
|
75537
75878
|
if (canonicalized.renames.length > 0) {
|
|
@@ -75554,7 +75895,8 @@ function loadOmoConfig(options = {}) {
|
|
|
75554
75895
|
...options.harness === undefined ? {} : { harness: options.harness },
|
|
75555
75896
|
...requestedProfile === undefined ? {} : { profile: requestedProfile }
|
|
75556
75897
|
});
|
|
75557
|
-
const
|
|
75898
|
+
const finalInput = mergeOmoConfigRecords(DEFAULT_RAW_CONFIG, resolved.config);
|
|
75899
|
+
const finalConfig = OmoConfigSchema.safeParse(finalInput);
|
|
75558
75900
|
if (finalConfig.success) {
|
|
75559
75901
|
return {
|
|
75560
75902
|
config: stripResolutionControlKeys(finalConfig.data),
|
|
@@ -75564,9 +75906,22 @@ function loadOmoConfig(options = {}) {
|
|
|
75564
75906
|
sources
|
|
75565
75907
|
};
|
|
75566
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
|
+
}
|
|
75567
75922
|
return {
|
|
75568
75923
|
config: stripResolutionControlKeys(OmoConfigSchema.parse(DEFAULT_RAW_CONFIG)),
|
|
75569
|
-
diagnostics: [...diagnostics, ...resolved.diagnostics, validationDiagnostic(
|
|
75924
|
+
diagnostics: [...diagnostics, ...resolved.diagnostics, validationDiagnostic(MERGED_OMO_CONFIG_PATH, finalConfig.error.issues)],
|
|
75570
75925
|
layers,
|
|
75571
75926
|
...resolved.profile === undefined ? {} : { profile: resolved.profile },
|
|
75572
75927
|
sources
|
|
@@ -75576,6 +75931,7 @@ var DEFAULT_RAW_CONFIG;
|
|
|
75576
75931
|
var init_loader2 = __esm(() => {
|
|
75577
75932
|
init_main();
|
|
75578
75933
|
init_schema();
|
|
75934
|
+
init_layer_validation();
|
|
75579
75935
|
init_merge();
|
|
75580
75936
|
init_paths();
|
|
75581
75937
|
init_resolution();
|
|
@@ -75590,6 +75946,7 @@ var init_loader2 = __esm(() => {
|
|
|
75590
75946
|
|
|
75591
75947
|
// packages/omo-config-core/src/loader/index.ts
|
|
75592
75948
|
var init_loader3 = __esm(() => {
|
|
75949
|
+
init_diagnostic_lines();
|
|
75593
75950
|
init_disabled_skills();
|
|
75594
75951
|
init_loader2();
|
|
75595
75952
|
init_merge();
|
|
@@ -89020,7 +89377,7 @@ var package_default2;
|
|
|
89020
89377
|
var init_package2 = __esm(() => {
|
|
89021
89378
|
package_default2 = {
|
|
89022
89379
|
name: "@oh-my-opencode/omo-codex",
|
|
89023
|
-
version: "5.1.
|
|
89380
|
+
version: "5.1.5",
|
|
89024
89381
|
type: "module",
|
|
89025
89382
|
private: true,
|
|
89026
89383
|
description: "Codex harness adapter for oh-my-openagent. Vendored Codex plugin namespace (omo) + TypeScript installer + telemetry.",
|
|
@@ -102021,6 +102378,7 @@ async function processEvents(ctx, stream, state) {
|
|
|
102021
102378
|
}
|
|
102022
102379
|
}
|
|
102023
102380
|
// packages/omo-opencode/src/config/validate.ts
|
|
102381
|
+
init_src4();
|
|
102024
102382
|
import { relative as relative7 } from "path";
|
|
102025
102383
|
|
|
102026
102384
|
// packages/omo-opencode/src/shared/disabled-providers.ts
|
|
@@ -102141,11 +102499,11 @@ function baseView(config) {
|
|
|
102141
102499
|
}
|
|
102142
102500
|
return result;
|
|
102143
102501
|
}
|
|
102144
|
-
function appendViews(views, layers, select) {
|
|
102502
|
+
function appendViews(views, layers, select, keyPrefix) {
|
|
102145
102503
|
for (const layer of layers) {
|
|
102146
102504
|
const config = select(layer.config);
|
|
102147
102505
|
if (Object.keys(config).length > 0)
|
|
102148
|
-
views.push({ config, path: layer.source.path });
|
|
102506
|
+
views.push({ config, keyPrefix, path: layer.source.path });
|
|
102149
102507
|
}
|
|
102150
102508
|
}
|
|
102151
102509
|
function recordFields(value, fields) {
|
|
@@ -102174,10 +102532,21 @@ function modelInput(view) {
|
|
|
102174
102532
|
};
|
|
102175
102533
|
}
|
|
102176
102534
|
function modelView(view) {
|
|
102177
|
-
const
|
|
102178
|
-
|
|
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)
|
|
102179
102548
|
return { config: {}, diagnostics: [] };
|
|
102180
|
-
const resolved = resolveModelReferences(
|
|
102549
|
+
const resolved = resolveModelReferences(modelConfig);
|
|
102181
102550
|
return {
|
|
102182
102551
|
config: {
|
|
102183
102552
|
...resolved.view.agents === undefined ? {} : { agents: resolved.view.agents },
|
|
@@ -102196,14 +102565,15 @@ function loadOmoOpenCodeConfigChain(directory, environment = process.env) {
|
|
|
102196
102565
|
});
|
|
102197
102566
|
const views = [];
|
|
102198
102567
|
const selectedProfile = loaded.profile;
|
|
102199
|
-
|
|
102200
|
-
appendViews(views, loaded.layers,
|
|
102201
|
-
appendViews(views, loaded.layers,
|
|
102202
|
-
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].`);
|
|
102203
102573
|
const resolvedModels = modelView(resolved.config);
|
|
102204
102574
|
if (Object.keys(resolvedModels.config).length > 0) {
|
|
102205
102575
|
const source = loaded.layers[0]?.source.path ?? directory;
|
|
102206
|
-
views.push({ config: resolvedModels.config, path: source });
|
|
102576
|
+
views.push({ config: resolvedModels.config, keyPrefix: "", path: source });
|
|
102207
102577
|
}
|
|
102208
102578
|
let protectedUserView = {};
|
|
102209
102579
|
for (const layer of loaded.layers) {
|
|
@@ -102290,7 +102660,7 @@ function unknownPaths(schema, value, path) {
|
|
|
102290
102660
|
if (def.type === "object" && isPlainRecord5(value) && def.shape !== undefined) {
|
|
102291
102661
|
const catchall = def.catchall !== undefined && definition(def.catchall).type !== "never" ? def.catchall : undefined;
|
|
102292
102662
|
return Object.entries(value).flatMap(([key, entry]) => {
|
|
102293
|
-
const propertySchema = def.shape
|
|
102663
|
+
const propertySchema = def.shape !== undefined && Object.hasOwn(def.shape, key) ? def.shape[key] : undefined;
|
|
102294
102664
|
if (propertySchema !== undefined)
|
|
102295
102665
|
return unknownPaths(propertySchema, entry, [...path, key]);
|
|
102296
102666
|
if (catchall !== undefined)
|
|
@@ -102328,6 +102698,9 @@ function findUnknownKeyPaths(schema, value) {
|
|
|
102328
102698
|
return unknownPaths(schema, value, []);
|
|
102329
102699
|
}
|
|
102330
102700
|
|
|
102701
|
+
// packages/omo-opencode/src/config/prune-plugin-view.ts
|
|
102702
|
+
init_src4();
|
|
102703
|
+
|
|
102331
102704
|
// packages/omo-opencode/src/config/schema/agent-names.ts
|
|
102332
102705
|
init_zod();
|
|
102333
102706
|
var BuiltinAgentNameSchema = _enum([
|
|
@@ -102405,19 +102778,19 @@ var FallbackModelsSchema = union([
|
|
|
102405
102778
|
|
|
102406
102779
|
// packages/omo-opencode/src/config/schema/internal/permission.ts
|
|
102407
102780
|
init_zod();
|
|
102408
|
-
var
|
|
102409
|
-
var
|
|
102410
|
-
|
|
102411
|
-
record(string2(),
|
|
102781
|
+
var PermissionValueSchema2 = _enum(["ask", "allow", "deny"]);
|
|
102782
|
+
var BashPermissionSchema2 = union([
|
|
102783
|
+
PermissionValueSchema2,
|
|
102784
|
+
record(string2(), PermissionValueSchema2)
|
|
102412
102785
|
]);
|
|
102413
102786
|
var AgentPermissionSchema = object({
|
|
102414
|
-
edit:
|
|
102415
|
-
bash:
|
|
102416
|
-
webfetch:
|
|
102417
|
-
task:
|
|
102418
|
-
doom_loop:
|
|
102419
|
-
external_directory:
|
|
102420
|
-
}).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());
|
|
102421
102794
|
|
|
102422
102795
|
// packages/omo-opencode/src/config/schema/agent-overrides.ts
|
|
102423
102796
|
var AgentOverrideConfigSchema = object({
|
|
@@ -102982,6 +103355,26 @@ var OhMyOpenCodeConfigSchema = object({
|
|
|
102982
103355
|
default_mode: DefaultModeConfigSchema.optional(),
|
|
102983
103356
|
_migrations: array(string2()).optional()
|
|
102984
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
|
+
|
|
102985
103378
|
// packages/omo-opencode/src/config/validate.ts
|
|
102986
103379
|
function shortPath(configPath) {
|
|
102987
103380
|
const candidate = relative7(process.cwd(), configPath);
|
|
@@ -102991,9 +103384,8 @@ function formatIssuePath(path) {
|
|
|
102991
103384
|
const formatted = path.map((segment) => String(segment)).join(".");
|
|
102992
103385
|
return formatted.length > 0 ? formatted : "<root>";
|
|
102993
103386
|
}
|
|
102994
|
-
function schemaMessages(configPath, rawConfig) {
|
|
102995
|
-
const
|
|
102996
|
-
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}`);
|
|
102997
103389
|
const unknownKeyMessages = findUnknownKeyPaths(OhMyOpenCodeConfigSchema, rawConfig).map((path) => `${shortPath(configPath)}: Unknown config key: ${formatIssuePath(path)}`);
|
|
102998
103390
|
return [...validationMessages, ...unknownKeyMessages];
|
|
102999
103391
|
}
|
|
@@ -103009,11 +103401,13 @@ function parseConfig(rawConfig) {
|
|
|
103009
103401
|
}
|
|
103010
103402
|
return config;
|
|
103011
103403
|
}
|
|
103012
|
-
function parseConfigView(
|
|
103404
|
+
function parseConfigView(view, homeDir) {
|
|
103405
|
+
const pruned = prunePluginView({ config: view.config, homeDir, keyPrefix: view.keyPrefix, path: view.path });
|
|
103013
103406
|
return {
|
|
103014
|
-
config: parseConfig(
|
|
103015
|
-
messages: schemaMessages(path,
|
|
103016
|
-
path
|
|
103407
|
+
config: parseConfig(pruned.config),
|
|
103408
|
+
messages: schemaMessages(view.path, view.config, pruned.issues),
|
|
103409
|
+
path: view.path,
|
|
103410
|
+
warnings: pruned.warnings
|
|
103017
103411
|
};
|
|
103018
103412
|
}
|
|
103019
103413
|
function mergeViews(views) {
|
|
@@ -103105,18 +103499,25 @@ function migrateRalphLoopConfig(config) {
|
|
|
103105
103499
|
}
|
|
103106
103500
|
function validatePluginConfig(directory, environment = process.env) {
|
|
103107
103501
|
const chain = loadOmoOpenCodeConfigChain(directory, environment);
|
|
103108
|
-
const
|
|
103109
|
-
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}`);
|
|
103110
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
|
+
];
|
|
103111
103511
|
const firstFailingView = views.find((view) => view.messages.length > 0);
|
|
103112
103512
|
const firstView = views[0];
|
|
103113
|
-
const userConfig = parseConfig(chain.protectedUserView);
|
|
103513
|
+
const userConfig = parseConfig(prunePluginView({ config: chain.protectedUserView, homeDir, keyPrefix: "", path: "" }).config);
|
|
103114
103514
|
const config = applyDisabledProviders(materializeAgentModelChains(protectUserFields(mergeViews(views), userConfig)));
|
|
103115
103515
|
warnLegacyUlwExecuteKey(chain.views);
|
|
103116
103516
|
return {
|
|
103117
103517
|
valid: messages.length === 0,
|
|
103118
103518
|
messages,
|
|
103119
|
-
|
|
103519
|
+
warnings,
|
|
103520
|
+
path: failing[0]?.path ?? firstFailingView?.path ?? firstView?.path ?? null,
|
|
103120
103521
|
config: migrateRalphLoopConfig(migrateLegacyUlwExecuteKey(config))
|
|
103121
103522
|
};
|
|
103122
103523
|
}
|
|
@@ -106240,14 +106641,15 @@ function toOmoConfig(config) {
|
|
|
106240
106641
|
function validateConfig() {
|
|
106241
106642
|
const validation = validatePluginConfig(process.cwd());
|
|
106242
106643
|
if (!validation.path) {
|
|
106243
|
-
return { exists: false, path: null, valid: true, config: null, errors: [] };
|
|
106644
|
+
return { exists: false, path: null, valid: true, config: null, errors: [], warnings: validation.warnings };
|
|
106244
106645
|
}
|
|
106245
106646
|
return {
|
|
106246
106647
|
exists: true,
|
|
106247
106648
|
path: validation.path,
|
|
106248
106649
|
valid: validation.valid,
|
|
106249
106650
|
config: toOmoConfig(validation.config),
|
|
106250
|
-
errors: [...validation.messages]
|
|
106651
|
+
errors: [...validation.messages],
|
|
106652
|
+
warnings: validation.warnings
|
|
106251
106653
|
};
|
|
106252
106654
|
}
|
|
106253
106655
|
function collectModelResolutionIssues(config) {
|
|
@@ -106300,6 +106702,12 @@ async function checkConfig() {
|
|
|
106300
106702
|
}));
|
|
106301
106703
|
if (legacyWarning !== undefined)
|
|
106302
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
|
+
})));
|
|
106303
106711
|
if (!validation.exists) {
|
|
106304
106712
|
return {
|
|
106305
106713
|
name: CHECK_NAMES[CHECK_IDS.CONFIG],
|