Commit Graph
216 Commits
Author SHA1 Message Date
Bohdan Triapitsyn aaffd6c598 fix: improve OpenCode update and desktop menu behavior
Restart OpenCode after successful updates so the new version is active
Open native About menu into the app About dialog
Update desktop View menu actions for the new layout
2026-05-20 17:29:00 +03:00
Isaac Sanchez-HawkinsandIsaac Sanchez 2f89757b9f fix: strip code before TTS markdown cleanup (#1327)
Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
2026-05-19 17:30:32 +03:00
Lam NguyenandBohdan Triapitsyn 4cfe7c80a3 feat(quota): add Wafer.ai quota provider (#1312)
* 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>
2026-05-19 17:29:36 +03:00
Bohdan Triapitsyn 3ac697adc7 fix: remove duplicate Zhipu usage provider
Keeps one Zhipu AI Coding Plan entry in usage settings
Preserves existing Zhipu aliases and config lookup
Removes duplicate backend quota registration
2026-05-19 14:49:03 +03:00
Bohdan Triapitsyn 87d13cf61b fix: enable web runtime notifications without push (#1322)
Web notifications now listen to the notification stream directly
Native notifications no longer depend on PWA push being enabled
Window focus is respected when deciding whether to send background push notifications
2026-05-19 13:16:47 +03:00
Bohdan Triapitsyn 174fa4e96d chore: retire zen-backed summarization
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.
2026-05-19 02:06:52 +03:00
Bohdan Triapitsyn d928185640 fix: make opencode health checks resilient
Avoids restarting OpenCode after transient health probe failures
Coalesces concurrent health checks and briefly caches probe results
Adds configurable health timeout, retry threshold, interval, and cache settings
2026-05-18 21:17:02 +03:00
Bohdan Triapitsyn 81c834d194 fix: normalize line endings in file diffs (#1306)
Prevents CRLF-only changes from flooding diff view
Keeps text diffs focused on real content changes
2026-05-18 19:21:07 +03:00
Bohdan Triapitsyn 622927c34c fix: suppress non-git remote lookup noise 2026-05-17 23:36:17 +03:00
Erman HAVUÇandBohdan Triapitsyn 631905764e feat(git): inline file diffs in commit history rows (#1291)
* chore: add .worktrees/ to gitignore for worktree workflow

* feat(git): add getCommitFileDiff service function

* docs(git): document getCommitFileDiff in module docs

* feat(git): add GET /api/git/commit-file-diff route

* feat(git): add CommitFileDiffResponse type and GitAPI method signature

* feat(git): add getCommitFileDiff HTTP client function

* feat(git): add getCommitFileDiff API facade

* feat(git): add getCommitFileDiff stub to VS Code bridge

* feat(git): add getCommitFileDiff to VS Code gitService and bridge handler

* feat(git): add inline file diff to history commit rows

* fix(git): consolidate CommitFileDiffResponse import to gitApi facade

* fix(git): pass directory through history, validate hash, propagate git errors

* fix(git): use exit code check for VS Code getCommitFileDiff error detection

* fix(git): VS Code rename detection, hash validation parity, retry on error

* fix(git): register scroll container as virtualizer root to fix empty space in history diffs

* fix(git): address greptile review — rename key extraction, directory guard, language detection, isBinary cleanup

* fix(git): harden history inline diffs

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-05-17 20:08:17 +03:00
Erman HAVUÇandBohdan Triapitsyn fa8fac2590 fix(git): use local-first base ref resolution in getLog, port to VS Code (#1284)
* 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>
2026-05-17 19:28:08 +03:00
Bohdan Triapitsyn bbc297202e fix: use opencode skills as source of truth 2026-05-17 14:51:25 +03:00
Erman HAVUÇandBohdan Triapitsyn e1977bbe63 feat(ui): collapsible thinking blocks with merged per-turn view and user toggle (#1273)
* feat: add collapsible reasoning traces with animated labels

* feat(ui): redesign reasoning blocks with merged collapsible Thought view

- Replace per-part reasoning blocks with a single merged block per turn
  (VSCode Copilot pattern), controlled by new `groupReasoningBlocks` store flag
- `ReasoningTimelineBlock` redesigned: chevron toggle, summary preview on
  collapsed header, 'Thinking'/'Justification' label when expanded, BusyDots
  while streaming, auto-scroll to bottom during live streaming
- Short texts (< 120 chars) render inline without a toggle
- Summary now strips markdown and truncates at a word boundary with ellipsis
- New `MergedReasoningPart` component merges all reasoning parts for a message
  into one block at the position of the first reasoning part
- `defaultExpanded` prop lets callers override initial expand state
- Remove `.thinking-dot` CSS animation (replaced by BusyDots component)
- Fix reasoning markdown font-size: use `--text-markdown` instead of `--text-meta`

* refactor(ui): scope working phrases inside useAssistantStatus and simplify reasoning status

- Move WORKING_PHRASES array and getRandomWorkingPhrase() inside the hook
  so they are no longer exported (were only consumed by ReasoningPart which
  no longer needs them)
- Change the 'reasoning' activity status text from a random working phrase
  to the deterministic string 'thinking' — matches the new UI label

* test(ui): expand ReasoningPart tests for new collapsible and summary behavior

- Update baseline test to use text long enough to trigger the collapsible
  path (short texts now render inline) and assert on the correct aria markup
- Add test for 'Justification' label when pre-expanded via defaultExpanded
- Add test for 'Thinking' label for the thinking variant when expanded
- Add test verifying summary is a word-boundary-truncated excerpt ending with
  an ellipsis character

* i18n: rename 'Reasoning Traces' to 'Thinking Blocks' and add thought key

- Rename settings label from 'Show Reasoning Traces' → 'Show Thinking Blocks'
  across all supported locales (en, es, ko, pl, pt-BR, uk, zh-CN)
- Add `chat.reasoningTrace.thought` key to all locales (used by merged
  reasoning block header in completed state)

* feat(ui): add collapsibleThinkingBlocks setting with full persistence wiring

- New boolean store field `collapsibleThinkingBlocks` (default true) with
  `setCollapsibleThinkingBlocks` action; persisted to localStorage
- Threaded through DesktopSettings, SettingsPayload (API types), desktop
  persistence (sanitize + apply), web appearance persistence, appearance
  auto-save watcher, and server-side settings-helpers sanitize/format
- Server defaults to true when the field is absent in formatSettingsResponse
- MessageBody reads the flag: false → render reasoning as plain AssistantTextPart;
  true → existing collapsible/merged block path

* feat(settings): expose Collapsible Reasoning Blocks toggle in visual settings

Add a checkbox under the 'Show Thinking Blocks' row (visible only when
showReasoningTraces is enabled) that toggles the collapsibleThinkingBlocks
preference. Follows the existing toggle pattern: div role=button, keyboard
handler for Enter/Space, Checkbox primitive, aria-pressed attribute.

* i18n: revert showReasoningTraces label rename and add collapsibleThinkingBlocks strings

- Revert 'Show Reasoning Traces' → 'Show Thinking Blocks' rename (the
  collapsibleThinkingBlocks toggle is now a separate control, so the parent
  label stays as 'Reasoning Traces' for clarity)
- Add `collapsibleThinkingBlocks` / `collapsibleThinkingBlocksAria` strings
  across all seven supported locales (en, es, ko, pl, pt-BR, uk, zh-CN)

* test(server): add settings-helpers coverage for collapsibleThinkingBlocks

- Verify sanitizeSettingsUpdate accepts boolean true/false and rejects
  non-boolean values (string, number)
- Verify formatSettingsResponse forwards the value correctly for both true
  and false, and defaults to true when the field is absent

* fix(ui): respect defaultExpanded prop and remove dead alwaysShowActions from ReasoningTimelineBlock

The useEffect on [isStreaming] was firing on mount and immediately calling
setIsExpanded(false) (since isStreaming is false for completed blocks),
overriding any defaultExpanded={true} passed by callers. The fix uses a
prevIsStreamingRef so the effect only collapses the block on a true→false
transition and is a no-op on initial mount.

Also removes alwaysShowActions from ReasoningTimelineBlockProps — the new
header design always shows the chevron, making the prop obsolete. The prop
was already absent from the component destructuring (a dead type entry) and
was silently ignored at runtime. Removed it from ReasoningPartProps,
MergedReasoningPartProps, and the two call-sites in MessageBody as well.

* chore: remove unused reasoningpresentation module and test

* fix(ui): polish collapsible reasoning block UI

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-05-16 17:20:16 +03:00
Bohdan Triapitsyn b79a40adce fix: proxy absolute same-origin preview requests
Fixes Preview backend calls built from window.location.origin
Routes same-origin fetch, XHR, EventSource, and WebSocket requests through the preview proxy
Keeps local full-stack apps working inside the Preview panel
2026-05-15 14:44:35 +03:00
Bohdan Triapitsyn 34fde831eb fix: make daemon startup ready handoff reliable
Wait longer for slow daemon startup
Fail cleanly when ready handoff does not complete
Avoid orphaned daemon processes after startup timeout
2026-05-14 15:00:25 +03:00
Bohdan Triapitsyn a12be061e3 feat: add OpenCode update and in-app Browser features 2026-05-14 14:45:04 +03:00
Bohdan Triapitsyn ef85c63336 fix: voice input in Electron - local Whisper STT + network error handling
- Add local Whisper STT via Transformers.js with Web Worker (no UI freeze)
- Default sttProvider to 'local' in Electron (browser STT unavailable)
- Fix infinite toast loop: stop auto-restart on network errors
- Add retry limit with exponential backoff for transient STT errors
- Append voice transcript to input field (append-inline), not replace
- Add model catalog with download/load button in Voice Settings
2026-05-14 01:19:52 +03:00
Bohdan Triapitsyn 7fb5ad0f48 fix: check window focus before summarization to avoid wasted Zen API calls
When notificationMode is 'hidden-only', the isWindowFocused check now
happens before summarization and template resolution, not after. This
prevents costly Zen API calls for notifications that would be skipped
anyway, and eliminates stale notifications arriving after the user has
already read the response and switched away.
2026-05-13 17:43:08 +03:00
a2c88f0142 Sync speech recognition settings across devices (#1217)
* fix: sync STT settings across devices
Persist speech recognition preferences through shared OpenChamber settings so mobile and desktop stay in sync.

* fix bot review

* fix(voice): sync transcribe-on-stop setting

---------

Co-authored-by: Konstantin Zolin <kzolin@alfabank.ru>
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-05-13 15:45:03 +03:00
11e5ab93a9 fix(quota): guard remaining usage percent (#1242)
* fix(quota): guard remaining usage percent

* test(quota): cover non-finite usage percents

* fix(ui): clean up virtual scroll frame

---------

Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-05-13 14:51:46 +03:00
Isaac Sanchez-HawkinsandIsaac Sanchez 1e1a7e02b7 test(opencode): restore missing PATH cleanly (#1243)
Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
2026-05-13 10:35:32 +03:00
Isaac Sanchez-HawkinsandIsaac Sanchez d66e077b99 fix(pwa): include root-scoped session shortcuts (#1244)
Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
2026-05-13 10:35:12 +03:00
Isaac Sanchez-HawkinsandIsaac Sanchez f01391dd72 fix(opencode): broadcast activity idle after cooldown (#1249)
Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
2026-05-13 10:32:30 +03:00
Isaac Sanchez-HawkinsandIsaac Sanchez 05c5683ecb fix(scheduled-tasks): skip scheduling after stop (#1251)
Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
2026-05-13 10:32:16 +03:00
Isaac Sanchez-HawkinsandIsaac Sanchez c005c59186 fix(quota): accept epoch reset timestamps (#1241)
* fix(quota): accept epoch reset timestamps

* fix(quota): format epoch reset windows

---------

Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
2026-05-13 10:30:42 +03:00
kjhqandartac f059bc8dd6 fix: remove GitHub hardcoding and generalize for non-GitHub git providers (#1216)
* fix: remove GitHub hardcoding and generalize for non-GitHub git providers

* fix: guard SSH path extraction against missing colon separator

---------

Co-authored-by: artac <artac@artacs-MacBook-Pro.local>
2026-05-13 10:19:31 +03:00
644050824e fix(terminal): reject file cwd values (#1204)
* fix(terminal): reject file cwd values

* test(terminal): remove stale cwd access mock

---------

Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-05-12 11:30:10 +03:00
Isaac Sanchez-HawkinsandIsaac Sanchez 89630af98d fix(settings): constrain plan path remapping (#1203)
Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
2026-05-12 11:12:17 +03:00
Isaac Sanchez-HawkinsandIsaac Sanchez 1f6cea50ed fix(tasks): preserve timestamps when listing (#1198)
Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
2026-05-12 11:10:56 +03:00
Isaac Sanchez-HawkinsandIsaac Sanchez 51356b4195 fix(projects): use fallback icon MIME (#1197)
Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
2026-05-12 11:10:39 +03:00
Isaac Sanchez-HawkinsandIsaac Sanchez 51e1967f68 fix(sessions): isolate folder save temp files (#1195)
* fix(sessions): isolate folder save temp files

* fix(sessions): remove failed save temp files

---------

Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
2026-05-12 11:10:06 +03:00
Isaac Sanchez-HawkinsandIsaac Sanchez 222d1b7f51 fix(tts): clamp generated summaries (#1187)
* fix(tts): clamp generated summaries

* fix(tts): preserve non-finite summary limits

* test(tts): stub fetch without vitest globals

---------

Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
2026-05-12 11:06:21 +03:00
Isaac Sanchez-HawkinsandIsaac Sanchez b944bd812c fix(quota): ignore invalid reset timestamps (#1182)
* fix(quota): ignore invalid reset timestamps

* fix(quota): guard reset-after timestamps

---------

Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
2026-05-12 11:05:22 +03:00
Isaac Sanchez-HawkinsandIsaac Sanchez 323347f50e fix(terminal): preserve UTF-8 replay chunks (#1181)
* fix(terminal): preserve UTF-8 replay chunks

* fix(terminal): avoid replay trim prepends

---------

Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
2026-05-12 11:05:03 +03:00
Isaac Sanchez-HawkinsandIsaac Sanchez 2a9c7e6bca fix(event-stream): clean up reconnect delay listeners (#1180)
* fix(event-stream): clean up reconnect delay listeners

* test(event-stream): clarify listener count

---------

Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
2026-05-12 11:04:46 +03:00
Isaac Sanchez-HawkinsandIsaac Sanchez 7721c2fe10 fix(event-stream): isolate subscriber failures (#1235)
* fix(event-stream): isolate subscriber failures

* fix(event-stream): handle async subscriber failures

---------

Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
2026-05-12 11:02:04 +03:00
Isaac Sanchez-HawkinsandIsaac Sanchez df12c3a2b5 fix(terminal): make SSE cleanup idempotent (#1234)
Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
2026-05-12 11:01:47 +03:00
Isaac Sanchez-HawkinsandIsaac Sanchez 060a5311ef fix(terminal): remove upgrade listener on shutdown (#1233)
Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
2026-05-12 11:01:31 +03:00
Isaac Sanchez-HawkinsandIsaac Sanchez eeabc304bd fix(opencode): clear server close timeout (#1224)
Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
2026-05-12 11:00:45 +03:00
Isaac Sanchez-HawkinsandIsaac Sanchez 4cbee27383 fix(opencode): clear readiness probe timers (#1226)
Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
2026-05-12 11:00:31 +03:00
Isaac Sanchez-HawkinsandIsaac Sanchez 0cfa37932e fix(updates): compare prerelease versions correctly (#1220)
Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
2026-05-12 10:57:47 +03:00
Isaac Sanchez-HawkinsandIsaac Sanchez eb3f0e7f72 test(opencode): avoid duplicate WSL env assertion (#1212)
* test(opencode): avoid duplicate WSL env assertion

* test(opencode): assert WSL rejection directly

---------

Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
2026-05-12 10:57:39 +03:00
Isaac Sanchez-HawkinsandIsaac Sanchez 614e9bbfbf test(opencode): restore PATH after lifecycle tests (#1210)
Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
2026-05-12 10:57:14 +03:00
Isaac Sanchez-HawkinsandIsaac Sanchez 733e1e2d21 fix(pwa): keep scoped shortcuts isolated (#1205)
Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
2026-05-12 10:55:31 +03:00
Wenqiang.Xu 3716deb16c fix: use platform-aware UTF-8 locale fallback for PTY (#1137)
C.UTF-8 does not exist on macOS, causing the terminal to fall back
to ASCII encoding when LANG is unset. Use en_US.UTF-8 on macOS and
C.UTF-8 on Linux. Also set LC_CTYPE with the platform-appropriate
value (UTF-8 on macOS, C.UTF-8 on Linux) for additional safety.
2026-05-08 16:19:24 +03:00
Isaac Sanchez-HawkinsandIsaac Sanchez 4a79af3fb7 fix(event-stream): cancel unavailable upstream bodies (#1142)
Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
2026-05-08 15:14:39 +03:00
Isaac Sanchez-HawkinsandIsaac Sanchez 4b65a16b12 fix(git): load sandbox db dependency in esm (#1140)
Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
2026-05-08 15:09:52 +03:00
zerone0xandBohdan Triapitsyn 3fbcdbc3dc fix(quota): stop showing misleading OpenRouter percentages (#1127)
* fix(quota): stop showing misleading OpenRouter percentages

Fixes #1085

* fix(quota): clean up OpenRouter credit labels

---------
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-05-07 23:39:53 +03:00
Bohdan Triapitsyn 585e2a55f1 fix: suppress inherited subagent notifications
Subagent completion notifications respect notification settings
Permission auto-accept now suppresses notifications for known child sessions
Server notification checks use OpenCode session parent semantics
2026-05-07 23:03:46 +03:00
Wenqiang.Xu cb8ea5e6c5 fix: set LANG env for PTY to support UTF-8/Unicode in terminal (#1129) 2026-05-07 23:03:09 +03:00