Improve chat session switching and history pagination, with most of the aggressive limits scoped to the VS Code webview where the freezes were observed.
Session history loading and pagination:
- Reduce the VS Code message page size to 30 records so switching sessions does not immediately hydrate large histories into the webview.
- Keep manual Load older messages in VS Code fixed at 30 records per request instead of growing the request size over time.
- Add a bounded VS Code initial-tail expansion path from 30 to 50, 80, and 120 records only when the initial page has no user-message turn boundary, preventing large final turns from rendering as an empty chat.
- Lower the normal web message page size from 200 to 150 for a mild shared optimization without adopting the aggressive VS Code limits.
- Make session pagination metadata reactive per session so ChatContainer receives cursor updates from materialization and reconnect paths without requiring a switch away and back.
- Write pagination metadata before publishing newly materialized messages so the first render sees the correct has-more state.
- Store cursor information from direct materialization and reconnect message fetches in the shared session prefetch metadata cache.
VS Code cache and memory pressure reductions:
- Use a shared per-directory session recency map so cache eviction is based on app-level recency instead of whichever useSync instance happened to run.
- Limit VS Code warm session cache retention to 4 sessions and evict heavy inactive message caches after switching away from a large session.
- Disable sidebar session prefetch in VS Code because warming extra sessions was increasing webview memory and GC pressure during navigation.
- Remove dropdown background message prefetch so opening the switcher does not start additional session materialization work.
- Drop cached session-message-record snapshots when evicting session data so stale derived records do not remain after the raw session cache is cleared.
- Add bounded LRU caching for session message record snapshots, with much smaller VS Code limits and a VS Code cap that avoids caching snapshots above 30 messages.
- Bound the turn-window model cache in VS Code and avoid caching turn models for sessions above the VS Code message-page size.
Chat render-path reductions:
- Reuse ChatContainer's already-materialized message records in plan detection instead of adding a second active-session message subscription.
- Add a no-op guard when marking session plan availability so repeated detections do not create new Map references and fan out renders.
- Add no-op guards for session switcher and dropdown open state updates to avoid unnecessary store updates and renders.
- Convert several session-specific hooks to useSyncExternalStore with empty-session no-subscribe behavior so empty IDs do not subscribe to broad store updates.
- Remount the chat viewport when the current session changes, isolating per-session viewport and list state.
- Change the virtualized message-list fallback to render only a tail window when the virtualizer has not produced rows yet, instead of rendering an entire large history.
VS Code layout and header improvements:
- Remove the broad useSessions subscription from the VS Code layout header path and subscribe only to the active session title and initial-session existence.
- Unmount the compact VS Code session sidebar when the user is in chat view instead of keeping the hidden session list mounted and subscribed.
- Compute the latest assistant model and latest context-token usage in a single reverse scan of current-session messages instead of scanning the same list twice.
- Remove switcher git-status warmup work so the switcher reads already-loaded branch labels without starting extra background git status requests.
Markdown and file-reference safeguards:
- Skip expensive syntax highlighting for very large code blocks, with a 200-line cap in VS Code and a softer 1200-line cap in web.
- Add an LRU cap to file-reference stat lookups so the cache cannot grow without bound across many rendered messages.
- Limit the number of file references annotated per render to 40 in VS Code and 200 in web to prevent large assistant outputs from spawning too many stat checks.
- Clear file-link annotations when file-reference mode is disabled so stale attributes and handlers do not remain on previously annotated nodes.
Assistant-message action and preview reductions:
- Skip preview URL scanning on VS Code, mobile, and mini-chat surfaces so assistant text and tool output are not scanned where the preview action is unavailable.
- Skip Save-as-Plan project lookup on VS Code, mini-chat, and mobile surfaces.
- Hide Save-as-Plan and Start MultiRun assistant-message actions on VS Code, mini-chat, and mobile surfaces.
- Resolve the current session directory on demand for assistant actions instead of subscribing each assistant message to the full session list.
Tool and task rendering optimizations:
- Prefer finalized task metadata summaries without fetching child-session messages when the summary is already present.
- Avoid polling or final-fetching task child sessions once a final metadata summary is available.
- Use VS Code-specific task child fetch limits of 30 records for initial, active, and idle fetches.
- Parse diff stats by scanning patch text line-by-line instead of splitting large patches into arrays.
- Count write-tool lines by scanning content instead of allocating a split array for large files.
- Avoid trimming large patch strings just to test whether they contain content.
- Memoize diff and write statistics so unchanged tool parts do not recalculate them on every render.
VS Code bridge improvements:
- Return JSON and text proxy responses through the VS Code bridge as bodyText instead of base64 so the webview avoids synchronous base64 decoding for common API responses.
- Keep binary responses on the base64 path while making bodyBase64 optional in the bridge contract.
- Strip content-length, content-encoding, and transfer-encoding headers from proxied responses because the bridge reconstructs the Response body.
Validation:
- bun run type-check
- bun run lint
- bun run vscode:build
* feat(quota): add Wafer.ai quota provider
- New provider: wafer.js fetches from https://pass.wafer.ai/v1/inference/quota
- Auth: reads wafer/wafer-ai/wafer_ai keys from auth file
- Timeout: AbortSignal.timeout(15_000) with timeoutSignal.aborted detection
- Response: parses remaining/limit/overage/usedPercent/window_end/plan_tier
- valueLabel: planTier + remaining/limit + overage suffix
- Window: 5h (18000s) via resolveWindowLabel
- Cross-runtime: added to web registry, UI types, VS Code dispatcher
* fix(quota): wafer provider fixes — auth alias, decompression, logo
- Add 'wafer.ai' auth alias to match actual auth key format
- Use 'Accept-Encoding: identity' header to fix Bun fetch
decompression issue with Cloudflare-backed responses
- Match copilot valueLabel format: 'planTier · X / Y left'
- Add wafer logo alias so Providers and Usage pages resolve
to the same wafer.ai logo from models.dev
* style(quota): fix indentation of timeoutSignal declaration
* fix(quota): derive window duration from API instead of hardcoding
Compute windowSeconds from window_end - window_start timestamps,
with WAFER_WINDOW_SECONDS (5h) as fallback if timestamps are missing.
---------
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
Prevents duplicate native notifications when a session is open in both sidebar and editor
Uses an extension-host claim step so only one VS Code webview displays each notification
Keeps notification behavior unchanged for single-panel sessions
Targets active editor chat before falling back to sidebar
Adds session open-in-editor action in the VS Code sidebar
Uses attachment badges for VS Code file and selection context
Disable the active Zen summarization flow because the unauthenticated/free Zen provider is no longer available and now returns usage-limit errors for this feature.
Keep /api/text/summarize as an API-compatible stub that returns local sanitized or distilled fallback text with summarized=false, rather than attempting external model calls.
Remove notification and voice playback summary behavior from runtime paths. Notification {last_message} now always uses normalized truncated text, and TTS playback ignores historical summarize request fields.
Hide the notification summary settings and voice summarize-before-playback controls while preserving legacy persisted settings for compatibility. Also disable Zen model startup validation and make Zen model list routes return empty results.
Update module documentation and tests to describe the retired provider behavior and the remaining compatibility stubs.
Move VS Code/Cursor desktop notifications onto the webview Notification API instead of the extension-host watcher path, which could not reliably produce native OS notifications.
Route OpenCode runtime events from the shared sync pipeline into the VS Code webview so completion, error, question, and permission notifications use the same live event stream as the UI.
Respect the OpenChamber notification settings in VS Code, including template rendering, completion cooldowns, permission auto-accept suppression, and the notify-while-focused mode.
Use VS Code's window focus signal from the extension host instead of document.hasFocus() inside the webview, so hidden-only notifications are suppressed while Cursor or VS Code is focused across platforms.
* chore: add .worktrees/ to gitignore for worktree workflow
* fix: resolve remote-tracking base ref in getLog for PR description generation
getLog was calling git log <base>..<head> with a bare branch name that
often doesn't exist locally (e.g. main when only origin/main is present),
causing a fatal 'unknown revision' error and HTTP 500.
Apply the same origin/<base> resolution already used in getRangeDiff and
getRangeFiles: check refs/remotes/origin/<base> first and prefer that ref
if it exists.
Also fix getGitLog in gitApiHttp.ts to read the JSON error body on
failure instead of falling back to response.statusText, so the actual
git error message surfaces in the toast instead of 'Internal Server Error'.
* fix(git): use local-first ref resolution in getLog and port to VS Code
- Replace unconditional origin/<from> preference in getLog() with a
local-first fallback: prefer the local ref, only use origin/<from>
when the local ref cannot be resolved, and pass through unchanged
when neither resolves so git surfaces a meaningful error.
- Extract the logic into an exported resolveBaseRefForLog(from, checkRef)
helper so it is unit-testable without a real git repo.
- Add service.test.js with 6 cases covering local-wins, origin-fallback,
neither-exists passthrough, and falsy/empty inputs.
- Port the same local-first resolution to packages/vscode/src/gitService.ts
getGitLog() to close the cross-runtime parity gap; also handles
from-only ranges as from..HEAD, matching the web service contract.
* fix(vscode): add missing to-only range branch in getGitLog
When only 'to' is supplied (no 'from'), the web service appends it as a
positional git-log argument. The VS Code port was missing this branch and
silently returned unbounded history instead. Adds the else-if to restore
full cross-runtime parity.
* fix(vscode): surface git log errors
---------
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
Replace server-enforced structured output with local JSON parsing for Git generation
Render generated commit and PR JSON responses as compact chat cards
Tighten generation prompts while preserving active session context
Add a Stashes dialog with create, apply, pop, and drop actions
Include untracked files automatically when stashing
Show file counts for current changes and stash entries
Combine fetch, pull with rebase, and push into one sync action
Keep remote dropdown focused on safe fetch actions
Block sync when uncommitted changes would conflict with rebase
* feat(chat): add active editor file context and related functionality
* feat(chat): improve active editor file context handling and update translations
* feat(i18n): standardize quotation marks in file attachment messages
* update Korean translation for image removal action in file attachment
* feat(chat): refine active editor file handling and optimize broadcast logic
* fix(chat): stabilize VS Code editor context chips
---------
Signed-off-by: David Saz <david.saz.g@gmail.com>
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
* fix: cross-verify update API claims against npm registry
* Update packages/web/server/lib/package-manager.js
Signed-off-by: Islam Nofl <islamnofl.official@gmail.com>
* fix: show live server version in AboutDialog instead of stale build-time constant
* fix: add comment to empty catch block to satisfy lint no-empty rule
* fix: preserve live about dialog version in electron
* fix: scope update checks by runtime
---------
Signed-off-by: Islam Nofl <islamnofl.official@gmail.com>
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
Resolves issue #1033 where remote GitHub MCP setups failed to work in OpenChamber because the `headers` property (which contains authorization credentials) was being dropped during configuration parsing in `packages/vscode/src/opencodeConfig.ts`.
* Add design spec: OpenCode readiness loading indicator
* Add implementation plan: OpenCode readiness loading indicator
* feat: add useOpenCodeReadiness hook
* feat: add i18n keys for common.loading
* feat: add loading state to ModelSelector
* feat: add loading state to AgentSelector
* feat: add loading state to ModelControls chat selectors
* update package-lock
* feat(github): add shared fork detection utility
* feat(github): make issue listing fork-aware
* feat(github): make PR listing fork-aware
* feat(types): add sourceRepo to issue/PR summary types
* feat(ui): add source badges to GitHub integration dialog
* feat(ui): add source badges to issue/PR picker dialogs
* feat(github): pass headRemote in PR creation for fork support
* feat(ui): add source→target label in PR tab for fork workflows
* fix(github): allow PR section on base branch when upstream remote exists
* fix(github): show PR section on any branch including main for fork→upstream PRs
* fix(github): allow PullRequestSection to render on base branch when upstream remote exists
* feat(github): auto-detect upstream repo for fork→upstream PR creation
- Add GET /api/github/repo/upstream endpoint to discover fork's upstream
- Fix PullRequestSection canShow to allow PR creation on base branch when repo is a fork
- Add virtual upstream target in remote dropdown (no explicit upstream remote needed)
- Add targetRepo parameter to /api/github/pr/create for direct upstream targeting
- Add repoUpstream() API client method and GitHubRepoUpstreamResult type
* feat(github): auto-detect upstream repo for fork→upstream PR creation
- Add GET /api/github/repo/upstream endpoint to discover fork's upstream
- Fix PullRequestSection canShow to allow PR creation on base branch when repo is a fork
- Add virtual upstream target in remote dropdown (no explicit upstream remote needed)
- Add targetRepo parameter to /api/github/pr/create for direct upstream targeting
- Add repoUpstream() API client method and GitHubRepoUpstreamResult type
* fix: complete fork→upstream PR workflow
- Server: return defaultBranch from /api/github/repo/upstream endpoint
- Server: fix cross-repo head ref construction (compare repos, not remote names)
- Server: filterActiveRemoteBranches checks all remotes, not just origin
- UI: set targetBaseBranch to upstream's default branch when using detected upstream
- UI: include all remote branches in base branch dropdown when using detected upstream
- UI: skip base===head check for cross-repo PRs (same branch name on different repos is valid)
- Types: add defaultBranch to GitHubRepoUpstreamResult
* chore: delete superpowers folder
* feat: add (local)/(remote) labels to PR branch display and adapt Repository button to selected remote
* feat: Repository button adapts to selected remote (upstream vs origin)
* fix: complete fork→upstream PR feature gaps
Server:
- Extend /api/github/repo/upstream to return defaultBranchSha and remoteName
- Reuse headRepo result instead of redundant resolveGitHubRepoFromDirectory call
- Return clear error when headRepo is null (invalid GitHub URL)
UI:
- Add upstream's default branch to availableBaseBranches when using detected upstream
- Use upstream's default branch SHA in git log for generate description (fixes 'No commits found in range main...main')
- Show qualified names (owner/repo · branch) in base branch dropdown when using detected upstream
Types:
- Add defaultBranchSha and remoteName to GitHubRepoUpstreamResult
* fix: move detectedUpstream state before availableBaseBranches to fix temporal dead zone
* fix: fetch upstream branches from GitHub API for base branch dropdown
- Add GET /api/github/repo/branches endpoint to fetch branches via Octokit
- Add repoBranches() to GitHub API client and interface
- Fetch upstream branches on detection and store in upstreamBranches state
- Include upstreamBranches in availableBaseBranches when using detected upstream
- Re-add availableBaseBranches memo and auto-correction effect that were lost
- Remove unnecessary qualified names from dropdown (upstream is already selected)
* fix: restore prStatusKey and statusEntry declarations lost during refactor
* fix: cleanly re-apply all fork→upstream PR UI changes
Restored PullRequestSection.tsx from clean base and re-applied:
- Expand detectedUpstream type with defaultBranch, defaultBranchSha, remoteName
- Add upstreamBranches state and fetch on upstream detection
- Include upstream branches in availableBaseBranches when using detected upstream
- Use upstream default branch SHA in generate description (fixes 'No commits found')
- Adapt Repository button URL to selected remote
- Add (local)/(remote)/(upstream) labels to branch display
* fix: move detectedUpstream/upstreamBranches before availableBaseBranches to fix TDZ
* style: add pill badge styling to upstream repo source labels
* fix: don't cache error PR status responses, allow force-bypass of server cache
* fix: resolve PR status cache bugs, stale directory fallback, and upstream re-detection
* fix: keep collapse button visible when scrolling long user messages
- Collapse button now sticks to top of scrollable user message content instead of scrolling away
* fix: checkbox focus ring blends into sidebar background
* fix: polish fork PR follow-ups
* fix: remove user message collapse artifact
* fix: tighten fork PR internals
* fix: check all remotes for fork PR status
* fix: recover sidebar PR status misses
---------
Signed-off-by: Islam Nofl <islamnofl.official@gmail.com>
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>