fix(hooks): store a hook delivered twice only once
A doubled hook registration (plugin + leftover checkout install) POSTs every event twice with a byte-identical payload, so the timeline showed each row twice and token/alert/lane side effects ran twice. POST /api/hooks/event now skips a payload identical to the session's LATEST event from the last 10s (findRecentDuplicateEvent). Latest-only keeps two legitimately identical Stop events of consecutive turns, which always have other events between.
This commit is contained in:
@@ -617,6 +617,37 @@ describe("Hook Event Processing", () => {
|
||||
assert.equal(res.body.error.code, "MISSING_SESSION");
|
||||
});
|
||||
|
||||
it("stores a hook delivered twice only once (double registration)", async () => {
|
||||
const hook = {
|
||||
hook_type: "PreToolUse",
|
||||
data: {
|
||||
session_id: "hook-dup-1",
|
||||
tool_name: "Bash",
|
||||
tool_use_id: "toolu_dup_1",
|
||||
tool_input: { command: "ls", description: "List files" },
|
||||
},
|
||||
};
|
||||
const first = await post("/api/hooks/event", hook);
|
||||
const second = await post("/api/hooks/event", hook);
|
||||
assert.equal(first.status, 200);
|
||||
assert.equal(second.status, 200);
|
||||
assert.equal(second.body.duplicate, true);
|
||||
const { n } = db
|
||||
.prepare("SELECT COUNT(*) AS n FROM events WHERE session_id = 'hook-dup-1'")
|
||||
.get();
|
||||
assert.equal(n, 1);
|
||||
|
||||
// A DIFFERENT payload in the same session still lands.
|
||||
await post("/api/hooks/event", {
|
||||
...hook,
|
||||
data: { ...hook.data, tool_use_id: "toolu_dup_2" },
|
||||
});
|
||||
const after = db
|
||||
.prepare("SELECT COUNT(*) AS n FROM events WHERE session_id = 'hook-dup-1'")
|
||||
.get();
|
||||
assert.equal(after.n, 2);
|
||||
});
|
||||
|
||||
it("should auto-create session and main agent on first PreToolUse", async () => {
|
||||
const res = await post("/api/hooks/event", {
|
||||
hook_type: "PreToolUse",
|
||||
|
||||
Reference in New Issue
Block a user