|
1 | 1 | # AGENTS.md |
2 | 2 |
|
3 | | -This file provides guidance to Codex (Codex.ai/code) when working with code in this repository. Use english for your response |
| 3 | +This file is the canonical guidance for coding agents working in this repository. Use English for all responses and all committed project text. |
4 | 4 |
|
5 | 5 | ## Project Overview |
6 | 6 |
|
7 | | -RxCode is a native macOS desktop client for the Codex CLI. Written in Swift + SwiftUI with two external dependencies: SwiftTerm (terminal emulation) and Sparkle (auto-update). |
| 7 | +RxCode is a native macOS desktop client for AI coding agents. It is written in Swift and SwiftUI, with a project-centric UI for Claude Code, Codex, and Agent Client Protocol (ACP) clients. The app includes streaming chat, permission approval flows, run profiles, Git worktree support, natural-language thread search, mobile sync, and briefing/change tracking. |
| 8 | + |
| 9 | +The main app target is a macOS app. The repository also contains shared Swift packages, widget/mobile-related code, website assets, and release tooling. |
8 | 10 |
|
9 | 11 | ## Writing Rules |
10 | 12 |
|
11 | | -- All text committed to the project — code comments, commit messages, PR descriptions, log messages — must be written in **English**. |
| 13 | +- Write code comments, log messages, commit messages, PR descriptions, documentation, and user-facing text in English. |
| 14 | +- Keep documentation factual and current. Prefer removing duplicated guidance over maintaining the same instructions in multiple files. |
| 15 | +- Preserve user changes. Do not revert unrelated local edits unless the user explicitly asks for that. |
12 | 16 |
|
13 | | -## Build & Run |
| 17 | +## Build And Run |
14 | 18 |
|
15 | 19 | ```bash |
16 | | -# Open in Xcode (build/run with Cmd+R) |
| 20 | +# Open in Xcode |
17 | 21 | open RxCode.xcodeproj |
18 | 22 |
|
19 | | -# CLI build |
| 23 | +# Debug build |
20 | 24 | xcodebuild -project RxCode.xcodeproj -scheme RxCode -configuration Debug build |
21 | 25 |
|
22 | 26 | # Release build |
23 | 27 | xcodebuild -project RxCode.xcodeproj -scheme RxCode -configuration Release build |
| 28 | + |
| 29 | +# Swift package build |
| 30 | +swift build --package-path Packages |
| 31 | + |
| 32 | +# Swift package tests |
| 33 | +swift test --package-path Packages |
24 | 34 | ``` |
25 | 35 |
|
26 | | -- Minimum deployment target: macOS 26.0+ |
27 | | -- No test suite (UI app) |
28 | | -- Bundle ID: `com.idealapp.RxCode` |
29 | | -- External dependencies: SwiftTerm (terminal emulation), Sparkle (auto-update) |
| 36 | +Project notes: |
| 37 | + |
| 38 | +- macOS app deployment target: macOS 26.0+ |
| 39 | +- Swift tools version: 6.2 |
| 40 | +- Main app bundle ID: `com.rxlab.RxCode` |
| 41 | +- App-level dependencies: SwiftTerm and Sparkle |
| 42 | +- Package dependencies: ViewInspector, Textual, and MarkdownUI |
| 43 | + |
| 44 | +## Repository Layout |
| 45 | + |
| 46 | +| Path | Purpose | |
| 47 | +| --- | --- | |
| 48 | +| `RxCode/` | macOS app target: app entry point, SwiftUI views, services, resources, and integrations. | |
| 49 | +| `RxCode/App/` | `AppState`, app lifecycle, session handling, streaming, project/worktree logic, mobile sync dispatch, and agent coordination. | |
| 50 | +| `RxCode/Services/` | Actor-based and service-oriented integrations for agents, permissions, GitHub, persistence, mobile sync, search, MCP, updates, and run profiles. | |
| 51 | +| `RxCode/Views/` | SwiftUI UI surfaces: main workspace, chat, sidebar, inspector, settings, terminal, permissions, search, run profiles, and onboarding. | |
| 52 | +| `Packages/Sources/RxCodeCore/` | Shared models, theme, utilities, run profile models, Git helpers, CLI session parsing, backend contracts, and reusable non-app UI primitives. | |
| 53 | +| `Packages/Sources/RxCodeChatKit/` | Reusable chat UI, message rendering, input bar, slash commands, shortcuts, diffs, queue UI, and plan/question views. | |
| 54 | +| `Packages/Sources/RxCodeSync/` | End-to-end encrypted sync protocol, pairing, APNs alert payloads, and mobile/desktop transport data structures. | |
| 55 | +| `RxCodeWidget/` | Widget and Live Activity support for active work and usage information. | |
| 56 | +| `RxCodeTests/`, `RxCodeUITests/` | App-level XCTest and UI test coverage. | |
| 57 | +| `Packages/Tests/` | Swift package tests for core, chat kit, and sync logic. | |
| 58 | +| `website/` | Public website and screenshot assets. | |
| 59 | +| `scripts/` | Build, signing, notarization, Sparkle, and release automation. | |
30 | 60 |
|
31 | 61 | ## Architecture |
32 | 62 |
|
33 | 63 | ### Core Patterns |
34 | 64 |
|
35 | | -- **Observable AppState** (`App/AppState.swift`): `@MainActor @Observable` single state container. Manages all app state including projects, sessions, chat, and permission approvals. |
36 | | -- **App entry point** (`App/RxCodeApp.swift`): Defines WindowGroup (main), WindowGroup(id: "project-window") for dedicated per-project windows, Settings window, and Command menu (theme, update). |
37 | | -- **Actor-based services**: All services are implemented as `actor` for concurrency safety. Isolated without locks. |
38 | | -- **SwiftUI only**: No Storyboards or XIBs. 100% declarative UI. |
39 | | - |
40 | | -### Package Structure |
41 | | - |
42 | | -The codebase is split into two Swift packages under `Packages/`: |
43 | | - |
44 | | -| Package | Role | |
45 | | -| --------------- | ---------------------------------------------------------------- | |
46 | | -| `RxCodeCore` | Shared models, theme, utilities — no UI dependencies | |
47 | | -| `RxCodeChatKit` | Chat UI components (ChatView, MessageBubble, InputBarView, etc.) | |
48 | | - |
49 | | -### Service Layer (`Services/`) |
50 | | - |
51 | | -| Service | Role | |
52 | | -| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | |
53 | | -| `ClaudeService` | Spawns Codex CLI as a subprocess, parses stdout NDJSON stream, buffers text deltas at 50ms intervals | |
54 | | -| `PermissionServer` | Network framework-based local HTTP server (ports 19836–19846). Receives CLI PreToolUse hook requests and holds the connection until UI approval | |
55 | | -| `GitHubService` | OAuth Device Flow authentication, Keychain token storage, SSH key generation/registration, repo cloning | |
56 | | -| `PersistenceService` | JSON file-based persistence at `~/Library/Application Support/RxCode/`. Per-project/session directory structure | |
57 | | -| `MarketplaceService` | Parallel fetch of plugin catalog from 4 Anthropic GitHub repos, 5-minute cache | |
58 | | -| `RateLimitService` | Anthropic usage API polling, OAuth token refresh, usage tracking | |
59 | | -| `UpdateService` | Sparkle-based auto-update manager. Starts updater on launch; exposes `checkForUpdates()` for menu-initiated checks | |
60 | | -| `BashSafety` | Whitelist-based read-only command validator. Blocks mutating git/Codex/npm subcommands and write redirections | |
61 | | - |
62 | | -### Data Flow |
63 | | - |
64 | | -1. User input → `AppState.send()` → `ClaudeService.send()` spawns CLI subprocess |
65 | | -2. CLI stdout → NDJSON `AsyncStream<StreamEvent>` → per-event processing in `processStream()` |
66 | | -3. Text deltas buffered at 50ms intervals to prevent SwiftUI update thrashing |
67 | | -4. On tool execution: PermissionServer receives HTTP request → UI approval modal → returns response |
68 | | -5. On project switch: in-progress stream detached to background Task, saved to disk on completion |
69 | | - |
70 | | -### View Structure (`Views/`) |
71 | | - |
72 | | -- `MainView`: NavigationSplitView (sidebar + detail) with project tab bar |
73 | | -- `ProjectWindowView`: Dedicated single-project window (opened by double-clicking a project tab) |
74 | | -- `SettingsView`: App settings window (model defaults, appearance, etc.) |
75 | | -- `Chat/`: Main chat UI, message streaming, slash commands, attachments, marketplace, file diff, status line |
76 | | -- `Sidebar/`: Project list, session history, file tree, Git status, file preview, GitHub repo list |
77 | | -- `Onboarding/`: Initial setup flow, GitHub login |
78 | | -- `Permission/`: Risk-based (Safe/Moderate/High) tool approval modals |
79 | | -- `Terminal/`: SwiftTerm-based built-in terminal |
80 | | -- `UserManualView`: In-app user guide (Help menu). NavigationSplitView with topic list and detail. Topics: overview, projects, chat, shortcuts, slash commands, attachments, shortcut buttons, terminal, marketplace, permissions |
81 | | -- `InspectorMemoPanel`: Sidebar inspector panel with a rich-text (NSTextView) memo editor, persisted per project |
82 | | - |
83 | | -### Compiler Settings |
84 | | - |
85 | | -- `SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor` — default MainActor isolation |
86 | | -- `SWIFT_APPROACHABLE_CONCURRENCY = YES` |
87 | | -- App Sandbox disabled (required for system integration) |
88 | | - |
89 | | -### Theme |
90 | | - |
91 | | -`Theme/ClaudeTheme.swift` + `Theme/AppTheme.swift` — terracotta accent (#D97757), light/dark mode, color palette, typography, corner radius constants (8/12/16/20) |
| 65 | +- **Observable app state**: `RxCode/App/AppState.swift` is a `@MainActor @Observable` state container. Behavior is split across `AppState+*.swift` extensions by domain. |
| 66 | +- **SwiftUI-only UI**: Use SwiftUI views. Do not introduce Storyboards or XIBs. |
| 67 | +- **Actor-based services**: Services that own mutable shared state should be actors or should clearly isolate concurrency through existing patterns. |
| 68 | +- **Backend abstraction**: Claude Code, Codex, and ACP flows share backend contracts from `RxCodeCore/Backend`. Avoid adding agent-specific branches when the shared protocol can express the behavior. |
| 69 | +- **Package boundaries**: Keep `RxCodeCore` broadly reusable and free of app-only UI dependencies. Put chat-specific SwiftUI components in `RxCodeChatKit`, sync protocol code in `RxCodeSync`, and app orchestration in `RxCode/`. |
| 70 | + |
| 71 | +### Agent Runtime Services |
| 72 | + |
| 73 | +| Service | Role | |
| 74 | +| --- | --- | |
| 75 | +| `ClaudeService` | Runs Claude Code, handles process discovery, streaming, summaries, and CLI session integration. | |
| 76 | +| `CodexAppServer` | Runs Codex app-server sessions, parses protocol events, fetches Codex models and rate limits. | |
| 77 | +| `ACPService` | Runs ACP clients such as OpenCode or Gemini CLI, manages pooled ACP sessions, protocol I/O, model discovery, and permission bridging. | |
| 78 | +| `ACPRegistryService` / `ACPInstallerService` | Fetches ACP registry data and installs compatible ACP client binaries. | |
| 79 | +| `PermissionServer` | Local HTTP server for CLI permission hooks and approval handoff to the UI. | |
| 80 | +| `MCPService` | Reads, writes, probes, and adapts MCP server configuration for supported agent runtimes. | |
| 81 | +| `IDEServer` tools | Exposes project/thread/search/memory tools to agents through the in-app IDE MCP server. | |
| 82 | + |
| 83 | +### Supporting Services |
| 84 | + |
| 85 | +| Service | Role | |
| 86 | +| --- | --- | |
| 87 | +| `PersistenceService` / `ThreadStore` | JSON-backed persistence under Application Support and thread/session storage. | |
| 88 | +| `ThreadSearchService` | On-device embedding and natural-language search over chat threads. | |
| 89 | +| `MobileSyncService` | E2E encrypted mobile pairing, relay communication, APNs fan-out, and live sync events. | |
| 90 | +| `RunService` / `RunProfileDetector` | Run profile execution and detection for Xcode, npm, make, and shell workflows. | |
| 91 | +| `GitHubService` | OAuth device flow, Keychain token storage, SSH key management, repository browsing, and cloning. | |
| 92 | +| `MarketplaceService` | Skill/plugin catalog fetching and installation support. | |
| 93 | +| `RateLimitService` | Claude usage API polling, OAuth token refresh, and usage tracking. | |
| 94 | +| `UpdateService` | Sparkle-based update manager. | |
| 95 | +| `BashSafety` | Read-only command validation for agent-exposed shell helpers. | |
| 96 | + |
| 97 | +## Data Flow |
| 98 | + |
| 99 | +1. User input enters `AppState.send(in:)`. |
| 100 | +2. `AppState` resolves the selected agent provider, model, effort, permission mode, working directory, and optional worktree. |
| 101 | +3. The selected backend (`ClaudeService`, `CodexAppServer`, or `ACPService`) emits an `AsyncStream<StreamEvent>`. |
| 102 | +4. `AppState+Stream.swift` processes stream events, updates chat state, tracks tools, handles permission requests, and persists messages. |
| 103 | +5. Permission requests route through the UI and, where needed, through `PermissionServer` or ACP/Codex protocol responses. |
| 104 | +6. Thread summaries, branch briefings, change tracking, search indexes, widgets, and mobile snapshots update from persisted session state. |
| 105 | + |
| 106 | +## UI Areas |
| 107 | + |
| 108 | +- `MainView`: main `NavigationSplitView` workspace. |
| 109 | +- `ProjectWindowView`: dedicated single-project windows. |
| 110 | +- `Chat/` and `RxCodeChatKit`: message list, input, slash commands, attachments, plans, questions, tool output, diffs, and status UI. |
| 111 | +- `Sidebar/`: projects, session history, briefing, file tree, Git status, GitHub repo list, and file previews. |
| 112 | +- `Inspector/`: changes, this-thread diff, and right-side contextual panels. |
| 113 | +- `RunProfile/`: run configuration editor, toolbar controls, and command output inspector. |
| 114 | +- `Settings/`: agent, ACP, MCP, mobile sync, commands, memory, appearance, and related settings. |
| 115 | +- `Terminal/`: SwiftTerm-based terminal UI. |
| 116 | +- `Permission/`: risk-aware approval modals and queued permission banners. |
| 117 | +- `Search/`: global natural-language search overlay. |
| 118 | + |
| 119 | +## Implementation Guidelines |
| 120 | + |
| 121 | +- Prefer existing app services, models, theme tokens, and helper utilities over new abstractions. |
| 122 | +- Keep UI consistent with the established SwiftUI style and `ClaudeTheme` / `AppTheme` tokens. |
| 123 | +- Avoid blocking the main actor with process, file, network, or parsing work. |
| 124 | +- When adding agent features, consider Claude Code, Codex, and ACP behavior unless the feature is explicitly provider-specific. |
| 125 | +- When changing sync payloads, preserve backward/forward compatibility where possible because mobile and desktop versions can differ. |
| 126 | +- When changing persistence formats, add migration or tolerant decoding rather than assuming all users have fresh data. |
| 127 | +- Use `rg` for code search and inspect surrounding code before editing. |
| 128 | + |
| 129 | +## Testing Expectations |
| 130 | + |
| 131 | +- For package logic, run focused `swift test --package-path Packages` tests when practical. |
| 132 | +- For app changes, prefer focused XCTest/UI test runs if the touched area has coverage. |
| 133 | +- For build-sensitive changes, run `xcodebuild -project RxCode.xcodeproj -scheme RxCode -configuration Debug build`. |
| 134 | +- If you cannot run the relevant verification, state that clearly in the final response. |
| 135 | + |
| 136 | +## Compiler And Platform Settings |
| 137 | + |
| 138 | +- `SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor` is enabled for the app and relevant targets. |
| 139 | +- `SWIFT_APPROACHABLE_CONCURRENCY = YES` is enabled for app/mobile-related targets. |
| 140 | +- App Sandbox is disabled for the main macOS app because RxCode integrates with local developer tools and projects. |
0 commit comments