Repository navigation
Release 0.1.0 - #1
Merged
Merged
Conversation
Arms work, turns agent hook events into alarm events, and sends them to the phone through ntfy. Zero runtime dependencies, Node 22+. Hooks print nothing, always exit 0 and send from a detached process. Only armed work rings, and nothing but the protocol's fields leaves the computer; both have tests (32 in all). Also installs into Codex as user-level hooks plus a personal skill.
Stop, StopFailure, Notification (permission prompts) and UserPromptSubmit hooks; the /code-alarm:alarm skill, generated from the same source as the Codex one; and code-alarm on the PATH through bin/. Both manifests pass claude plugin validate.
…proval Owner testing in Codex found that the model's code-alarm done needed approval, since it writes outside the sandbox, and the PermissionRequest hook turned that into a needs-you alarm two seconds before done. Unattended, done would have waited for an approval nobody could give. Now the Claude Code skill pre-approves code-alarm via allowed-tools, and install codex writes a rules file allowing only code-alarm's own commands. Both agents' PermissionRequest hooks recognise those commands: a pending done, needs-you or failed counts as that signal, and the rest are ignored. Claude Code's needs-you comes from PermissionRequest instead of Notification, which doesn't say what's waiting. Arming can be --notify, which sends one ordinary notification (ntfy priority 3) instead of the alarm; events carry a level field. 38 tests.
The owner's quiet test arrived silently: ntfy's default priority (3) shows no pop-up, and on this Samsung no vibration either. A notify should get attention once, so it is now ntfy priority 4 (high): pop-up, sound and vibration, without the keep-alerting loop that only applies to 5. The local log now records each send's level.
F13: the rules file works. Codex on Windows wraps each command in PowerShell but unwraps it before matching, so the ["node", <cli>, ...] prefix matches (verified with codex exec). The owner's test still asked because the Codex processes had been running since before the rules file was written, and Codex reads rules only at startup.
- Own-command detection parses the command line (quotes, separators, shell wrappers) instead of matching text, so `echo code-alarm done` or a commit message no longer counts as the done signal, and `code-alarm done;` does. - "Signalled this turn" is kept per agent session (CLAUDE_CODE_SESSION_ID, CODEX_THREAD_ID), so one session's signal can't silence another's Stop, even when a nap and a project arming both cover the folder. - A project arming is claimed (atomic rename) before its alert is sent, so two racing hooks send one alert. Re-arming resets the needs_input limit. - install codex writes the rules with JSON-quoted strings and token-list examples (a path with an apostrophe broke them), refuses paths with " $ `, backs up rules or skill files it didn't write, and uninstall removes only its own files. - status never prints any part of the topic; init --force works on a broken config; a hook no longer waits for an agent that keeps stdin open. - The npm package includes LICENSE and README; the marketplace description moves to metadata, so `claude plugin validate .` passes cleanly.
- Own-command detection follows plain `cd`s, so `cd B && code-alarm done` signals B, and gives up on anything it can't follow ($(...), backticks, `cd $HOME`), which then counts as an ordinary approval. - An end-of-turn hook that fires twice for one turn sends once: its event ID is claimed (a create-exclusive file under events/, cleared after a day). - A signal is recorded before the arming is claimed, and a failure to record it no longer drops the alert. - A hook that read an older arming can't use up a newer one: the claim checks the arming it renamed and puts a fresh one back. - The installed Codex skill carries its own ownership comment; a skill that merely has a "# Code Alarm" heading is someone else's.
- Brackets (subshells, groups) make a command line unknown, so `(cd ../b); code-alarm done` is an ordinary approval. - A signal wins over a silent code-alarm command beside it: `code-alarm status; code-alarm done` is the done signal. - Pruning old event claims tolerates another hook deleting them first, so the exclusive claim is always attempted. - Restoring a re-armed arming uses a hard link, which never replaces an even newer one. - A claim that fails for any reason but "already used" (e.g. a file held open on Windows) removes the arming and still sends, instead of leaving a false "already sent".
Codex runs PermissionRequest hooks before it decides who answers, and its auto-review usually approves within a second or two, so an armed session was paged for escalations nobody needed to approve (F14). A command already approved for the session fires the hook too. The payload can't tell these apart, and permission_mode only reflects the approval policy. So a Codex request is now recorded as pending (hashes of the session and the command, never the command) and a detached waiter sends needs_input 45 s later only if it's still pending. install codex adds an async PostToolUse hook: the command running answers its request. Stop, StopFailure and UserPromptSubmit clear the session's requests. If the request can't be recorded, needs_input goes out at once as before. Claude Code is unchanged.
Draganoider
marked this pull request as ready for review
October 15, 2026 00:32
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.
What this changes
The first release, 0.1.0: the
code-alarmCLI, the Claude Code plugin and its marketplace, andcode-alarm install codex. It rings the phone through ntfy when armed Claude Code or Codex workfinishes, stops or needs you. Details in CHANGELOG.md.
Merged and tagged on 14 October 2026; the repository is public and
code-alarm@0.1.0is on npm.Checks
cd cli && npm run checkpasses (67 tests), and the rebuilt bundle, plugin binary and skill are committedcli/test/privacy.test.tspasses, and the protocol is unchanged (or bumped)## [Unreleased]inCHANGELOG.mdRelease steps
cli/package.jsonandplugins/claude-code/.claude-plugin/plugin.jsonclaude plugin validate .passes;npm pack --dry-runships the bundle, LICENSE and READMEcode-alarmto npm fromcli/(an npm account with 2FA):code-alarm@0.1.0, shasumfade13fb…## [Unreleased]to## [0.1.0] — 2026-10-14in the changelog, ontestv0.1.0onmainclaude plugin marketplace add Draganoider/code-alarm)