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:
2026-09-23 09:18:17 +07:00
parent 1b561c22d9
commit 92cee94431
6 changed files with 66 additions and 8 deletions
+5 -3
View File
@@ -159,9 +159,11 @@ npm run install-hooks
> **Skip this entirely when the `agenthub` plugin is installed.** The plugin declares
> the same eight hooks itself (inline in `.claude-plugin/plugin.json`, each
> running `${CLAUDE_PLUGIN_ROOT}/scripts/hook-handler.js`). Running both means
> every event is POSTed twice — events carry no id, so ingest cannot deduplicate
> them and every token and cost figure doubles — as does every event in the feed
> and every subagent row (one `Agent` call producing two cards). `scripts/plugin-bootstrap.js`
> every event is POSTed twice. Events carry no id, so ingest can only drop a
> POST whose payload is byte-identical to the session's LATEST event from the last
> 10 seconds (`findRecentDuplicateEvent`, since v1.8.1) — that stops the doubled
> feed rows, token/cost figures and subagent cards, but the second hook process
> still runs on every event, so remove the duplicate registration anyway. `scripts/plugin-bootstrap.js`
> removes checkout-installed entries on session start (backup:
> `~/.claude/settings.json.agenthub-bak`) — and since v1.6.17 a settings file that
> still carries them also blocks the bootstrap's fast path (`hasLegacyHooks`),