refactor: move native hook relay registry to SQLite (#109289)

* refactor: store native hook relays in SQLite

* chore: satisfy relay store CI checks
This commit is contained in:
Peter Steinberger
2026-07-16 12:14:06 -07:00
committed by GitHub
parent 3f89aae98d
commit 6c39e713d4
13 changed files with 1031 additions and 289 deletions
+51
View File
@@ -6,6 +6,11 @@ import path from "node:path";
import { pathToFileURL } from "node:url";
import { afterEach, describe, expect, it } from "vitest";
import { useAutoCleanupTempDirTracker } from "../../test/helpers/temp-dir.js";
import {
registerNativeHookRelay,
testing as nativeHookRelayTesting,
} from "../agents/harness/native-hook-relay.js";
import { resolveOpenClawStateSqlitePath } from "../state/openclaw-state-db.paths.js";
const tempDirs = useAutoCleanupTempDirTracker(afterEach);
const activeChildren = new Set<ChildProcessWithoutNullStreams>();
@@ -13,6 +18,7 @@ const outputTimeoutMs = 20_000;
const exitAfterOutputTimeoutMs = 5_000;
afterEach(async () => {
nativeHookRelayTesting.clearNativeHookRelaysForTests();
await Promise.all(Array.from(activeChildren, terminateChild));
});
@@ -202,6 +208,51 @@ async function runHooksRelay(params: { event: "post_tool_use" | "pre_tool_use";
}
describe("hooks CLI process lifecycle", () => {
it("uses the explicit relay database when the child has a different state directory", async () => {
const relay = registerNativeHookRelay({
provider: "codex",
relayId: "process-explicit-state-db",
sessionId: "session-1",
runId: "run-1",
allowedEvents: ["post_tool_use"],
});
await expect
.poll(() => nativeHookRelayTesting.getNativeHookRelayBridgeRecordForTests(relay.relayId))
.toBeDefined();
const childStateDir = path.join(tempDirs.make("openclaw-hooks-relay-other-state-"), "state");
await fs.mkdir(childStateDir, { recursive: true });
const result = await runHooksCli({
args: [
"hooks",
"relay",
"--provider",
"codex",
"--relay-id",
relay.relayId,
"--state-db",
resolveOpenClawStateSqlitePath(),
"--generation",
relay.generation,
"--event",
"post_tool_use",
"--timeout",
"5000",
],
label: "hooks relay explicit state database",
env: {
OPENCLAW_DISABLE_BUNDLED_PLUGINS: "1",
OPENCLAW_NO_RESPAWN: "1",
OPENCLAW_STATE_DIR: childStateDir,
},
stdin: JSON.stringify({ hook_event_name: "PostToolUse" }),
});
expect(result, result.stderr).toMatchObject({ code: 0, signal: null });
expect(result.stderr).toBe("");
expect(result.stdout).toBe("");
}, 60_000);
it("exits after one-shot outputs when plugins leave ref'd handles", async () => {
const fixture = await createLingeringPluginFixture();