lazycodex-ai 5.1.4 → 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 +464 -186
- package/dist/cli-node/index.js +464 -186
- package/package.json +1 -1
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +309 -133
- package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
- package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
- package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/rules/package.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lazycodex-ai",
|
|
3
|
-
"version": "5.1.
|
|
3
|
+
"version": "5.1.5",
|
|
4
4
|
"description": "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -6958,7 +6958,6 @@ function normalizeLegacyModelFields(entry) {
|
|
|
6958
6958
|
delete normalized["reasoningEffort"];
|
|
6959
6959
|
delete normalized["thinking"];
|
|
6960
6960
|
delete normalized["textVerbosity"];
|
|
6961
|
-
delete normalized["maxTokens"];
|
|
6962
6961
|
delete normalized["providerOptions"];
|
|
6963
6962
|
if (typeof entry["model"] === "string")
|
|
6964
6963
|
normalized["model"] = canonicalModelString(entry["model"]);
|
|
@@ -6976,10 +6975,15 @@ function normalizeLegacyModelFields(entry) {
|
|
|
6976
6975
|
providerOptions["textVerbosity"] = entry["textVerbosity"];
|
|
6977
6976
|
if (Object.keys(providerOptions).length > 0)
|
|
6978
6977
|
normalized["provider_options"] = providerOptions;
|
|
6979
|
-
if (entry["max_tokens"] !== undefined)
|
|
6978
|
+
if (entry["max_tokens"] !== undefined) {
|
|
6980
6979
|
normalized["max_tokens"] = entry["max_tokens"];
|
|
6981
|
-
|
|
6980
|
+
if (entry["maxTokens"] === undefined || typeof entry["maxTokens"] === "number") {
|
|
6981
|
+
delete normalized["maxTokens"];
|
|
6982
|
+
}
|
|
6983
|
+
} else if (typeof entry["maxTokens"] === "number") {
|
|
6982
6984
|
normalized["max_tokens"] = entry["maxTokens"];
|
|
6985
|
+
delete normalized["maxTokens"];
|
|
6986
|
+
}
|
|
6983
6987
|
return normalized;
|
|
6984
6988
|
}
|
|
6985
6989
|
var OmoLegacyFallbackModelObjectInputSchema = object({
|
|
@@ -7009,6 +7013,19 @@ function isRecord3(value) {
|
|
|
7009
7013
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7010
7014
|
}
|
|
7011
7015
|
var OmoAgentModelEntrySchema = union([string2(), OmoFallbackModelObjectSchema]);
|
|
7016
|
+
var PermissionValueSchema = _enum(["ask", "allow", "deny"]);
|
|
7017
|
+
var BashPermissionSchema = union([
|
|
7018
|
+
PermissionValueSchema,
|
|
7019
|
+
record(string2(), PermissionValueSchema)
|
|
7020
|
+
]);
|
|
7021
|
+
var OmoAgentPermissionSchema = object({
|
|
7022
|
+
edit: PermissionValueSchema.optional(),
|
|
7023
|
+
bash: BashPermissionSchema.optional(),
|
|
7024
|
+
webfetch: PermissionValueSchema.optional(),
|
|
7025
|
+
task: PermissionValueSchema.optional(),
|
|
7026
|
+
doom_loop: PermissionValueSchema.optional(),
|
|
7027
|
+
external_directory: PermissionValueSchema.optional()
|
|
7028
|
+
}).catchall(PermissionValueSchema.optional());
|
|
7012
7029
|
var OmoAgentDefInputSchema = object({
|
|
7013
7030
|
description: string2().optional(),
|
|
7014
7031
|
prompt: string2().optional(),
|
|
@@ -7025,7 +7042,9 @@ var OmoAgentDefInputSchema = object({
|
|
|
7025
7042
|
disallowed_tools: array(string2()).optional(),
|
|
7026
7043
|
max_turns: number2().int().nonnegative().optional(),
|
|
7027
7044
|
temperature: number2().min(0).max(2).optional(),
|
|
7028
|
-
disable: boolean2().optional()
|
|
7045
|
+
disable: boolean2().optional(),
|
|
7046
|
+
permission: OmoAgentPermissionSchema.optional(),
|
|
7047
|
+
prompt_append: string2().optional()
|
|
7029
7048
|
}).strict();
|
|
7030
7049
|
var OmoAgentDefSchema = preprocess((value) => isRecord3(value) ? normalizeLegacyModelFields(value) : value, OmoAgentDefInputSchema);
|
|
7031
7050
|
var OmoAgentsConfigSchema = record(string2(), OmoAgentDefSchema);
|
|
@@ -7714,6 +7733,16 @@ function canonicalizeLegacyHarnessBlocks(document) {
|
|
|
7714
7733
|
return { document: canonicalized, renames };
|
|
7715
7734
|
}
|
|
7716
7735
|
|
|
7736
|
+
// ../../omo-config-core/src/loader/types.ts
|
|
7737
|
+
import { existsSync as existsSync2, lstatSync, readFileSync, realpathSync } from "node:fs";
|
|
7738
|
+
var MERGED_OMO_CONFIG_PATH = "(merged omo config)";
|
|
7739
|
+
var DEFAULT_READ_FILE_SYSTEM = {
|
|
7740
|
+
existsSync: existsSync2,
|
|
7741
|
+
lstatSync,
|
|
7742
|
+
readFileSync,
|
|
7743
|
+
realpathSync
|
|
7744
|
+
};
|
|
7745
|
+
|
|
7717
7746
|
// ../../../node_modules/.bun/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/scanner.js
|
|
7718
7747
|
function createScanner(text, ignoreTrivia = false) {
|
|
7719
7748
|
const len = text.length;
|
|
@@ -8588,6 +8617,255 @@ function mergeOmoConfigRecords(base, override) {
|
|
|
8588
8617
|
return result;
|
|
8589
8618
|
}
|
|
8590
8619
|
|
|
8620
|
+
// ../../omo-config-core/src/loader/prune-invalid-leaves.ts
|
|
8621
|
+
var MAX_PRUNE_PASSES = 32;
|
|
8622
|
+
function isContainer(value) {
|
|
8623
|
+
return typeof value === "object" && value !== null;
|
|
8624
|
+
}
|
|
8625
|
+
function childOf(container, segment) {
|
|
8626
|
+
return Array.isArray(container) ? container[Number(segment)] : container[String(segment)];
|
|
8627
|
+
}
|
|
8628
|
+
function hasChild(container, segment) {
|
|
8629
|
+
if (Array.isArray(container)) {
|
|
8630
|
+
const index = Number(segment);
|
|
8631
|
+
return Number.isInteger(index) && index >= 0 && index < container.length;
|
|
8632
|
+
}
|
|
8633
|
+
return Object.hasOwn(container, String(segment));
|
|
8634
|
+
}
|
|
8635
|
+
function segmentsOf(path) {
|
|
8636
|
+
return path.map((segment) => typeof segment === "number" ? segment : String(segment));
|
|
8637
|
+
}
|
|
8638
|
+
function targetPaths(root, issue) {
|
|
8639
|
+
const base = segmentsOf(issue.path);
|
|
8640
|
+
if (issue.code === "unrecognized_keys")
|
|
8641
|
+
return issue.keys.map((key) => [...base, key]);
|
|
8642
|
+
let node = root;
|
|
8643
|
+
let depth = 0;
|
|
8644
|
+
for (const segment of base) {
|
|
8645
|
+
if (!isContainer(node) || !hasChild(node, segment))
|
|
8646
|
+
break;
|
|
8647
|
+
node = childOf(node, segment);
|
|
8648
|
+
depth += 1;
|
|
8649
|
+
}
|
|
8650
|
+
return [base.slice(0, depth)];
|
|
8651
|
+
}
|
|
8652
|
+
function isAncestor(ancestor, path) {
|
|
8653
|
+
return ancestor.length < path.length && ancestor.every((segment, index) => segment === path[index]);
|
|
8654
|
+
}
|
|
8655
|
+
function compareDescending(left, right) {
|
|
8656
|
+
const length = Math.min(left.length, right.length);
|
|
8657
|
+
for (let index = 0;index < length; index += 1) {
|
|
8658
|
+
const a = left[index];
|
|
8659
|
+
const b = right[index];
|
|
8660
|
+
if (a === b)
|
|
8661
|
+
continue;
|
|
8662
|
+
if (typeof a === "number" && typeof b === "number")
|
|
8663
|
+
return b - a;
|
|
8664
|
+
return String(b).localeCompare(String(a));
|
|
8665
|
+
}
|
|
8666
|
+
return right.length - left.length;
|
|
8667
|
+
}
|
|
8668
|
+
function removeChild(container, segment) {
|
|
8669
|
+
if (Array.isArray(container))
|
|
8670
|
+
container.splice(Number(segment), 1);
|
|
8671
|
+
else
|
|
8672
|
+
delete container[String(segment)];
|
|
8673
|
+
}
|
|
8674
|
+
function isEmpty(container) {
|
|
8675
|
+
return Array.isArray(container) ? container.length === 0 : Object.keys(container).length === 0;
|
|
8676
|
+
}
|
|
8677
|
+
function removePathAndEmptiedAncestors(root, path) {
|
|
8678
|
+
const chain = [root];
|
|
8679
|
+
for (const segment of path.slice(0, -1)) {
|
|
8680
|
+
const current = chain[chain.length - 1];
|
|
8681
|
+
if (current === undefined)
|
|
8682
|
+
return;
|
|
8683
|
+
const next = childOf(current, segment);
|
|
8684
|
+
if (!isContainer(next))
|
|
8685
|
+
return;
|
|
8686
|
+
chain.push(next);
|
|
8687
|
+
}
|
|
8688
|
+
for (let depth = path.length - 1;depth >= 0; depth -= 1) {
|
|
8689
|
+
const container = chain[depth];
|
|
8690
|
+
const segment = path[depth];
|
|
8691
|
+
if (container === undefined || segment === undefined)
|
|
8692
|
+
return;
|
|
8693
|
+
removeChild(container, segment);
|
|
8694
|
+
if (depth === 0 || !isEmpty(container))
|
|
8695
|
+
return;
|
|
8696
|
+
}
|
|
8697
|
+
}
|
|
8698
|
+
function prunePass(root, issues) {
|
|
8699
|
+
const byKey = new Map;
|
|
8700
|
+
for (const issue of issues) {
|
|
8701
|
+
for (const path of targetPaths(root, issue)) {
|
|
8702
|
+
if (path.length === 0)
|
|
8703
|
+
return null;
|
|
8704
|
+
const key = path.map((segment) => String(segment)).join(".");
|
|
8705
|
+
if (!byKey.has(key))
|
|
8706
|
+
byKey.set(key, { key, message: issue.message, path });
|
|
8707
|
+
}
|
|
8708
|
+
}
|
|
8709
|
+
const targets = [...byKey.values()];
|
|
8710
|
+
const outermost = targets.filter((target) => !targets.some((other) => isAncestor(other.path, target.path))).sort((left, right) => compareDescending(left.path, right.path));
|
|
8711
|
+
const next = structuredClone(root);
|
|
8712
|
+
for (const target of outermost)
|
|
8713
|
+
removePathAndEmptiedAncestors(next, target.path);
|
|
8714
|
+
return { dropped: outermost, next };
|
|
8715
|
+
}
|
|
8716
|
+
function pruneInvalidConfigPaths(config, issues, validate, maxPasses = MAX_PRUNE_PASSES) {
|
|
8717
|
+
const dropped = [];
|
|
8718
|
+
let current = config;
|
|
8719
|
+
let pending = issues;
|
|
8720
|
+
for (let pass = 0;pass < maxPasses; pass += 1) {
|
|
8721
|
+
const step = prunePass(current, pending);
|
|
8722
|
+
if (step === null || step.dropped.length === 0)
|
|
8723
|
+
return { ok: false, dropped };
|
|
8724
|
+
dropped.push(...step.dropped);
|
|
8725
|
+
current = step.next;
|
|
8726
|
+
if (Object.keys(current).length === 0)
|
|
8727
|
+
return { ok: false, dropped };
|
|
8728
|
+
const validation = validate(current);
|
|
8729
|
+
if (validation.success)
|
|
8730
|
+
return { ok: true, config: current, dropped };
|
|
8731
|
+
pending = validation.issues;
|
|
8732
|
+
}
|
|
8733
|
+
return { ok: false, dropped };
|
|
8734
|
+
}
|
|
8735
|
+
|
|
8736
|
+
// ../../omo-config-core/src/loader/layer-validation.ts
|
|
8737
|
+
function validationDiagnostic(path, issues) {
|
|
8738
|
+
const issuePaths = issues.map((issue) => issue.path.map((segment) => String(segment)).join("."));
|
|
8739
|
+
return {
|
|
8740
|
+
kind: "validation",
|
|
8741
|
+
message: `Invalid omo config at ${path}: ${issuePaths.join(", ")}`,
|
|
8742
|
+
path,
|
|
8743
|
+
issuePaths
|
|
8744
|
+
};
|
|
8745
|
+
}
|
|
8746
|
+
function invalidValueDiagnostics(path, dropped) {
|
|
8747
|
+
return dropped.map((entry) => ({
|
|
8748
|
+
kind: "invalid-value",
|
|
8749
|
+
message: `Ignored invalid value in ${path}: ${entry.key}: ${entry.message}`,
|
|
8750
|
+
path,
|
|
8751
|
+
issuePaths: [entry.key]
|
|
8752
|
+
}));
|
|
8753
|
+
}
|
|
8754
|
+
function unrecognizedKeyIssues(issues) {
|
|
8755
|
+
return issues.flatMap((issue) => issue.code === "unrecognized_keys" ? [{ keys: issue.keys, path: issue.path.map((segment) => String(segment)) }] : []);
|
|
8756
|
+
}
|
|
8757
|
+
function isRecord9(value) {
|
|
8758
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8759
|
+
}
|
|
8760
|
+
function sanitizeUnsafeKeys(value, path = []) {
|
|
8761
|
+
if (Array.isArray(value)) {
|
|
8762
|
+
const issues = [];
|
|
8763
|
+
const sanitized = value.map((entry, index) => {
|
|
8764
|
+
const nested = sanitizeUnsafeKeys(entry, [...path, String(index)]);
|
|
8765
|
+
issues.push(...nested.issues);
|
|
8766
|
+
return nested.value;
|
|
8767
|
+
});
|
|
8768
|
+
return { issues, value: sanitized };
|
|
8769
|
+
}
|
|
8770
|
+
if (!isRecord9(value))
|
|
8771
|
+
return { issues: [], value };
|
|
8772
|
+
const issues = [];
|
|
8773
|
+
if (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) {
|
|
8774
|
+
issues.push({ keys: ["__proto__"], path });
|
|
8775
|
+
}
|
|
8776
|
+
const sanitized = {};
|
|
8777
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
8778
|
+
if (isUnsafeObjectKey(key)) {
|
|
8779
|
+
issues.push({ keys: [key], path });
|
|
8780
|
+
continue;
|
|
8781
|
+
}
|
|
8782
|
+
const nested = sanitizeUnsafeKeys(entry, [...path, key]);
|
|
8783
|
+
issues.push(...nested.issues);
|
|
8784
|
+
sanitized[key] = nested.value;
|
|
8785
|
+
}
|
|
8786
|
+
return { issues, value: sanitized };
|
|
8787
|
+
}
|
|
8788
|
+
function containerAt(record, path) {
|
|
8789
|
+
let node = record;
|
|
8790
|
+
for (const segment of path) {
|
|
8791
|
+
if (Array.isArray(node)) {
|
|
8792
|
+
const index = Number(segment);
|
|
8793
|
+
if (!Number.isInteger(index) || index < 0 || index >= node.length)
|
|
8794
|
+
return null;
|
|
8795
|
+
node = node[index];
|
|
8796
|
+
} else if (isRecord9(node) && Object.hasOwn(node, segment)) {
|
|
8797
|
+
node = node[segment];
|
|
8798
|
+
} else {
|
|
8799
|
+
return null;
|
|
8800
|
+
}
|
|
8801
|
+
}
|
|
8802
|
+
return isRecord9(node) ? node : null;
|
|
8803
|
+
}
|
|
8804
|
+
function stripUnrecognizedKeys(record, issues) {
|
|
8805
|
+
const stripped = structuredClone(record);
|
|
8806
|
+
const issuePaths = [];
|
|
8807
|
+
for (const issue of issues) {
|
|
8808
|
+
const container = containerAt(stripped, issue.path);
|
|
8809
|
+
if (container === null)
|
|
8810
|
+
continue;
|
|
8811
|
+
for (const key of issue.keys) {
|
|
8812
|
+
delete container[key];
|
|
8813
|
+
issuePaths.push([...issue.path, key].join("."));
|
|
8814
|
+
}
|
|
8815
|
+
}
|
|
8816
|
+
return { issuePaths, stripped };
|
|
8817
|
+
}
|
|
8818
|
+
function toRecord(value) {
|
|
8819
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
8820
|
+
return null;
|
|
8821
|
+
const record = {};
|
|
8822
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
8823
|
+
record[key] = entry;
|
|
8824
|
+
}
|
|
8825
|
+
return record;
|
|
8826
|
+
}
|
|
8827
|
+
var validateLayerRecord = (record) => {
|
|
8828
|
+
const parsed = OmoConfigLayerSchema.safeParse(record);
|
|
8829
|
+
return parsed.success ? { success: true } : { success: false, issues: parsed.error.issues };
|
|
8830
|
+
};
|
|
8831
|
+
function validateConfigLayer(path, data) {
|
|
8832
|
+
const sanitized = sanitizeUnsafeKeys(data);
|
|
8833
|
+
const record = toRecord(sanitized.value);
|
|
8834
|
+
const unsafeIssuePaths = sanitized.issues.flatMap((issue) => issue.keys.map((key) => [...issue.path, key].join(".")));
|
|
8835
|
+
const unsafeDiagnostics = unsafeIssuePaths.length === 0 ? [] : [{ kind: "unknown-keys", message: `Ignored unknown keys in ${path}: ${unsafeIssuePaths.join(", ")}`, path, issuePaths: unsafeIssuePaths }];
|
|
8836
|
+
const validation = OmoConfigLayerSchema.safeParse(sanitized.value);
|
|
8837
|
+
if (validation.success) {
|
|
8838
|
+
if (record !== null)
|
|
8839
|
+
return { loaded: true, diagnostics: unsafeDiagnostics, value: record };
|
|
8840
|
+
return {
|
|
8841
|
+
loaded: false,
|
|
8842
|
+
diagnostics: [{ kind: "validation", message: `Invalid omo config at ${path}: root must be an object`, path }]
|
|
8843
|
+
};
|
|
8844
|
+
}
|
|
8845
|
+
const rejected = { loaded: false, diagnostics: [validationDiagnostic(path, validation.error.issues)] };
|
|
8846
|
+
const unknownIssues = unrecognizedKeyIssues(validation.error.issues);
|
|
8847
|
+
if (record === null)
|
|
8848
|
+
return rejected;
|
|
8849
|
+
let candidate = record;
|
|
8850
|
+
let issues = validation.error.issues;
|
|
8851
|
+
const diagnostics = [...unsafeDiagnostics];
|
|
8852
|
+
if (unknownIssues.length > 0) {
|
|
8853
|
+
const { issuePaths, stripped } = stripUnrecognizedKeys(record, unknownIssues);
|
|
8854
|
+
if (issuePaths.length > 0) {
|
|
8855
|
+
diagnostics.push({ kind: "unknown-keys", message: `Ignored unknown keys in ${path}: ${issuePaths.join(", ")}`, path, issuePaths });
|
|
8856
|
+
}
|
|
8857
|
+
const strippedValidation = validateLayerRecord(stripped);
|
|
8858
|
+
if (strippedValidation.success)
|
|
8859
|
+
return { loaded: true, diagnostics, value: stripped };
|
|
8860
|
+
candidate = stripped;
|
|
8861
|
+
issues = strippedValidation.issues;
|
|
8862
|
+
}
|
|
8863
|
+
const pruned = pruneInvalidConfigPaths(candidate, issues, validateLayerRecord);
|
|
8864
|
+
if (!pruned.ok)
|
|
8865
|
+
return rejected;
|
|
8866
|
+
return { loaded: true, diagnostics: [...diagnostics, ...invalidValueDiagnostics(path, pruned.dropped)], value: pruned.config };
|
|
8867
|
+
}
|
|
8868
|
+
|
|
8591
8869
|
// ../../omo-config-core/src/loader/paths.ts
|
|
8592
8870
|
import { userInfo } from "node:os";
|
|
8593
8871
|
import { dirname as dirname5, join as join8, posix, resolve as resolve3 } from "node:path";
|
|
@@ -8597,15 +8875,6 @@ function toPosixPath(path) {
|
|
|
8597
8875
|
return path.split("\\").join("/");
|
|
8598
8876
|
}
|
|
8599
8877
|
|
|
8600
|
-
// ../../omo-config-core/src/loader/types.ts
|
|
8601
|
-
import { existsSync as existsSync2, lstatSync, readFileSync, realpathSync } from "node:fs";
|
|
8602
|
-
var DEFAULT_READ_FILE_SYSTEM = {
|
|
8603
|
-
existsSync: existsSync2,
|
|
8604
|
-
lstatSync,
|
|
8605
|
-
readFileSync,
|
|
8606
|
-
realpathSync
|
|
8607
|
-
};
|
|
8608
|
-
|
|
8609
8878
|
// ../../omo-config-core/src/loader/paths.ts
|
|
8610
8879
|
var MAX_PROJECT_CONFIG_DIRECTORY_DEPTH = 256;
|
|
8611
8880
|
var ACCOUNT_HOME_DIR = userInfo().homedir;
|
|
@@ -8701,7 +8970,7 @@ function resolveOmoProfileName(options = {}) {
|
|
|
8701
8970
|
const env = options.env ?? process.env;
|
|
8702
8971
|
return profileName(options.profile) ?? profileName(env["OMO_PROFILE"]) ?? profileName(env["OCX_PROFILE"]) ?? profileNameFromOpenCodeConfigDir(env["OPENCODE_CONFIG_DIR"]);
|
|
8703
8972
|
}
|
|
8704
|
-
function
|
|
8973
|
+
function toRecord2(value) {
|
|
8705
8974
|
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
8706
8975
|
return;
|
|
8707
8976
|
return Object.fromEntries(Object.entries(value));
|
|
@@ -8722,13 +8991,13 @@ function harnessLayer(config, harness) {
|
|
|
8722
8991
|
const legacyKeys = Object.entries(OMO_CONFIG_LEGACY_HARNESS_ALIASES).filter(([, target]) => target === canonical).map(([legacy]) => harnessBlockKey(legacy));
|
|
8723
8992
|
let layer = {};
|
|
8724
8993
|
for (const key of [...legacyKeys, harnessBlockKey(canonical)]) {
|
|
8725
|
-
layer = mergeOmoConfigRecords(layer,
|
|
8994
|
+
layer = mergeOmoConfigRecords(layer, toRecord2(config[key]) ?? {});
|
|
8726
8995
|
}
|
|
8727
8996
|
return layer;
|
|
8728
8997
|
}
|
|
8729
8998
|
function resolveOmoConfigView(options) {
|
|
8730
|
-
const profiles =
|
|
8731
|
-
const profile = options.profile === undefined ? undefined :
|
|
8999
|
+
const profiles = toRecord2(options.config["profiles"]);
|
|
9000
|
+
const profile = options.profile === undefined ? undefined : toRecord2(profiles?.[options.profile]);
|
|
8732
9001
|
const diagnostics = profile === undefined && options.profile !== undefined ? [{
|
|
8733
9002
|
kind: "profile",
|
|
8734
9003
|
message: `Activated omo profile "${options.profile}" does not exist; using the base configuration`,
|
|
@@ -8783,70 +9052,9 @@ function stripResolutionControlKeys(config) {
|
|
|
8783
9052
|
} = config;
|
|
8784
9053
|
return resolved;
|
|
8785
9054
|
}
|
|
8786
|
-
function validationDiagnostic(path, issues) {
|
|
8787
|
-
const issuePaths = issues.map((issue) => issue.path.map((segment) => String(segment)).join("."));
|
|
8788
|
-
return {
|
|
8789
|
-
kind: "validation",
|
|
8790
|
-
message: `Invalid omo config at ${path}: ${issuePaths.join(", ")}`,
|
|
8791
|
-
path,
|
|
8792
|
-
issuePaths
|
|
8793
|
-
};
|
|
8794
|
-
}
|
|
8795
|
-
function unrecognizedKeyIssues(issues) {
|
|
8796
|
-
return issues.flatMap((issue) => issue.code === "unrecognized_keys" ? [{ keys: issue.keys, path: issue.path.map((segment) => String(segment)) }] : []);
|
|
8797
|
-
}
|
|
8798
|
-
function hasUnsafeUnrecognizedKey(issues) {
|
|
8799
|
-
return issues.some((issue) => issue.keys.some((key) => isUnsafeObjectKey(key)));
|
|
8800
|
-
}
|
|
8801
|
-
function hasTamperedPrototype(value) {
|
|
8802
|
-
if (Array.isArray(value))
|
|
8803
|
-
return value.some((entry) => hasTamperedPrototype(entry));
|
|
8804
|
-
if (!isRecord9(value))
|
|
8805
|
-
return false;
|
|
8806
|
-
const prototype = Object.getPrototypeOf(value);
|
|
8807
|
-
if (prototype !== Object.prototype && prototype !== null)
|
|
8808
|
-
return true;
|
|
8809
|
-
return Object.values(value).some((entry) => hasTamperedPrototype(entry));
|
|
8810
|
-
}
|
|
8811
|
-
function isRecord9(value) {
|
|
8812
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8813
|
-
}
|
|
8814
|
-
function containerAt(record, path) {
|
|
8815
|
-
let container = record;
|
|
8816
|
-
for (const segment of path) {
|
|
8817
|
-
const next = container[segment];
|
|
8818
|
-
if (!isRecord9(next))
|
|
8819
|
-
return null;
|
|
8820
|
-
container = next;
|
|
8821
|
-
}
|
|
8822
|
-
return container;
|
|
8823
|
-
}
|
|
8824
|
-
function stripUnrecognizedKeys(record, issues) {
|
|
8825
|
-
const stripped = structuredClone(record);
|
|
8826
|
-
const issuePaths = [];
|
|
8827
|
-
for (const issue of issues) {
|
|
8828
|
-
const container = containerAt(stripped, issue.path);
|
|
8829
|
-
if (container === null)
|
|
8830
|
-
continue;
|
|
8831
|
-
for (const key of issue.keys) {
|
|
8832
|
-
delete container[key];
|
|
8833
|
-
issuePaths.push([...issue.path, key].join("."));
|
|
8834
|
-
}
|
|
8835
|
-
}
|
|
8836
|
-
return { issuePaths, stripped };
|
|
8837
|
-
}
|
|
8838
|
-
function toRecord2(value) {
|
|
8839
|
-
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
8840
|
-
return null;
|
|
8841
|
-
const record = {};
|
|
8842
|
-
for (const [key, entry] of Object.entries(value)) {
|
|
8843
|
-
record[key] = entry;
|
|
8844
|
-
}
|
|
8845
|
-
return record;
|
|
8846
|
-
}
|
|
8847
9055
|
function readConfigSource(path, scope, fileSystem) {
|
|
8848
9056
|
if (!fileSystem.existsSync(path)) {
|
|
8849
|
-
return { source: { exists: false, loaded: false, path, scope } };
|
|
9057
|
+
return { diagnostics: [], source: { exists: false, loaded: false, path, scope } };
|
|
8850
9058
|
}
|
|
8851
9059
|
let content;
|
|
8852
9060
|
try {
|
|
@@ -8854,68 +9062,23 @@ function readConfigSource(path, scope, fileSystem) {
|
|
|
8854
9062
|
} catch (error) {
|
|
8855
9063
|
const message = error instanceof Error ? error.message : String(error);
|
|
8856
9064
|
return {
|
|
8857
|
-
|
|
9065
|
+
diagnostics: [{ kind: "read", message: `Failed to read ${path}: ${message}`, path }],
|
|
8858
9066
|
source: { exists: true, loaded: false, path, scope }
|
|
8859
9067
|
};
|
|
8860
9068
|
}
|
|
8861
9069
|
const parsed = parseJsoncSafe(content);
|
|
8862
9070
|
if (parsed.errors.length > 0) {
|
|
8863
9071
|
return {
|
|
8864
|
-
|
|
9072
|
+
diagnostics: [{
|
|
8865
9073
|
kind: "parse",
|
|
8866
9074
|
message: `JSONC parse error in ${path}: ${parsed.errors.map((error) => error.message).join(", ")}`,
|
|
8867
9075
|
path
|
|
8868
|
-
},
|
|
8869
|
-
source: { exists: true, loaded: false, path, scope }
|
|
8870
|
-
};
|
|
8871
|
-
}
|
|
8872
|
-
if (hasTamperedPrototype(parsed.data)) {
|
|
8873
|
-
return {
|
|
8874
|
-
diagnostic: { kind: "validation", message: `Invalid omo config at ${path}: "__proto__" member is not allowed`, path },
|
|
8875
|
-
source: { exists: true, loaded: false, path, scope }
|
|
8876
|
-
};
|
|
8877
|
-
}
|
|
8878
|
-
const parsedRecord = toRecord2(parsed.data);
|
|
8879
|
-
const validation = OmoConfigLayerSchema.safeParse(parsed.data);
|
|
8880
|
-
if (!validation.success) {
|
|
8881
|
-
const unrecognized = unrecognizedKeyIssues(validation.error.issues);
|
|
8882
|
-
if (hasUnsafeUnrecognizedKey(unrecognized)) {
|
|
8883
|
-
return {
|
|
8884
|
-
diagnostic: validationDiagnostic(path, validation.error.issues),
|
|
8885
|
-
source: { exists: true, loaded: false, path, scope }
|
|
8886
|
-
};
|
|
8887
|
-
}
|
|
8888
|
-
const rejected = {
|
|
8889
|
-
diagnostic: validationDiagnostic(path, validation.error.issues),
|
|
9076
|
+
}],
|
|
8890
9077
|
source: { exists: true, loaded: false, path, scope }
|
|
8891
9078
|
};
|
|
8892
|
-
const unknownIssues = unrecognizedKeyIssues(validation.error.issues);
|
|
8893
|
-
if (parsedRecord === null || unknownIssues.length === 0)
|
|
8894
|
-
return rejected;
|
|
8895
|
-
const { issuePaths, stripped } = stripUnrecognizedKeys(parsedRecord, unknownIssues);
|
|
8896
|
-
if (!OmoConfigLayerSchema.safeParse(stripped).success)
|
|
8897
|
-
return rejected;
|
|
8898
|
-
return {
|
|
8899
|
-
diagnostic: {
|
|
8900
|
-
kind: "unknown-keys",
|
|
8901
|
-
message: `Ignored unknown keys in ${path}: ${issuePaths.join(", ")}`,
|
|
8902
|
-
path,
|
|
8903
|
-
issuePaths
|
|
8904
|
-
},
|
|
8905
|
-
source: { exists: true, loaded: true, path, scope },
|
|
8906
|
-
value: stripped
|
|
8907
|
-
};
|
|
8908
9079
|
}
|
|
8909
|
-
|
|
8910
|
-
|
|
8911
|
-
diagnostic: { kind: "validation", message: `Invalid omo config at ${path}: root must be an object`, path },
|
|
8912
|
-
source: { exists: true, loaded: false, path, scope }
|
|
8913
|
-
};
|
|
8914
|
-
}
|
|
8915
|
-
return {
|
|
8916
|
-
source: { exists: true, loaded: true, path, scope },
|
|
8917
|
-
value: parsedRecord
|
|
8918
|
-
};
|
|
9080
|
+
const layer = validateConfigLayer(path, parsed.data);
|
|
9081
|
+
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 } };
|
|
8919
9082
|
}
|
|
8920
9083
|
function legacyCategoryDiagnostic(path, renames) {
|
|
8921
9084
|
const detail = renames.map((rename) => rename.dropped ? `${rename.path} ignored because ${rename.canonical} is also configured` : `${rename.path} renamed to ${rename.canonical}`).join(", ");
|
|
@@ -8950,8 +9113,7 @@ function loadOmoConfig(options = {}) {
|
|
|
8950
9113
|
})) {
|
|
8951
9114
|
const loaded = readConfigSource(candidate.path, candidate.scope, fileSystem);
|
|
8952
9115
|
sources.push(loaded.source);
|
|
8953
|
-
|
|
8954
|
-
diagnostics.push(loaded.diagnostic);
|
|
9116
|
+
diagnostics.push(...loaded.diagnostics);
|
|
8955
9117
|
if (loaded.value !== undefined) {
|
|
8956
9118
|
const canonicalized = canonicalizeLegacyCategoryNames(loaded.value);
|
|
8957
9119
|
if (canonicalized.renames.length > 0) {
|
|
@@ -8974,7 +9136,8 @@ function loadOmoConfig(options = {}) {
|
|
|
8974
9136
|
...options.harness === undefined ? {} : { harness: options.harness },
|
|
8975
9137
|
...requestedProfile === undefined ? {} : { profile: requestedProfile }
|
|
8976
9138
|
});
|
|
8977
|
-
const
|
|
9139
|
+
const finalInput = mergeOmoConfigRecords(DEFAULT_RAW_CONFIG, resolved.config);
|
|
9140
|
+
const finalConfig = OmoConfigSchema.safeParse(finalInput);
|
|
8978
9141
|
if (finalConfig.success) {
|
|
8979
9142
|
return {
|
|
8980
9143
|
config: stripResolutionControlKeys(finalConfig.data),
|
|
@@ -8984,9 +9147,22 @@ function loadOmoConfig(options = {}) {
|
|
|
8984
9147
|
sources
|
|
8985
9148
|
};
|
|
8986
9149
|
}
|
|
9150
|
+
const pruned = pruneInvalidConfigPaths(finalInput, finalConfig.error.issues, (record) => {
|
|
9151
|
+
const parsed = OmoConfigSchema.safeParse(record);
|
|
9152
|
+
return parsed.success ? { success: true } : { success: false, issues: parsed.error.issues };
|
|
9153
|
+
});
|
|
9154
|
+
if (pruned.ok) {
|
|
9155
|
+
return {
|
|
9156
|
+
config: stripResolutionControlKeys(OmoConfigSchema.parse(pruned.config)),
|
|
9157
|
+
diagnostics: [...diagnostics, ...resolved.diagnostics, ...invalidValueDiagnostics(MERGED_OMO_CONFIG_PATH, pruned.dropped)],
|
|
9158
|
+
layers,
|
|
9159
|
+
...resolved.profile === undefined ? {} : { profile: resolved.profile },
|
|
9160
|
+
sources
|
|
9161
|
+
};
|
|
9162
|
+
}
|
|
8987
9163
|
return {
|
|
8988
9164
|
config: stripResolutionControlKeys(OmoConfigSchema.parse(DEFAULT_RAW_CONFIG)),
|
|
8989
|
-
diagnostics: [...diagnostics, ...resolved.diagnostics, validationDiagnostic(
|
|
9165
|
+
diagnostics: [...diagnostics, ...resolved.diagnostics, validationDiagnostic(MERGED_OMO_CONFIG_PATH, finalConfig.error.issues)],
|
|
8990
9166
|
layers,
|
|
8991
9167
|
...resolved.profile === undefined ? {} : { profile: resolved.profile },
|
|
8992
9168
|
sources
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/components/bootstrap/dist/cli.js\" hook session-start",
|
|
9
9
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\bootstrap.ps1\"",
|
|
10
10
|
"timeout": 30,
|
|
11
|
-
"statusMessage": "(OmO 5.1.
|
|
11
|
+
"statusMessage": "(OmO 5.1.5) Checking Bootstrap Provisioning"
|
|
12
12
|
}
|
|
13
13
|
]
|
|
14
14
|
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"type": "command",
|
|
9
9
|
"command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook pre-tool-use",
|
|
10
10
|
"timeout": 5,
|
|
11
|
-
"statusMessage": "(OmO 5.1.
|
|
11
|
+
"statusMessage": "(OmO 5.1.5) Recommending Git Bash MCP"
|
|
12
12
|
}
|
|
13
13
|
]
|
|
14
14
|
}
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"type": "command",
|
|
21
21
|
"command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-compact",
|
|
22
22
|
"timeout": 5,
|
|
23
|
-
"statusMessage": "(OmO 5.1.
|
|
23
|
+
"statusMessage": "(OmO 5.1.5) Resetting Git Bash MCP Reminder"
|
|
24
24
|
}
|
|
25
25
|
]
|
|
26
26
|
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"type": "command",
|
|
9
9
|
"command": "node \"${PLUGIN_ROOT}/components/lazycodex-executor-verify/dist/cli.js\" hook subagent-stop",
|
|
10
10
|
"timeout": 10,
|
|
11
|
-
"statusMessage": "(OmO 5.1.
|
|
11
|
+
"statusMessage": "(OmO 5.1.5) Verifying LazyCodex Executor Evidence"
|
|
12
12
|
}
|
|
13
13
|
]
|
|
14
14
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"version": "5.1.
|
|
4
|
-
"inputDigest": "sha256:
|
|
3
|
+
"version": "5.1.5",
|
|
4
|
+
"inputDigest": "sha256:ce1030fda9d0a09a2739fc8318901714ddc3c2245a9f5eb4cce5a6b327ddedcc",
|
|
5
5
|
"outputs": [
|
|
6
6
|
{
|
|
7
7
|
"path": "cli.d.ts",
|