Commit Graph
20 Commits
Author SHA1 Message Date
Bohdan Triapitsyn e970154809 fix(chat): yield the work status card to the context panel in project-less chats
The visibility hook looked the context panel up under the directory the
card reports about. A managed Chat reports about none, so the lookup ran
against an empty key and answered "closed" while the panel was open.

It now resolves the key the way the rail and the panel do, through
useEffectiveDirectory. The reporting directory is no longer an input to
this hook at all.
2026-08-22 20:31:31 +03:00
Bohdan Triapitsyn d849742d22 fix(chats): hide repository work status
Prevent managed Chat drafts and sessions from inheriting an active project's repository context in the Work Status panel while retaining directory-independent status sections.
2026-08-22 01:31:02 +03:00
Bohdan Triapitsyn 90d8868bfc fix(ui): keep work status PR checks current 2026-08-20 01:38:43 +03:00
Bohdan Triapitsyn 434e5ea9aa fix(knowledge): show draft pins in work status 2026-08-19 00:22:54 +03:00
Bohdan Triapitsyn f9d1ded81a fix(knowledge): scope pins to sessions 2026-08-19 00:07:57 +03:00
Bohdan Triapitsyn f6a4492527 fix(ui): clarify work status hierarchy and MCP loading 2026-08-18 18:54:06 +03:00
Serhii Dziupin a01b7eec78 Merge pull request #2914 from pocharlies/fix/context-usage-server-total
fix(ui): stop the context meter from counting every internal round-trip
2026-08-18 11:07:04 +03:00
Bohdan Triapitsyn 34e8a24b20 feat(knowledge): rebuild the project notes panel as Project knowledge (#2973)
The panel stored notes, todos and plans inside one shared JSON file that
six unrelated domains also wrote to, synchronised itself through window
CustomEvents, and could only read plans. It is now Project knowledge:
server-owned storage with explicit routes, a store with rollback, a
section sidebar, plans that open and edit in place, and search across
all of it.

Notes and plans the user pins travel with every message sent in that
project. Pinning is project state, not an attachment to one message, so
it holds until unpinned and the work status panel names what is riding
along and can detach it.

Agent memory is added alongside, in two scopes: what is true about the
user, and what is true about this codebase. The split is not cosmetic —
a wrong project fact costs one project and is noticed, while a wrong
global fact quietly shapes every session everywhere and the user has no
code to check it against. It stays separate from notes so an agent
mistake cannot land in what the user wrote. Sessions receive an index of
titles only; bodies are read on demand, because an index carrying full
text grows until it crowds out the conversation.

Deciding what a session must be told, and whether it has been told, now
lives on the server. The client owned it before, which meant sessions
started without a UI — scheduled tasks, sessions the agent dispatches —
received nothing at all, and a tab's record of what it had sent outlived
the conversation: after compaction the agent no longer held the block
while the tab went on believing it did. What was delivered is recorded
in the session's own metadata, and compaction restores it through the
runtime that already restores pinned messages, in the same turn.

Agent memory ships dark behind OPENCHAMBER_MEMORY_ENABLE: unset, there
is no tool, no routes, no session index, no settings row and no panel
tab. Absent rather than switched off, so nothing invites turning on a
feature that has not been announced. Pinned notes and plans are
unaffected and ship as normal.
2026-08-18 02:59:04 +03:00
dibanez 9e1a9b59b1 fix(ui): stop the context meter from counting every internal round-trip
The token breakdown of an assistant message accumulates across every API
round-trip inside the turn: each tool call re-reads the whole cached
prompt, so input/cache.read add up to several times the context window.
Every context-usage surface summed those fields, which is why the meter
could read 330% of a 1M window whose real fill was 232,872 tokens
(23.3%), and why reopening an older session jumps the readout (#2562).

The server reports the final round-trip's window as tokens.total
(optional in the message schema; opencode 1.18.18 returns it, verified
against its live /session/:id/message API). Prefer it everywhere the
window fill is displayed and fall back to summing only when the server
did not send it: contextTokensFromBreakdown in tokenUtils now owns that
rule, and the context store extractor, sync store getter, work status
panel, context sidebar, VS Code layout, mini chat, and mobile metadata
all use it instead of their own inline sums.

Fixes #2562
2026-08-15 21:46:49 +02:00
Bohdan Triapitsyn 72cd861eb8 fix(quota): match the Claude Code integration provider to Claude quota
The opencode-claude integration registers its provider as `claude-code`, which
never matched the `claude` quota provider, so the collapsed Usage section in
the work status panel showed no limit for a model from that integration.

Claude windows also reported no duration, leaving the headline to fall back to
whichever row came first instead of the limit that runs out soonest. The
session and weekly windows now carry their length; extra usage stays without
one because it is a monthly spend cap.
2026-08-14 21:07:55 +03:00
Bohdan Triapitsyn 069d9ad5c9 feat: cap subagent list height in work status panel
Limits the expanded subagents list to eight rows
Adds independent scrolling so other sections stay visible
Documents the new subagents panel behavior
2026-08-12 02:10:27 +03:00
Bohdan Triapitsyn 22b3665077 feat: show work status on draft sessions and resolve project worktrees
Keeps the work status panel aligned to the draft's target directory
Resolves project labels for sibling worktrees using shared session-directory logic
Adds coverage for resolving a worktree back to its registered project
2026-08-11 17:00:23 +03:00
Bohdan Triapitsyn a20b87e984 fix(work-status): label project details clearly 2026-08-11 17:00:23 +03:00
Bohdan Triapitsyn b55152db6f fix(usage): refresh work status quotas automatically 2026-08-11 12:58:36 +03:00
Bohdan Triapitsyn a0207e3857 test: cover work-status empty panel recovery 2026-08-10 23:31:58 +03:00
Aaron Hogue 02872ff9d3 fix: keep work-status panel reachable when all sections are hidden (#2805)
* fix: keep work-status panel reachable when all sections are hidden

When every section was unchecked in the Panel Sections dialog, the panel
went transparent and inert, making the settings gear icon unreachable.
The only recovery was knowing to toggle the panel off and on from the
header, which still rendered the same empty/inert state.

Changes:
- Panel stays interactive (not inert) when visible, even with zero
  rendered sections. This matches how other panels in the app use inert
  only for visually-collapsed (width/height = 0) states.
- Empty state shows 'No sections selected' with a link to reopen the
  sections dialog, matching the centered text-muted-foreground pattern
  used by the file tree, review panel, and home page empty states.
- Sections dialog gains a 'Show all' link (visible whenever any section
  is hidden) and a warning when all sections are unchecked, matching the
  keybinds settings 'Reset to defaults' pattern.
- Added i18n keys to all 10 locale files (English fallback).

Fixes #2804

* Round 1: fix interactive guard for fresh-mount; translate i18n keys

Address openchamber-bot review findings:

1. (blocker) Replace English fallback strings in all 10 non-English
   locale files with real translations per locale-ui-patterns guidance.

2. (non-blocker) Restore the renderedSections > 0 guard for the
   transient no-data-on-mount state so the panel doesn't flash a bare
   bordered card. The interactive condition is now:
     visible && (renderedSections > 0 || allSectionsHidden)
   Empty-state rendering is gated on allSectionsHidden alone (not
   renderedSections === 0) so it works correctly on fresh mount when
   all sections were already hidden in persisted settings.

Validation:
  tsc --noEmit: 0 errors
  bun test work-status: 34 pass, 0 fail

* Round 2: use .every() guard, dedup chooseLabel key, add tests

1. Replace >= length check with areAllWorkStatusSectionsHidden() helper
   that uses .every() — stale section ids left in persisted settings
   from a future removal can no longer inflate the count.

2. Remove duplicate chooseLabel i18n key from all 11 locales — the
   empty-state link now reuses the existing sections.open key.

3. Add 6 focused tests for areAllWorkStatusSectionsHidden covering
   empty, null/undefined, partial, full, stale-id, and stale+full.

Validation:
  tsc --noEmit: 0 errors
  bun test work-status: 40 pass (6 new), 0 fail
2026-08-10 23:28:50 +03:00
Bohdan Triapitsyn 75978cf188 fix(mcp): reliable OAuth across runtimes and honest pre-restart UI
MCP authorization was broken in several stacked ways. The browser return
leg landed on the SPA behind the auth gate, so the system browser saw a
login page instead of finishing; the pending-context store silently
saved nothing because its route had no JSON body parser; and the
callback-URL config write started deferring behind Apply & Restart, so
authorization ran against a runtime without the URL and dead-ended on
OpenCode's loopback listener.

The return leg is now completed entirely server-side by an
unauthenticated GET /mcp/oauth/callback that only forwards a code whose
state matches a parked context. Desktop with the local server and VS
Code switch to OpenCode's native flow over its fixed loopback port —
no config writes or restarts at all, with a one-time cleanup of the
previously written callback URL — and its completion signal drives the
page instead of blind status polling. Remote, hosted-web, and mobile
keep the server-callback flow, applying a queued callback-URL write
immediately since authorization cannot wait for a manual restart.

Also: a server queued behind Apply & Restart now shows an Awaiting
restart badge and explanation instead of connect/reauthorize buttons
that can only fail, and Reauthorize is offered only while the server is
actually connected.
2026-08-10 20:23:45 +03:00
Bohdan Triapitsyn 2c30af5807 refactor: remove macOS vibrancy support and unify glass surfaces
Drops the macOS vibrancy toggle, IPC, and related settings copy
Updates dialogs, popovers, tooltips, and dropdowns to use shared glass styles
Adds sticky header fade behavior to model picker and sidebar lists
2026-08-10 15:10:37 +03:00
Bohdan Triapitsyn 90a16d1d44 fix(chat): refresh work status from git hints 2026-08-10 15:10:36 +03:00
Bohdan Triapitsyn f4743ea060 feat(chat): work-status panel, and MCP auth and settings fixes (#2776)
Adds a work-status panel beside the transcript. Context fill, model and
cost, todos, running subagents and the permission requests blocking
them, branch and working-tree state, MCP servers, pinned messages and
context sources were scattered across the header, the composer and the
context panel — a blocked subagent was reported nowhere at all. The
panel reads them from live channels rather than persisted history, and
becomes an overlay where the chat is too narrow to seat a column.

It is on by default, including for existing installs. Because it now
carries these readouts, the desktop header and composer drop the ones it
duplicates: todo and changed-files chips, usage and MCP tabs. VS Code
and mobile keep theirs — neither hosts the panel.

Fixes MCP authorization, which was broken from the panel, invalidated by
a directory switch through a redirect URI that encoded the working
directory, and left the desktop app in the background because browsers
will not follow a custom-protocol link without a user gesture. The
settings page no longer asks the user to understand the MCP spec before
adding a server: one field takes the command or the link, with the kind
inferred and a visible override, and client-registration fields appear
only when a server actually asks for its own credentials.

Also: skills load from the panel instead of only when the composer's
slash autocomplete opens; the header button names the current instance
rather than falling through to the word "Instance" for relay hosts.

Three new optional UI settings keys, all migrated. No change to stored
MCP server configuration.
2026-08-09 19:30:25 +03:00