Commit Graph
53 Commits
Author SHA1 Message Date
Tom Rochette 0244d7ffcd feat: add quick-add button to directory explorer rows (#1351) 2026-05-23 21:37:51 +03:00
Bohdan Triapitsyn 6fd3afd25a feat: replace prompt templates with snippets
Replace the prompt-template workflow with snippet support that is compatible with opencode snippet conventions. Snippets are now stored and loaded from global and project snippet directories, including legacy pluralized paths, with frontmatter metadata for aliases and descriptions. Snippet expansion supports recursive references plus prepend and append sections, while inject sections are treated as unsupported no-ops so OpenChamber remains compatible without requiring an external plugin.

Add the snippets settings experience and remove the old prompt-template settings surface. The new settings page and sidebar support creating, editing, deleting, selecting, and describing snippets, with localized copy across every supported locale. The settings navigation now exposes Snippets with a dedicated icon and metadata.

Wire snippets into all prompt-entry surfaces that need them. Chat, multi-run groups, and scheduled task prompts now offer hash-trigger snippet autocomplete and expand snippets before sending work to OpenCode. Chat also uses an adaptive compact placeholder on mobile or narrow composer widths so helper trigger guidance stays readable in constrained layouts.

Keep multi-run aligned with grouped prompts. Multi-run sessions now use a shared title builder that handles both legacy titles and the newer g1, g2 prompt-group title format. Fusion parsing now recognizes grouped multi-run titles, scopes fusion sources to the same prompt group, and creates fusion sessions under the matching group so outputs from different prompts are not mixed accidentally.

Harden the icon sprite pipeline. The sprite generator now discovers icon names used through typed icon maps, JSX icon props, IconName returns, and generated-value flows without scanning unrelated string literals or the generated sprite itself. The generated sprite is strictly typed so invalid icon names are caught by type checking, and existing invalid or unsafe icon references were cleaned up across settings, provider, Git identity, scheduled task, voice, header, and sidebar surfaces.

Update backend configuration routes and documentation for snippets. The OpenCode config route layer now exposes snippet CRUD and expansion endpoints, accepts JSON bodies for snippet writes, and removes the old prompt-template provider. Scheduled task runtime expansion now uses snippets before dispatching messages.

Add regression coverage for snippet storage and expansion, config-route JSON handling, and multi-run title parsing. Validated with full type checking, full linting, targeted multi-run title tests, and targeted OpenCode snippet/config route tests.
2026-05-21 20:00:35 +03:00
Tom Rochette 6cc1afc963 Multi-run with configurable prompt templates (#1111)
* Multi-run with configurable prompt templates

* Fixes

* Fix handleDuplicate fire-and-forget: await createTemplate and handle failure

* Add Polish translations for prompt template and multirun group keys

* fix: migrate remaining Remix icons to Icon component in MultiRunLauncher

---------

Signed-off-by: Tom Rochette <roctom@gmail.com>
2026-05-21 16:35:42 +03:00
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
Roberto Bertó 46bef9b0c7 Fix/dismissible infinite toasts (#1319)
* fix: make PWA install and OpenCode update toasts dismissible

Both 'Install OpenChamber' and 'OpenCode update available' toasts use
duration: Infinity with no close affordance, so they persist on screen
until the user accepts (install/update) or reloads the tab. For users
who do not want to install the PWA or upgrade right now, this is
intrusive and there is no opt-out.

Add a Dismiss button (sonner cancel action) to both toasts. When the
user dismisses:

- PWA: persist a flag in localStorage so the prompt does not reappear
  on future sessions. Accepting Install still works as before.
- OpenCode update: persist the dismissed version in localStorage. The
  toast will appear again only when a newer version becomes available.

Adds new i18n keys pwa.installPrompt.dismiss and
opencodeUpdate.toast.actions.dismiss across all seven locales (en,
es, ko, pl, pt-BR, uk, zh-CN).

* test: extract toast dedup helpers and cover with 28 unit tests

Lift the dismissal-decision logic out of usePwaInstallPrompt and
OpenCodeUpdateToast into a React-free sibling module so it can be
unit-tested directly. The React surfaces remain sole owners of side
effects (storage writes, toast.info, event listeners); the new module
only answers 'should we show?'.

New module openCodeUpdateDedup.ts exposes four helpers:
- shouldShowPwaInstallToast(input) - three gates: dismissed,
  sessionShown, hasActiveToast.
- shouldShowOpenCodeUpdateToast(input) - empty version, seen set,
  dismissed===version gates; a different dismissed version lets the
  toast resurface for the new release.
- resolveOpenCodeUpdateVersion(detail) - parses CustomEvent payloads
  defensively (null/non-object/non-string -> '').
- resolveOpenCodeUpgradeStatusVersion(status) - parses upgrade status
  payloads (status falsy / available!==true / latestVersion non-string
  -> '').

Consumers now call the helpers and only run the side-effect when the
decision is true. Behaviour is unchanged.

Coverage: 28 tests via bun:test, 33 expects, all pass first try.
2026-05-19 16:57:23 +03:00
Bohdan Triapitsyn c81441ecfc feat: improve VS Code editor chat actions
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
2026-05-19 15:53:54 +03:00
Bohdan Triapitsyn f40110698f fix: preserve markdown when saving notes
Change the chat text-selection Add to notes action to use the existing markdown selection payload, matching Add to chat formatting behavior while still falling back to plain text when markdown extraction is unavailable.

Stop distilling or summarizing selected text before saving it to project notes. The action now appends the selected content directly so code, lists, emphasis, and other markdown survive.

Increase the project notes text limit from 1000 to 3000 characters to account for saving raw selected text instead of a short generated summary.

Update user-facing copy across locales from distilled insight language to selected text language.
2026-05-19 02:07:07 +03:00
Bohdan Triapitsyn 56a2319934 fix: improve slash and mention autocomplete (#1309)
Shows loaded skills in slash autocomplete with clear type badges
Stabilizes keyboard navigation across autocomplete menus
Fixes skill link rendering and skill autocomplete scrolling
2026-05-18 19:11:29 +03:00
Roberto Bertó fbffce4fdf feat: add copy-as-markdown and copy-as-json buttons to question card (#1305)
* feat: add copy-as-markdown and copy-as-json buttons to question card

Adds two small icon buttons in the QuestionCard header so users can copy
the full question payload (text, options, descriptions) to the clipboard
in either Markdown or JSON form. Useful for forwarding interactive
questions to an external LLM or note.

- Markdown serialization preserves question headers, multi-select hints
  and option descriptions.
- JSON serialization mirrors the on-wire QuestionRequest shape for
  programmatic reuse.
- Toast feedback on success/failure using the shared @/components/ui
  wrapper and the existing copyTextToClipboard helper (clipboard API
  with execCommand fallback).
- New i18n keys added across all 7 locales.

* test: extract question serializers and cover with 15 unit tests

The two serializers backing the copy-as-markdown and copy-as-json
buttons on QuestionCard were defined as top-level consts inside
QuestionCard.tsx. Exposing them for unit tests would trip the
react-refresh/only-export-components ESLint rule because that file
also exports the QuestionCard component.

Move serializeQuestionAsMarkdown and serializeQuestionAsJson into a
React-free sibling module, questionSerializers.ts, and re-import them
from QuestionCard.tsx. Behavior is byte-identical.

Add 15 unit tests via bun:test covering header fallback, multi-select
hint gating, blank-description elision, ordering across multiple
questions, JSON canonical shape (no transient id/sessionID), boolean
normalisation, and the empty-questions edge case.
2026-05-18 17:54:19 +03:00
Erman HAVUÇandBohdan Triapitsyn 6369cf76a7 feat(ui): context panel enhancements — resizable panels, drag-and-drop todo ordering, and persistent sizes (#1269)
* fix: remove max-h-80 cap on quick notes textarea so resized height is respected

* feat: add drag & drop reordering to project todo items

* feat: make todo panel resizable with density-aware sizing

* feat: open plan import file picker at project root

* feat: persist quick notes and todo panel sizes across sessions

* refactor(ui): scale content height with padding in projectnotestodopanel

* Update packages/ui/src/components/session/ProjectNotesTodoPanel.tsx

Signed-off-by: Erman HAVUÇ <ermanhavuc@gmail.com>

* fix(ui): harden context panel resizing and import

---------

Signed-off-by: Erman HAVUÇ <ermanhavuc@gmail.com>
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-05-17 23:26:26 +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
Bohdan Triapitsyn 8900b8f0f2 fix(ui): smooth reasoning collapse animation 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
youfchandBohdan Triapitsyn 9c71119835 feat(ui): revert indicator with undo/redo, message list, and attachment restore (#1279)
* feat(ui): revert indicator with undo/redo, message list, and attachment restore

Add bidirectional undo/redo with redo stack navigation and expandable
revert indicator in StatusRow. List reverted messages with inline
revert/fork actions. Restore file attachments on revert.

- Add revert indicator with count, expandable popover, per-button spinner
- Restore file/image attachments when reverting to a message
- Clear previous attachments on revert when target has none
- Restore-all bypasses redo stack for direct unrevert
- Survive popover close/reopen without losing loading state
- Fix flash when sending message after revert
- Fix count disappearing on browser refresh
- Remove dead code (undoStack, getRevertHistory, fork-from-here)
- Fix toast grammar (Undid -> Reverted, Redid -> Redone)
- Add i18n keys for revert popover across all locales

* fix(ui): Greptile review fixes and i18n for revert toasts

- Fix handleSlashUndo toast always showing [No text] (moved getSyncParts before revertToMessage)
- Add inputStore rollback in revertToMessage catch (restore attachments + text on API failure)
- Change portal ID to per-session (prevent multi-session collisions)
- Add i18n keys for undo/redo/restored toasts across all 7 locales
- Use formatMessage in store for localized toast strings

* fix(ui): add missing sessionId to click-outside effect deps

* fix(ui): remove unused sessionActions import in ChatMessage

* fix(ui): derive revert dock from session state

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-05-16 16:44:37 +03:00
Bohdan Triapitsyn 9828ddb4b1 feat: open subagent sessions read-only in context panel
Adds read-only embedded chat mode without hiding permission prompts
Opens subagent sessions in the context panel instead of replacing the main chat
Fixes context panel message loading for embedded sessions
2026-05-15 22:16:04 +03:00
Bohdan Triapitsyn b6149614bd feat: add session switcher dropdown in header
Open recent sessions from chat headers
Support session switching in mini chat
Share pinned and active session state
2026-05-15 18:16:09 +03:00
Bohdan Triapitsyn 3e53d7e071 feat: add fusion for multi-run sessions
Adds Run fusion for multi-run-like sessions
Combines sibling outputs into a new fusion session
Adds configurable Fusion prompts in Magic Prompts settings
2026-05-15 13:26:46 +03:00
Bohdan Triapitsyn 713bb6dfb1 feat: add optional multi-run isolation
Adds an Isolate runs toggle for Git projects
Allows Git multi-runs to share the same directory
Keeps non-Git runs unisolated with clear footer info
2026-05-15 11:35:23 +03:00
Bohdan Triapitsyn ba019c05a6 feat: make agent switching shortcut configurable (#1186)
Adds Cycle Agent to shortcut settings with Tab as the default
Applies custom shortcut in chat input and model selector
Updates help dialog to show saved shortcut values
2026-05-15 00:27:39 +03:00
Bohdan Triapitsyn a1777689e7 feat: support multi-run for non-Git projects
Creates non-Git multi-runs in the same project directory
Shows concise footer info when worktree isolation is unavailable
Displays default model variants with a friendly label
2026-05-14 23:33:10 +03:00
Bohdan Triapitsyn a12be061e3 feat: add OpenCode update and in-app Browser features 2026-05-14 14:45:04 +03:00
Bohdan Triapitsyn 92f1fa7dfe fix: avoid opencode structured output session breakage
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
2026-05-14 02:16:52 +03:00
c1948fe691 Adds an option to transcribe server STT audio when stopping voice input. (#1219)
* feat(voice): add transcribe-on-stop recognition option

* fix(voice): tighten transcribe-on-stop cleanup

* fix(voice): address transcribe-on-stop review feedback

* fix(voice): scope transcribe-on-stop to server STT

---------

Co-authored-by: Konstantin Zolin <kzolin@alfabank.ru>
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-05-13 15:30:25 +03:00
Isaac Sanchez-HawkinsandIsaac Sanchez 7506b736dd fix(git): label branch rename buttons (#1239)
Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
2026-05-12 11:03:26 +03:00
Isaac Sanchez-HawkinsandIsaac Sanchez ebf87f64dc fix(ui): label session rename buttons (#1238)
Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
2026-05-12 11:02:53 +03:00
Bohdan Triapitsyn 1a0f3bea8e fix: allow PR worktrees from existing local branches
Use existing local PR branches instead of blocking worktree creation
Only block PR branches already checked out in another worktree
Clarify local branch validation messages across locales
2026-05-08 16:59:31 +03:00
Bohdan Triapitsyn e1ff21bc0a feat: add Electron Mini Chat windows (#1161)
Add dedicated Electron Mini Chat windows for focused chat sessions without the full desktop shell. Mini Chat can open existing sessions or draft sessions, supports pinning above other windows, transfers sessions or drafts back to the main window, and deduplicates existing-session windows.

Expose Mini Chat entry points from the main header, session sidebar, command palette, and `mod+alt+n`. Add a dedicated Vite entry and React runtime so the compact surface can stay isolated from full-app chrome while still sharing chat, sync, theme, locale, model, agent, and worktree behavior.

Keep Mini Chat behavior scoped to the compact surface:
- limit assistant/user message actions to the appropriate Mini Chat set
- hide workspace changed-files UI in Mini Chat
- keep draft worktree selection and streaming directory state in sync
- mark sessions viewed while they are open in Mini Chat
- support Mini Chat-specific keyboard shortcuts for input focus, model selection, thinking variant cycling, favorite model cycling, and opening new Mini Chat drafts

Harden Electron integration by gating Mini Chat controls on desktop IPC availability, restricting pin/unpin IPC to Mini Chat windows, and only closing Mini Chat after the main window handoff succeeds.
2026-05-08 12:22:59 +03:00
Bohdan Triapitsyn d764ad6872 feat: add repository cloning to project setup
Add project can clone repositories into a chosen folder
Command palette now opens the add project flow
Clone flow supports selecting Git identities
2026-05-07 01:10:17 +03:00
7eff2f725f feat: add Polish localization (#1123)
* Add Polish (pl) localization

* translations

* fix: add missing Polish translations

* copy en keys to pl

* fix: complete Polish settings translations

* fix: localize PWA install prompt

* fix pwa install prompt lifecycle and complete Polish locale keys

* polish polish locale wording for natural phrasing

---------

Co-authored-by: levy52 <levy52@vp.pl>
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-05-06 19:38:58 +03:00
Bohdan Triapitsyn c9289eb24f feat: add stash access in clean git state
Show a Stashes button when the working tree is clean
Keep stash management available even without visible file changes
2026-05-06 15:13:38 +03:00
Bohdan Triapitsyn 170d334921 feat: add manual save mode to file editor
Added a persistent autosave toggle for file editing
Manual save mode applies across current and future opened files
Updated localized toolbar labels
2026-05-06 02:27:07 +03:00
Bohdan Triapitsyn a02f0cd7c7 fix: improve git operation progress banner
Replace placeholder conflict text with localized copy
Split in-progress operation details and actions into clearer rows
Keep merge and rebase status messages consistent
2026-05-06 01:58:36 +03:00
Bohdan Triapitsyn 6b25fd7d20 fix: show pull request unavailable state
Replace the empty PR tab with a clear unavailable message
Explain when pull request actions are available
2026-05-06 00:55:56 +03:00
Bohdan Triapitsyn cce782a62b fix: simplify existing pull request header
Reflow PR status and checks into a cleaner two-row header
Remove the remote selector from existing PRs
Keep remote context as read-only tracking info
2026-05-06 00:46:40 +03:00
Bohdan Triapitsyn 32929d592e fix: make branch updates use latest remote refs
Fetch remote targets before merge or rebase
Prefer remote branch targets over stale local branches
Fix Update copy and branch search input
2026-05-06 00:32:55 +03:00
Bohdan Triapitsyn 8540f51395 fix: make commit sync use safe sync flow
Rename commit push action to Commit & sync
Use fetch and rebase before pushing committed changes
Keep sync result toasts consistent
2026-05-06 00:12:39 +03:00
Bohdan Triapitsyn 7b66bca2c5 fix: clarify sync button and result toasts
Show sync label when no remote changes are known
Report pulled file counts in sync success toasts
Count pulled files correctly in VS Code sync
2026-05-05 23:53:21 +03:00
Bohdan Triapitsyn 93267927ff feat: add git stash management
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
2026-05-05 23:39:20 +03:00
Bohdan Triapitsyn c80c2b62a8 feat: add one-click git sync button
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
2026-05-05 20:45:31 +03:00
jwcrystalandBohdan Triapitsyn 63b4a5b996 feat(ui): enable TimelineDialog with full-text search across all message roles in one session (#1104)
* feat: register open_timeline_dialog shortcut (mod+t)

* feat: enhance TimelineDialog with full-text search across all roles

* feat: add open_timeline_dialog shortcut labels to all locales

* feat: wire TimelineDialog into ChatContainer

* fix: add setTimelineDialogOpen to hook dependency array

* fix: tighten timeline dialog interactions

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-05-05 11:21:06 +03:00
David SazandBohdan Triapitsyn 5475ef2db3 Feat/add ide opened file to chat context (#1106)
* 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>
2026-05-05 01:24:03 +03:00
Bohdan Triapitsyn 7fc22bc69b feat: auto-detect OpenCode CLI on onboarding screen
Polls every 2.5s and transitions automatically once the CLI is reachable
Advanced settings and troubleshooting moved into collapsible accordions
New i18n keys added for status indicator and section titles across 6 locales
2026-05-05 00:41:30 +03:00
Bohdan Triapitsyn 43f98e0344 feat(ui): add recent section toggle 2026-05-03 16:32:14 +03:00
Bohdan Triapitsyn 24533dfe32 feat(palette): unify quick open into command palette with multi-source search
Merge file picker into command palette. Single Cmd+P entry searches
files, sessions, settings pages and commands; groups re-order by best
fuzzy score per source. Sessions show branch labels; git status is
lazily fetched for all session directories on open.

Drop QuickOpenDialog and Cmd+K shortcut.
2026-04-30 18:37:37 +03:00
Bohdan Triapitsyn bbd83d60c6 fix: use valid Zen summaries for notes 2026-04-30 13:07:37 +03:00
bd9a91335c feat(preview): embedded dev-server preview pane + dev shutdown controls (#1062)
* feat: embedded preview proxy for local dev servers

Add a same-origin server proxy under /api/preview/proxy/:id and
matching UI surfaces so local dev servers (Vite, Next, etc.) can be
embedded inside OpenChamber.

Server (packages/web/server):
- New lib/preview/proxy-runtime.js: cookie-gated HTTP+WebSocket proxy
  to loopback hosts only, with TTL'd targets and SSRF allowlist.
- index.js wires the runtime alongside terminal/event-stream.

UI (packages/ui):
- ContextPanel preview tab with iframe, reload, and open-in-browser.
- Inline html code-block preview in MarkdownRenderer.
- Terminal auto-detects loopback URLs and offers to open them.
- i18n keys across en, es, pt-BR, uk, zh-CN.

* perf(preview): cache proxy targets across PreviewPane remounts

Module-scoped Map keyed by upstream URL so tab switches and component
remounts within the same page session reuse the existing proxy
registration instead of POSTing a fresh target each time.

In-memory only by design: the server holds the target map in memory
and the auth cookie is HttpOnly + scoped to the proxy id, so a stale
persisted entry would 404 after a server restart. Entries are evicted
on registration error and on a 30s safety margin before TTL expiry.

* feat(preview): surface dev-server-down state with retry overlay

Iframes don't expose HTTP status to the parent, so when the proxy
returns a 502 (upstream dev server is offline) the iframe just renders
the raw JSON error body. Probe the proxy URL out-of-band with HEAD
(falling back to GET on 404/405) and replace the iframe with a
friendly 'Dev server is not responding' overlay + retry button when
the upstream is unreachable.

Re-probes on reload, on URL change, and on proxy re-registration.

* feat(preview): strip frame-busting response headers

Many dev servers (Next.js, others) send X-Frame-Options: SAMEORIGIN
and/or a CSP with frame-ancestors that block embedding inside the
OpenChamber iframe. The proxy is same-origin and already
authenticated per-target, so embedding is otherwise safe.

- Drop X-Frame-Options outright on proxied responses.
- Surgically remove only the frame-ancestors directive from
  Content-Security-Policy and Content-Security-Policy-Report-Only,
  preserving every other directive. Drops the header entirely if no
  directives remain.
- Verified end-to-end: upstream sending both headers comes through
  with X-Frame-Options removed, CSP retaining default-src/script-src
  but no frame-ancestors, and unrelated headers untouched.

* docs(preview): design for remote-host relay agent

Design-only doc for the next phase of the embedded preview feature:
when OpenChamber runs remotely (cloud/shared/tunnel) and the user's
dev server runs on their local machine. Covers architecture (local
agent + outbound control WebSocket + server dispatch), pairing flow,
wire protocol, security model, failure modes, open questions, and
implementation milestones. No code changes.

* feat(preview): auto-open preview pane for loopback URLs in chat

Detect http(s) loopback URLs in incoming assistant messages and open the
preview pane automatically, deduped per (session, url) pair so re-renders
or repeated mentions do not steal focus. Add an inline Preview button
next to loopback links in chat markdown as a manual fallback when the
auto-open was dismissed or the URL appeared in an older message.

- url.ts: isLoopbackHttpUrl / extractLoopbackUrls helpers
- ChatContainer: module-level dedupe Set + effect on active session tail
- MarkdownRendererImpl: optional onPreviewLoopback in main renderer only
  (SimpleMarkdownRenderer for tool diffs is intentionally untouched)
- Reuses existing terminalView.preview.open i18n keys

* feat: preview enhancements, dev shutdown, and reliability fixes

Add preview start/stop UI in ContextPanel/Header, improve URL detection (Python HTTP server logs, trailing punctuation, IPv6 loopback), fix proxy path filtering to avoid disrupting non-preview WebSockets. Add dev-only /api/system/dev-shutdown endpoint and Header button to terminate local dev processes and orphaned preview servers. Improve terminal cleanup with process group killing, event pipeline reconnect backoff. Update file read APIs with optional flag and cache control. Add /api/system/free-port endpoint, detectDevServer.ts utility, and preview/shutdown i18n strings for 5 languages.

* fix: harden preview support

* fix: keep terminal toolbar interactive

* fix: keep expanded terminal below header

* fix: keep preview iframe under proxy path

* fix: respect project action preview urls

* fix: rewrite preview asset urls

* feat: capture preview console logs

* feat: annotate preview elements

* feat: attach preview annotation screenshots

* fix: improve proxied preview hmr

* feat: refine preview action UX

* fix: address preview review feedback

* fix: show auto-discover preview wait state

---------

Co-authored-by: William Biggers <will@Williams-MacBook-Pro.local>
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-04-30 00:03:38 +03:00
Islam NoflandBohdan Triapitsyn 21253d7fc2 feat: fork-aware issue/PR listing & OpenCode startup loading indicator (#1061)
* 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>
2026-04-29 12:03:39 +03:00
Bohdan Triapitsyn c83986cd94 feat: improve project directory picker
Adds command-palette style project browsing
Keeps native Finder picker as optional desktop action
Supports disabled existing projects and create-and-add paths
2026-04-27 15:45:14 +03:00
Dave OteroandBohdan Triapitsyn b62faadd15 Improve and unify the model picker across desktop and mobile (#1037)
* feat: improve agent and quick model picker behavior

* fix: keep the active model highlighted in the quick picker

* feat: streamline mobile model selection

Open the full mobile model picker directly and remove the intermediate controls drawer so mobile model changes follow the same core selection flow as desktop.

Add inline thinking-mode chips that show each model's remembered or default variant, apply model and variant together on tap, and fall back to a dedicated overflow panel for larger variant sets. Also keep favorites and recents searchable on mobile and fix clearing remembered default variants so the picker stays consistent across sessions.

* fix: polish desktop model picker interactions

Stabilize desktop model picker behavior by keeping keyboard and hover selection in sync, preventing hover-driven closes, and making the footer hints visually stable.

Also make quick-picker thinking mode changes apply consistently when switching plan/build or agent mode inside the picker, clamp left/right variant cycling at the ends, and keep thinking feedback visible even when the selected variant cannot move further.

* fix: condense mobile model picker rows

Tighten the mobile model picker to use a more compact, consistent row layout across favorites, recents, and provider sections while keeping context length and capability icons easy to scan.

Also preserve inline thinking-mode selection, improve metadata spacing, and keep the mobile controls readable without reintroducing the heavier drawer-based flow.

* fix: include all primary-like agents in picker cycling

Keep desktop Tab cycling and mobile tap cycling aligned with the rest of the selection UI by including agents marked as all or left unset, not just strict primary agents.

* fix: preserve remembered agent variants in picker flows

* Fix model picker variant restore

* Polish favorite model drag handle

* Fix Korean model picker locale

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-04-27 13:28:51 +03:00
Jinwoo An (안진우) b0dd3b52b9 feat: add Korean locale (#1040) 2026-04-27 11:05:43 +03:00