Skip to content

claude: a SessionEnd hook that leaves a resume task on taskbook - #191

Closed
alycda wants to merge 3 commits into
developfrom
claude-session-taskbook
Closed

alycda wants to merge 3 commits into
developfrom
claude-session-taskbook

Conversation

@alycda

@alycda alycda commented Sep 30, 2026

Copy link
Copy Markdown
Owner

Summary

Stacked on mise-taskbook (ae9124e), which puts tb in the global mise tools.

Every Claude Code session now leaves one task on tb's @claude board when it ends:

resume: claude --resume <session id> (in <directory>, <reason>)

Claude's SessionEnd hook gives the script only the session id, cwd and end reason (clear, resume, logout, prompt_input_exit, other), so the task is a resume pointer, not a summary.

  • tools/claude/hooks/session-end-taskbook.sh: the hook. Exits 0 whatever happens, so a missing tb can't stall Claude's exit. Finds tb on PATH, then through ~/.local/bin/mise, since the desktop app's hook environment has no mise activation. A session that ends twice is found by ID and not added again. @ in the cwd is replaced (tb reads @word as a board). TASKBOOK_DIR points it at another data dir.
  • tools/claude/hooks.json + tools/claude/install-hooks: the settings entry, merged into ~/.claude/settings.json by mise run claude-hooks. A merge, not a [dotfiles] link: Claude writes theme, model and tui into that file. Keeps hand-added hooks; a second run changes nothing. jq joins the root tools for it.
  • mise.toml: links the script to ~/.claude/hooks/, adds jq, adds the claude-hooks task (manual, like the others).
  • .devcontainer/mise/devcontainer.json: bind-mounts the host's ~/.taskbook and runs claude-hooks at create, so a session in the container lands on the same board.
  • tasks/20260930-061909: docker/dev.sh (main) and the Nix devcontainer are not covered. They have no tb (none in lib/packages.nix, by the choice in tools/mise/global.toml), and dev.sh's ~/.claude is the claude-home volume. The task lists the three pieces.

Nothing on the host was changed by this PR. To turn it on for an account: mise dotfiles apply then mise run claude-hooks.

Testing

  • tests/claude-hooks.bats: 9 tests, stubbed tb, cover the hook (task text, dedupe, @ in cwd, TASKBOOK_DIR, no tb, empty input) and the installer (keeps Claude's keys, keeps a hand-added hook, idempotent, creates the file).
  • tests/mise.bats still passes with the new [dotfiles] entry.
  • End to end against real tb 1.5.0 in a scratch TASKBOOK_DIR, with env -i and no mise activation: task created, second end deduped, mise fallback found tb, about 20 ms per run (SessionEnd's default budget is 1.5 s; hooks.json sets a 10 s timeout, which raises it).
  • shellcheck, editorconfig-checker, biome on the devcontainer json, devcontainer read-configuration resolves the mount, mise fmt --check.
  • devcontainer up of the mise devcontainer with the new mount: not run.
  • mise run claude-hooks on a real account, then a real session end: not run, by design of this PR.

rumdl flags README.md:52 (the home-manager switch command); that line predates this PR.

🤖 Generated with Claude Code

@alycda
alycda added this pull request to stack #193 September 30, 2026 06:25
Base automatically changed from mise-taskbook to develop October 16, 2026 08:48
alycda and others added 3 commits October 16, 2026 01:48
Where a session left off used to live only in its transcript, which on the
mise account is mostly inside docker volumes. Claude Code's SessionEnd hook
now runs tools/claude/hooks/session-end-taskbook.sh, which puts one task per
session on tb's @claude board:

    resume: claude --resume <id> (in <dir>, <reason>)

Claude sends the hook only the session's id, cwd and end reason, so the task
is a pointer to resume from, not a summary.

The script never fails: it exits 0 whatever happens, so a missing tb can't
stall Claude's exit, and it finds tb through mise when the hook's environment
(the desktop app's) has no mise activation. A session that ends twice (/clear,
then the terminal closes) is found by its ID and not added again. An @ in the
cwd is replaced, since tb reads @word out of a description as a board.

Only the script is a [dotfiles] link. The settings entry is merged into
~/.claude/settings.json by tools/claude/install-hooks (`mise run
claude-hooks`), because Claude writes theme, model and tui into that file, so
a link would track them too. The merge keeps hooks added by hand and changes
nothing the second time. jq joins the root tools for it.

tests/claude-hooks.bats stubs tb and covers the hook and the installer.
SessionEnd hooks share a 1.5 s budget unless a per-hook timeout raises it, so
hooks.json sets 10 s; a real run against tb 1.5.0 takes about 20 ms.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Bind-mount the host's ~/.taskbook, so tb inside and outside the container
show one board, and run `mise run claude-hooks` at create, so a Claude session
in the container leaves its resume task like one on the host does. A volume
would be a second board that nothing outside reads. tb takes storage.lock
around writes, so a host session and a container session ending together is
fine.

The Nix devcontainer and docker/dev.sh (on main) are not covered: there is no
tb in lib/packages.nix yet, by the choice in tools/mise/global.toml. The
follow-up is in tasks/.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
What a dev.sh container (main) needs before a Claude session in it reaches
the @claude board: tb in the image, the host's ~/.taskbook mounted, and the
hook merged into the claude-home volume's settings.json.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
@alycda
alycda force-pushed the claude-session-taskbook branch from 712df4c to 7f8031d Compare October 16, 2026 08:48
@alycda alycda closed this Oct 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant