npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

agent-activity

v1.0.9

Published

CLI for Agent Activity — let coding agents report progress to an iPhone via updatable notifications and Live Activities.

Readme

agent-activity

Command-line tool for Agent Activity — let a coding agent (or any script) report progress to your iPhone as updatable notifications and Live Activities (Lock Screen + Dynamic Island).

agent-activity speaks the AgentPacket JSON envelope defined in PACKET_SCHEMA.md. It POSTs that envelope to the Agent Activity iOS app over your LAN (http://<iphone-ip>:8473/v1/packet), or to a relay over HTTPS when you're off the local network.

  • Zero dependencies. Pure Node.js built-ins. No build step.
  • Node 18+.

Install

npm install -g agent-activity@latest

It's a single executable script: no compile step and no runtime dependencies. Use agent-activity in docs and scripts; agentactivity is installed as a secondary alias for typo-free terminal use.

For repo development, run npm link inside cli/ or call node cli/bin/agent-activity.js directly.


Codex usage + fallback delegation

agent-activity codex usage --json
agent-activity codex live --interval 60
agent-activity codex config --delegation-enabled true --target-agent claude --target-command claude --target-model sonnet
agent-activity codex delegate --dry-run

codex usage fetches Codex 5-hour and weekly usage from codex app-server and writes ~/.agent-activity/codex-usage.json. The macOS app reads that file for a local usage panel. Delegation is off by default; enable it with agent-activity codex config --delegation-enabled true. Then codex delegate starts the fallback agent once per reset window when 5-hour remaining is <=20% or weekly remaining is <=10%. Use --dry-run to print the command without launching it.


Connect

Use the same flow shown in the iPhone onboarding:

agent-activity qr

Scan the generated QR image in Agent Activity, or choose Pair with Code and enter the 10-character code printed under it. First run creates relay credentials automatically and stores them at ~/.agent-activity/config.json. Delivery defaults to auto: saved LAN host, then Bonjour-discovered LAN devices, then relay only if local delivery fails.

agent-activity config set --host 192.168.1.42 --port 8473
agent-activity config show
agent-activity up                                    show QR + short pairing code
agent-activity status                                show saved/discovered devices
agent-activity reset-pairing                         delete saved iPhone connection
agent-activity qr                                      show QR image + short pairing code
agent-activity health        # confirm the phone answers

Config is stored at ~/.agent-activity/config.json (mode 0600):

{
  "host": "192.168.1.42",
  "port": 8473,
  "relayUrl": "wss://relay.example/…",
  "token": "…",
  "via": "auto",
  "devices": [{ "id": "iphone-17e", "name": "iPhone 17e" }]
}

Off the LAN — relay

When the agent runs somewhere that can't reach the phone directly, configure a relay. In auto mode the CLI still tries local network first, then POSTs to <relay>/v1/packet?token=<token> over HTTPS.

agent-activity config set --relay wss://relay.example.com --token YOUR_TOKEN

Precedence

Every setting can come from (highest wins) flags → env vars → config file → defaults:

| Setting | Flag | Env var | Default | |---------|------------|--------------------|---------| | host | --host | AGENT_ACTIVITY_HOST | — | | port | --port | AGENT_ACTIVITY_PORT | 8473 | | relay | --relay | AGENT_ACTIVITY_RELAY | — | | token | --token | AGENT_ACTIVITY_TOKEN | — | | via | --via | AGENT_ACTIVITY_VIA | auto |

--via auto (default) prefers the LAN and falls back to the relay if the phone is unreachable. Force one with --via lan or --via relay.

Global flags work before or after the command:

agent-activity --host 192.168.1.42 ping
agent-activity ping --host 192.168.1.42

Add --json to any command for machine-readable output. Every command exits nonzero on failure.


Commands

agent-activity config set    --host <ip> [--port 8473] [--relay <wss-url>] [--token <t>] [--via auto|lan|relay]
agent-activity config show
agent-activity pair <aa1.code>                       save iPhone pairing code
agent-activity devices                               show paired/discovered iPhones in a table, including alarm status
agent-activity devices rename <id> <name>            rename saved iPhone connection
agent-activity devices remove                        delete saved iPhone connection
agent-activity health                                    GET /health on the LAN server
agent-activity ping [--to <id> | --all] connectivity check (no UI)
agent-activity blockage --project <id> --body <blocker> [--request <next step>] [--destination-url <url>]
agent-activity notify --project <id> [--name <n>] --title <t> [--destination-url <url>] [--to <id> | --all]
agent-activity notify update --id <id> --project <id> [--progress] [--body] [--status] [--image] [--to <id> | --all]
agent-activity notify dismiss --id <id> --project <id> [--to <id> | --all]
agent-activity live start    [--project <id>] [--name <n>] --title <t> [...]   → prints the activity id
agent-activity live update --id <id> --project <id> [...] (also: --id --id b, or --project p, --to <id> | --all)
agent-activity live end --id <id> --project <id> [--dismiss immediate|default|after:<sec>] [--to <id> | --all]
agent-activity alarm set     --title <t> (--at <iso-date> | --in <duration>) prints alarm UUID
agent-activity alarm cancel  --id <uuid>
agent-activity artifact <file.md|file.html> [--artifact-id id] [--title …] [--type plan] [--ttl-days 7] [--passcode 1234] [--no-notify]  publish a shareable artifact
agent-activity artifacts [--json] [--to <id> | --all] list active/archived/expired/deleted artifacts
agent-activity codex usage [--cached]                  fetch/store or show Codex usage
agent-activity codex live [--once] [--interval 120]    stream usage to Live Activity
agent-activity codex delegate [--dry-run] [--force]    start opt-in fallback agent when low
agent-activity codex config [--target-agent claude] [--target-model sonnet]
agent-activity list          [--json] [--local]         list ongoing Live Activities (aliases: ps, activities)
agent-activity logs                                      list active Live Activities
agent-activity discover                                  mDNS scan for servers on the LAN (optional)

Run agent-activity <command> --help for the full flag list of any command.

Codex usage and delegation

agent-activity codex usage reads Codex 5-hour and 7-day windows through the Codex app-server and stores the latest sample at ~/.agent-activity/codex-usage.json.

agent-activity codex usage --json
agent-activity codex live --interval 120
agent-activity codex config --delegation-enabled true --target-agent claude --target-command claude --target-model sonnet
agent-activity codex delegate --dry-run

Delegation is off by default. When enabled, it delegates from Codex to Claude when the 5-hour window has 20% or less remaining, or the weekly window has 10% or less remaining. Use cron or launchd for frequent checks:

*/5 * * * * /opt/homebrew/bin/agent-activity codex delegate >/tmp/agent-activity-codex-delegate.log 2>&1

Notifications

Blockage alerts

When an agent is blocked on user input, use blockage instead of a vague ping. It sends one updatable sound notification with the exact blocker and optional next step. Tapping it opens --destination-url, or the current Codex/ChatGPT URL from env (AGENT_ACTIVITY_DESTINATION_URL, CODEX_TASK_URL, CODEX_THREAD_URL, etc.) when available.

agent-activity blockage \
  --project build \
  --body "Missing OPENAI_API_KEY in .env" \
  --request "Add the key, then reply done"

Reuse --id to update the same blocker instead of stacking alerts. Use --dry-run --json to inspect the packet without sending it.

An updatable banner. Reuse the same --id to update it in place — no new-banner spam. If you omit --id on a fresh notify, one is generated and printed/returned so you can update it later.

# present a notification with a progress bar
agent-activity notify \
  --project deploy --name "Deploy" \
  --title "Deploying to prod" \
  --body "Uploading build…" \
  --progress 0.15 \
  --destination-url "https://example.com/report.html" \
  --id deploy-42 \
  --symbol "arrow.up.circle.fill" --tint "#0A84FF" --sound

# update it in place
agent-activity notify update --id deploy-42 --project deploy \
  --progress 0.8 --body "Running migrations…"

# remove it
agent-activity notify dismiss --id deploy-42 --project deploy

--image accepts an https://… URL, a data:image/png;base64,… data URL, or raw base64 — the phone downloads/decodes it and attaches it.

--destination-url opens when the notification is tapped.

Notification progress example (one-liner loop)

ID=build-$(date +%s)
agent-activity notify --project ci --title "CI build" --id "$ID" --progress 0.0 --body "Queued"
for p in 0.25 0.5 0.75 1.0; do
  agent-activity notify update --id "$ID" --project ci --progress "$p" --body "Building… ${p}"
  sleep 2
done
agent-activity notify update --id "$ID" --project ci --progress 1.0 --body "Done ✅" --sound

Alarms

agent-activity alarm set schedules an actual iOS AlarmKit alarm. Use it when a user asks to be reminded, called, alerted when work finishes, or alerted at a milestone. Scheduling requires alarm access enabled in Agent Activity onboarding/settings and starts a companion Live Activity shortly before the alarm. Scheduled alarms appear in the iOS Alerts tab, where the user can cancel them; CLI cancellation uses the same alarm id.

agent-activity alarm set --title "Check build" --body "Tests should be done" --in 10m --ringtone retroBell --alarm-lead-minutes 5
agent-activity alarm set --title "Review artifact" --in 10m --symbol doc.richtext.fill --tint "#34C759" --image "$IMG" --destination-url "$URL" --alarm-button-title "Open artifact"
agent-activity alarm set --title "Stand up" --at 2026-06-30T15:00:00Z
agent-activity alarm cancel --id <uuid>

--in accepts 30s, 10m, 2h, 1d. --ringtone accepts systemDefault, retroBell, digitalPulse, cosmicAlert, rhythmAlarm, or bubbleChime. --symbol, --tint, --image, --destination-url, and --alarm-button-title brand the app-owned Alerts row and companion Live Activity; native AlarmKit currently uses the title, tint, and button labels. Actual AlarmKit alarms are created on device, so LAN and connected relay delivery can create them; the APNs worker cannot create a local alarm unless the app receives and handles the packet.

agent-activity devices prints ALARMS, AGENT, and AUTH columns. ALARMS means this Mac can schedule alarms on that iPhone, AGENT is the phone-wide agent-alarm switch, and AUTH is iOS alarm permission. Enable per-device alarm access in the iPhone app under Settings → Connections.

Artifacts

agent-activity artifact publishes a local Markdown or HTML file through the relay Worker and prints a public, unguessable URL (<relay>/r/<id>) you can open on any device. .md files are rendered to a standalone, dark-mode-friendly HTML page; .html files are uploaded verbatim.

# publish a Markdown report (rendered to HTML); the link expires in 7 days
agent-activity artifact build-summary.md

# stable artifact id; each upload to same id increments version
agent-activity artifact plan.html --artifact-id q3-migration-plan

# custom title, 14-day expiry, and a 4-digit passcode gate
agent-activity artifact perf.html --title "Perf regression deep-dive" \
  --type audit --ttl-days 14 --passcode 4821

# machine-readable output, and skip the phone notification
agent-activity artifact notes.md --json --no-notify

# list artifacts created by this relay token
agent-activity artifacts
  • The artifact is stored by the relay Worker and auto-deletes after --ttl-days (integer 1–30, default 7).
  • --artifact-id reuses the same public URL and increments version / versionCount on each upload.
  • Published artifacts include CLI provenance: hostname, working directory, git branch/commit/subject/dirty state, and CI run info when present.
  • --title defaults to the first # heading (Markdown), the <title> tag (HTML), or the filename.
  • --type controls the artifact icon: report, plan, preview, design, audit, code, or data. If omitted, the CLI infers one from title/name.
  • --passcode NNNN (exactly 4 digits) makes viewers unlock the page first; repeated wrong guesses lock it out and eventually destroy the artifact.
  • Uploads are capped at 2 MB of HTML.
  • Unless --no-notify, the CLI also sends a notification whose destinationURL is the report URL, so tapping the alert on the iPhone opens the report. Use --to <id> / --all to pick devices, as with notify.
  • Requires relay credentials — agent-activity config set --relay <url> --token <t>, or pair via agent-activity connect.
  • --json prints the Worker's raw response: { "ok": true, "id": "…", "url": "https://…/r/…", "expiresAt": 1751…, "locked": false }.

Live Activities

A persistent Lock Screen + Dynamic Island widget. live start prints the activity id on its own line (and returns it as id in --json) — capture it to address subsequent updates and the end.

Styles: bar (linear progress), ring (circular), tasks (checklist), pulse (indeterminate working state).

--destination-url sets the URL opened when the Live Activity is tapped. On Codex runs, live start uses exact-link env (AGENT_ACTIVITY_DESTINATION_URL, CODEX_DESTINATION_URL, CODEX_TASK_URL, CODEX_THREAD_URL, CHATGPT_CODEX_URL) first, then ChatGPT universal links from CODEX_SHARE_ID, CODEX_TASK_ID, or CODEX_CONVERSATION_ID.

ID=$(agent-activity live start \
  --project build --name "Build pipeline" \
--title "Compiling" --status "Resolving deps" \
--style bar --symbol "hammer.fill" --tint "#34C759" \
--destination-url "$CODEX_TASK_URL" \
--total 8 --completed 0)

agent-activity live update --id "$ID" --project build \
  --status "Compiling module 4/8" --completed 4 --progress 0.5

agent-activity live end --id "$ID" --project build --dismiss after:5

--tasks

For the tasks style, pass a comma-separated list; each item is name or name:done:

agent-activity live update --id "$ID" --project build \
  --tasks "Lint:done,Typecheck:done,Build,Test,Deploy"

becomes:

"tasks": [
  { "id": "lint", "name": "Lint", "done": true },
  { "id": "typecheck", "name": "Typecheck", "done": true },
  { "id": "build", "name": "Build", "done": false },
  { "id": "test", "name": "Test", "done": false },
  { "id": "deploy", "name": "Deploy", "done": false }
]

--dismiss

How the activity disappears when you end it: immediate, default, or after:<seconds> (e.g. after:300 keeps the final state up for 5 minutes).


Enumerate ongoing activities — list (ps, activities)

agent-activity list fetches the device's GET /v1/activities and prints a clean, aligned table of the Live Activities currently running — so an agent can discover which projects/ids are live and act on them. ps and activities are aliases.

agent-activity list
# Ongoing Live Activities (3):
# ID       PROJECT  STATUS     PROGRESS  PHASE    UPDATED
# act-aaa  build    Compiling  50%       running  2m ago
# act-bbb  build    Linking    —         running  31s ago
# act-ccc  deploy   Uploading  20%       running  just now
  • PROGRESS is shown as 0–100%, or when indeterminate (negative/omitted).
  • UPDATED is a relative time derived from the activity's updatedAt (blank if the device doesn't provide one).
  • --json emits the raw activities array (straight from GET /v1/activities), ideal for scripting.
  • If the device is unreachable you get the same friendly error as the other LAN commands, and a nonzero exit.
