The PwrAgent desktop

The desktop app is where you live day-to-day. It drives a coding agent — Codex by default, or Gemini, Grok, Kimi, or Qwen if you install and enable them (see Agent backends). On Codex it reads and writes the same on-disk session state Codex Desktop uses, so your threads, transcripts, and authentication are shared between the two by default — open either one and your work is there.

What makes the PwrAgent side worth running:

State lives under ~/.pwragent/ (overridable with PWRAGENT_HOME or --profile <name>). No cloud relay and no PwrAgent-owned account — see Settings for how the desktop discovers your local Codex install and how authentication works.

Install the desktop from GitHub Releases. macOS uses the signed DMG; Linux uses Debian packages with manual upgrades documented in Linux Install.

The rest of this page is the operator-facing tour of what the desktop does, what’s not in it yet, and what’s on the roadmap.

What’s in the desktop today

First-run onboarding wizard

First-run onboarding wizard on the Codex Profile step, showing three card options: Shared (reuse existing Codex login), Isolated (fresh Codex profile for PwrAgent), and Multiple (paired profiles for work / personal / projects). A progress strip at the top tracks the wizard's numbered steps, with Profiles active and Messaging and Review still to come.
The wizard's Profiles step (the in-page heading reads Codex Profile). Shared (default) reuses your existing Codex login so PwrAgent and Codex Desktop share threads; Isolated creates one named Codex profile just for PwrAgent; Multiple sets up several paired profiles in one pass for work / personal / projects separation. (Captured on an earlier build whose progress strip carried six stops; it tracks five today.)

The first time you launch PwrAgent on a fresh profile, a wizard walks you through a few short choices, applies them to that profile’s config.toml, and drops you on the main app with everything wired up. No surprise modals later — you do this once per profile.

A Welcome screen opens the wizard, then the progress strip tracks five numbered steps, every one skippable to a sensible default:

  1. Thread presentation. Theme (dark / light / system) and density (mission-control / compact). Both flip the UI live as you click so you can see what you’re picking.
  2. AI Providers. Which coding agent will back your threads. Codex is the default; the step also carries per-platform install commands (with a copy button) and a docs link for Gemini CLI, Grok Build, Kimi Code, and Qwen Code, and shows which ones it already found on this machine. Skip it if Codex is all you want — see Agent backends for the full picture.
  3. Profiles. Three ways to pair PwrAgent with Codex:
    • Shared — PwrAgent and Codex Desktop share a single Codex auth + thread list. Default; closest to “just install and go.”
    • Isolated — one named PwrAgent profile, one matching CODEX_HOME directory. Pick this when you want a clean split from Codex Desktop or from your other PwrAgent install.
    • Multiple — up to five paired PwrAgent + Codex profiles in one pass. Pick this when you already know you want work / personal / side-project separation.

    Isolated and Multiple prompt you to name the new profile(s) inline before moving on.

  4. Messaging. Short safety preamble (what messaging is for, what it isn’t, and what gets stored where), then a provider picker for the six platforms (Telegram, Discord, Slack, Mattermost, Feishu / Lark, LINE). Skip is the default — Continue is gated behind an explicit acknowledgement checkbox, so nobody wires a bot by accident. For each platform you tick, a compact inline setup card walks the credential paste / Test / pair flow without leaving the wizard. Scope-aware pairing flips into shared-space pairing where the provider has spaces (Slack workspaces, Discord servers, Telegram supergroups, etc.).
  5. Review. Recap of what you chose, what got created, and the entry points (Settings → Profiles, Settings → Messaging) for whatever you skipped.

On Finish, PwrAgent auto-switches into the new paired profile if you picked Isolated or Multiple, so the very next window is already operating under the right ~/.pwragent/profiles/<name>/ and the matching ~/.codex/profiles/<name>/.

Want to replay it? Help → Replay Onboarding. Reopens the wizard without resetting any of your settings — useful as a guided tour or when you forget where a specific setting lives.

The wizard auto-fires only on profiles that have never finished it (detected via [onboarding] completed = false in the profile’s config.toml). Existing profiles upgrade silently.

