* feat: add FileChangeSummary component for multi-file diff preview in ToolPart
Provides an aggregated diff card for apply_patch and multi-edit tools,
showing per-file stats with click-to-expand diff view.
* feat: add PendingChangesBar above chat input with collapse/expand and file opening
- Collapsed/expanded toggle with aggregate +N -N stats (green/red)
- Relative path display, chat-column alignment with ChatInput
- Click file to open in diff viewer (web/desktop) or editor (VS Code)
- Support edit/multiedit/apply_patch/write tool metadata extraction
- Add PendingChangesBar to main chat view (ChatContainer)
* feat: dual-mode ChangedFilesBar — Git diff state vs latest AI turn
Git mode: reads git status from useGitStore (status.files + diffStats),
auto-clears on commit/restore. Shows 'N files changed in workspace'.
Non-Git mode: latest assistant turn only (no accumulation), clears on new
user message or manual dismiss. Shows 'AI updated N files in the last reply'.
Both modes: dismiss button with signature-based tracking.
Add pendingChangesBarDismissed state to session-ui-store, cleared on sendMessage.
* fix: address code review issues in ChangedFilesBar
- Gate non-git mode on streaming state to prevent flicker during AI turns
- Return null when isGitRepo is unknown (loading state)
- Add group/row class for reject button visibility in FileChangeSummary
- Use per-session Map for dismiss tracking to prevent cross-session leaks
- Include additions/deletions in dismiss signature for re-edit detection
- Extract shared parsePatchStats/parseCount to fileChangeHelpers
* chore: revert local .opencode/package-lock.json changes from PR
* fix: per-part fallback guard and git-only reject button
- Fix extractChangedFiles to use per-part files.length snapshot instead
of global guard, preventing file entries from being skipped when
earlier parts already contributed files
- Hide reject button in FileChangeSummary when not in a git repo,
preventing silent revert failures
* refactor: remove FileChangeSummary — dead code redundant with ToolPart
FileChangeSummary duplicated diff rendering that ToolPart already
provides (PatchDiff, per-file stats, DiffViewToggle). The only unique
feature was a git revert button, which conflicts with the design
principle of not having accept/reject on file change previews.
Moved parsePatchStats/parseCount back into PendingChangesBar (sole
consumer) and deleted the shared helper module.
* chore: remove stray Tester.txt
* fix: deduplicate Fallback 4 'Diff' placeholder via seen set
* chore: update non-Git mode copy to neutral 'changed in the last reply'
* fix(chat): unify changes row with tasks
---------
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
Run OpenChamber and OpenCode as separate persistent services — useful when you want to access your
dev machine over a VPN (e.g. Tailscale) or LAN without a Cloudflare tunnel.
How it works:
OpenCode runs as its own service, binding only to localhost.
OpenChamber connects to it via OPENCODE_HOST and --host 0.0.0.0 makes it reachable on your VPN IP.
--foreground keeps the CLI process alive so systemd can track and restart it.
Why set PATH and SSH_AUTH_SOCK?
systemd user services start with a minimal environment — no shell profile is sourced.
Without an explicit PATH, OpenCode won't find tools installed via Homebrew, npm, or ~/.local/bin.
Without SSH_AUTH_SOCK, git operations over SSH (push, pull, clone) will fail because the agent socket isn't inherited.
Adjust the PATH to match your own tool installation paths.
%t expands to $XDG_RUNTIME_DIR (e.g. /run/user/1000), where most SSH agents write their socket.
OpenChamber will be reachable at http://<your-vpn-hostname>:3000 from any device on your VPN.
Note:--host 0.0.0.0 is required to listen on all interfaces. The default
bind address is 127.0.0.1 (localhost only). Use --host <ip> or
OPENCHAMBER_HOST=<ip> to bind to a specific interface instead.
Managed-local path note: OPENCHAMBER_TUNNEL_CONFIG must point to a path inside the container user home (/home/openchamber/...). If your Cloudflare config references a credentials JSON file, that file path must also be accessible inside the container (mount with volumes).
Website docs source lives at packages/docs/content/docs/reverse-proxy.mdx.
Tunnel behavior notes
OpenChamber supports one active tunnel per running instance (port).
Starting a tunnel with a different mode/provider on the same instance replaces the current tunnel.
Replacing or stopping a tunnel revokes existing connect links and invalidates remote tunnel sessions for that instance.
Connect links are one-time tokens; generating a new link revokes the previous unused link.
Data Directory Permission Note: The data/ directory is mounted into the container for persistent storage (config, sessions, SSH keys, workspaces). Before running, ensure the directory exists and has proper permissions:
My wife, who - with zero AI background - sat down with the app for the first time and built the firework celebration that plays on every successful push.
Every contributor who shaped this project with their PRs, ideas, and attention to detail.