agent-activity list --json | jq -r '.[].id'      # just the ongoing ids

Local id cache — list --local

Every live start records { id, project, title, startedAt } to ~/.agent-activity/activities.json, and every live end removes that id. This lets an agent re-discover the ids it started even while offline (no device round trip):

agent-activity list --local
# Locally-tracked Live Activities (2):
# ID            PROJECT  TITLE          STARTED
# act-18dbb14d  web      Building web   just now
# act-470d05b9  api      Building api   30s ago

agent-activity list --local --json               # raw cache records

The cache is small and self-healing: if the file is missing or corrupt it is treated as empty and recreated on the next write — it never blocks a live start/end.

Update many activities at once

Each activity is addressable by its own id (returned by live start). To update several in one call:

# 1) Repeat --id to target specific activities:
agent-activity live update --id act-aaa --id act-bbb \
  --status "Paused for review" --phase waiting

# 2) Omit --id and pass --project to update EVERY ongoing activity in that
#    project. The CLI fetches /v1/activities, finds all whose projectID matches,
#    and applies the update to each — printing one result line per id:
agent-activity live update --project build \
  --phase success --status "Build succeeded" --tint "#34C759"
# ✓ act-aaa
# ✓ act-bbb

A single --id behaves exactly as before. With --json, multi-update emits { ok, count, results:[{ id, ok }] }. The command exits nonzero if any individual update failed.

