Repository navigation
feat: Herdr restores panes through ak, ak last, release v1.2.0 - #41
Open
xergioalex wants to merge 2 commits into
Open
xergioalex wants to merge 2 commits into
xergioalex wants to merge 2 commits into
Conversation
…minal Herdr restores an agent pane from the session id the CLI's integration reports and, by default, restarts the bare CLI (`claude --resume <id>`): no profile home, no key from the env file, no autonomy flag - the session is not found, the wrong account opens, or the CLI asks for a login. - lib/restore.py: an interactive `ak <kind> [@Profile]` inside a Herdr pane starts a detached watcher that re-reports each new session id with resume_argv `ak <kind> @<profile> [--ask] --resume <id>` (same source and agent, later seq). It reports again on every id change because Herdr keeps an older resume_argv when a later report omits it. It exits with the CLI, writes nothing, and gets no key or token. macOS, Linux and Windows; AGENTKIT_HERDR_RESUME=0 turns it off. - lib/last.py: every interactive launch records kind, profile and posture per directory (launches.json in the state dir, 0600); `ak last` relaunches it with -c, `ak last -r` opens the picker, `ak last ls` lists. - Tests: tests/py/restore_checks.py (also run natively on Windows CI) and the `restore` scope with a fake herdr; the security scope accounts for the launch record. - Docs: profiles, SECURITY, TESTING_GUIDE, README, skill, env template, CHANGELOG. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Version 1.2.0 in every version source: lib/common.py, the three skills' metadata, the install and skill commands in the README and docs, the schemas' $id, the issue template, the tests that assert it, and the addon registry (.dwp/config.json). - CHANGELOG 1.2.0 (dated 2026-10-27): the Herdr resume watcher and `ak last`; link references for 1.2.0. - SECURITY.md lists 1.2.0 as latest. - Interface stays 1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
After a reboot or a Herdr restart, Herdr reopens each agent pane from the session id the CLI's Herdr integration reported, and by default runs the bare CLI:
claude --resume <id>,grok --resume <id>. Withoutakthe CLI has no profile home, no key from the env file and no autonomy flag, so:ak claude @work1) is looked up in~/.claudeand not found, or opens in the wrong account;ak grokwithXAI_API_KEYin the env file) shows its login menu.Outside Herdr there was no short way back to "the last agent I ran here" without remembering its kind and profile.
What changes
Herdr resumes through
ak(lib/restore.py)Herdr's
pane.report_agent_sessionaccepts aresume_argv, which is the command Herdr runs on restore. An interactiveak <kind> [@profile]inside a Herdr pane (HERDR_ENV=1,HERDR_PANE_ID) now starts a small detached watcher next to the CLI. Each time Herdr records a new session id for that CLI, the watcher reports it again with:The report keeps Herdr's own source and agent and uses a later seq.
resume_argv, even with a different id, keeps the earlierresume_argv. After a/clear, Herdr would otherwise resume the previous conversation.@defaultincluded. A default profile set later cannot move the session to another account.--askis kept for opted-out launches, and provider variants keep their kind.herdrCLI, not a raw socket. Liveness usesos.kill(pid, 0)on POSIX andOpenProcess/WaitForSingleObjecton Windows, whereos.killwould terminate the process. The watcher detaches with a double fork on POSIX and withDETACHED_PROCESSon Windows.PATH, the home and temp variables andHERDR_*, so no key, token or profile home reaches it. It writes nothing, prints nothing and exits with the CLI.ak profiles hooks <cli> @name.AGENTKIT_HERDR_RESUME=0.ak last(lib/last.py)Every interactive launch records its kind, profile and posture per working directory, in
launches.jsonin the state dir (mode 0600, the 200 most recent directories, no key or session id).ak lastrelaunches it with-c.ak last -ropens the CLI's picker in that account.ak last lslists the record.ak runis not recorded.Interface
Interface stays 1:
ak doctor --json,ak envandak runare unchanged. New: theak lastsubcommand and theAGENTKIT_HERDR_RESUMEvariable.Tests
tests/py/restore_checks.py(python only, added to the native Windows CI step) covers:restorescope: the real launcher with a fakeherdr. It checks the reported command forclaude @workand forgrokwith@defaultand--ask, that no key reaches the watcher, that Herdr is never called outside a pane or with the opt-out, and theak last,ak last -randak last lsflows.securityscope: the trust-cwd write check now excludeslaunches.jsonand checks separately that the file is 0600 and holds no key.bash tests/run.shgivespassed: 2452 failed: 0 skipped: 1.bash scripts/check-public-hygiene.shis clean.Verified by hand on macOS with Herdr 0.9.5
ak claude @work1andak grok(API key,@default) in real panes. Herdr'ssession.jsonstoredagent_resume.argv = ["ak","claude","@work1","--resume",<id>]and["ak","grok","@default","--resume",<id>].@work1session. Each watcher exited with its CLI.Release
This PR also carries the v1.2.0 release commit (version sources, dated CHANGELOG section, SECURITY.md), following the v1.1.0 convention. After merge, the annotated tag
v1.2.0on the merge commit triggersrelease.yml(tarball, SHA256SUMS, notes).🤖 Generated with Claude Code