A status console for AI coding agents, resident in the macOS notch.
macOS 14+ · Swift 6 · AppKit + SwiftUI · Reads local files only
Developers frequently run several AI coding agents in parallel: Claude Code in one terminal, Codex in another, TRAE or Qoder inside an IDE. Each agent reports its progress only inside its own window, so determining which agent is still working, which is blocked on a permission request, and which finished some time ago requires switching between windows.
Opsnook reads the session files that these agents write to local disk, normalises them into a single set of states, and displays the result in the notch area of the menu bar. The collapsed pill shows the highest-priority state across all sessions; the expanded panel lists every session, and permission requests from Claude Code can be approved or denied without leaving the panel.
codex_demo.mov
- Concurrent monitoring of seven agents: Claude Code, Codex, Antigravity, ZCode, WorkBuddy (CodeBuddy), TRAE SOLO and Qoder. Desktop and CLI variants of the same agent are detected and labelled separately.
- Six normalised states shared by all agents: needs approval, waiting for input, error, running, done, idle. Sessions are ordered by state priority.
- In-panel approvals for Claude Code. Decisions are returned to Claude through a
blocking
PermissionRequesthook, so the agent resumes as soon as a decision is made. - Session timeline. A swimlane view that replays one session: user input, tool calls, searches, file reads and edits, shell commands, git and network activity. Subagents are drawn in their own lanes. The view supports filtering by event type, search, zooming and both horizontal and vertical layouts.
- Usage and cost view. Token counts and estimated spend for today and the last seven days, broken down per agent.
- Workspace view. Uncommitted changes and branch status for the repositories the agents are working in.
- Focus return. Selecting a session row activates the application that owns it.
- Native macOS behaviour: the window collapses to a slim pill and expands on hover
or with
⌥⌘H, supports multiple displays, and is localised in English and Simplified Chinese. - Local processing only. Opsnook parses files already present on disk. No prompt, command, path or log is transmitted, and no account is required.
| Agent | Vendor | Capability level |
|---|---|---|
| Claude Code | Anthropic | L3: status, timeline, usage, in-panel approvals |
| Codex | OpenAI | L2: status, timeline, usage |
| Antigravity | L2: status, timeline | |
| TRAE SOLO | ByteDance | L2: status, timeline |
| Qoder | Alibaba | L2: status, timeline |
| WorkBuddy (CodeBuddy) | Tencent | L2: status, timeline |
| ZCode | Z.ai | L2: status, timeline |
Capability levels are defined in docs/AGENT_INTEGRATION_PLAN.md:
L1 covers running and idle only, L2 adds task title, project, branch and completion
or failure, and L3 adds approval requests answered from within the panel. An agent is
supported at L3 only when it exposes an official, blocking channel for returning a
decision.
The state derivation rules for each agent are documented one file per agent in
docs/sessions_status_logic/.
- macOS 14 or later. A Mac with a hardware notch is preferable; on displays without one, Opsnook draws an equivalent region at the top centre of the screen.
- The agents to be monitored, installed and used locally.
- A real
gitexecutable, for the workspace view only. Inside the App Sandbox/usr/bin/gitis an xcselect shim that fails, so Opsnook looks for agitbundled in the application, then for the one shipped with the Command Line Tools or Xcode. A build that bundles nogitwill show an empty workspace view on a machine without developer tools installed; the rest of the application is unaffected. Seedocs/SANDBOX.mdsection 5. - To build from source: Xcode 16 or later (Swift 6) and XcodeGen.
Opsnook runs inside the App Sandbox. On first launch it asks for read access to the data directory of each agent, and optionally to the workspace root, through the standard folder selection dialog. Access is scoped to the selected directories, persisted as a security-scoped bookmark, and can be revoked at any time in Settings.
# 1. Unit tests for the logic layer (no Xcode project required)
cd Packages/OpsnookKit && swift test
# 2. Generate the Xcode project (required after project.yml changes)
cd ../.. && xcodegen generate
# 3. Build the application
xcodebuild -project Opsnook.xcodeproj -scheme Opsnook-AppStore \
-configuration Debug-AppStore -derivedDataPath /tmp/OpsnookBuild \
CODE_SIGNING_ALLOWED=NO build
# 4. Run
/tmp/OpsnookBuild/Build/Products/Debug-AppStore/Opsnook.app/Contents/MacOS/OpsnookOpsnook-AppStore is the only scheme. The Xcode project is generated from
project.yml and is not committed.
No signing team is committed to the repository. To sign a build, supply your own
Team ID in any of these ways: create App/Config/Local.xcconfig (git-ignored) with
DEVELOPMENT_TEAM = <your Team ID>, pass DEVELOPMENT_TEAM=<your Team ID> on the
xcodebuild command line, or select a team in Xcode under Signing & Capabilities.
For a compile-only check, CODE_SIGNING_ALLOWED=NO as shown above needs no team.
Opsnook runs inside the App Sandbox. The capability degradations this implies, and
where they live in the code, are described in docs/SANDBOX.md.
App/ Application target: lifecycle, windows, dependency wiring
Packages/OpsnookKit/
Sources/OpsnookCore Models, state machine, session store (no OS side effects)
Sources/OpsnookAdapters One adapter per agent, plus the shared parsing helpers
Sources/OpsnookIntegration OS side effects: file access, focus, hooks, notifications
Sources/OpsnookUI SwiftUI views, design system, view models, timeline
Tests/ Unit tests for the four modules above
docs/ Product, architecture, and per-agent parsing documents
design/ Interface mockups, the project page, and icon sources
images/ Screenshots used by the documentation
scripts/ Packaging scripts
The dependency direction is fixed: OpsnookCore is depended upon by the other three
modules and depends on none of them. OpsnookCore does not import AppKit or SwiftUI,
which keeps the state machine testable without a running application.
| Document | Contents |
|---|---|
AGENTS.md |
Conventions for contributors and AI coding agents working in this repository |
docs/PRD.md |
Product requirements: state vocabulary, feature list F1–F18 |
docs/TECHNICAL_DESIGN.md |
Architecture, layering, concurrency model, capability degradation |
docs/FEATURES.md |
Implemented features with screenshots and code locations |
docs/PROJECT_FILE_GUIDE.md |
Purpose of every tracked file |
docs/CODE_TO_FEATURE_MAP.md |
Mapping from each UI element to the code that produces it |
docs/AGENT_INTEGRATION_PLAN.md |
Integration matrix and criteria for adding an agent |
docs/sessions_status_logic/ |
Session file format and state derivation, one file per agent |
docs/SANDBOX.md |
App Sandbox constraints, capability degradation, file access |
CONTRIBUTING.md |
How to build, test and submit a change |
SECURITY.md |
How to report a vulnerability |
CHANGELOG.md |
Notable changes per release |
LICENSE |
GNU General Public License, version 3 |
LICENSE-EXCEPTION.md |
Copyright notice and the App Store distribution permission |
The documents under docs/ are written in Chinese. README.md, CONTRIBUTING.md,
SECURITY.md, CHANGELOG.md and LICENSE-EXCEPTION.md are in
English, so that the repository can be approached without reading Chinese; the design
rationale and the per-agent parsing research remain in Chinese.
An adapter is a directory under Sources/OpsnookAdapters plus a registration entry.
The UI is not modified. The required steps are:
- Document the agent's session file location, format and state fields as a new file
in
docs/sessions_status_logic/, following the structure used by the existing files. - Implement a parser that turns the session file into
SessionSnapshotvalues, and an adapter conforming toAgentAdapter. - Add the brand and kind to
AgentCatalog, add the agent's data directory toAgentDirectoryAccess, and register the adapter fromApp/Composition/AppContainer.swift.AdapterRegistryitself needs no change: it is the runtime container adapters are registered into. - Add sample records under
Tests/OpsnookAdaptersTestscovering both current and malformed input.
Parsers must degrade rather than fail: an unrecognised record is skipped, and an unreadable file reports a degraded health state instead of raising an error.
Opsnook parses local session files inside the App Sandbox using security-scoped
bookmarks granted by the user. No prompt, command, path, log or any other session
content is transmitted anywhere, and no account is required. The privacy manifest in
App/Resources/PrivacyInfo.xcprivacy declares no tracking and no collected data
types.
The application makes exactly one kind of outbound network request, and only when
the user asks for it: the workspace view can run git push on a repository, which
contacts whatever remote that repository is configured with. This is why the sandbox
entitlements include com.apple.security.network.client. Nothing else in Opsnook
opens a network connection; there is no telemetry, no update check and no
analytics.
Issues and pull requests are welcome. Read AGENTS.md first: it records
the conventions this repository relies on, including the rule that every shared
literal has a single source of truth, and the requirement that parser changes come
with sample records covering both current and malformed input. Run swift test in
Packages/OpsnookKit before opening a pull request, and build the application target
when the change touches App/ or project.yml. CONTRIBUTING.md
summarises the same rules in English.
Contributions are accepted under the same license as the project.
Copyright © 2026 Opsnook contributors.
Opsnook is free software: you can redistribute it and/or modify it under the terms
of the GNU General Public License, version 3, as published by the Free Software
Foundation. See LICENSE for the full text.
The program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for details.
Because Apple's App Store imposes terms on recipients that GPL-3.0 does not by
itself allow a distributor to accept on their behalf, the copyright holders grant
an additional permission under section 7 of the license, covering distribution of
the compiled binary through such platforms. The source remains available under
GPL-3.0 without change. See LICENSE-EXCEPTION.md.
The brand icons under
Packages/OpsnookKit/Sources/OpsnookUI/Resources/BrandIcons/ are from the Lobe Icons
project and are distributed under the MIT license; see LICENSE.lobe-icons.txt in
that directory. Agent names and logos are trademarks of their respective owners and
are used here only to identify the tools being monitored.