Targeting multiple devices

devices output includes stable id values. Use them to control where packets go:

agent-activity devices                    # find registered IDs
agent-activity ping --to test-device      # only this device
agent-activity ping --all                 # all paired devices
agent-activity live update --id "$ID" --project build --to test-device --status "Step 1"
agent-activity live end --id "$ID" --project build --to test-device --dismiss after:5

If neither --to nor --all is used, CLI uses activeDeviceId from config (or first paired device).

Full example — an agent reports build progress

A realistic sequence an agent would run: start an activity, push several updates, flip to success, and end it.

#!/usr/bin/env bash
set -euo pipefail

PROJECT="ios-app"

# 1) Start the Live Activity (capture the id it prints).
ACT=$(agent-activity live start \
  --project "$PROJECT" --name "iOS App" \
  --title "Build & Test" --status "Starting…" \
  --style tasks --symbol "gearshape.2.fill" --tint "#5E5CE6" \
  --total 4 --completed 0 \
  --tasks "Install deps,Compile,Test,Archive")

echo "Live Activity: $ACT"

# 2) Step through the work, updating status / progress / tasks.
agent-activity live update --id "$ACT" --project "$PROJECT" \
  --status "Installing dependencies" --completed 1 --progress 0.25 \
  --tasks "Install deps:done,Compile,Test,Archive"

