Message your Claude Code agents from your phone — and wake idle terminal sessions hours later, exactly where you left them.
curl;
you read and reply in this portal or the installed phone app, with real push notifications.listen.js). The listener long-polls the server for hours at zero token cost
and exits the moment you send a message — and Claude Code wakes an idle session
whenever one of its background tasks exits. Your message lands in the real terminal
session, scrollback intact.Log into the VM, open PowerShell, paste:
irm https://ping.helixai.ca/install.ps1 | iex
The installer (≈3 seconds, idempotent — re-run any time):
listen.js, stop-hook.js and install-hook.js
into %USERPROFILE%\.helixping~/.claude/settings.json — existing settings and
hooks are preservedClaude Code sessions that are already open load the new hook after you type
/hooks once in them (or restart the session). New sessions get it automatically.
Requires Node 18+ on the VM (all helix VMs have it).
mkdir "$env:USERPROFILE\.helixping"
curl.exe -s -o "$env:USERPROFILE\.helixping\listen.js" https://ping.helixai.ca/client/listen.js
curl.exe -s -o "$env:USERPROFILE\.helixping\stop-hook.js" https://ping.helixai.ca/client/stop-hook.js
curl.exe -s -o "$env:USERPROFILE\.helixping\install-hook.js" https://ping.helixai.ca/client/install-hook.js
node "$env:USERPROFILE\.helixping\install-hook.js"
Tell any agent:
Create a HelixPing channel so I can reach you from my phone:
POST https://ping.helixai.ca/channel with JSON {"name":"<topic>","agent":"<your name>"}
then follow the "prompt" field in the response exactly.
The channel appears in your app with a push notification.
| Indicator | Meaning |
|---|---|
| listening | Listener is parked. Your message wakes the agent within seconds. |
| asleep | No live listener. Either the agent is mid-task (the Stop hook hands it your message when it finishes) or the session is gone. |
| Force nudge | Shown only when asleep and a session is registered. Resumes the session
headless through PulseDeck (claude -p --resume).
If the terminal is still open this forks its history — use it as
“terminal is gone” recovery, not as a faster ping. |
| File | What it is |
|---|---|
| install.ps1 | The one-shot VM installer above. |
| listen.js | Background wake-up listener (Node 18+, no dependencies). |
| stop-hook.js | Claude Code Stop hook — blocks idle with unread messages / dead listener. Fail-open. |
| install-hook.js | Merges the hook into ~/.claude/settings.json safely. |
| Symptom | Fix |
|---|---|
| Hook never fires in an open session | Type /hooks once in that session (reloads config) or start a new session. |
| Listener start sits at a permission prompt | Allow node / curl.exe commands on that VM
(e.g. Bash(node *), Bash(curl.exe *) in settings permissions),
or approve with "don't ask again". |
| Did the hook install? | type "$env:USERPROFILE\.claude\settings.json" — look for
stop-hook.js under hooks.Stop. |
| Is the server seeing a session? | curl.exe -s "https://ping.helixai.ca/hook/check?session=<session-id>"
→ {"block":...}. |
| No push on the phone | App must be installed (Add to Home screen), 🔔 tapped, and Chrome notifications allowed for the site. Test via "Send test notification" in the app footer. |
JSON posts fail with invalid_json |
Windows shells mangle inline JSON — write it to a file and use
curl.exe --data "@file.json" (the prompt block shows how). |
| Call | Purpose |
|---|---|
POST /channel {name, agent} | Create a channel → code + prompt block. |
POST /msg {channel, body, client_msg_id?} | Message Will (push to his phone). |
GET /msg?channel=&since= | Read the thread; track the highest id as since. |
GET /wait?channel=&wait=25 | What the listener calls — don't call it by hand; run listen.js in the background. |
HelixPing · runs on VM-NODE-AI-S1 · open the app