mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 10:40:43 +00:00
fix(config): parse quoted bracket paths
This commit is contained in:
@@ -82,6 +82,12 @@ install method aligned:
|
||||
|
||||
The Gateway core auto-updater (when enabled via config) reuses this same update path.
|
||||
|
||||
For package-manager installs, `openclaw update` resolves the target package
|
||||
version before invoking the package manager. If the installed version exactly
|
||||
matches the target and no update-channel change needs to be persisted, the
|
||||
command exits as skipped before package install, plugin sync, completion refresh,
|
||||
or gateway restart work.
|
||||
|
||||
## Git checkout flow
|
||||
|
||||
Channels:
|
||||
|
||||
@@ -273,6 +273,41 @@ describe("config cli", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("dry-runs nested plugin install updates without dropping sibling fields", async () => {
|
||||
const resolved = {
|
||||
plugins: {
|
||||
installs: {
|
||||
"openclaw-web-search": {
|
||||
source: "npm",
|
||||
spec: "@ollama/openclaw-web-search",
|
||||
installPath: "/tmp/openclaw-web-search",
|
||||
version: "0.2.2",
|
||||
resolvedName: "@ollama/openclaw-web-search",
|
||||
resolvedVersion: "0.2.2",
|
||||
resolvedSpec: "@ollama/openclaw-web-search@0.2.2",
|
||||
integrity: "sha512-test",
|
||||
resolvedAt: "2026-04-22T10:33:58.083Z",
|
||||
installedAt: "2026-04-22T10:33:58.240Z",
|
||||
},
|
||||
},
|
||||
},
|
||||
} as unknown as OpenClawConfig;
|
||||
setSnapshot(resolved, resolved);
|
||||
|
||||
await runConfigCommand([
|
||||
"config",
|
||||
"set",
|
||||
'plugins.installs["openclaw-web-search"].spec',
|
||||
'"@ollama/openclaw-web-search@0.2.2"',
|
||||
"--strict-json",
|
||||
"--dry-run",
|
||||
]);
|
||||
|
||||
expect(mockWriteConfigFile).not.toHaveBeenCalled();
|
||||
expect(mockError).not.toHaveBeenCalled();
|
||||
expect(mockLog).toHaveBeenCalledWith(expect.stringContaining("Dry run successful"));
|
||||
});
|
||||
|
||||
it("writes agents.defaults.llm.idleTimeoutSeconds without disturbing sibling defaults", async () => {
|
||||
const resolved: OpenClawConfig = {
|
||||
agents: {
|
||||
|
||||
@@ -108,6 +108,25 @@ function isIndexSegment(raw: string): boolean {
|
||||
return /^[0-9]+$/.test(raw);
|
||||
}
|
||||
|
||||
function parseBracketPathSegment(raw: string, fullPath: string): string {
|
||||
const trimmed = raw.trim();
|
||||
if (!trimmed) {
|
||||
throw new Error(`Invalid path (empty "[]"): ${fullPath}`);
|
||||
}
|
||||
if (trimmed.startsWith('"') || trimmed.startsWith("'")) {
|
||||
try {
|
||||
const parsed = JSON5.parse(trimmed) as unknown;
|
||||
if (typeof parsed === "string" && parsed.trim()) {
|
||||
return parsed;
|
||||
}
|
||||
} catch (err) {
|
||||
throw new Error(`Invalid path bracket string (${trimmed}): ${fullPath}`, { cause: err });
|
||||
}
|
||||
throw new Error(`Invalid path bracket string (${trimmed}): ${fullPath}`);
|
||||
}
|
||||
return trimmed;
|
||||
}
|
||||
|
||||
function parsePath(raw: string): PathSegment[] {
|
||||
const trimmed = raw.trim();
|
||||
if (!trimmed) {
|
||||
@@ -147,7 +166,7 @@ function parsePath(raw: string): PathSegment[] {
|
||||
if (!inside) {
|
||||
throw new Error(`Invalid path (empty "[]"): ${raw}`);
|
||||
}
|
||||
parts.push(inside);
|
||||
parts.push(parseBracketPathSegment(inside, raw));
|
||||
i = close + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user