Files
ai-agent/backend/meta.py
Gabriel Vidal 8dcd4183d5 feat(hooks): conversation-done hooks — follow-up prompts after a task finishes
Settings → Hooks, cron's twin for the other end of a task: instead of a
schedule it has an event (conversation-done) + a delay, and a firing resumes
the conversation that just finished rather than spawning a new one.

Seeded with an enabled `post-task` hook (delay 1 min) whose prompt asks the
agent to save memories on the tricky parts, update README/CLAUDE.md, copy
artefacts into .ai/artefacts/, tear down worktrees and processes, and update
the changelog.

- backend/hooks.py: HookStore (/data/hooks.json — hooks + a persistent pending
  queue) and a 10s HookScheduler daemon; the scheduler claims an entry off the
  queue before firing, so a deploy cutover can't double-resume.
- backend/main.py: /api/hooks CRUD + /run + /prompt, read-only /api/claude-hooks
  (the repo's native .claude/settings.json hooks), _enqueue_hooks on both finish
  paths (exit watcher + POST /api/notify), _fire_hook, due-time preconditions.
- backend/meta.py: meta.hooks {hookId: iso} merged, not replaced — that mapping
  is the once-per-hook-per-session loop guard, without which the follow-up's own
  DONE would re-trigger the hook forever.
- frontend: Hooks page (delay/skip/cap controls, prompt editor, pending queue,
  run history, native-hooks section), route + settings category, HookBadge on
  conversation cards and detail, api/queries/SSE/optimistic wiring, mock backend
  handlers + seed.

Skips cron-spawned sessions and subagent conversations by default; no transcript
cap. Native-hook editing stays out — writing .claude/settings.json from the
container is host-level code execution.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 18:51:49 +02:00

8.5 KiB