mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 06:20:43 +00:00
fix(plugins): fast-path strict manifest json
This commit is contained in:
@@ -21,6 +21,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Agents/runtime context: deliver hidden runtime context through prompt-local system context while keeping the transcript-only custom entry out of provider user turns, and strip stale copied runtime-context prefaces from user-facing replies. Fixes #72386; carries forward #72969. Thanks @jhsmith409.
|
||||
- Channels/Telegram: skip the optional webhook-info API call during polling-mode status checks and startup bot-label probes so long-polling setups avoid an unnecessary Telegram round trip. Carries forward #72990. Thanks @danielgruneberg.
|
||||
- CLI/message: resolve targeted `openclaw message` channels to their owning plugin before loading the registry, and fall back to configured channel plugins when the channel must be inferred, so scripted sends avoid full bundled plugin registry scans without assuming channel ids match plugin ids. Fixes #73006. Thanks @jasonftl.
|
||||
- Plugins/startup: parse strict JSON plugin manifests with native JSON first and keep JSON5 as the compatibility fallback, reducing manifest registry CPU during Gateway boot and CLI startup. Fixes #73011. Thanks @jasonftl.
|
||||
- CLI/models: keep route-first `models status --json` stdout reserved for the JSON payload by routing auth-profile and startup diagnostics to stderr. Fixes #72962. Thanks @vishutdhar.
|
||||
- Sessions: ignore future-dated session activity timestamps during reset freshness checks and cap future `updatedAt` values at the merge boundary so clock-skewed messages cannot keep stale sessions alive forever. Fixes #72989. Thanks @martingarramon.
|
||||
- Sessions: apply search, activity filters, and limits before gateway row enrichment so bounded session lists avoid scanning discarded transcripts. Carries forward #72978. Thanks @yeager.
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
loadPluginManifestRegistry,
|
||||
type PluginManifestRecord,
|
||||
} from "../plugins/manifest-registry.js";
|
||||
import { parseJsonWithJson5Fallback } from "../utils/parse-json-compat.js";
|
||||
import { resolveRegistryPluginModuleLocationFromRecords } from "./facade-resolution-shared.js";
|
||||
|
||||
const ALWAYS_ALLOWED_RUNTIME_DIR_NAMES = new Set([
|
||||
@@ -195,7 +196,7 @@ function readBundledPluginManifestRecordFromDir(params: {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
const raw = JSON5.parse(fs.readFileSync(manifestPath, "utf8")) as {
|
||||
const raw = parseJsonWithJson5Fallback(fs.readFileSync(manifestPath, "utf8")) as {
|
||||
id?: unknown;
|
||||
enabledByDefault?: unknown;
|
||||
channels?: unknown;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import JSON5 from "json5";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { loadPluginManifest, MAX_PLUGIN_MANIFEST_BYTES } from "./manifest.js";
|
||||
import { cleanupTrackedTempDirs, makeTrackedTempDir } from "./test-helpers/fs-fixtures.js";
|
||||
|
||||
@@ -11,6 +12,7 @@ function makeTempDir() {
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
cleanupTrackedTempDirs(tempDirs);
|
||||
});
|
||||
|
||||
@@ -33,6 +35,24 @@ describe("loadPluginManifest JSON5 tolerance", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("uses native JSON parsing for standard JSON manifests", () => {
|
||||
const json5Parse = vi.spyOn(JSON5, "parse");
|
||||
const dir = makeTempDir();
|
||||
fs.writeFileSync(
|
||||
path.join(dir, "openclaw.plugin.json"),
|
||||
JSON.stringify({
|
||||
id: "strict-json",
|
||||
configSchema: { type: "object" },
|
||||
}),
|
||||
"utf-8",
|
||||
);
|
||||
|
||||
const result = loadPluginManifest(dir, false);
|
||||
|
||||
expect(result.ok).toBe(true);
|
||||
expect(json5Parse).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("parses a manifest with trailing commas", () => {
|
||||
const dir = makeTempDir();
|
||||
const json5Content = `{
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import JSON5 from "json5";
|
||||
import type { ChannelConfigRuntimeSchema } from "../channels/plugins/types.config.js";
|
||||
import { MANIFEST_KEY } from "../compat/legacy-names.js";
|
||||
import { matchBoundaryFileOpenFailure, openBoundaryFileSync } from "../infra/boundary-file-read.js";
|
||||
@@ -23,6 +22,7 @@ import type { JsonSchemaObject } from "../shared/json-schema.types.js";
|
||||
import { normalizeOptionalString } from "../shared/string-coerce.js";
|
||||
import { normalizeTrimmedStringList } from "../shared/string-normalization.js";
|
||||
import { isRecord } from "../utils.js";
|
||||
import { parseJsonWithJson5Fallback } from "../utils/parse-json-compat.js";
|
||||
import {
|
||||
normalizeManifestCommandAliases,
|
||||
type PluginManifestCommandAlias,
|
||||
@@ -1178,7 +1178,7 @@ export function loadPluginManifest(
|
||||
}
|
||||
let raw: unknown;
|
||||
try {
|
||||
raw = JSON5.parse(fs.readFileSync(opened.fd, "utf-8"));
|
||||
raw = parseJsonWithJson5Fallback(fs.readFileSync(opened.fd, "utf-8"));
|
||||
} catch (err) {
|
||||
return {
|
||||
ok: false,
|
||||
|
||||
Reference in New Issue
Block a user