The staggered re-send lived as three near-identical private methods in
the chat view, agent manager, and session editor providers. One helper
now owns the delays, the connected gate, and the replaced-target guard;
the providers keep thin wrappers over their own panel/view identity.
Also restores the package.json trailing newline the branch dropped.
- discard an in-flight discovery when the runtime switches, mirroring the
isRequestCurrent pattern, so a late completion cannot repopulate the
cleared map and suppress a fresh scan
- treat a 501 from /api/fs/git-dirs as an explicit 'unsupported' marker
instead of a generic failure; the VS Code webview now answers the route
with unsupportedWebRouteResponse so non-repo roots show the honest
not-a-repository state without a futile Retry
Right-click now opens the session menu under the cursor (the sidebar's
context-menu pattern; the same header-supplied items back both the
"..." dropdown and the context menu via injected menu primitives) and
still never changes the active tab. Hovering a tab shows the sidebar's
session tooltip — title, last-activity time, project, branch and PR
status — after a delay, suppressed while a menu is open or a drag is in
flight. Each tab carries the sidebar's status dot at its end (accent
while the session runs, info-blue for unread), hidden while the hover
controls overlay it. Tab titles fade out instead of ending in "...",
and while the active tab is renaming its hover controls stay hidden so
only the rename controls show.
* fix(ui): open app deep links from chat after confirmation
DOMPurify's default URI policy stripped href from anchors with custom
application schemes (obsidian://, vscode://, ...), so every app link
rendered in chat was dead across web, desktop, VS Code, and mobile.
- Classify safe app-link schemes in lib/url.ts (browser-handled,
scriptable, webview-internal, network, and self-deep-link schemes
stay excluded) and let openExternalUrl accept them
- Keep app-link hrefs through the markdown sanitize hook
- Intercept app-link clicks in the markdown renderer and route them
through a confirmation dialog (Trust and open / Open once, dismiss
to cancel) mounted in the desktop/web app root and the mobile shell
- Persist per-device trusted schemes in a zustand store; trusted
schemes open without asking again
* feat(settings): manage trusted app link schemes in General
Add an App links section to Settings > General listing the application
schemes trusted on this device with a delete action; removing a scheme
restores the confirmation dialog for it. Register the section in
settings search.
* fix(ui): enforce app link confirmation
* fix(ui): handle app links by runtime
* fix(vscode): keep app links unsupported
* fix(settings): clarify trusted app links
---------
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
* feat(skills): remove ClawHub catalog integration
Drop the ClawHub registry as a skills catalog source across web server,
shared UI, VS Code, docs, and locales. The catalog now serves git-based
sources only: the curated Anthropic repo and user-defined repositories.
Also removes the now-unused adm-zip dependency.
* feat(skills): redesign catalog around curated GitHub repositories
Replace the single-source dropdown with a card grid of curated GitHub
repositories (Anthropic, OpenAI, Cursor pstack/skills, Matt Pocock) plus
user-defined sources. Source cards show skill counts, GitHub stars, and
last-updated time; a global search covers all loaded sources.
Server: curated sources gain GitHub repo metadata (stars, pushed_at)
fetched best-effort with a 3-hour in-memory and on-disk cache; scans
run through a concurrency-limited, deduplicated cache with 3-hour TTL
persisted across restarts. Refresh still bypasses the cache.
Shared UI: source cards, global search with clear button, per-skill
GitHub links, install/installed states. VS Code curated list updated
to match. All new copy translated across 12 locales.
* fix(skills): address catalog review findings
- GitHub metadata fetch timeout drops to 1.5s (under the catalog
client's 3s deadline) and failed lookups cache briefly (5 min) so
repeated catalog loads do not re-hit a failing API.
- Disk cache files are written with owner-only permissions (0o600);
rename preserves the mode.
- loadSource deduplicates concurrent in-flight requests per source and
the shared isLoadingSource flag now clears only when the last active
source load finishes.
* fix: reconcile busy sessions after managed OpenCode restart
Forced health-check restarts previously rebound the event stream without
settling in-flight turns, so sessions stayed busy with no terminal state.
Interrupt those sessions, classify health failures, and retain bounded
process diagnostics for post-restart diagnosis.
Fixes#2943
Co-authored-by: serkraser <serkraser@gmail.com>
* fix: surface interrupted chats after OpenCode restart
Complete unfinished assistant turns as aborted once the session is
authoritatively idle, and show a persistent toast so users can continue
instead of remaining silently stranded.
Fixes#2943
Co-authored-by: serkraser <serkraser@gmail.com>
* fix: redact Basic auth credentials in restart diagnostics
The key/value sanitizer stopped at whitespace, so Authorization: Basic
credentials survived in stderr tails and health snapshots. Redact the
scheme token before that rule runs.
Co-authored-by: serkraser <serkraser@gmail.com>
The webview only leaves its initial loading screen once it receives a
connectionStatus=connected postMessage. VS Code drops postMessage calls made
before the webview's acquireVsCodeApi bridge is ready, so on slow/remote
networks the single send in _sendCachedState() can be lost forever, leaving
the sidebar stuck on #initial-loading.
Re-send connectionStatus at staggered delays (0.5s-20s) when connected, in
ChatViewProvider, AgentManagerPanelProvider and SessionEditorPanelProvider.
Stops automatically when the view/panel is disposed or replaced. Message is
idempotent.
Fixes#2996
Share the desktop session-card currency formatter (lib/money.ts) and surface
the current session's cost in the extension chat-header context usage tooltip.
Treating every undefined parse as empty config let a file that is not JSON
at all (YAML, plain text) read as {}, so a later write would back it up and
replace it - the same data loss this fix is meant to prevent. Only a
comment-only parse, where ValueExpected is the sole error, counts as empty.
Configure a default API base URL per git provider (github/gitlab/gitea)
in settings.json gitProviders, with GitHub Enterprise support (Octokit
baseUrl + device-flow web origin derived from the API base), and replace
the client-side custom-domains list with server-persisted detection URL
chips (SSH/HTTPS forms normalized to hosts). The configured API base host
auto-counts as a detection host. Settings round-trip through the existing
/api/config/settings sanitizer; the UI store hydrates from server settings
with a one-time localStorage migration.
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
Branch status resolves an open PR across the whole fork network first, so a
merged fork PR can never hide an open upstream PR for the same head. Only when
no target has an open PR does the branch's newest closed/merged PR come back,
as history.
The panel shows that history as a compact note and offers creating the next PR
below it, instead of either sticking on a terminal PR or going blank after a
merge. Terminal associations stay persisted for reload continuity but are never
treated as authority: they revalidate on the discovery cadence and on focus.
History is looked up only for the branch's own remote and name, and remembered
per repo+branch, so the extra lookup cannot exhaust the route's resolve budget.
The checks summary and merge-permission lookup are skipped for a closed or
merged PR, where neither is actionable.
Plugin listing still called readConfigFile per layer, so one unparseable
project file made GET /api/config/plugins and VS Code listPluginEntries
fail. Reuse readConfigLayer isolation and pin comment-only empty parse
in the VS Code suite.
Co-authored-by: serkraser <serkraser@gmail.com>