fix(ci): restore hook and guardrail tests

This commit is contained in:
Vincent Koc 2026-03-19 09:51:43 -07:00
parent cb552bcc42
commit 0a8885d6c1
4 changed files with 27 additions and 39 deletions

View File

@ -24,9 +24,8 @@ vi.mock("../config/config.js", async (importOriginal) => {
};
});
vi.mock("../../extensions/telegram/src/update-offset-store.js", async (importOriginal) => {
const actual =
await importOriginal<typeof import("../../extensions/telegram/src/update-offset-store.js")>();
vi.mock("../../extensions/telegram/api.js", async (importOriginal) => {
const actual = await importOriginal<typeof import("../../extensions/telegram/api.js")>();
return {
...actual,
deleteTelegramUpdateOffset: offsetMocks.deleteTelegramUpdateOffset,

View File

@ -10,8 +10,8 @@ import { resolveBundledHooksDir } from "./bundled-dir.js";
import { shouldIncludeHook } from "./config.js";
import {
parseFrontmatter,
resolveOpenClawMetadata,
resolveHookInvocationPolicy,
resolveOpenClawMetadata,
} from "./frontmatter.js";
import { resolvePluginHookDirs } from "./plugin-hooks.js";
import type {
@ -256,69 +256,53 @@ function loadHookEntries(
});
const bundledHooks = bundledHooksDir
? loadHooksFromDir({
? loadHookEntriesFromDir({
dir: bundledHooksDir,
source: "openclaw-bundled",
})
: [];
const extraHooks = extraDirs.flatMap((dir) => {
const resolved = resolveUserPath(dir);
return loadHooksFromDir({
return loadHookEntriesFromDir({
dir: resolved,
source: "openclaw-workspace", // Extra dirs treated as workspace
});
});
const pluginHooks = pluginHookDirs.flatMap(({ dir, pluginId }) =>
loadHooksFromDir({
loadHookEntriesFromDir({
dir,
source: "openclaw-plugin",
pluginId,
}),
);
const managedHooks = loadHooksFromDir({
const managedHooks = loadHookEntriesFromDir({
dir: managedHooksDir,
source: "openclaw-managed",
});
const workspaceHooks = loadHooksFromDir({
const workspaceHooks = loadHookEntriesFromDir({
dir: workspaceHooksDir,
source: "openclaw-workspace",
});
const merged = new Map<string, Hook>();
const merged = new Map<string, HookEntry>();
// Precedence: extra < bundled < plugin < managed < workspace (workspace wins)
for (const hook of extraHooks) {
merged.set(hook.name, hook);
for (const entry of extraHooks) {
merged.set(entry.hook.name, entry);
}
for (const hook of bundledHooks) {
merged.set(hook.name, hook);
for (const entry of bundledHooks) {
merged.set(entry.hook.name, entry);
}
for (const hook of pluginHooks) {
merged.set(hook.name, hook);
for (const entry of pluginHooks) {
merged.set(entry.hook.name, entry);
}
for (const hook of managedHooks) {
merged.set(hook.name, hook);
for (const entry of managedHooks) {
merged.set(entry.hook.name, entry);
}
for (const hook of workspaceHooks) {
merged.set(hook.name, hook);
for (const entry of workspaceHooks) {
merged.set(entry.hook.name, entry);
}
return Array.from(merged.values()).map((hook) => {
let frontmatter: ParsedHookFrontmatter = {};
const raw = readBoundaryFileUtf8({
absolutePath: hook.filePath,
rootPath: hook.baseDir,
boundaryLabel: "hook directory",
});
if (raw !== null) {
frontmatter = parseFrontmatter(raw);
}
return {
hook,
frontmatter,
metadata: resolveOpenClawMetadata(frontmatter),
invocation: resolveHookInvocationPolicy(frontmatter),
};
});
return Array.from(merged.values());
}
export function buildWorkspaceHookSnapshot(

View File

@ -36,9 +36,8 @@ const RUNTIME_API_EXPORT_GUARDS: Record<string, readonly string[]> = {
],
"extensions/googlechat/runtime-api.ts": ['export * from "openclaw/plugin-sdk/googlechat";'],
"extensions/matrix/runtime-api.ts": [
'export * from "openclaw/plugin-sdk/matrix";',
'export * from "./src/auth-precedence.js";',
'export { findMatrixAccountEntry, hashMatrixAccessToken, listMatrixEnvAccountIds, resolveConfiguredMatrixAccountIds, resolveMatrixChannelConfig, resolveMatrixCredentialsFilename, resolveMatrixEnvAccountToken, resolveMatrixHomeserverKey, resolveMatrixLegacyFlatStoreRoot, sanitizeMatrixPathSegment } from "./helper-api.js";',
'export * from "./helper-api.js";',
],
"extensions/nextcloud-talk/runtime-api.ts": [
'export * from "openclaw/plugin-sdk/nextcloud-talk";',

View File

@ -28,6 +28,9 @@ const resolveGatewayInstallToken = vi.hoisted(() =>
})),
);
const isSystemdUserServiceAvailable = vi.hoisted(() => vi.fn(async () => true));
const readSystemdUserLingerStatus = vi.hoisted(() =>
vi.fn(async () => ({ user: "test-user", linger: "yes" as const })),
);
const resolveSetupSecretInputString = vi.hoisted(() =>
vi.fn<() => Promise<string | undefined>>(async () => undefined),
);
@ -99,6 +102,7 @@ vi.mock("../daemon/service.js", () => ({
vi.mock("../daemon/systemd.js", () => ({
isSystemdUserServiceAvailable,
readSystemdUserLingerStatus,
}));
vi.mock("../infra/control-ui-assets.js", () => ({
@ -153,6 +157,8 @@ describe("finalizeSetupWizard", () => {
resolveGatewayInstallToken.mockClear();
isSystemdUserServiceAvailable.mockReset();
isSystemdUserServiceAvailable.mockResolvedValue(true);
readSystemdUserLingerStatus.mockReset();
readSystemdUserLingerStatus.mockResolvedValue({ user: "test-user", linger: "yes" });
resolveSetupSecretInputString.mockReset();
resolveSetupSecretInputString.mockResolvedValue(undefined);
});