feat(init): install SessionStart auto-bootstrap hook (self-arming agents)#33
Merged
Conversation
…nts) After an IDE/CLI restart the agent sat idle until someone typed "/loop check rooms" by hand. Ship the proven 07-12 prototype as a product feature: a SessionStart hook that makes every fresh session self-arm the room loop. - scripts/session-bootstrap.sh: generic hook script. Reads the hook stdin JSON (source: startup|resume|compact), counts backlog in the poller notification file, and emits suppressed additionalContext telling the agent to arm a persistent Monitor on the file, read and clear the backlog, and keep a fallback ScheduleWakeup armed. Config via IAK_NEW_FILE / poller.notification_file, IAK_HANDLE / poller.handle, IAK_CONFIG_JSON, IAK_BOOTSTRAP_FALLBACK_SEC — same conventions as check-rooms-hook.sh and claudemb-poll.sh. Never blocks session start. - src/claude-settings.mjs: careful settings.json hook merge (dedup by command, .bak backup before first write, unrelated hooks untouched), mirroring install.sh's ensure_hook semantics. - bin/cli.mjs init: copies the script into .claude/scripts/ and merges the hook into .claude/settings.json for claude-code/antigravity. "Config already exists" no longer aborts init, so re-running upgrades existing installs; every step is guarded and idempotent. - scripts/install.sh: registers the SessionStart hook alongside UserPromptSubmit + Stop, now with a settings.json.bak backup. - test/session-bootstrap.test.mjs: hook JSON for startup/compact/empty and garbage stdin, backlog counting, env-over-config precedence, merge idempotency and preservation, and an end-to-end double-init run. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3510facf10
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
P1 (codex, #33): the bootstrap told agents to truncate the whole notification file - recreating the exact read-vs-append race #32 just fixed. Instructions now direct agents to the consumed-only room_ack MCP tool, with raw-clear only as a no-MCP fallback plus an immediate re-check. P2: install.sh skipped hook wiring entirely when ~/.claude/settings.json did not exist yet - fresh one-shot installs now get a minimal file created so self-arming works on day one. Co-Authored-By: Claude Fable 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 every IDE/CLI restart the room agent sat idle until Petrus manually typed
/loop check roomsinto the session. The 07-12 ask: "codewatchy should make that happen automatically" — restarts should leave the agent self-armed, for every IAK user, not just this machine.Lineage
This productizes the prototype that has been running in production on the Mac mini since 2026-07-12 (
~/.claude/scripts/session-bootstrap.sh+ a hand-editedSessionStartentry in~/.claude/settings.json). Same mechanism, de-petrus-ified.Design
scripts/session-bootstrap.sh— aSessionStarthook script. It reads the hook stdin JSON (source:startup|resume|compact), counts backlog lines in the poller's notification file, and emits{"suppressOutput": true, "hookSpecificOutput": {"hookEventName": "SessionStart", "additionalContext": ...}}instructing the agent to:ScheduleWakeup(~1500s),compact, verify via TaskList instead of re-arming blindly.Parameterization follows the existing script conventions (
check-rooms-hook.sh,claudemb-poll.sh):IAK_NEW_FILEenv, else configpoller.notification_file, else/tmp/iak-new-messages.txt(the poller default /NOTIFY_FILE_DEFAULT);IAK_HANDLEenv, elsepoller.handle;IAK_CONFIG_JSONenv, elseide-agent-kit.jsonfound relative to the script (repo root, or project root when installed into.claude/scripts/). Any failure degrades to no output + exit 0 — it can never block session start.Wiring, both existing install paths:
ide-agent-kit init --ide claude-code(and antigravity): copies the script into.claude/scripts/and merges the hook into.claude/settings.jsonvia the newsrc/claude-settings.mjshelper. Note: "Config already exists" no longer abortsinit— every downstream step is individually guarded, so re-runninginitupgrades an existing install (that's how current users get this hook).scripts/install.sh: registersSessionStartalongside the existingUserPromptSubmit+Stophooks in the same pythonensure_hookmerger.Idempotency & safety
ensure_hook) — runninginitor the installer twice adds nothing.settings.json.bakbackup taken before the first mutating write (repo.bakconvention); no backup churn on no-op runs.Test coverage (
test/session-bootstrap.test.mjs, 14 tests)startup,compact, empty stdin, and non-JSON stdinpoller.notification_file,poller.handle) are honored; env overrides beat config.bakbackup on change, creates file when missing (temp-dir fixtures)iak init --ide claude-codetwice in a temp cwd → exactly one hook entrynpm test: 134 pass, 0 fail.bash -nclean on both shell scripts; install.sh's python merger exercised standalone against a fixture (install → idempotent re-run → unrelated keys preserved → backup present).Review
@codexmb — adversarial review requested per the cross-model PR review rule, before merge.
🤖 Generated with Claude Code