Pstack Pulse logo

Pstack Pulse

OrganizationPopular
udecode
pstack-pulse

Show every Claude Code and Codex session on the iPhone lock screen through ActivitySmith and in the Mac menubar, with each plan page's pipeline, and buzz when a session needs you, ships or fails.

Overview

Publisherudecode
Repositorydotai
Skill namepstack-pulse
Stars
1.2K
Forks
82
Bundled files
14
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 14 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by udecode on GitHub. Read the source before you install it.

Installation

Install the Pstack Pulse AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/udecode/dotai/tree/main/skills/pstack-pulse
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/udecode/dotai.git /tmp/dotai
mkdir -p .claude/skills
cp -r /tmp/dotai/skills/pstack-pulse .claude/skills/pstack-pulse
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Pstack Pulse in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Pstack Pulse on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Pstack Pulse is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

pstack pulse

A daemon on this Mac turns hook events from every Claude Code and Codex session into ActivitySmith Live Activities. It shows only pstack sessions: those whose title starts with a pstack stage or state emoji, as the Session title rule sets it, such as "🚧 scrub (2/5)". A lone session gets its own card. With two or more, a summary card comes first. It is titled with the project's name when every session shares one project. When they span several, its title counts their states, such as "1 needs you · 3 working · 1 to resume". It updates in place as sessions spread. The phone's other four cards go to sessions waiting on you: those that need you, through a question or a permission prompt, then failed ones, then runs waiting for you to resume them or whose title shows Waiting, Blocked or Paused. Working sessions fill the cards left over. A shown card keeps its place until a session that ranks higher needs it, because every new card spends one of the remote starts iOS allows. A session card shows the stage and the (n/total) count from the session's title as a stage bar, its stage name in the subtitle, an Open button and a Plan button while the session's plan is still open. A question turns the session's card orange and puts the question in its subtitle, without ending the card. A project is every clone and worktree of one git origin, so two clones of plate share a card. A repository without an origin is its own project, and sessions outside any repository share one called other. The summary card lists each session that needs you, failed or is working. Across projects, the project with the fewest sessions comes first, so one ellie session leads five plate ones. Each one shows the session's name with its stage emoji in large type, as on its session card, and under it, in small type, the stage from its title, or Needs you or Failed, in its state color. Sessions that need you come first, then failed and working ones. After them come, in yellow, sessions whose turn ended while their title still shows a stage. Such a run is not finished and waits for you to resume it, and each one shows its stage too. A run whose title is back to its bare name is finished and leaves the card. A card with more than eight sessions shows seven and a more value. While a session needs you, the card's subtitle shows its question and the card's one button opens that session. Otherwise the subtitle counts the failed, working and to-resume sessions, or across projects names each project with its session count, and the button opens the session list. A card never changes type, so a question starts no new card. It pushes a notification when a session needs you or fails, and sets the app badge to the number of sessions that need you. A git push buzzes as shipped only once its turn ends, once for the newest push of the turn, and not at all when that turn hands back a page, which buzzes as replied. While you have used the Mac in the last three minutes, a push waits one minute and goes out only if it still stands: a prompt you answer, a failure you follow with a new turn, or a reply you answer by continuing the session sends nothing. Away from the Mac, a push goes at once. ActivitySmith cannot take back a push it has sent. You answer in the vendor's own app. Tapping a push opens the session: a Claude session's Remote Control link opens it in the Claude app, and a Codex push opens the ChatGPT app. A push's Plan button opens the session's plan page while that plan is open. A Claude session with Remote Control off has no link the phone can open, so tapping its push opens its plan page instead, and a card that asks for it opens the session list. ActivitySmith takes links only for a card's button, not for a tap on the card itself. That button takes only web and Shortcuts links, so a card that asks for a Codex session opens the session list too. <skill> below is this skill's base directory, and every command is node <skill>/scripts/pulse.mjs <command>.