Sidebar with the Updated lens active, showing pinned threads at the top and recent activity below
The Updated lens, populated. Pins sit in a statically-ordered shelf at the top; unpinned threads sort by most-recent activity below.

The left sidebar carries five thread lenses, switched from the tab strip at the top of the list. The tabs render as icons — hover one for its name and a one-line explanation. All five draw from the same pool of active (non-archived) threads; they differ in what they include and how they sort:

Lens Shows Sort
Attention Threads that want you — live turns and review-ready work. The tab renders live indicators instead of an icon. By urgency.
Drafts Threads with a reply you started and never sent. Most recent first.
Updated (default) All threads. Active ones bubble up as the agent posts. Most-recently-updated first.
Created All threads. Stable sort — rows don’t jump around mid-work the way they do in Updated. Newest created first.
Directories Threads grouped by linked Git directory. Within each directory, newest created first (stable).

Use Updated when you want “what’s the agent doing right now” front and center. Use Created when you’d rather the order stay put while you work through a list. Use Directories when you’re deliberately switching between several repos and want them visually separated. Attention and Drafts are triage lenses — they let live, review-ready, and unsent work surface without disturbing the other three.

Whether a thread gets promoted into Attention when its turn ends is a setting: Settings → General → Attention lens.

Updated, Created, and Directories each carry a Pins section at the top; in Directories the pins belong to their directory rather than to the global list.

The sidebar remembers which lens you left it on, per profile — relaunching the app reopens the last-used lens rather than resetting to Updated.

Thread rows also carry status chips as features engage: a Scheduled or Queued chip when a composer send is waiting (see Scheduled sends), an integrated terminal running chip when a terminal is live in that thread (see Integrated terminal), and PR-state chips (draft / conflicted / merged / closed) on threads with an associated pull request.

Pins

A pin keeps a thread visible at the top of the list regardless of activity. The pinned section is statically ordered (you set the order yourself) and scrolls independently of the rest of the list, so a long pin section never buries the rest of your threads.

In Directories, pins belong to their parent directory rather than to the global list, so each directory gets its own statically- ordered pin shelf. The Attention and Drafts lenses have no pin shelf — they’re filtered views, not orderings.

The Directories lens also lets you pin entire directories (and workspaces) above the divider so your active projects stay on top regardless of which one most recently woke up. Pinned directories carry over across restarts.

To pin or change pin order:

Unread marker

When a thread you haven’t actively viewed gets new agent output, its row picks up an orange cookie — a small filled circle next to the thread title. The cookie clears the next time you open the thread (or select it in the sidebar). Same indicator in every lens. You can also mark a thread unread from its right-click menu when you want the cookie back.

Thread workspaces: Local and Worktree

Each PwrAgent thread is rooted in a project (a Git repository). Within a project, a thread runs in one of two workspaces:

Threads can be handed off between Local and Worktree from the status card — PwrAgent moves the thread’s working state and updates the binding. Local-to-Worktree handoff asks which branch should remain checked out in Local before it moves you over; Worktree-to- Local handoff asks for confirmation.

Worktree storage location is configurable — see Settings → Worktrees.

When you archive a thread that owns a managed worktree, PwrAgent removes the worktree for you (with safety checks — it refuses to touch your primary checkout and skips worktrees shared with other threads). The thread’s status surface tells you whether the worktree was cleaned up or kept. The same applies when a Worktree thread hands off back to Local. Note this is worktree removal — environment teardown hooks are still on the roadmap (see Coming soon).

Linked project directories

A thread isn’t limited to the single project it launched from. You can link additional project directories to a thread — from the thread context rail’s Linked Projects tab or by referencing a directory in the composer — without changing the transcript or moving the workspace. Each linked directory gets its own branch scoping and pull-request discovery, so a thread that spans a service repo and its client repo tracks both.

Sub-threads, forks, and handoffs

Threads can have children. Right-click a thread row and you’ll find two families of actions, each offered for Same Worktree, New Worktree, or Local:

