jackin❯ Desktop Agent Hub
Status: Open — implementation program (daemon, native macOS status bar, desktop app, notifications)
Problem
jackin❯ is already becoming the control plane for isolated developer agents: workspaces define project boundaries, roles define runtime shape, and the daemon PR introduces the host-side process needed for reactive features. The missing piece is a native macOS operator surface that shows what is running, what needs review, and what agent accounts are close to exhaustion without forcing the operator to keep every terminal tab in view.
The desired experience is not a replacement for Claude Code, Codex, or Amp. The agent UI remains the agent's own TUI. jackin❯ Desktop should be the Mac-native control surface around those agents: start workspaces, see active containers, jump to pull requests, monitor token/account state, and receive attention prompts when an agent is blocked or finished.
This roadmap targets the complete Desktop Agent Hub experience: daemon-backed state, native macOS status bar, native desktop window, Ghostty workspace launch/focus, GitHub PR inbox, account/token status, and notification/attention routing. The phased plan below is the review strategy, not a reduced scope.
Existing local foundation
- The proposal layers on the roadmap items that motivated it: jackin❯ daemon, Live bidirectional auth sync, Agent attention prompts, and Host bridge — secrets and approved host actions. Those documents define the backend responsibilities Desktop should surface rather than reimplement.
- PR 283 implements the first daemon shape: per-user Unix socket, singleton lock, lifecycle commands, launchd / systemd install, keep-awake reconciliation, cache warmup, and macOS notification dispatch.
crates/jackin-runtime/src/runtime/launch.rsalready bind-mounts the daemon socket into role containers as/jackin/daemon.sockand injectsJACKIN_DAEMON_SOCKET=/jackin/daemon.sockwhen available.- The daemon draft also proves the minimal container-to-host notification path
over JSON Lines through
jackin-notify. crates/jackin/src/console/tui.rsis the current TUI workspace manager model. It exposes the same concepts the desktop app needs: workspace list, General / Mounts / Roles / Secrets / Auth tabs, dirty-save flow, modal pickers, and per-workspace summaries.crates/jackin-config/src/app_config/workspaces.rsandcrates/jackin-config/src/app_config.rsare the correct source of truth for workspace CRUD. Desktop should get workspace data through daemon endpoints that reuse these modules, with CLI or library calls reserved for fallback/bootstrap paths. It must not parse TOML itself.crates/jackin-core/src/agent.rsconfirms the initial supported agents are exactlyclaude,codex,amp,kimi, andopencode.
Prototype research
These apps are references, not implementation templates. jackin❯ should borrow specific native macOS interaction patterns from them while keeping the jackin❯ daemon, workspace, isolation, and agent-runtime model.
OpenUsage
Reference: https://github.com/robinebers/openusage
Useful ideas:
- Menu-bar-first usage panel focused on subscription visibility rather than full provider management.
- Provider tiles with progress bars, badges, reset windows, and clear stale/error labels.
- Automatic refresh with an operator-chosen cadence.
- Global shortcut to open the usage panel without hunting for the status item.
- Local HTTP API for other tools to read cached usage state.
- Proxy support for provider requests.
- Plugin-shaped provider extension point, even though current plugins are bundled while the API settles.
Implementation details worth borrowing selectively:
- The product model treats usage state as cached local data with a fast UI path, not as a live blocking request every time the menu opens.
- Provider implementations are separate from the menu surface, so adding or repairing a provider does not rewrite the UI.
- The local API is intentionally loopback-only. If jackin❯ exposes account usage outside the app, the daemon should provide a similarly local, explicitly scoped endpoint rather than a broad network listener.
What not to copy:
- OpenUsage is a generic AI subscription tracker. jackin❯ Desktop should not become a catalog of every AI provider; it should start with the runtimes jackin❯ launches and accounts the operator explicitly wires into jackin❯. Provider adapter shape and host-mutation policy live in the telemetry roadmap.
CodexBar
Reference: https://github.com/steipete/CodexBar
Useful ideas:
- Native macOS menu bar app, no Dock-first workflow.
- Provider refresh loop with a compact status item and richer menu details.
- Per-provider account and quota display, including multi-account support.
- Local cost scans over Claude and Codex logs.
- Manual and automatic credential-source settings with clear failure states.
Implementation details worth borrowing selectively:
Sources/CodexBar/StatusItemController.swiftshows the expected split: AppKit owns theNSStatusItemand menus, while SwiftUI renders rich menu cards and settings panes.Sources/CodexBar/UsageStore+Refresh.swiftshows the shape of provider refresh state: enabled providers refresh in the background, errors are throttled when prior data exists, and UI state stays responsive.- CodexBar's docs/codex.md documents reliable Codex paths: prefer
~/.codex/auth.jsonOAuth/API orcodex app-server; avoid launching the interactive TUI for routine background refresh. - CodexBar's docs/claude.md documents Claude paths: OAuth API where possible, file / Keychain fallback, and CLI PTY only as fallback/diagnostic.
- CodexBar's docs/amp.md and AmpUsageFetcher.swift
explain why Amp is brittle in CodexBar: it scrapes
https://ampcode.com/settingsusing browser cookies and expects asessioncookie. The recurring "please re-login to Amp" state can be caused by browser cookie import drift, expired web cookies, or Amp changing its embeddedfreeTierUsagepayload. jackin❯ should not make Amp status depend solely on browser cookies if the Amp CLI/account state is already available inside a jackin❯ runtime.
What not to copy:
- CodexBar's provider catalog is intentionally broad. jackin❯ should not inherit a generic "29 providers" architecture for a three-agent product.
- Hidden web scraping and cookie import should be optional diagnostics, not the primary path for jackin❯-owned account state.
- Token monitoring should be scoped to accounts jackin❯ launches, not every provider installed on the host.
Tokemon, Token Tracker, Brim, MeterBar, Control Tower
Source priorities, confidence labels, and accuracy reasoning for these apps live in Token & Cost Telemetry → Better accuracy references. Desktop borrows their macOS UI patterns:
- Brim — native rings for 5-hour and weekly windows; explicit refresh/freshness widget.
- MeterBar — simple multi-account dashboard layout; menu-bar plus CLI JSON pairing.
- Control Tower — quiet-hours, alert routing, and usage-history detail pages.
- Tokemon — terminal statusline export shape, burn-rate projection display.
- Token Tracker — menu bar + widget split for at-a-glance vs. detail views.
The data model and the UsageConfidence + UsageSnapshotStatus labels are the telemetry roadmap's contract; Desktop renders them.
RepoBar
Reference: https://github.com/steipete/RepoBar
Useful ideas:
- Native macOS menu bar repository dashboard with rich submenus.
- Repository cards/submenus that combine GitHub data and local checkout state.
- Cache-first GitHub data model with ETags, persistent cache, and rate-limit visibility.
- Local project discovery that scans git roots, reads branch/ahead/behind/dirty state, and avoids destructive sync.
Implementation details worth borrowing selectively:
Sources/RepoBar/StatusBar/StatusBarMenuBuilder.swiftbuilds the menu from a stable "menu plan" signature so expensive SwiftUI menu rows are not rebuilt on every open.Sources/RepoBarCore/LocalProjects/LocalProjectsService.swiftis a useful reference for bounded local git status collection, dirty-file summaries, and ahead/behind detection.Sources/RepoBar/Support/LocalRepoManager.swiftadds TTL caches and security scoped folder access. jackin❯ Desktop can avoid broad project scanning by using jackin❯ saved workspaces and mounted paths, but the cache approach is still useful.- RepoBar's PR/issues/actions submenus are close to the desired "jump straight to pull request" workflow.
What not to copy:
- RepoBar is centered on GitHub account/repository management. jackin❯ Desktop is centered on active jackin❯ workspaces and agent sessions; GitHub is a secondary integration for PR links and status.
- RepoBar scans a configured projects folder. jackin❯ should default to the workspaces jackin❯ already knows about and the containers jackin❯ is currently running.
Product shape
Menu bar item
The menu bar item should answer one question at a glance: "Do I need to look at jackin❯ right now?"
Proposed states:
- Idle: no running jackin❯ roles.
- Running: one or more active workspaces, with a compact count.
- Waiting: at least one agent has called
attention.waitingor inferred idle waiting. This should visually dominate running state. - Ready for review: an agent has pushed or reported a PR as ready.
- Auth/account warning: Claude, Codex, Amp, Kimi, or OpenCode account status requires operator action.
- Daemon disconnected: Desktop cannot reach the jackin❯ daemon.
The menu bar label should be conservative:
- Icon only by default.
- Optional text:
3active sessions,2 waitwhen attention is required, or the most constrained active account when quota is the highest-risk status. - Quota visibility is first-class and on by default for active sessions:
Claude 36%,Codex 18%,Amp login, or a compact ring/gauge icon. The status item can stay visually quiet, but the operator must be able to see low quota, stale quota, or auth failure from the menu bar without opening the full Desktop window. - The popover must explain the provider, account, quota window, reset time, freshness, and source before the operator trusts the number.
Main menu
The main menu should be PR-first, then workspace-aware. The fastest path should be: open the status item, pick the PR, land in GitHub. Workspaces matter because they explain which local jackin❯ sessions and repositories are currently active, but the operator's day-to-day decision is usually "which pull request do I need to open now?"
- Header: daemon status, active session count, last refresh time.
- My open pull requests: PRs created by the operator, sorted newest first, with direct browser actions.
- Active projects: repositories recently touched by jackin❯ work, grouped by owner/org and filterable later in the app window.
- Active workspaces: each row shows workspace name, repo/branch, role, agent, container state, last event, and primary action.
- Ready for review: PR rows promoted to the top when an agent explicitly reports a PR as ready.
- Accounts: cards for the configured built-in jackin❯ runtimes (Claude, Codex, Amp, Kimi, OpenCode), one or more accounts each.
- Recent / saved workspaces: launch shortcuts for jackin❯ workspaces not currently running.
- Footer: Open Desktop, Refresh, Open Console, Settings, Quit.
Account rows follow the Token & Cost Telemetry account-snapshot model: quota window, reset time, source, stale/error state, confidence label, and repair action. The jackin❯ daemon is the data source; Tokemon, Token Tracker, Brim, MeterBar, CodexBar, and OpenUsage are comparison references.
The menu should be usable without opening the full Desktop window. A first-pass shape:
jackin❯
Running: 3 workspaces Last refresh 10s ago
My open PRs
jackin-project/jackin #299 Desktop Agent Hub 2m ago Open
acme/backend #184 auth sync cleanup 1h ago Open
tailrocks/site #72 docs pass 2d ago Open
Active projects
jackin-project/jackin 1 workspace 2 agents 1 PR
Open project on GitHub
Open pull requests
Active workspaces
jackin-project/jackin
Role: the-architect Agent: Codex Branch: docs/desktop-hub
Open PR #299
Open repository on GitHub
Open in Ghostty
Stop role
acme/backend
Role: backend-engineer Agent: Claude Branch: feature/live-auth
No PR detected
Open repository on GitHub
Open pull requests page
Open in Ghostty
Saved workspaces
jackin-project/jackin Start...
tailrocks/site Start...
Accounts
Claude Enterprise 36% left resets 3h provider
Claude Personal 88% left resets 4h provider
Codex Personal 62% left resets 2h provider
Amp Personal needs loginThis is closer to a compact operations menu than a dashboard. The default click target for a PR row opens the PR in the browser. Holding Option or opening the submenu can expose secondary actions like copy URL, open checks, copy branch, or reveal the workspace that produced the PR.
The My open PRs section is intentionally inspired by GitHub's authenticated pull-request inbox (https://github.com/pulls/inbox): a compact, always-available view of active pull requests. jackin❯ should not clone GitHub's full UI or attempt to show every GitHub detail. It should take the useful idea — a focused inbox for the work the operator is actively responsible for — and scope it to recently active jackin❯ projects plus optional org/project filters.
Workspace drill-down
Every workspace row should be a small hierarchy:
- Workspace row: name, active/running state, number of repositories mounted, number of running roles, and last relevant event.
- Repository rows under that workspace: each Git remote detected from mounted repos or worktrees, with branch and dirty/ahead/behind status when cheap.
- Repository actions:
- Open repository on GitHub.
- Open repository in Finder / editor.
- Open pull requests page for that repository.
- Open current branch PR if one exists.
- Copy remote URL / branch name.
This solves the "I cannot currently see those repositories" pain directly: jackin❯ Desktop should only show repositories that belong to jackin❯ workspaces or running sessions, not the entire disk and not every GitHub repository the account can access.
Workspace row actions:
- Open Ghostty / hardline into the running role.
- Open PR in browser.
- Open repository in editor or Finder.
- Copy branch name.
- Stop / eject role.
- Mute attention for this workspace.
Desktop window
The status item is the glance surface; the window should stay simple for the first version. Do not port the full jackin console workspace editor into macOS yet. The existing TUI is already the right place for creating/editing workspace settings, mounts, roles, secrets, and auth. The desktop window should help the operator see current focus, launch existing workspaces, monitor running agents, inspect token/account state, and open PRs quickly.
Recommended layout:
NavigationSplitView.- Sidebar: Pull Requests, Projects, Workspaces, Running Agents, Accounts, Settings.
- Pull Requests: an inbox-style list of open PRs authored by the operator, newest first, with filters for organization, project/repository, workspace-linked only, draft/open, and ready-for-review.
- Projects: GitHub repositories jackin❯ has seen recently through saved workspaces, running sessions, mounted repos, branch activity, or PR tracking. This is not "all GitHub repositories"; it is the operator's current working set.
- Workspaces: saved jackin❯ workspaces with a launch button, active/running badge, number of running agents, primary repositories, and last activity. No create/edit form in v1.
- Running Agents: current role containers grouped by workspace/project, with agent runtime, role, branch, PR, attention state, focused-account quota, workspace spend, and stop/hardline/open actions.
- Accounts: Claude/Codex/Amp/Kimi/OpenCode account cards with source, plan/quota, reset time, confidence, last refresh, stale/error state, and repair/login actions.
- Usage: workspace/session spend view showing tokens and cost by workspace, role, agent, model, and time window.
Compact visibility rule: every Desktop view that can start, focus, or stop an agent should show the active account quota beside that agent. The full Accounts and Usage screens are for inspection; the Running Agents, Workspaces, and menu-bar surfaces are for immediate "can I safely keep working?" decisions.
Launching a workspace from the app should always use Ghostty in v1. The app can open a new Ghostty tab or new Ghostty window and run the appropriate jackin load / jackin hardline flow with --debug only for operator-requested smoke validation, not normal app launches. Other terminal adapters are out of scope until the Ghostty path proves the product shape.
The desktop app must remain optional. Installing jackin CLI should not require
the app. Installing the app should require or bootstrap a compatible jackin
CLI and daemon.
Desktop should treat the daemon as its primary data plane. The status bar and window ask the daemon for workspace, session, GitHub PR, account, attention, and host-bridge state because the daemon is the component that can keep those statuses warm and reactive. Direct CLI calls from the app are reserved for one-shot actions or fallback cases where the daemon is unavailable, broken, or would make the UI/UX worse.
The Desktop account UI should not try to reconcile conflicting numbers silently. If provider quota says "64% used" and local logs imply "31% used," the row shows provider quota as the enforced availability and local logs as workspace/session attribution. This is the core accuracy distinction from the Token & Cost Telemetry roadmap item.
Architecture proposal
Components
jackinCLI/library: source of truth for config, workspace CRUD, runtime launch/eject/hardline, GitHub URL resolution, auth-source resolution.jackin daemon: per-user host process and control socket. It owns reactive state, event streams, notifications, live auth sync, account monitors, and host-bridge approvals.jackin❯.app: native macOS app. It owns UI, launch-at-login preference, menu bar status item, settings window, and system integrations that require app identity. It reads reactive state from the daemon first and uses CLI calls only for narrow fallback or one-shot flows.- Optional helpers: small Swift helpers for LocalAuthentication approval and login/account diagnostics, invoked by the daemon or app.
Recommended protocol changes to PR 283
PR 283 is a good daemon foundation, but Desktop needs a more intentional API before this is merged as "the" daemon contract.
Add request/response shapes:
daemon/hello: protocol version, daemon version, capabilities, socket paths.workspace/list: saved workspaces fromAppConfig.session/list: running Capsule-backed instances with labels, workspace, role, agent, branch, PR candidate URLs, state, started time, last activity.workspace/launch: launch an existing saved workspace/role/agent through the daemon/app action path.session/action: hardline/open-in-ghostty/stop/eject/mute.event/subscribe: JSON Lines stream of session, attention, auth, PR, and daemon health events.account/list: configured Claude/Codex/Amp/Kimi/OpenCode accounts and latest quota snapshots, including freshness and confidence.account/refresh: explicit account status refresh with provider-specific backoff.usage/workspace: token/cost totals for a workspace over today, week, month, lifetime, or a custom range.usage/session: token/cost totals for one running Capsule session.usage/focused: active account quota plus session/workspace spend for the currently focused Capsule pane.github/project_inbox: open PRs for recently active jackin❯ projects, with org/project filters.github/my_open_prs: open PRs authored by the operator, sorted by created date descending.github/repository_prs: PRs for a workspace/repo/branch, cache-first.desktop/open: daemon-assisted actions for browser open, Ghostty launch/focus, and native notification click handling.
Keep Notify as a low-level primitive, but do not make Desktop infer all state
from notification messages.
Daemon state model
The daemon should maintain an in-memory state cache and append a small event log:
~/.jackin/run/jackin-daemon.sock
~/.jackin/run/jackin-daemon.log
~/.jackin/events/events.jsonl
~/.jackin/cache/github/
~/.jackin/cache/accounts/
~/.jackin/cache/usage/Session discovery can start from Docker labels already present in
crates/jackin-runtime/src/runtime/launch.rs:
jackin.managed=truejackin.kind=rolejackin.class=<role>jackin.display_name=<display>- plus new labels for workspace name, agent, branch, and primary repo.
The Desktop app should not shell out to docker directly. It asks the daemon,
and the daemon reuses jackin❯ runtime discovery code.
Account monitoring
Support only the current jackin❯ agents:
- Claude:
- support at least two operator accounts: Enterprise/company and personal.
- prefer Claude OAuth/API/file/Keychain state already used by jackin❯ live auth sync; CLI PTY only as diagnostic fallback.
- Codex:
- support personal account from
~/.codex/auth.json/CODEX_HOME. - prefer API/app-server style status where possible.
- support personal account from
- Amp:
- treat CodexBar's browser-cookie scraping as a last resort.
- first research whether Amp CLI has a local auth/config/session file or a noninteractive status endpoint that jackin❯ can read.
- if Amp only exposes web state, surface that as "web-cookie source" so the operator understands why relogin is needed.
Account status should be daemon-owned because it is useful to CLI, TUI, and Desktop. Desktop displays it; it does not own the scraping/token logic.
The daemon should cache account and usage data once on the host and fan it out to the Desktop app, jackin console, CLI commands, and Capsule. Running role containers should not each poll providers independently. If an agent needs to read the latest state from inside a container, Capsule should expose a read-only control-channel response or a daemon-materialized file under /jackin/run/usage/ with freshness metadata. The host cache is the write authority; container files are views.
Host-side effects
Desktop may display, refresh, and request repairs for daemon-owned account and usage state, but the daemon remains the only writer for the telemetry cache described in the Token & Cost Telemetry roadmap item. Desktop repair controls must surface any host-side write before it happens; background refresh must not silently alter provider config, Keychain entries, browser profiles, dotfiles, Git config, or user repositories.
GitHub / PR integration
The highest-value Desktop feature is direct PR access.
There are three related but distinct surfaces:
- Workspace PRs. PRs connected to the current workspace/session/branch. These appear inside the workspace drill-down and should answer: "What can I review for this running agent?"
- My open PRs. Every open PR authored by the operator across repositories jackin❯ knows about, sorted by creation date descending. These appear near the top of the status menu so the operator can immediately jump to the newest PR Jack created.
- Project inbox. A GitHub pull-request inbox scoped to recently active jackin❯ projects. This is the main desktop-window view and should support filters by organization, repository/project, workspace-linked status, draft/open status, and eventually "ready for my review" vs "authored by me".
Data sources in order:
- Agent-reported PR URL through an attention/progress event.
- Current branch in the mounted repo/worktree plus GitHub remote:
gh pr view --json url,state,title,headRefName,baseRefName,isDraftor a daemon GitHub client. - Cache of recently opened PRs for that workspace/branch.
- GitHub REST/GraphQL fallback if
ghis unavailable.
The menu should promote PRs as soon as a PR URL is known. It should not wait for full RepoBar-style repository hydration.
For My open PRs, the daemon should query cache-first and refresh in the background:
- Preferred first implementation:
gh search prs --author @me --state open --json repository,title,url,number,createdAt,updatedAt,headRefName,isDraftif the installedghsupports it, or equivalentgh apicalls. - Fallback: GitHub GraphQL search:
type:pr is:open author:@me archived:false, sorted bycreated-desc. - Scope: start with repositories present in jackin❯ saved/running workspaces and repositories with recent jackin❯-observed activity. Add an optional "all accessible repositories" mode later only if the current-focus model proves too narrow.
- Sorting: newest
createdAtfirst, oldest at the bottom. Do not sort by updated time for the default view because the user's mental model is "what did Jack just create?" - Row content: repository name, PR number, title, draft/open marker, created relative time, and optional workspace badge if a jackin❯ workspace matches.
- Empty state: "No open PRs authored by you in jackin❯ workspaces."
The daemon should expose this as a specific endpoint rather than asking the app
to run gh:
github/my_open_prs: returns authored open PRs sorted newest first.github/project_inbox: returns open PRs for recently active jackin❯ projects with org/project filters.github/repository_prs: returns open PRs for a workspace repository.github/open: opens a repository, repository PR page, or PR URL through the host browser action path.
Native macOS design
Use a native SwiftUI/AppKit app, targeting macOS Tahoe 26 where available while remaining usable on the minimum supported macOS.
Design rules:
- Use
MenuBarExtra/NSStatusItemfor the menu bar item. - Prefer
MenuBarExtrawith a menu-style surface for the first MVP if the content stays shallow. Use a window-style popover only when workspace drill-downs need richer SwiftUI rows than native menus can comfortably hold. - Use SwiftUI
NavigationSplitView,List,Table,Form,Toolbar, and standard controls for the main window. - Use Liquid Glass only where system components provide it naturally: toolbars, sidebars, popovers, controls, and navigation. Do not build a custom frosted dashboard everywhere.
- Keep content dense and developer-oriented: status rows, tables, badges, and actions. Avoid marketing-card layout.
- Respect Reduce Transparency, Increase Contrast, and keyboard navigation.
- Prefer SF Symbols for menu/status indicators.
Apple references:
- Liquid Glass overview: https://developer.apple.com/documentation/TechnologyOverviews/liquid-glass
- macOS menu bar guidance: https://developer.apple.com/design/human-interface-guidelines/the-menu-bar
- SwiftUI menu bar extra guidance: https://developer.apple.com/documentation/SwiftUI/Building-and-customizing-the-menu-bar-with-SwiftUI
- WWDC25 "Build a SwiftUI app with the new design": https://developer.apple.com/videos/play/wwdc2025/323
Proposed implementation phasing
This program should be delivered as a quiet, long-running implementation track, not as one large feature branch. The agent running the goal should keep building without asking for step-by-step approval, but every externally reviewed unit must be a small pull request.
The phases are delivery slices for review, not optional scope reductions. The long-running goal should continue through daemon APIs, menu bar, desktop window, notifications, and attention routing unless blocked by a documented design issue or repository constraint that must be resolved first.
Delivery rules:
- Create sequential pull requests, not one large PR. Each PR should be reviewable on its own and should leave the repo in a useful state.
- The implementation track is complete only when all major stages have been delivered as separate reviewable PRs: daemon contract, daemon data endpoints, native status bar, PR/project inbox, account status, Ghostty actions, desktop window, notifications, and attention routing.
- Implement all PRs without waiting for operator approval, but do not merge any of them. The operator owns merge decisions and will explicitly ask for fixes when a reviewed PR needs changes.
- Stack PRs in dependency order by branching each next PR from the previous PR branch. PR 2 depends on PR 1, PR 3 depends on PR 2, and so on. This makes the implementation chain visible while still keeping each stage small.
- Never hijack the middle of the chain. If PR 1 needs fixes after PR 2 or PR 3 already exists, fix PR 1 first, then replay/adjust the downstream stacked branches so the chain remains coherent.
- Every PR body must identify its place in the chain: previous PR, this PR, next PR, base branch, and whether it is blocked on an earlier PR landing. The reviewer should always know which PR to review first and which PR comes next.
- Keep every PR focused on one stage: daemon contract, session discovery, GitHub PR lookup, menu bar shell, account status cards, workspace launch, desktop window, attention integration, or host-bridge UI. Do not combine unrelated stages just because they are part of the same goal.
- Follow the repo's existing PR and commit standards for every PR in the chain:
AGENTS.md,PULL_REQUESTS.md, andCONTRIBUTING.md. This includes the expected PR body shape, verification notes, Conventional Commit subjects, DCO signoff, and the required agent co-author trailers when agents contribute. - Every PR must include focused tests or an explicit reason tests are not meaningful for that slice. UI PRs should include the strongest practical local verification for the current repo shape.
- Continue silently between PRs: after opening one PR, start the next branch on top of that PR branch unless blocked by CI, merge conflicts, or a design contradiction that cannot be resolved from the roadmap.
- Treat the daemon draft PR as editable, not fixed. If a required Desktop contract belongs in PR 283, update that daemon PR directly instead of working around a weak daemon API in later Desktop branches.
- Keep PR descriptions stage-aware: what this PR adds, what it intentionally defers, how to verify it, and which PR should be reviewed next after this one lands.
Phase 0 — Validate daemon contract before merge
- Keep PR 283 as the base, but add explicit capability/version handshake.
- Add
workspace/list,session/list,workspace/launch,github/my_open_prs,github/project_inbox,github/repository_prs, andevent/subscribe. - Add labels at container launch for workspace name, agent, branch, and primary mount/repo.
- Add tests around daemon protocol compatibility, session discovery, PR sorting, and project filtering.
Phase 1 — Menu bar MVP
- PR 1: Native
jackin❯.appskeleton with menu bar extra and daemon connection health only. - PR 2: Add active workspaces and running-agent counts.
- PR 3: Add My open PRs newest-first and active projects.
- PR 4: Add open actions for hardline / Ghostty, repository, and PR.
- PR 5: Add account cards for the built-in jackin❯ runtimes using daemon-provided status. Implementations may stage individual providers by adapter maturity, but the Desktop model and daemon API stay shaped for Claude/Codex/Amp/Kimi/OpenCode from the start.
Phase 2 — Simple desktop window
- PR 1: Add the simple native window shell with
NavigationSplitView. - PR 2: Add the inbox-style Pull Requests view with organization/project filters.
- PR 3: Add the Projects view for recently active jackin❯ repositories.
- PR 4: Add the Workspaces view for saved workspace visibility and launch-only actions.
- PR 5: Add the Running Agents view with per-workspace agent counts and Ghostty open/hardline actions.
- Keep workspace creation/editing in
jackin consoleacross all Phase 2 PRs.
Phase 3 — Attention and PR readiness loop
- Implement
jackin-attentionMCP server and richer daemon attention events. - Promote "waiting" and "ready for review" states in the menu bar.
- Notification click opens the exact Ghostty session or PR.
Phase 4 — Live auth sync and host bridge UI
- Desktop surfaces account sync state and repair actions.
- Desktop provides the approval UI for host bridge requests using LocalAuthentication.
- Add audit timeline and policy editing.
Open questions
- Should
jackin❯.appembed thejackinbinary, require Homebrew-installedjackin, or support both with version negotiation? - Should the daemon live in the Rust CLI binary long term, or should Desktop ship a macOS-specific LaunchAgent wrapper that launches the Rust daemon?
- What is the real Amp local auth/status surface? This needs dedicated research before copying CodexBar's browser-cookie strategy.
- What is the exact Ghostty launch/focus contract for v1: new tab by default, new window by preference, or always new window for isolation?
- Should PR lookup use
ghas the first implementation, or should jackin❯ build a small GitHub client in the daemon immediately?
Related work
- jackin❯ daemon — base daemon lifecycle, control socket, notification bridge, and the contract this feature depends on.
- Live bidirectional auth sync — daemon adapter that should own account/auth sync state for the built-in jackin❯ runtimes and GitHub CLI.
- Agent attention prompts — daemon/MCP path for waiting, finished, and ready-for-review events.
- Host bridge — secrets and approved host actions — future approval UI and audit timeline that Desktop should surface natively.
- GitHub link tracking — adjacent PR/repo/link-state tracking work from the Agent Orchestration Program.
- Agent runtime status — live busy/idle/waiting status vocabulary that the menu bar should eventually use.
- Token & Cost Telemetry — broader
token/cost tracking work; Desktop reads the same built-in-runtime account
snapshots as
jackin console, CLI usage views, and Capsule instead of owning a narrower provider list. - CodexBar — native menu bar reference for provider/account quota display, refresh loops, and status-item UI. Borrow selectively; avoid its broad provider catalog and browser-cookie-first Amp model as jackin❯ defaults.
- RepoBar — native menu bar reference for repository/PR menus, cache-first GitHub state, and local checkout status. Borrow the active-workflow ideas; keep jackin❯ centered on workspaces and running agents rather than all accessible GitHub repositories.