What it reports

  • Claude sessions buzz for:
    • a question or plan approval, at once;
    • a permission prompt left unanswered for about six seconds. Claude reports it through its permission_prompt notification, which desktop sessions send from Claude Code 2.1.233 on; in a terminal, typing restarts the six seconds. A call that a rule allows, or that another hook allows within six seconds, stays silent. The push shows Claude's own notification text, which may not name the tool. Your next prompt or the end of the turn clears the card. No hook says when a prompt is answered, so the card stays on needs you for the rest of the turn after you answer. While one prompt or question waits, a second prompt does not buzz. After you deny a prompt, Claude stops and waits, so the card stays on needs you until your next prompt;
    • a push the remote branch has;
    • a required check still failing when the turn stops;
    • an API error;
    • a session that died while working.
  • Codex sessions from the app or the CLI buzz for questions and permission prompts, and show their plan. Codex pushes, failed checks and lost processes are not observed, because Codex hooks carry no git result or tool failure.
  • A required check counts only when the Bash command is the check itself, optionally with flags, such as bun check --bail. Any other form, such as bun check | tail, a chain or a second line, records nothing, because its exit status is not the check's. A configured check that is itself a chain never counts.
  • A session is working while a turn runs. It stays working after the turn while a background shell, subagent or monitor it started still runs, because that work wakes it with a new turn. An open artifact page watch does not count, because it never wakes the session. A dev server left running in the background keeps the session working until the server stops.
  • Panel seats, smoke runs, headless claude -p runs, subagents and Codex exec and review threads never show. A session started with PSTACK_PULSE_OFF=1 in its environment never shows either.
  • A turn that hands back a plan page buzzes once as " replied", with the first line of its last message. It does not count as needing you, so the card and the badge stay as they are. A hand-back counts only when the turn published a page from the plans folder's artifacts while the session is bound to a plan.
  • A buzz goes out at least once while its event still needs you. A refused push is retried until ActivitySmith accepts it; a question you answer first is never sent. If the daemon crashes, or the network drops, after ActivitySmith accepts a push but before the daemon saves that, the push goes out again, because the push API has no idempotency key.

Install

On another Mac, install the skill and its companion first with npx --yes skills add udecode/dotai --skill pstack-pulse --skill rca --agent claude-code --global -y. The phone needs its own ActivitySmith account and app, and cards show only sessions in repositories synced by sync-pstack, whose Session title rule gives each title its stage.

  1. Run install, adding --auto-update when the owner wants the daily update in Updates. It is done when it prints the hook files, daemon: started, menubar: started and the session list URL. The daemon picks up the key within 30 seconds of it being stored.
  2. Hand the owner the three steps it prints, which only the owner can do:
    • Store the ActivitySmith key in the Keychain with the security add-generic-password line.
    • Publish the read-only session list with the tailscale funnel line. The list lives at a secret path and accepts no input.
    • In Codex, open /hooks once and trust the pstack-pulse hooks.
  3. Ask the owner to turn off the Claude app's own "Push when actions required", so each question buzzes once.
  4. Run doctor. It is done when every line reads ok or warn. A warn line names an optional part and what is lost without it.

Updates

The daemon checks its skill folder every 30 seconds. Once a change reads the same twice, it rewrites its hooks, rebuilds the menubar when its Swift source changed, and exits, and launchd starts it again on the new code. So an update is only npx --yes skills update pstack-pulse rca --global --yes, which update runs. With install --auto-update, the daemon runs update once a day, so every push to dotai's main branch reaches the Mac within a day; install --no-auto-update turns that off. update logs its result to the daemon log. install points the hooks and the daemon at the fnm default node, or else Homebrew's, when that node is version 22 or later, so upgrading node does not break them.