Forked threads don’t re-bill the inherited history — the Pricing tab marks the fork point and costs only what the child itself runs.

Handoffs are the agent-initiated version: an agent working a thread can delegate a task into a new child thread (optionally in its own isolated worktree), send messages to other threads, or move its own thread into a linked worktree and keep working there. Delegated children group under the root thread the same way manual sub-threads do, and pending worktree setup is visible on the child while it materializes. Handoff targets are restricted to directories the thread already trusts.

Integrated terminal

Every thread can open an integrated terminal from the thread header — a real shell rooted in the thread’s current workspace (Local or Worktree, whichever the thread is on). It renders as a resizable pane inside the thread view.

The part that earns its keep: terminals are owned by the main process, so a running terminal survives navigation. Switch threads, open Settings, come back — the shell is still there, scrollback intact. Thread rows wear a live-dot chip while a terminal is running in that thread, and the quit dialog counts running terminals as active work before letting the app close.

Codex environments

When you start a thread on a worktree, PwrAgent can run a Codex environment before the thread takes its first turn. Environments are configured at the Codex level (alongside AGENTS.md and .codex/ metadata) and PwrAgent surfaces them in the launchpad alongside the provider, model, and access-mode pickers.

Despite the name, environments are not Codex-only — PwrAgent reads .codex/environments/*.toml itself and runs the setup hook for a thread on any provider.

What you get:

Environments are usable today but not yet editable inside the PwrAgent UI — you author them at the Codex level and PwrAgent picks them up. In-app editing is on the roadmap, and so is running an environment’s [cleanup] script: PwrAgent reads it today but never executes it (see Coming soon).

Per-thread settings

Unlike Codex Desktop, where model / reasoning effort / Fast mode / permissions mode are global, PwrAgent scopes them per thread. You can run an experiment on a cheaper model with Default Access while a refactor runs on a stronger model with Full Access — the settings stay scoped to their thread. Set them on the Start Card before sending the first prompt, or on the bound-thread status card afterward.

Provider comes first. A thread runs on one agent backend — Codex by default, or Gemini / Grok / Kimi / Qwen if you’ve installed and enabled them. Changing the Provider on the launchpad re-populates Model, Reasoning, and the rest, because those depend on what the selected agent reports. Once the thread exists the provider is fixed; fork the thread to try the same work on a different agent. See Agent backends.

On Codex, the model picker tracks what Codex actually offers — the GPT-5.6 family (Sol / Terra / Luna) shows up with its model-specific max / ultra reasoning tiers, and PwrAgent remembers your preferred reasoning level per model. Fast mode maps to Codex’s priority service tier — same model, faster scheduling; it’s a Codex control and doesn’t appear on other providers.

Every ACP agent reports its own models, modes, and reasoning levels over the protocol, and the pickers render whatever came back rather than a list PwrAgent hardcoded.

Profile-wide baselines for all of this live in Settings → AI Providers → New thread defaults.

Auto-naming

PwrAgent gives threads automatic names so the sidebar list is scannable as it grows. The first prompt is the primary signal; the agent’s responses adjust the name as the thread takes shape. You can rename manually from the thread header at any time.

Project breadcrumb

The selected thread’s header shows a compact project breadcrumb so directory-launched threads read like PwrSnap › AI API Rate Limiting instead of leaving the project context implicit. Useful when several threads share similar titles across repos — at a glance you know which checkout you’re operating in.

The thread title in that breadcrumb is clickable: clicking it scrolls the selected row back into view in the sidebar thread list, which matters when you’ve scrolled the sidebar away from the currently-open thread.

Access modes

The two access modes that gate what the agent can do:

The mode is per-thread (see above). Mid-turn changes queue at the turn boundary — see Driving an agent from a messenger → Start Card buttons for the queueing details, which apply equally on the desktop.

Default Access and Full Access are PwrAgent’s own controls, and they apply to Codex threads. Most ACP agents ship their own runtime mode selector — Kimi’s Default / Plan / Auto / Yolo, for instance — and when an agent advertises one, PwrAgent shows that instead rather than stacking a second, mirrored dropdown on top. Grok has no selector of its own, so it gets this pair and PwrAgent drives Grok’s always-approve control when you flip it. Per-provider detail is in Agent backends → What differs.

Approval surface

When a thread is in Default Access and the agent wants to run something approval-gated, the desktop shows an inline approval card inside the transcript. Approvals are mirrored to any bound messengers so you can approve from wherever you happen to be reading the conversation.

Transcript copy buttons

Every user and assistant message in the transcript exposes a Copy affordance on hover/focus in its header — one click puts the full message on your clipboard, no manual text selection.

Code blocks and blockquotes get their own scoped copy controls so you can lift a replay prompt, a command snippet, or a quoted section cleanly without picking up the surrounding prose.

If the agent’s reply is wide enough that the transcript splits it across multiple visual segments (large tables in particular), the copy button on the first segment puts the whole original message on your clipboard — the rendered layout doesn’t change what gets copied.

Markdown composer

The composer parses Markdown as you type:

Codex Desktop doesn’t have this yet.

Pasting is fidelity-preserving: mixed prose + code pastes, nested code fences, lists inside blockquotes, and HTML-only clipboard content all reconstruct as proper Markdown instead of flattening to plain text — and what you copy back out of the composer matches what you pasted in. Pasted images become managed attachments that keep their filenames through the composer and transcript.

The slash menu carries more than local skills: backend-native commands (Codex’s and each ACP agent’s own slash commands) are surfaced in the same autocomplete, so / shows you everything the bound backend can do. And File → New Thread (⌘N / Ctrl+N) opens a fresh launchpad from anywhere.

@ directory & file references

Type @ in the composer and an autocomplete opens over your tracked project directories (most-recently-used first, filtered as you type). Picking one mints a durable @label chip at the cursor; the outgoing message carries it as a tilde-shortened path the agent can act on.

Undo / redo (per-thread)

While a thread is focused, Cmd+Z undoes the most recent change to that thread’s composer, and Cmd+Shift+Z (or Cmd+Y) redoes. Each thread carries its own independent undo stack — switching threads doesn’t merge the histories, and undo never crosses thread boundaries.

Undo also restores a $skill chip you just removed with Backspace, recovering both the chip and its position in the surrounding text — so an accidental delete doesn’t cost you the chip you spent time picking.

For recovery across threads or app restarts, see Composer draft history below — the mechanic there reaches further back than the per-thread undo stack does.

Composer draft history (↑ recovers your last message)

Every keystroke in the composer is autosaved to a per-profile store, including the text, any $skill chips, pasted images, and any rich formatting you applied. Drafts survive everything that historically lost them in other agent UIs:

To recover a previous draft, focus an empty composer and press (ArrowUp). The composer fills with the most recent candidate. Keep pressing to cycle further back through up to 20 recent candidates (per-profile); (ArrowDown) cycles forward through the same list.

Candidates include:

The recovery cycle is anchored on the blank composer state. Start typing once you’ve found the draft you want and the cycle ends — the next will move the cursor in the usual way.

Draft history is per PwrAgent profile — switching profiles via --profile <name> gives that profile its own independent history. Drafts never leave your machine.

Codex Desktop doesn’t have this yet either.

Thread context rail

The edited-files surface above the composer mid-turn. The header reads 'EDITED 2 FILES, +4, -1' with a SIDEBAR toggle on the right. Two file rows below: Update AGENTS.md (+3 / -0) and Update README.md (+1 / -1). The agent is 'Thinking…' and the composer's Send button is replaced by Stop / Queue while the turn is in flight.
The edited-files surface mid-turn — today this lives in the rail's Edits tab. EDITED 2 FILES, +4, -1 is the cumulative diff summary; each file row expands inline to show its diff. (Captured on an earlier build with the single-panel rail; the tabbed rail supersedes it.)

The right side of the thread view is the thread context rail — a tabbed panel, pinned open by default, that carries everything about the thread that isn’t the transcript. Ten tabs, in the order the rail lists them:

Toggle the rail with B on macOS or Ctrl+Alt+B on Windows and Linux, or from the thread header. While a turn is in flight, the Edits tab is the live “what has it actually changed” answer — when the turn completes the final state stays put, so walking back to the desk after a ten-minute turn you’re one glance from the answer instead of scrolling the transcript for it.

Pricing and usage

Every thread keeps a persistent cost ledger in the rail’s Pricing tab: per-turn usage cards (cached / uncached / reasoning / image tokens), per-turn durations, a Live marker on the in-flight turn, and running totals in USD and/or Codex Credits (display units are toggleable in Settings → Usage & Pricing). Forked threads show a zero-cost fork point — inherited history isn’t re-billed. Sub-agent runs carry their own usage cards, including cold / hot context-replay estimates.

Down in the composer’s footer sits the context-window moon — a moon-phase glyph that fills as the thread’s context window does. Hover it for the structured usage card: percent full, remaining tokens, and current-request vs session-total breakdowns with cache-hit meters. When you’re deep into the window it shifts to the warning treatment before Codex starts compacting.

Multi-message queueing

Composer with a turn in flight on the "Convert OAuth flow to PKCE" thread; "Review changes against main" (a queued /review against the base branch) and "now squash and push --force-with-lease" stacked as queued chips above the composer
The two QUEUED chips above the composer will fire FIFO when the in-flight make a branch and PR turn finishes. The composer's Send is replaced by Stop / Queue while a turn is active.

You don’t have to wait for the agent to finish a turn before queueing the next thing. While a turn is running, the composer’s Send stages your message as a queued turn instead of discarding the click — the queued message appears as a chip above the composer with a small × for cancel.

You can queue as many follow-ups as you want, and they dispatch FIFO, one turn at a time. The pattern that earns its keep:

  1. Send make a branch and PR for the OAuth refactor (turn 1).
  2. While that’s running, queue /review (turn 2).
  3. While that’s queued, queue now squash and push --force-with-lease (turn 3).

You walk away. By the time you come back, turn 1 has produced a branch and a PR, turn 2 has run a review pass and addressed findings, turn 3 has squashed and force-pushed. Slash commands queue exactly like free-form messages — /review, /status, and the rest are first-class queueable.

Queued turns are visible in the composer (chips with cancel ×) and in the transcript (a “queued: …” pill on the in-flight turn showing what’s next). Cancel any queued turn by clicking its × in the composer chip — earlier and later queue items keep their order.

This is the desktop counterpart to the messaging queue / steer flow; the two read and write the same per-thread queue, so a turn you queued from your phone shows up in the desktop’s composer chip list immediately, and vice versa.

Scheduled sends

The composer’s Send button is split — the chevron opens a schedule menu: Send in 15m / 30m / 1h / 2h, plus “at the next usage-limit reset” when the backend reports one (handy for queueing work to fire the moment your 5-hour Codex window rolls over).

Scheduled messages sit in the same queued-message area with a live countdown. Until dispatch they stay editable and deletable; while editing you get an explicit schedule checkbox and a Send now bypass. Sidebar thread rows carry a solid Scheduled chip (or the softer Queued chip) so you can see at a glance which threads have work waiting to fire.

/review — code reviews

Type /review in the composer and an inline review composer opens: pick the target — the thread’s base branch (the default, derived from the thread’s own git state), a specific commit (--commit <sha>), or custom instructions (--custom …) — and hit Start review. The review runs as a review turn and the findings render directly in the transcript.

Reviews run natively on Codex. Turning on PwrAgent-managed Code Review in Settings → Experimental routes them through a PwrAgent-managed child turn instead, which is what makes /review available on Grok and Kimi too, with per-review provider, model, and reasoning overrides. Gemini and Qwen don’t offer it — see Agent backends → What differs.

Threads with multiple linked worktrees ask which project / workspace to review first, so the diff is always against the workspace you meant. Reviews show up as sub-agent runs in the rail, with their own usage accounting.

Skills browser ($ autocomplete and chips)

Composer mid-message ("Let&#39;s use $ce") with the Skills autocomplete listbox open below it, showing matching skill rows like $ce:plan, $ce:brainstorm, $ce:compound
Typing $ in the composer opens the Skills listbox. Subsequent characters filter incrementally — here $ce narrows to skills whose names start with ce. Pick a row to insert it as an inline chip.

PwrAgent surfaces Codex skills (including plugin-exposed skills) directly in the composer. Type $ and an autocomplete dropdown opens with every skill the bound Codex profile exposes — the same $skill-name mention syntax Codex itself uses, but with inline picking and rich tooltips so you don’t have to remember the exact name.

Pick a skill → it lands as an inline chip at the cursor (the chip carries the skill name, a tooltip with the skill’s description, and a small × to remove it). The chip expands into the skill’s full mention markdown when the turn is submitted, so the agent sees $skill-name exactly as if you’d typed it.

You can mix skill chips with free-form text in any order: prose, chip, more prose, another chip. Multiple chips in one message are each prepended once.

The skill list is shared with the messaging Skills browser — both surfaces draw from the same Codex App Server skill registry. Adding a new plugin-exposed skill makes it appear in $ autocomplete on the desktop and in the paged Skills browser on every bound messenger automatically.

Search and navigation

Three search surfaces, plus browser-style history:

The sidebar’s inline filter still accepts branch names, PR numbers, emoji markers, and free text — filtering applies to whichever lens is active and respects its sort order.

Pin behavior is covered above under Sidebar lenses → Pins.

Agent tool results that reference other threads (a handoff’s child, a cross-thread message) come back with clickable thread links — click one and the app navigates straight to that thread. The links use an internal pwragent://thread/… scheme that resolves inside the app only; it’s deliberately navigation-only (no action verbs) and is never handed to the OS, so a link can take you somewhere but can never do something.

Native notifications

Opt-in system notifications for the moments that actually need you: an approval waiting, an agent asking a question, and turn completion / failure / cancellation. The approval notification is actionable — Approve from the notification resolves it without raising the window. Notifications auto-close when the thing they announced is handled, and clicking one routes you to the right thread.

Quit confirmation

If threads are mid-turn, sends are queued or scheduled, or integrated terminals are running, quitting asks first — with a rundown of what’s active so you’re not killing a 20-minute turn by muscle memory. Opt out in Settings → General if you like to live dangerously.

Files window

Local Markdown files the agent mentions in the transcript open as in-app previews instead of bouncing to an external editor, and a detached Files window can hold several Markdown files from the thread’s workspace side by side — handy when the agent writes a plan or a report you want open while the conversation continues.

Star Map

The title bar’s Star Map button opens a full-screen mission-control view of your work. Threads orbit as cards, projects sit at the centre of their own systems, and the whole thing pans and zooms — fly with W A S D, drag cards to arrange them, marquee-select several at once, and filter with chips. Floating chat cards carry a real Markdown composer, so you can send a turn without leaving the map, and K / Ctrl+K flies straight to a thread. Arrangements persist.

It’s the surface for “I have thirty threads across six repos and want to see the shape of it,” rather than a replacement for the sidebar.

Pull requests and Auto-fix PR

PwrAgent tracks the pull requests your threads produce. PR chips appear on thread rows and in the rail’s Pull requests tab with draft / conflicted / merged / closed state, and background PR status keeps them fresh across every open project rather than only the thread you have selected. It needs the gh CLI signed in, and it’s on by default — see Settings → Git.

Auto-fix PR goes one step further: when a linked pull request starts failing CI or becomes conflicted, PwrAgent can wake the owning thread and dispatch one bounded repair turn with the failed run’s context attached. It’s on by default for new threads, per-thread toggleable, and runs on a dispatch budget so a thrashing CI job can’t spawn turns without limit.

Sub-agents and MCP

When a thread delegates — a Codex-native sub-agent, a /review run, the title helper — the work shows up in the rail’s Sub-agents tab while it’s happening, with its own usage accounting. Open one in a read-only transcript window to see what it actually did, or stop a running one.

MCP servers configured for your Codex profile are managed from Settings → Plugins, and the thread surfaces any pending MCP interaction inline in the transcript.

Connect to PwrSnap

PwrSnap is the screenshot app in the same PwrSuite family. Connect it once and any thread you choose can ask its agent to search your capture Library, read edited previews, request edits, export images, and build Sizzle Reels — every one of those actions runs through PwrSnap, gated by the permissions you approve on PwrSnap’s side.

Where the prompt lives. Open a New thread and a PwrSuite connection card sits above the composer, headed Screenshots your agents can actually use. It appears for every backend PwrAgent drives — Codex and the ACP agents (Gemini, Grok, Kimi, Qwen) — and its single action button tracks what PwrAgent can see on this machine:

Prerequisite. PwrSnap has to be installed and listening. In PwrSnap, go to Settings → Local Agents and turn on Enable local-agent access — it’s off by default. If you click Connect to PwrSnap while that switch is off, PwrAgent launches PwrSnap if it can, waits a few seconds for the listener, and then shows:

Enable Local Agent Access in PwrSnap, then choose Connect to PwrSnap again.

Flip the switch in PwrSnap and click Connect to PwrSnap once more; the card re-checks PwrSnap’s state every time the PwrAgent window regains focus.

What clicking Connect does. PwrAgent performs the standard MCP OAuth handshake against PwrSnap’s local server itself — there is no key to generate and nothing to paste. It registers as PwrAgent and asks for the full set of Library, capture, export, edit, trash, and Sizzle Reel permissions so that PwrSnap can offer you every role. Your default browser opens a Continue in PwrSnap holding page while PwrSnap opens its own native approval window. That window is where the decision happens: give the session a Session Name you’ll recognize later, pick an access role (one of PwrSnap’s built-ins or a custom set of permissions and a history horizon), and choose Allow access or Deny. The exact permissions the agent ends up with are whatever you approve there — PwrAgent requests the superset and PwrSnap narrows it. PwrSnap’s side of the window is documented under Agents → Connect an agent on docs.pwrsnap.com.

Once you allow it, the browser tab lands on a PwrAgent page that reads PwrAgent is connected to PwrSnap and the launchpad card switches to the Use in this thread switch. The connection is stored per PwrAgent profile, so you connect once and then opt threads in individually.

You have five minutes. Both sides time the approval out: PwrSnap expires an unanswered request after five minutes, and PwrAgent stops waiting for the callback on the same clock. If it lapses, the card reports that the authorization timed out — just click Connect to PwrSnap again.

Disconnecting and reconnecting. Revocation happens in PwrSnap, not PwrAgent: open PwrSnap → Settings → Local Agents, find the session by the name you gave it, and click Revoke. PwrSnap re-checks policy on every call, so the revoke bites on the agent’s very next request — and narrowing a session’s role there works the same way, no reconnect needed. PwrAgent finds out the same moment: the next PwrSnap tool call in a thread fails with PwrSnap needs to be reconnected from New Thread. Reconnecting means running the approval again from a New thread card with Connect to PwrSnap, and PwrSnap will show you a fresh approval window with a fresh Session Name.

One caveat in current builds: PwrAgent doesn’t notice the revoke on its own, so it hangs on to the old credential and the launchpad card keeps offering the Use in this thread switch instead of the Connect button. Reconnect-after-revoke is tracked under Not yet.

Federation note. On a thread that runs on a federated peer (see Federation), the card reads PwrSnap is available on <machine> and only offers the per-thread switch — and only once that machine’s owner has connected their own PwrSnap. It never connects to PwrSnap on the machine you’re viewing from.

Federation

A PwrAgent profile can federate with other PwrAgent instances — your laptop and a workstation, say — so each can see and drive the other’s threads. Enrolled peers appear in the Profiles app menu; their threads mount into remote viewer windows with live transcript and PR sync, remote integrated terminals, and one K / Ctrl+K search across every connected instance.

Federation is off until you set it up, and the setup is its own screen — see Settings → Federation.

Multiple profiles

PwrAgent has two independent profile mechanisms that compose. Read once; the rest of the section is a worked setup.

PwrAgent profiles

A PwrAgent profile is selected by the PWRAGENT_PROFILE env var at launch. Each profile carries its own:

Creating a new PwrAgent profile is trivial: pick a name, set the env var, launch. PwrAgent creates the profile on first run under ~/.pwragent/profiles/<name>/.

Use case. Two PwrAgent profiles pointed at the same Codex auth share the underlying Codex threads, settings, and account — but they’re independent at the PwrAgent layer. That’s how you run multiple bots of the same platform (e.g. one Telegram bot for personal work and another Telegram bot for a small team, both driving the same Codex thread list).

Codex profiles

A Codex profile is an isolated CODEX_HOME directory the Codex App Server uses for its own state — auth tokens, thread history, config. Each Codex profile points at its own OpenAI Codex identity (or the same identity, if you want).

Use case. Two Codex profiles for a single PwrAgent install: ~/.codex/profiles/work/ (your day-job Codex account) and ~/.codex/profiles/personal/ (your personal account). Threads stay separated; auth stays separated. Switch between them by changing the Codex auth profile selection in Settings → AI Providers.

Cheekier use case. Four Codex profiles, each pointed at a different Codex Pro account, because you are an animal and need four accounts worth of tokens to rule the world. PwrAgent will not stop you.

How the two profile mechanisms compose

What’s isolated PwrAgent profile Codex profile
PwrAgent settings (config.toml)
PwrAgent state DB (state.db)
Messaging adapters + bot tokens
Codex threads + history
Codex auth (OpenAI account)
Per-thread settings stickiness

You can compose them however you want. Examples:

Managing profiles in the app

Both kinds of profiles are managed from Settings → Profiles:

Existing Codex threads can also be copied or moved between Codex profiles from Settings → Thread Management — see Settings → Thread Management.

Settings → Profiles panel listing PwrAgent profiles
Settings → Profiles. Every PwrAgent profile under ~/.pwragent/profiles/ is listed; the active one is highlighted. Switching restarts the app under the selected profile.

Profiles app menu

The macOS menu bar has a Profiles menu (between View and Window) that lists every PwrAgent profile and lets you switch without going through Settings.

Switching from this menu is window-aware: if a target profile already has a running PwrAgent process, the menu focuses that process’s main window instead of spawning a second one. If the process is alive but its window has been closed, the menu re-creates the main window inside the existing process. A new process spawns only when the target profile isn’t running at all.

The menu refreshes after profile creates and deletes so the entries stay current with whatever’s on disk under ~/.pwragent/profiles/.

Launching a profile from the command line

For automation or when you want to pin a specific PwrAgent profile at launch:

Installed .app — recommended:

open -na PwrAgent --args --profile work

The --profile <name> argument is the supported launch flag — it flows through Launch Services into the app’s argv, so the app shows up correctly in the Dock and Cmd-Tab list.

From source:

PWRAGENT_PROFILE=dev pnpm dev:no-messaging

The PWRAGENT_PROFILE env var still works as a fallback for any context where passing argv isn’t convenient (the dev server and shell-script launchers being the typical cases).

Under the hood

The in-app profile management writes to your config file the same shape an experienced operator would write by hand:

Verifying without going through the UI:

# Confirm the active PwrAgent profile selected the right Codex auth
# profile.
rg -n 'profile = "work"|\[models.codex\]' \
  ~/.pwragent/profiles/<your-pwragent-profile>/config.toml

# Once a Codex thread runs under the selected profile, confirm
# Codex state lands in the isolated CODEX_HOME.
find ~/.codex/profiles/work -maxdepth 4 -type f | sort | head -80

You should see entries like auth.json, config.toml, session_index.jsonl, sessions/, and (if used) worktrees/.

Mental model

The two settings live at different layers and don’t interact. Pick each one for its own reason.

Not yet

Features the desktop doesn’t have today that operators have asked about — captured here so you can plan around them:

Coming soon

Active development areas that have shipped designs but aren’t in release builds yet:

Watch the GitHub repo for the relevant PRs.

See also