agent-activity live update --id "$ACT" --project "$PROJECT" \
  --status "Compiling" --completed 2 --progress 0.50 \
  --tasks "Install deps:done,Compile:done,Test,Archive"

agent-activity live update --id "$ACT" --project "$PROJECT" \
  --status "Running tests" --completed 3 --progress 0.75 \
  --tasks "Install deps:done,Compile:done,Test:done,Archive"

agent-activity live update --id "$ACT" --project "$PROJECT" \
  --status "Archiving" --completed 4 --progress 1.0 \
  --tasks "Install deps:done,Compile:done,Test:done,Archive:done"

# 3) Flip to a success state, then end (keep it visible 30s).
agent-activity live update --id "$ACT" --project "$PROJECT" \
  --status "Build succeeded ✅" --phase success --tint "#34C759"

agent-activity live end --id "$ACT" --project "$PROJECT" --dismiss after:30

On failure, an agent would instead:

agent-activity live update --id "$ACT" --project "$PROJECT" \
  --status "Tests failed" --phase failure --tint "#FF453A" --symbol "xmark.octagon.fill"
agent-activity live end --id "$ACT" --project "$PROJECT" --dismiss default

# …and optionally fire a notification so it shows up even if the activity was dismissed:
agent-activity notify --project "$PROJECT" --title "Build failed" \
  --body "3 tests failing in CheckoutTests" --tint "#FF453A" --sound

