From 0a8885d6c1a287a04c5258b8a214097b6a9b2ac0 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Thu, 19 Mar 2026 09:51:43 -0700 Subject: [PATCH] fix(ci): restore hook and guardrail tests --- src/commands/channels.mock-harness.ts | 5 +- src/hooks/workspace.ts | 52 +++++++------------ src/plugin-sdk/runtime-api-guardrails.test.ts | 3 +- src/wizard/setup.finalize.test.ts | 6 +++ 4 files changed, 27 insertions(+), 39 deletions(-) diff --git a/src/commands/channels.mock-harness.ts b/src/commands/channels.mock-harness.ts index d1f412b0399..6a448a9750e 100644 --- a/src/commands/channels.mock-harness.ts +++ b/src/commands/channels.mock-harness.ts @@ -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(); +vi.mock("../../extensions/telegram/api.js", async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, deleteTelegramUpdateOffset: offsetMocks.deleteTelegramUpdateOffset, diff --git a/src/hooks/workspace.ts b/src/hooks/workspace.ts index 7b86d9d23c8..351690ab9d3 100644 --- a/src/hooks/workspace.ts +++ b/src/hooks/workspace.ts @@ -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(); + const merged = new Map(); // 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( diff --git a/src/plugin-sdk/runtime-api-guardrails.test.ts b/src/plugin-sdk/runtime-api-guardrails.test.ts index 35de2096e88..a8a7f4cd769 100644 --- a/src/plugin-sdk/runtime-api-guardrails.test.ts +++ b/src/plugin-sdk/runtime-api-guardrails.test.ts @@ -36,9 +36,8 @@ const RUNTIME_API_EXPORT_GUARDS: Record = { ], "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";', diff --git a/src/wizard/setup.finalize.test.ts b/src/wizard/setup.finalize.test.ts index cd3bc67ddb7..1fee8c154f4 100644 --- a/src/wizard/setup.finalize.test.ts +++ b/src/wizard/setup.finalize.test.ts @@ -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>(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); });