Add post-flush command hook - #277
Conversation
There was a problem hiding this comment.
Pull request overview
Adds an optional “post-flush” hook that runs a user-configured shell command after an in-session annotation flush (O), piping the exact annotation snapshot on stdin and executing via Bubble Tea’s terminal handoff so helpers can write to /dev/tty (e.g., OSC 52), then restoring mouse tracking.
Changes:
- Introduces
--post-flush-command(CLI/env/config) and wires it at the composition root into the UI via a consumer-sidePostFlushHookinterface. - Adds
app/handoffto construct anexec.Cmdthat reads the flush snapshot from stdin while discarding stdout. - Extends the UI flush path (
app/ui/output.go) to run the optional hook viatea.ExecProcess, with tests and documentation updates.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| site/docs.html | Documents --post-flush-command and provides an OSC 52 example helper script. |
| README.md | Adds the new flag to the options table and documents the OSC 52 post-flush workflow. |
| docs/ARCHITECTURE.md | Updates architecture map/data flow and documents the new app/handoff subsystem and UI interface. |
| CLAUDE.md | Updates repo structure overview with the new app/handoff package. |
| app/ui/output.go | Runs optional post-flush hook after a successful atomic O flush via tea.ExecProcess and restores mouse tracking. |
| app/ui/output_test.go | Adds unit tests for hook invocation and completion handling. |
| app/ui/model.go | Adds PostFlushHook interface, injects it via ModelConfig, and handles the completion message in Update. |
| app/main.go | Wires handoff.New(opts.PostFlushCommand) into ui.ModelConfig.PostFlushHook. |
| app/handoff/handoff.go | Implements the hook runner producing sh -c <command> with snapshot on stdin and stdout discarded. |
| app/handoff/handoff_test.go | Tests that stdin snapshot is delivered to the command as expected and validates empty-command behavior. |
| app/config.go | Adds --post-flush-command option with env/config support and trims whitespace. |
| app/config_test.go | Tests flag/env/config precedence and ensures dump-config includes the new key. |
| .claude/rules/gotchas.md | Updates internal documentation for the output flush path to include the optional post-flush hook behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
umputun
left a comment
There was a problem hiding this comment.
lgtm, happy to merge. Build/test/lint/race green, exec surface is clean (snapshot is stdin-only, command is user-config, no injection), mouse-restore matches the editor path, and the typed-nil PostFlushHook is handled.
a few nice-to-fix items, none blocking:
handleFlushOutputformats the snapshot twice on the hook path:store.WriteFileformats internally, thenstore.FormatOutput()runs again for the hook stdin (app/ui/output.go:387). Same goroutine and the store isn't mutated between them, so it's correct, just redundant. Could format once and hand the same string to both the write and the hook.- the flag description "run command after flushing annotations" doesn't say it fires on the
Oflush and so needs-o. Worth a word, otherwise someone sets--post-flush-command=pbcopyon its own and wonders whyOdoes nothing. - the hook runs synchronously through
tea.ExecProcess, so a hung command blocks the TUI until it returns (and SIGTERM can't quit meanwhile). Same as the$EDITORpath, so nothing new, but since this one fires automatically on everyOa one-line doc note that it should be a fast, non-interactive command wouldn't hurt.
on whether it should need -o at all: your r-branch flow already writes --output then pipes through osc-copy, so the coupling matches how you use it. Fine as is.
|
Thanks — all three nits were applied in 5981dbe:
I also considered allowing the post-flush hook to run standalone without an output file. That does make sense as a follow-up, but I kept the existing coupling here to avoid expanding the scope and blowing up this diff. |
|
all three look good. Returning the snapshot from |
Source: #113 (reply in thread)
Summary
Oflush/dev/tty, then restore mouse trackingVerification
make testmake lintmake build