Skip to content

Release 0.1.0 - #1

Merged
Draganoider merged 15 commits into
mainfrom
test
Oct 15, 2026
Merged

Draganoider merged 15 commits into
mainfrom
test

Conversation

@Draganoider

@Draganoider Draganoider commented Oct 14, 2026 •

Copy link
Copy Markdown
Owner

What this changes

The first release, 0.1.0: the code-alarm CLI, the Claude Code plugin and its marketplace, and
code-alarm install codex. It rings the phone through ntfy when armed Claude Code or Codex work
finishes, stops or needs you. Details in CHANGELOG.md.

Merged and tagged on 14 October 2026; the repository is public and code-alarm@0.1.0 is on npm.

Checks

  • cd cli && npm run check passes (67 tests), and the rebuilt bundle, plugin binary and skill are committed
  • Nothing new leaves the computer: cli/test/privacy.test.ts passes, and the protocol is unchanged (or bumped)
  • Hooks still print nothing and exit 0
  • A line under ## [Unreleased] in CHANGELOG.md
  • No attribution lines in commits or this description

Release steps

  • Version 0.1.0 in cli/package.json and plugins/claude-code/.claude-plugin/plugin.json
  • A Codex review of the whole repository, three rounds, with fixes
  • claude plugin validate . passes; npm pack --dry-run ships the bundle, LICENSE and README
  • Codex auto-review and "needs you": fixed (approvals ring only when unanswered for 45 s)
  • Owner: make the repository public and turn on private vulnerability reporting
  • Owner: publish code-alarm to npm from cli/ (an npm account with 2FA): code-alarm@0.1.0, shasum fade13fb…
  • Rename ## [Unreleased] to ## [0.1.0] — 2026-10-14 in the changelog, on test
  • Merge with a merge commit, then tag v0.1.0 on main
  • Install from the marketplace on a clean machine (claude plugin marketplace add Draganoider/code-alarm)

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
Draganoider marked this pull request as ready for review October 15, 2026 00:32
@Draganoider
Draganoider merged commit b200a85 into main Oct 15, 2026
15 checks passed
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