{"slug": "show-hn-ai-pulse-a-fake-led-strip-beside-the-macos-dock-that-shows-agent-status", "title": "Show HN: AI Pulse a fake LED strip beside the macOS Dock that shows agent status", "summary": "AI Pulse, a new macOS app by developer Leo G., places a virtual LED strip beside the Dock to show the status of AI coding agents, using a single aggregate signal to indicate running, waiting, finished, or broken states. The app, built with Swift 6 and requiring macOS 14+, uses no private APIs or accessibility permissions, and includes a CLI for agent integration. It is available as a free download from GitHub, with releases not yet notarized.", "body_md": "An ambient macOS light strip for AI coding agents, inspired by the\n[SidePulse](https://sidepulse.io/) hardware gadget — but as an app. A slim strip of eight virtual\nLEDs floats in the unused space beside the Dock and shows, with a single\naggregate signal and no per-model distinction, whether anything is running,\nwaiting for you, finished, or broken:\n\nReduce Motion replaces every animation with a static treatment. The original per-agent icon pill remains available via Settings → Appearance → Indicator style.\n\nAI Pulse is **not** embedded in the Dock — macOS exposes no public API for\nDock accessories. It is a Dock-adjacent, borderless, nonactivating `NSPanel`\n\npositioned from public screen geometry (`NSScreen.frame`\n\nvs `visibleFrame`\n\n).\nNo private APIs, no Accessibility/Screen Recording permissions, no injection.\n\nGrab `AI-Pulse-<version>.zip`\n\nfrom the\n[latest release](https://github.com/leog/ai-pulse/releases/latest), unzip,\nmove `AI Pulse.app`\n\nto `/Applications`\n\n, and launch. Releases are not yet\nnotarized, so on first launch right-click the app → **Open** (on macOS 15+,\nalso allow it under **System Settings → Privacy & Security → Open Anyway**).\nThe `aipulse`\n\nCLI ships inside the bundle at\n`AI Pulse.app/Contents/Helpers/aipulse`\n\n.\n\nReleases are cut automatically when a PR merges: patch by default, minor or\nmajor when the PR carries a `release:minor`\n\n/ `release:major`\n\nlabel.\n\n- macOS 14+\n- Xcode 16+ / Swift 6 toolchain\n\n```\nswift build                         # build everything (app, CLI, kit)\nswift test                          # unit + integration tests (AIPulseKit)\nswift run AIPulseApp                 # launch the pill (accessory app: no Dock icon)\nswift run AIPulseApp --snapshot DIR  # render pill + hover card PNGs headlessly and exit\nswift run aipulse health             # CLI: check the local event service\n./Scripts/make-app.sh               # assemble + sign dist/AI Pulse.app\n./Scripts/make-gifs.sh              # regenerate docs/ GIFs from headless frames (needs ffmpeg)\n```\n\n`docs/pulse-social.gif`\n\nis a larger, captioned cut of the same state cycle,\nmade for sharing.\n\nFor day-to-day use, run the bundled app rather than the bare binary: the\nscript signs it with your Apple Development identity, giving a stable code\nsignature so the Keychain trusts the app across rebuilds (bare `swift run`\n\nbinaries are ad-hoc signed and trigger a Keychain consent prompt after\nevery rebuild — that is also why `AIPULSE_DEV_EPHEMERAL_TOKEN=1`\n\nexists for\ndev loops). The CLI is embedded at `AI Pulse.app/Contents/Helpers/aipulse`\n\n.\n\n(The app product is `AIPulseApp`\n\nbecause `AIPulse`\n\nand the `aipulse`\n\nCLI would\ncollide on case-insensitive filesystems.)\n\nAI Pulse listens on `127.0.0.1:7455`\n\n(configurable in Settings). On launch it\nstores a bearer token in the Keychain and writes `~/Library/Application Support/AIPulse/cli.json`\n\n(mode 0600) so the `aipulse`\n\nCLI authenticates\nwithout tokens ever appearing in shell commands:\n\n```\naipulse agent upsert \\\n  --id \"claude-code:$PWD:$SESSION_ID\" \\\n  --name \"Claude Code\" --provider anthropic \\\n  --instance \"$(basename \"$PWD\")\" \\\n  --state working --message \"Implementing Dock placement\"\n\naipulse agent update \\\n  --id \"claude-code:$PWD:$SESSION_ID\" \\\n  --state waitingForInput --message \"Waiting for permission\" --sequence 2\n\naipulse agent remove --id \"claude-code:$PWD:$SESSION_ID\"\naipulse agents        # list everything the pill knows\n```\n\nEndpoints: `POST /v1/agents/upsert`\n\n, `POST /v1/agents/{id}/event`\n\n,\n`DELETE /v1/agents/{id}`\n\n, `GET /v1/agents`\n\n, `GET /v1/health`\n\n(health is the\nonly unauthenticated route). The server binds to the loopback interface\nonly, caps request sizes, validates every payload (`AgentReducer`\n\n+\n`RequestValidator`\n\n), rejects unsafe URL schemes, and never executes\nanything received in an event.\n\nDev note: rebuilding the app changes its ad-hoc code signature, so Keychain\nreads re-prompt per build; launch with `AIPULSE_DEV_EPHEMERAL_TOKEN=1`\n\nduring\ndevelopment to skip the Keychain and use a per-run token instead.\n\nQuit via the pill's right-click menu → **Quit AI Pulse** (or kill the process).\n\n`Sources/AIPulseKit`\n\n— AppKit-free, fully unit-tested core:`Domain/`\n\n—`Agent`\n\n,`AgentState`\n\n,`AgentAction`\n\n(typed safe actions + URL scheme allowlist),`AgentEventPayload`\n\n(wire model),`AgentIntegrationLevel`\n\n,`StatusPriority`\n\n(urgency sort).`Store/AgentStore`\n\n— single source of truth; all surfaces render from it.`Placement/`\n\n—`ScreenSnapshot`\n\n, best-effort`DockGeometry`\n\ninference, pure`PlacementPolicy`\n\n(gutter → adjacent → corner fallbacks, clamping).\n\n`Sources/AIPulse`\n\n— the app:`Presentation/Pill/`\n\n— nonactivating`AIPulsePanel`\n\n, SwiftUI capsule, per-state icons (glyph + badge + ring, never color alone), hover card.`Presentation/AgentList/`\n\n,`Presentation/Settings/`\n\n— conventional keyboard-accessible windows.`Placement/DockPlacementController`\n\n— debounced screen-change observation; no polling.\n\nMilestones 1–3 are complete:\n\n-\n**M1**— nonactivating panel, pill UI, mock agents, hover card, context menu. -\n**M2**— bottom/left/right Dock placement, multi-display selection with a Settings display picker, debounced screen/space-change observation, off-screen clamping, opt-in auto-hidden-Dock following (best-effort, from the Dock's public preference domain — read-only, no Dock interaction). -\n**M3**—`AgentReducer`\n\nevent normalization (versioning, ID validation, sequence/timestamp ordering, duplicate rejection, safe-action mapping), centralized`StalenessPolicy`\n\n(working agents stale after a configurable silence, then demoted to disconnected after a longer one; agents whose backing process has exited are demoted within one sweep via a PID liveness check; completed agents expire after a configurable delay; waiting, approval, and failed states never expire on timers), and persistence to`~/Library/Application Support/AIPulse/agents.json`\n\nwith restart restore: unresolved attention states come back as-is, live-only states come back as`disconnected`\n\nuntil their source reports again. -\n**M4**— loopback-only HTTP event service (`LocalHTTPServer`\n\n), Keychain bearer token + 0600 handshake file for the CLI, transport validation, the`aipulse`\n\npublisher CLI, and end-to-end integration tests. Verified live: CLI → HTTP → reducer → store → pill in ~150 ms round-trip. -\n**M5**— Claude Code adapter (`ClaudeCodeAdapter`\n\n+`aipulse claude-hook`\n\n), built against the documented hook lifecycle: SessionStart→idle, UserPromptSubmit/PreToolUse→working, PermissionRequest and permission-prompt Notifications→approvalRequired, idle-prompt Notifications→waitingForInput, Stop→completed, StopFailure→failed, SessionEnd→removed. One pill entry per session per project. Prompt text, tool inputs, and assistant output are never decoded, so they can never be published. The hook always exits 0 and prints nothing. -\n**M6**— optional dynamic Dock icon (off by default; Settings → Appearance). Aggregates the same AgentStore snapshot as the pill via`DockTileAggregator`\n\n: failure > attention > working > neutral, with an`NSDockTile`\n\ncustom content view for the state treatment and`badgeLabel`\n\nshowing the count of unacknowledged urgent agents. The floating pill and the Dock icon are independently toggleable; the icon never bounces.\n\nAll six MVP milestones are complete, followed by the pivot to the\nlights-first presentation (`LightAggregator`\n\n+ `LightStripView`\n\n), keeping\nthe icon pill as an option.\n\nThis repository ships `.claude/settings.json`\n\nregistering `aipulse claude-hook`\n\nfor the relevant hook events (via the debug build path), so\nClaude Code sessions in this repo appear in the pill automatically once the\napp is running. For system-wide use:\n\n```\nswift build -c release\nsudo cp .build/release/aipulse /usr/local/bin/\n```\n\nthen register the same hooks in `~/.claude/settings.json`\n\n, replacing the\ncommand with plain `aipulse claude-hook`\n\n. Claude Code asks you to approve\nproject hooks the first time it loads them.\n\nAI Pulse displays status sent by local agent integrations. It does not read prompts, terminal contents, editor contents, or application windows.\n\nContributions are welcome — see [CONTRIBUTING.md](/leog/ai-pulse/blob/main/CONTRIBUTING.md) for the\nproject's design principles, testing expectations, and how to add a new\nagent integration. [docs/DEBUGGING.md](/leog/ai-pulse/blob/main/docs/DEBUGGING.md) covers the\ndebugging surface: environment variables, headless snapshots, log\nstreaming, on-disk state, and fixes for the common failure modes.", "url": "https://wpnews.pro/news/show-hn-ai-pulse-a-fake-led-strip-beside-the-macos-dock-that-shows-agent-status", "canonical_source": "https://github.com/leog/ai-pulse", "published_at": "2026-08-10 22:07:41+00:00", "updated_at": "2026-08-10 22:41:17.327131+00:00", "lang": "en", "topics": ["ai-tools", "developer-tools"], "entities": ["AI Pulse", "Leo G.", "SidePulse", "GitHub", "macOS", "Swift"], "alternates": {"html": "https://wpnews.pro/news/show-hn-ai-pulse-a-fake-led-strip-beside-the-macos-dock-that-shows-agent-status", "markdown": "https://wpnews.pro/news/show-hn-ai-pulse-a-fake-led-strip-beside-the-macos-dock-that-shows-agent-status.md", "text": "https://wpnews.pro/news/show-hn-ai-pulse-a-fake-led-strip-beside-the-macos-dock-that-shows-agent-status.txt", "jsonld": "https://wpnews.pro/news/show-hn-ai-pulse-a-fake-led-strip-beside-the-macos-dock-that-shows-agent-status.jsonld"}}