Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### Fixed

- Parse OpenClaw hook names after their source declaration became private and added a TypeScript `satisfies` constraint.
- Run synthetic gateway lifecycle hooks around ordinary probes while preserving capture indexes and report order, so `gateway_stop` teardown cannot invalidate later compatibility checks.
- Link isolated plugin workspaces to the OpenClaw checkout without npm normalizing duplicated dependency and peer declarations back to registry ranges.
- Keep mocked Zod schemas chainable through unsupported methods such as `pipe()` and `catch()`.
Expand Down
11 changes: 10 additions & 1 deletion src/openclaw-target.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export async function readOpenClawTargetSurface(options = {}) {
const registrySource = await readFile(registryPath, "utf8");
const compatRecordEntries = parseCompatRecordEntries(registrySource);
const hookTypesSource = existsSync(hookTypesPath) ? await readFile(hookTypesPath, "utf8") : "";
const hookNames = hookTypesSource ? parseExportedStringArray(hookTypesSource, "PLUGIN_HOOK_NAMES") : [];
const hookNames = hookTypesSource ? parseConstStringArray(hookTypesSource, "PLUGIN_HOOK_NAMES") : [];
const apiBuilderSource = existsSync(apiBuilderPath) ? await readFile(apiBuilderPath, "utf8") : "";
const apiRegistrars = apiBuilderSource ? parseApiRegistrars(apiBuilderSource) : [];
const manifestTypesSource = existsSync(manifestTypesPath) ? await readFile(manifestTypesPath, "utf8") : "";
Expand Down Expand Up @@ -198,6 +198,15 @@ export function parsePluginSdkExports(packageJson) {

export function parseExportedStringArray(source, exportName) {
const match = source.match(new RegExp(`export\\s+const\\s+${exportName}\\s*=\\s*\\[([\\s\\S]*?)\\]\\s+as\\s+const`));
return parseStringArrayMatch(match);
}

function parseConstStringArray(source, constName) {
const match = source.match(new RegExp(`(?:export\\s+)?const\\s+${constName}\\s*=\\s*\\[([\\s\\S]*?)\\]\\s+as\\s+const`));
return parseStringArrayMatch(match);
}

function parseStringArrayMatch(match) {
if (!match) {
return [];
}
Expand Down
2 changes: 1 addition & 1 deletion test/openclaw-target.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ test("OpenClaw target parser reads public target surface facts", async (t) => {
);
await writeFile(
path.join(targetRoot, "src/plugins/hook-types.ts"),
`export const PLUGIN_HOOK_NAMES = ["before_tool_call", "llm_input"] as const;\n`,
`const PLUGIN_HOOK_NAMES = ["before_tool_call", "llm_input"] as const satisfies readonly PluginHookName[];\n`,
"utf8",
);
await writeFile(
Expand Down
Loading