Status and repair

  • status lists every live session with its state, then the cards on the phone and the badge.
  • doctor checks the key, the daemon, the menubar, both hook files and the node they run, the Claude session registry and the list secret. It warns when it has seen no pstack-titled session, when there is no session list URL and when auto-update is off. It also warns when cc-same or cswap is missing from the daemon's PATH, which only costs the account names.
  • The daemon logs to ~/Library/Logs/pstack-pulse.log and keeps its state in ~/.pstack-pulse/. An inbox file it cannot read as an event moves to ~/.pstack-pulse/inbox/bad/.
  • A card's pipeline comes from node .agents/pstack/plan-page.mjs <plan> --rail in the session's own repository. A repository synced before that mode existed shows "No plan" until its next sync-pstack run.
  • install owns only the hook entries whose command ends in --owner=pstack-pulse. It keeps every other hook in the same group, saves a first backup of each settings file beside it, and writes through a temporary file, so a crash never leaves half a file; a change another program makes during that write is lost. Claude's PreToolUse hook runs only for AskUserQuestion and ExitPlanMode.
  • Only one daemon runs at a time: it holds a socket under /tmp named for its state folder, and a second daemon that finds the socket answering exits.
  • uninstall stops the daemon and the menubar, deletes their LaunchAgents and removes only its own hook entries. It ends its cards and clears the badge, says what is still on the phone if that fails, prints the line that stops the Funnel, and keeps the state folder.

Menubar

The menubar puts the phone's sessions on the Mac, one row each. Its number counts the sessions that need you, in orange. With none, it counts failed sessions in red, then working ones. A moon means every session is idle, and a struck-through bolt means the daemon does not answer. Its menu shows the fleet totals, which the phone no longer shows, then a row for every live session: those that need you first, then failed, working and idle. Each row shows the session's title, state, project, stage and stage bar. Clicking a row opens the session in the Claude desktop app, by the desktop id that Claude's session registry records, or on claude.ai when the session has none. A row under it opens the session's plan page while that plan is open. The phone shows at most five cards, but the menu has no limit. Its Connect all sessions to Remote Control item opens a new Code session in the Claude app, in ~/.pstack-pulse, with a request typed in to turn Remote Control on for every non-archived session; press Enter to run it. It goes through the app because a headless claude -p has no session tools. New sessions connect on their own while the app's Connect new sessions to Remote Control setting is on, so the item is for sessions that lost their link, such as after an account switch.

install compiles menubar/PulseMenu.swift with Xcode's swiftc into ~/.pstack-pulse/bin/pstack-pulse-menu and runs it as the dev.pstack.pulse.menu LaunchAgent. Without swiftc it prints that the menubar was not built and installs everything else. menubar rebuilds and restarts only the menubar. Quit stops it until the next login. Any other exit restarts it. It reads the daemon's board.json on the session list port every two seconds. About three seconds after it starts, it writes its menubar position, and whether macOS draws it, to ~/Library/Logs/pstack-pulse-menu.log. There, shown=false means macOS is not drawing it right then. --dump prints the menu as text and quits, which checks it without screen recording access.

Pet

The pet is paused while the menubar covers the Mac, so install never starts it. node <skill>/scripts/pulse.mjs pet opens a floating pet in the corner of the screen, above every window and on every Space, using the Codex desktop pet's sprite format and animations. It runs while any session works, waits with an orange badge counting the sessions that need you, plays its failed animation while one has failed, and jumps for ten seconds after a push ships. Click it for a tray that lists what needs you, with buttons that open the session or its plan page; drag it anywhere, and it keeps that spot. The first start fetches Electron through npx and the Codex sprite from OpenAI's pet CDN into ~/.pstack-pulse/pets/. The pet reads the daemon's state.json on the session list port every two seconds. --snapshot saves pet-snapshot.png and pet-snapshot-tray.png in ~/.pstack-pulse/ and quits, which checks the render without screen recording access.

Tests

node --test <skill>/scripts/pulse.test.mjs

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Pstack Pulse AI skill do?

Show every Claude Code and Codex session on the iPhone lock screen through ActivitySmith and in the Mac menubar, with each plan page's pipeline, and buzz when a session needs you, ships or fails.

Why use Pstack Pulse on TypingMind?

Because you install it once and use it with any model. Pstack Pulse is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Pstack Pulse in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/udecode/dotai/tree/main/skills/pstack-pulse. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Pstack Pulse?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Pstack Pulse?

As many as you like. As long as a model supports skills, you can use Pstack Pulse with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Pstack Pulse AI skill free?

It is published on GitHub by udecode. Check the repository for licensing terms. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