Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ Programa is a fork of [cmux](https://github.com/manaflow-ai/cmux); for history p
## [Unreleased]

### Added
- A Storage button in the sidebar footer opens a popover with your free disk space, the worktrees Programa can remove, Xcode, Android and package manager caches, and how much disk each open workspace uses with its biggest build folders. Each Clean button shows what it would remove and removes nothing until you confirm. See `docs/workspace-interface.md`.
- `programa storage scan` lists every git worktree and developer cache with its size and the reason it would be kept, and `programa storage clean` removes merged worktrees and the caches their tools rebuild on their own. `--xcode`, `--android` and `--packages` limit a run to one kind of cache and `--dry-run` shows what would go. The `storage.scan` and `storage.clean` socket methods do the same.
- Every 6 hours Programa removes worktrees under `~/.programa/worktrees` whose branch is merged and that went unused for 24 hours, along with Xcode DerivedData, Gradle and package manager caches unused for 14 days and unavailable simulators. It keeps any worktree with uncommitted changes, an ignored `.env` file, an open workspace or a process running inside it. Turn it off with `worktrees.autoRemoveMerged` and `storage.autoCleanCaches`.
- When free space on your home volume drops below 20 GB, Programa sends one notification that opens the Storage popover. Change the threshold with `storage.lowDiskWarningGB`, or set it to 0 to turn the warning off.
- On macOS 26 each pane card has a header with split right, split down, zoom and close buttons that act on that pane, plus a new tab button when the pane has one tab. In a narrow pane the buttons drop out one at a time, and close always stays.
- Drag a tab out of the window and release it to open it in a new window, with its shell and scrollback intact. Press Escape during the drag to cancel.
- The "N helpers running" line on a sidebar row opens a popover with that workspace's helpers: Claude Code subagents, OSC 7501 child records and helpers reported over the socket. Each row shows the helper's state, task, run time and final report; copy the report or open it in a markdown pane beside the terminal. Finished helpers stay listed until you press Clear. See `docs/workspace-interface.md`.
- Programs that report OSC 7501 child records get one helper per child in that popover, with a progress bar, and a notification when a child needs your input on a pane you are not looking at.
- `programa resume` restarts the last Claude Code, Codex or OpenCode session that ended in a pane by typing its resume command into the pane's shell. After a restart, Resume Agent Session in the command palette does the same.
Expand All @@ -31,6 +37,10 @@ Programa is a fork of [cmux](https://github.com/manaflow-ai/cmux); for history p
- `programa aside install-mcp` also registers Programa in Aside's own MCP settings, so Aside can start agents in Programa panes and read their results. `uninstall-mcp` removes it and `programa aside status` shows it. See `docs/aside-browser.md`.

### Changed
- Sidebar rows start with the running agent's icon, or a terminal symbol, and show one status line under the title, with the agent's state as a colored pill and how long ago the status changed on the right. Hover a row for a ••• button that opens its right-click menu. The directory line is hidden when it is `~` or repeats the title, and the selected row is a raised white pill while the window is active.
- The sidebar toggle, notifications bell and new workspace button sit right after the window's traffic lights.
- The sidebar slides in and out when you toggle it, and fades instead when Reduce Motion is on.
- The diagnostics log keeps weeks of history instead of about a day and a half, because it no longer records routine socket connections that open and close within a second.
- A workspace with a single tab hides its tab bar, along with the new-tab and split buttons, and leaves an empty strip in its place so the window can still be dragged from the top. A glass + button in that strip's right corner opens a new tab. The bar comes back when the pane gets a second tab or the workspace is split, so every split pane keeps its close and new-tab buttons.
- A focused terminal that has nothing new to show uses about half as much CPU. It stops waking up on every screen refresh after a quarter second of quiet and starts again on the next change.
- Only one copy of Programa runs at a time: launching a second copy brings the running app forward and exits.
Expand Down Expand Up @@ -61,6 +71,12 @@ Programa is a fork of [cmux](https://github.com/manaflow-ai/cmux); for history p
- The `programa omo`, `omx` and `omc` wrappers for oh-my-openagent, Oh My Codex and Oh My Claude Code. The `programa claude`, `codex` and `opencode` integrations are unchanged. See `docs/removed/omo-omx-omc-wrappers.md` to restore them.

### Fixed
- When Claude Code is killed, its tab stays open with a banner offering Resume or Close, and processes the session left running are stopped.
- `programa resume` skips a Claude session that ended before its first prompt, since there is nothing to reopen.
- After a program is killed, the next prompt resets mouse reporting and the alternate screen, so the terminal stops acting as if the program were still running.
- Closing a split no longer flashes the empty panel view for a frame.
- The usage popover in the sidebar footer shows Claude's usage when Claude Code has written only one of its two rate limit windows. The Claude section was hidden in that case, so only OpenAI showed.
- Force quitting an app you launched from a pane no longer quits Programa and every pane with it. Panes no longer share Programa's privacy permissions, so macOS asks the first time a pane reads Desktop, Documents or Downloads.
- Pressing Esc to interrupt Claude Code no longer leaves its pane showing Working for good. Claude Code 2.1.295 and later reports its own status, so Programa's hooks stop writing it on top.
- A shell that survives a restart keeps updating its pane: its prompt state, folder, branch and ports reach the restored pane, so `programa resume` works there without `--force`. Before, the shell kept reporting to the pane id from before the restart.
- `programa handoff` pastes into a pane whose terminal has not started yet instead of failing.
Expand Down
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ By default, `reload.sh` builds but does **not** launch the app. The script print
./scripts/reload.sh --tag fix-zsh-autosuggestions --launch
```

By default, every `--tag` shares one DerivedData directory (`programa-shared`), so switching tags or re-running the same tag is a warm incremental build instead of a cold one. Tags still get their own bundle id, app name, socket, and log — only the build directory is shared. Pass `--isolated` to give a tag its own DerivedData directory again (today's old default), e.g. when you need two tags to build fully independently:
By default, every `--tag` shares one DerivedData directory (`programa-shared`), so switching tags or re-running the same tag is a warm incremental build instead of a cold one. Tags still get their own bundle id, app name, socket, and log; only the build directory is shared. Pass `--isolated` to give a tag its own DerivedData directory, e.g. when you need two tags to build fully independently:

```bash
./scripts/reload.sh --tag fix-zsh-autosuggestions --isolated
Expand Down Expand Up @@ -178,7 +178,7 @@ The app has a **Debug** menu in the macOS menu bar (only in DEBUG builds). Use i

These run in CI; run the relevant one before pushing:

- `python3 scripts/check-structural-budgets.py`: line budgets for lifecycle owner files. `CLI/programa.swift`, `CLI/CLI+Hooks.swift`, `Sources/TerminalController.swift` and `Sources/CommandPaletteController.swift` sit at their cap, so free lines (or move code into a new file) before adding any.
- `python3 scripts/check-structural-budgets.py`: line budgets for lifecycle owner files such as `CLI/programa.swift` and `Sources/TerminalController.swift`. Run it before adding lines to a file it lists; it prints each file's current count and cap. When a file is near its cap, free lines or move code into a new file first.
- `scripts/check-v2-contract.sh`: v2 socket methods are contract-first. Edit `contracts/v2/methods.json`, then `python3 scripts/gen-v2-contract.py`; never hand-edit the generated Swift.
- `python3 scripts/check-settings-docs.py`: every settings key and shortcut action is documented.
- New Swift files need four `project.pbxproj` entries (PBXBuildFile, PBXFileReference, group child, Sources build phase) or the build fails with "cannot find type in scope".
Expand Down
2 changes: 1 addition & 1 deletion Resources/settings.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@
"showClaudeQuota": {
"type": "boolean",
"default": true,
"description": "Show Claude Code rate-limit headroom (5h/7d windows) in the sidebar footer, read from ~/.claude/tmp/rate-limits.json when present."
"description": "Show the Provider Usage button in the sidebar footer, with Claude and OpenAI usage when available."
}
}
},
Expand Down
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
- [keyboard-shortcuts.md](keyboard-shortcuts.md): default shortcuts, action ids and chord syntax for custom bindings.
- [settings-json.md](settings-json.md): every key in `~/.config/programa/settings.json`.
- [programa-json.md](programa-json.md): `programa.json` commands and recipes, the layout schema, and saved layouts.
- [workspace-interface.md](workspace-interface.md): the pane tab bar, agent logos on tabs, edge fades, and the ports panel.
- [workspace-interface.md](workspace-interface.md): the pane tab bar and header, moving a tab to a new window, sidebar rows, the ports, storage and provider usage popovers, helpers and turn checkpoints, and resuming an agent session.
- [terminal-themes.md](terminal-themes.md): terminal themes, opacity, blur and font.
- [notifications.md](notifications.md): notifications, the sidebar agent indicator, and agent hook examples.
- [program-status.md](program-status.md): the OSC 7501 program status protocol for reporting what a program is doing.
Expand Down
13 changes: 6 additions & 7 deletions docs/plans/rust-core-concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,12 @@ notify --title <text> [--subtitle][--body][--tab][--panel]`, `list-notifications
`CLI-MCP/MCPServer+Capabilities.swift`, `CLI-MCP/MCPSocketBridge.swift`,
`CLI-MCP/ToolCatalog.swift`, `CLI-MCP/ResourceCatalog.swift`, `CLI-MCP/MCPErrorMapping.swift`).
Separate binary embedded at `Contents/Resources/bin/programa-mcp` inside the app bundle; talks to
the running app over the same v2 socket. 187 tools, one per exposed socket method with `.` ->
`_` (`surface.read_text` -> `surface_read_text`, `review.comment.add` -> `review_comment_add`).
Thirteen tools carry an explicit `focus_` prefix because they are allowed to move macOS focus:
`focus_window`, `focus_workspace_select`, `focus_workspace_next`, `focus_workspace_previous`,
`focus_workspace_last`, `focus_surface`, `focus_pane`, `focus_pane_last`, `focus_review_open`,
`focus_worktree_open`, `focus_browser_webview`, `focus_browser_element`,
`focus_browser_tab_switch` (`worktree_create` is a deliberate exception: it drops the underlying
the running app over the same v2 socket. One tool per exposed socket method with `.` -> `_`
(`surface.read_text` -> `surface_read_text`, `review.comment.add` -> `review_comment_add`); the
tool definitions live in `CLI-MCP/Tools/`, and `tools/list` on a running server returns them.
Tools that are allowed to move macOS focus carry an explicit `focus_` prefix instead, such as
`focus_window`, `focus_surface` and `focus_pane`; `CLI-MCP/Tools/FocusTools.swift` defines them
(`worktree_create` is a deliberate exception: it drops the underlying
method's `focus` param entirely). Not exposed: `debug.*` (DEBUG-only, UI-test hooks) and app-chrome
methods (`auth.login`, `settings.open`, `feedback.*`, `markdown.open`, `app.*`). Resources:
`programa://tree` (full window/workspace/pane/surface tree) and
Expand Down
2 changes: 1 addition & 1 deletion docs/release.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ repository secret with the same name is ignored by the release job.
| `APPLE_APP_SPECIFIC_PASSWORD` | App-specific password for notarization |
| `APPLE_TEAM_ID` | Apple team id |
| `SPARKLE_PRIVATE_KEY` | Signs the appcast and enclosures; the workflow derives the public key embedded in the app from it. The release fails without it |
| `APPLE_PROVISION_PROFILE_BASE64` | Provisioning profile embedded in the app. Kept as a safety net: no entitlement in `programa.entitlements` is Apple-restricted now, so the app launches without a profile and an embedded one is harmless. If a restricted `com.apple.developer.*` entitlement is added back, the profile is required, because macOS kills the app at launch without it even though signing and notarization succeed. The workflow step still fails the build when the secret is missing. Candidate for removal once a release is confirmed to launch without it |
| `APPLE_PROVISION_PROFILE_BASE64` | Provisioning profile embedded in the app. Kept as a safety net: no entitlement in `programa.entitlements` is Apple-restricted, so the app launches without a profile and an embedded one is harmless. If a restricted `com.apple.developer.*` entitlement is added, the profile is required, because macOS kills the app at launch without it even though signing and notarization succeed. The workflow step still fails the build when the secret is missing. Candidate for removal once a release is confirmed to launch without it |

## Milestone version bumps

Expand Down
2 changes: 1 addition & 1 deletion docs/settings-json.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Sidebar settings from Settings > Sidebar.
| Key | Type | Default | What it does |
|---|---|---|---|
| `matchTerminalBackground` | boolean | `false` | Use the terminal background instead of the sidebar tint. |
| `showClaudeQuota` | boolean | `true` | Show Claude Code rate-limit headroom (5h/7d windows) in the sidebar footer, read from ~/.claude/tmp/rate-limits.json when present. |
| `showClaudeQuota` | boolean | `true` | Show the Provider Usage button in the sidebar footer, which opens Claude and OpenAI rate limit usage. See [workspace-interface.md](workspace-interface.md#provider-usage). |

## `automation`

Expand Down
Loading
Loading