Full example — an agent fans out across many activities

Start three activities, list them, update one by id, update a whole project at once, then end them. Copy-paste friendly:

#!/usr/bin/env bash
set -euo pipefail

# 1) Start three Live Activities (two in "build", one in "deploy").
#    Each `live start` prints its id on the last line — capture it.
A=$(agent-activity live start --project build  --name "Build" --title "Frontend"  --style bar | tail -1)
B=$(agent-activity live start --project build  --name "Build" --title "Backend"   --style bar | tail -1)
C=$(agent-activity live start --project deploy --name "Deploy" --title "Staging"  --style pulse | tail -1)
echo "started: $A $B $C"

# 2) See what's ongoing (from the device). The same ids appear here.
agent-activity list
#   …or, offline, the ids THIS machine started:
agent-activity list --local

# 3) Update a single activity by its id.
agent-activity live update --id "$A" --project build --progress 0.4 --status "Bundling"

# 4) Update EVERY ongoing activity in the "build" project at once
#    (omit --id, pass --project). One result line per id is printed.
agent-activity live update --project build --phase success --status "Build done" --progress 1.0

# 5) End them. Repeat --id to end several explicit ids in one call;
#    `live end` also removes each id from the local cache.
agent-activity live update --id "$A" --id "$B" --status "Wrapping up"
agent-activity live end --id "$A" --project build  --dismiss after:5
agent-activity live end --id "$B" --project build  --dismiss after:5
agent-activity live end --id "$C" --project deploy --dismiss after:5

agent-activity list --local        # now empty

Discover (optional, mDNS)

If your network allows multicast DNS, you can scan for the app instead of typing the IP:

agent-activity discover
# Found 1 service(s):
#   Agent Activity  192.168.1.42:8473
#     agent-activity config set --host 192.168.1.42 --port 8473

mDNS is best-effort — VPNs and isolated/guest Wi-Fi often block it. If nothing shows up, just use config set --host <ip> directly. Discovery failures never throw; the command exits 0 with guidance.


Output & exit codes

  • Human-readable by default; --json prints the server's { ok, id, message } response (or { ok:false, error } on failure).
  • Exit code 0 on success, non-zero on any error (bad flags, unreachable host, HTTP 4xx/5xx, auth rejection).
  • Set NO_COLOR=1 to disable ANSI colors.

Wire format

Every command builds one AgentPacket JSON envelope and POSTs it. The shape is the single source of truth in PACKET_SCHEMA.md:

{
  "kind": "notify" | "activity" | "ping",
  "action": "present|update|dismiss" | "start|update|end",
  "project": "build", "projectName": "Build", "id": "stable-id",
  "title": "…", "body": "…", "status": "…",
  "destinationURL": "https://chatgpt.com/codex/tasks/…",
  "progress": 0.37, "completed": 3, "total": 8,
  "symbol": "hammer.fill", "emoji": "🛠️", "tint": "#34C759",
  "style": "bar|ring|tasks|pulse", "phase": "running|waiting|success|failure",
  "tasks": [ { "id": "t1", "name": "Lint", "done": true } ],
  "image": "https://… | data:image/png;base64,… | <raw base64>",
  "sound": true, "dismiss": "immediate|default|after:300"
}

Endpoints used: GET /health, POST /v1/packet (ping), POST /v1/notify, POST /v1/activity, GET /v1/activities (list/logs), and POST /v1/artifacts on the relay Worker (artifact); /v1/reports remains a compatibility alias.

The local id cache (~/.agent-activity/activities.json) is CLI-only state — it is written on live start/end and read by list --local; it is never sent to the device.