Skip to content

Fix file history, notifications, and brew post_install#1

Closed
will-osborne wants to merge 23 commits intomainfrom
desktop-app
Closed

Fix file history, notifications, and brew post_install#1
will-osborne wants to merge 23 commits intomainfrom
desktop-app

Conversation

@will-osborne
Copy link
Copy Markdown
Owner

Summary

  • File history tracking: Claude Code writes files internally and never sends fs/write_text_file requests to the client. File history was empty because RecordFileChange was only called from that unused handler. Now extracts before/after content from _meta.claudeCode.toolResponse in tool_call_update events.
  • Desktop notifications: Blanket NSApp.isActive suppression prevented all notifications while the app was open. Permission requests now always fire; run completions notify unless you're watching that specific session.
  • Brew post_install: macOS com.apple.provenance and TCC restrictions prevent brew's subprocess from modifying ~/Applications. Now fails gracefully with a manual ditto command instead of a cryptic error.

Test plan

  • Send a prompt that edits files, open File History panel — verify diffs appear
  • With Orbitor focused on session A, let session B finish — verify banner notification
  • With Orbitor focused on session A, let session A finish — verify no notification
  • With Orbitor in background, let any session finish — verify banner notification
  • Permission request arrives — verify notification fires regardless of focus
  • brew upgrade orbitor on macOS — verify graceful warning instead of EPERM crash

🤖 Generated with Claude Code

will-osborne and others added 23 commits March 25, 2026 13:25
…, UI polish

- Fix hold-space dictation by swallowing initial keyDown when prompt is empty
- Scroll to bottom on session open/switch
- Add delete session via right-click context menu and inspector
- Fix model picker not reflecting active model on session change
- Add pulse animation to active status badges (working, waiting-input, starting)
- Auto-focus chat input on session switch
- Fix new sessions stuck connecting (yield empty history batch)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…nt response

- Read MCP server definitions from ~/.claude.json (Claude) or
  ~/.copilot/mcp-config.json (Copilot) and pass to session/new
- Also reads project-local .mcp.json from the working directory
- Fix Interrupt() returning early when interruptCancel was nil (after
  prompt call completed), so SIGINT is always sent to the agent process

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Transform native config format (headers/env as objects) into ACP's
expected format (headers/env as [key, value] pair arrays). Also
normalizes type "local" → "stdio" and strips non-ACP fields.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ACP expects env entries as objects like {"name": "KEY", "value": "VAL"},
not [key, value] array pairs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot's ACP implementation doesn't support mcpServers in session/new
(no mcpCapabilities advertised). It reads ~/.copilot/mcp-config.json
natively. Pass project-local .mcp.json via --additional-mcp-config CLI
flag instead. Claude still uses ACP mcpServers (which it supports).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Move "Agent Finished" notification from ChatState (active session only)
  to SessionListState polling loop so all sessions trigger notifications
- Track isRunning state transitions across polls to detect completions
- Show blue dot badge on session rows with activity since last viewed
- Clear unread indicator when session is selected

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- handlers.go: use *bool for skipPermissions/planMode so omitted fields
  don't overwrite existing values with false (was the root cause of toggles
  resetting when only model was changed)
- session.go: only respawn process when copilot model actually changes;
  remove erroneous condition that respawned every running session on any
  UpdateSession call
- Add "status" WS message handling: parse server "respawning" broadcasts
  and show reconnecting state in the chat UI until history reloads

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Stale package lists on GitHub's Ubuntu runners cause 404 errors when
fetching gcc-14-cross dependencies. Update first to get fresh metadata.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Backend:
- Add EnhancePrompt, Debrief, and Suggestions LLM methods to Summarizer
- Add POST /api/enhance-prompt, GET /api/sessions/{id}/debrief, GET /api/sessions/{id}/suggestions

Desktop app:
- Session sidebar: live run timer, PR URL badge, relative last-activity
- Chat: jump-to-latest button, post-run debrief card with file change summary, suggestions chips
- ChatState: track files touched, run start/duration, error count
- PromptInputView: char/token counter, prompt history navigation (⌘↑/↓), AI enhancer button (⌘E), suggestion chips
- InspectorView: files changed list, git branch context, error count indicator, last run duration
- ContentView: persistent status bar (server status, session count, running count)
- Command palette (⌘K), diff viewer, file attachments, image paste, auto-reconnect
- APIClient: enhancePrompt, sessionDebrief, sessionSuggestions methods

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Move StatusBar inside NavigationSplitView detail pane to fix bottom content cutoff
- Fix debrief expand/collapse logic and cap debrief text height
- Brew formula now installs macOS desktop app and symlinks to ~/Applications
- Release workflow extracts and substitutes desktop app SHA256

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
version inside a resource block refers to the resource's own version,
not the formula's. Use a hardcoded URL and update it via sed in the
release workflow instead.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ditto --keepParent on Orbitor.app made it the single root entry, so
Homebrew would chdir into it and fail to find Orbitor.app to install.
Wrap in orbitor-desktop/ so Homebrew chdirs there instead.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Ruby's make_symlink is blocked in Homebrew's post_install sandbox (EPERM).
Use cp -R via system command instead, and reference opt_prefix for a
stable path across upgrades.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
UNUserNotificationCenter.delegate must be set before the app finishes
launching. Move notification setup into NSApplicationDelegateAdaptor so
it runs at the correct time instead of being deferred to @State init.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
onKeyPress on ZStack was swallowed by the focused TextField. Move
up/down arrow and escape handlers directly onto the TextField where
they fire correctly while typing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace plain Text with MarkdownTextView so debrief output renders
inline formatting, code blocks, and other markdown from the LLM.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
rm -rf fails with EPERM on app bundles that macOS has protected after
being run. ditto copies file-by-file overwriting in-place, no delete needed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Backend: track before/after file content for each write tool call,
  grouped by prompt run. New RunHistory type stores records in-memory
  per session. GET /api/sessions/{id}/run-history endpoint.
- Frontend: RunHistoryView sheet (accessible from inspector header)
  shows a run timeline on the left, file list + LCS-based diff viewer
  on the right. Color-coded +/- lines with line numbers and context.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add RunRecord.swift and RunHistoryView.swift to Orbitor.xcodeproj so
  they compile in CI (they existed on disk but weren't referenced)
- Fix `theme.bg` → `theme.panel` in FileDiffView background

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ndle

macOS marks app bundles as protected after they've been run by the user,
causing ditto (and rm -rf) to fail with EPERM. Restore write permissions
first so the old bundle can be removed cleanly before copying the new one.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Restored sessions from the database were missing the `history` field
(added in f33f74e), causing a nil pointer panic on first prompt.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
File history: Claude Code writes files internally and never sends
fs/write_text_file requests. Extract before/after content from
_meta.claudeCode.toolResponse in tool_call_update events instead.

Notifications: Remove blanket NSApp.isActive suppression that prevented
all notifications while the app was open. Permission requests now always
notify; run completions notify unless you're actively watching that
specific session.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant