Commit Graph
2534 Commits
Author SHA1 Message Date
Serhii Dziupin 9761f5ff3c Merge pull request #2910 from openchamber/feat/third-party-integrations-dashboard-6ead 2026-08-14 19:53:13 +03:00
Bohdan Triapitsyn 37e12e272b fix(ui): restore context panel session chats 2026-08-14 19:49:17 +03:00
Bohdan Triapitsyn 5fbd1c0962 fix: stop comment typing from triggering page shortcuts
Adds a keydown handler on the comment input that stops propagation
Keeps Enter-to-submit behavior working in the annotation overlay
Cleans up the new event listener when the overlay is removed
2026-08-14 19:16:18 +03:00
Cursor AgentandSerhii Dziupin c39eb54acb docs(changelog): note Integrations settings page in Unreleased
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
2026-08-14 15:31:50 +00:00
Serhii Dziupin 3ae8d3fe45 feat: include restart notice in integration success toasts 2026-08-14 15:19:26 +00:00
Serhii Dziupin 10b928a786 feat: refresh third-party integration descriptions 2026-08-14 15:19:26 +00:00
Serhii Dziupin 6e55df9bed feat(integrations): point third-party plugins at OpenChamber packages 2026-08-14 15:19:26 +00:00
Serhii DziupinandSerhii Dziupin 0e0580f95c fix(integrations): remove unnecessary Refresh control
Data already reloads on mount, after mutations, and after Apply & Restart,
so the section Refresh button was redundant noise.

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
2026-08-14 15:19:26 +00:00
Serhii DziupinandSerhii Dziupin 22ffc4c87f fix(integrations): drop duplicate accordion status; reword copy
Remove the repeated installed/status block inside expanded third-party
cards, and phrase page/plugin descriptions as adding a subscription to
use as an OpenChamber provider.

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
2026-08-14 15:19:26 +00:00
Serhii DziupinandSerhii Dziupin 70f8f2e15b fix(icons): inject missing sprite symbols for newly added icons
The icon sprite was injected once and never updated, so HMR/new glyphs
like telegram-fill left <use> refs empty. Append missing symbols on render.

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
2026-08-14 15:19:25 +00:00
Serhii DziupinandSerhii Dziupin a838f62b41 feat(integrations): add Discord/Telegram Coming soon placeholders
Show greyed non-interactive messenger cards with a Coming soon badge
(matching integration card chrome, no expandable controls), and refresh
third-party statuses immediately after Apply & Restart clears pending
plugin restarts.

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
2026-08-14 15:19:25 +00:00
Serhii DziupinandSerhii Dziupin 2303740b4a fix(integrations): restore brand icons and provider logo fallbacks
The Integrations cards render Icon(plugin.icon), so Claude Code /
Command Code / Cursor brand glyphs belong in the sprite. Also restore
claude-code.svg and the Command Code ProviderLogo fallback used after
Set up opens the Providers page. Leave out unused opencode.svg.

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
2026-08-14 15:19:25 +00:00
Serhii DziupinandSerhii Dziupin 53ab67ea35 refactor(integrations): drop unused logos, brand icons, and card wrapper
Keep only the Settings Integrations page wiring: three plugins, i18n,
search/metadata, and the plugins-store registry boolean needed for
failure status. Remove ProviderLogo fallbacks, SVG assets, custom sprite
icons, and the separate IntegrationCard layer.

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
2026-08-14 15:19:25 +00:00
Serhii DziupinandSerhii Dziupin 0aba428e95 fix(i18n): strip BOM from zh-TW settings after import insert
Adding the third-party integrations import shifted the existing UTF-8 BOM
onto line 2 and tripped no-irregular-whitespace.

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
2026-08-14 15:19:25 +00:00
Serhii DziupinandSerhii Dziupin af380081c2 feat(settings): add third-party integrations dashboard
Add a Settings → Integrations page for installing and managing the three
supported OpenCode provider plugins (Claude Code, Command Code, Cursor),
with search, i18n, and plugin-registry status wiring.

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
2026-08-14 15:19:25 +00:00
Bohdan Triapitsyn 3f266232f9 release v1.18.4 2026-08-14 17:48:03 +03:00
Bohdan Triapitsyn e8e6e4cacf fix(mobile): keep tokenless connections alive across launch and resume
A server running with authentication disabled pairs and connects fine, but
the saved connection has no bearer token. Auto-connect silently bailed on
the missing token and the resume reprobe reported it as 'unreachable',
so every return to the app kicked the user to the connect screen.

Treat a saved tokenless connection as valid: probe it without a bearer and
let the probe decide — auth disabled connects, auth enabled later reports
needs-login. Bail out only when an expected token cannot be read.
2026-08-14 17:29:49 +03:00
Bohdan Triapitsyn 12b5857b3f fix(markdown): align image gallery authorization 2026-08-14 17:27:07 +03:00
ChangeHow 90780258cd fix(markdown): correct image gallery rendering (#2894) 2026-08-14 17:10:36 +03:00
Bohdan Triapitsyn fe1f6130d6 fix(chat): keep messages chronological across ID rollover 2026-08-14 16:53:05 +03:00
Bohdan Triapitsyn 7cf869d5eb fix(server): survive stray uncaught exceptions and invalid dev-tunnel base URLs
A single uncaught exception (e.g. a Node-internal socket error) no longer
shuts the local server down; only a sustained storm does. The dev-tunnel
client now rejects non-http(s) base URLs cleanly instead of throwing an
uncaught exception in the connection handler.
2026-08-14 12:45:35 +03:00
Bohdan Triapitsyn b5c9da4ff0 release v1.18.3 2026-08-14 00:55:17 +03:00
Bohdan Triapitsyn 94e07e4edd fix(mobile): share exported message images 2026-08-14 00:49:42 +03:00
Bohdan Triapitsyn 7c5fcb535e chore: bump @opencode-ai/sdk to 1.18.18 2026-08-14 00:26:07 +03:00
Bohdan Triapitsyn 2a6f2dc270 chore(vscode): update unreleased changelog 2026-08-14 00:17:52 +03:00
Bohdan Triapitsyn 29e7a2380d fix(markdown): open local file links 2026-08-14 00:13:03 +03:00
Bohdan Triapitsyn 1b02310a28 fix (vscode): focus chat input after opening the chat view
Opens the chat view before focusing the input
Routes a new webview command to focus the composer
Refocuses the input after adding a VS Code selection attachment
2026-08-13 23:50:54 +03:00
Bohdan Triapitsyn 2a5be62c58 fix(git): clarify GitHub pull request link 2026-08-13 23:44:49 +03:00
Bohdan Triapitsyn 55fcd5092e fix(mobile): support file downloads and image previews 2026-08-13 23:44:36 +03:00
Bohdan Triapitsyn 0da89f3f88 chore: update changelog with unreleased changes 2026-08-13 23:33:48 +03:00
Bohdan Triapitsyn a5aa32446d feat(browser): replace the preview proxy with a real browser panel and an agent web tool (#2883)
The preview panel worked by proxying a dev server through OpenChamber's own
origin and rewriting the HTML that came back. Anything the rewriter did not
anticipate broke, and pages that refuse to be embedded never loaded at all.
This deletes the proxy (-1604 lines and its tests) and merges the preview and
browser panels into one surface backed by a real Chromium view.

What the panel is now

- A `<webview>` in its own session partition: logins and cookies persist, hot
  reload works because nothing is rewritten, DevTools are one click away.
- Annotation: pick one element, drag a region, or draw freehand, write a note,
  and it reaches chat with a screenshot of the visible page with the marks on it.
- Toolbar: hard reload, page zoom, device sizes, a light/dark switch that
  applies to the page rather than the app, and cookie/cache clearing scoped to
  the panel alone.
- Several pages at once, each tab showing the page's own favicon, and an address
  bar that suggests pages already visited in this project.
- Dev servers are listed from what is actually listening on the machine, checked
  against what a project announced, so a server is offered no matter how it was
  started. One that is still starting is waited for instead of failing.

Remote dev servers

The desktop app binds a local port and pipes raw bytes to the OpenChamber host
over the existing authenticated connection, so the page keeps its own origin at
the root of its own host. The reachable set is exactly what discovery reports
and is re-checked per connection, so an authenticated client cannot dial
arbitrary local services on the host. Links and redirects to another loopback
port stay on the machine that served the page. A tunnel that cannot be opened is
reported; it is never replaced by the plain loopback URL, which would answer
from the user's own machine under a remote address.

Agent control

Browser actions are a separate `openchamber_web` tool: open, snapshot, click,
type, scroll, inspect computed styles, resize between mobile/tablet/desktop, and
capture a screenshot into `.openchamber/screenshots/` in the project. The
existing `openchamber` tool keeps sessions, worktrees and scheduled tasks. Each
has its own setting in the new Settings -> General -> OpenChamber Tools section,
and the plugin is not injected at all when both are off.

Capability belongs to the connected client, not to configuration: a client
declares on its event stream that it can drive a page, which only a Chromium
host does. Exactly one client performs each request — it claims the request
before acting, and the first claim wins — because deciding by whose result
arrives first would be too late for a click that already happened. No client
listening is answered immediately with an explanation rather than a timeout.

Runtime boundaries

Web tabs get a plain iframe that can display a page but not inspect one. The
VS Code extension no longer offers the surface at all, since nothing that makes
the panel worth having works there. Mobile is unaffected.

Native boundary

Camera, microphone, location and device-picker requests from panel pages are
denied — Electron grants them by default when no handler is set, and the panel
loads whatever address the user types. Page capture, appearance emulation and
storage clearing verify that their target belongs to the panel's own session
instead of trusting a web-contents id from the renderer.

Persisted state

Stored `preview` tabs migrate to `browser` (v13 -> v14). Context panel tab
limits are now per surface, so filling one surface no longer evicts another's
tabs. Address history is stored per project and per runtime.

Documentation

`preview.mdx` and `desktop-browser.mdx` rewritten across all locales, the agent
tool settings path corrected, new `DOCUMENTATION.md` for the browser-control
broker and the dev tunnel, and the `ui-api-decoupling` skill updated where it
still described the deleted proxy.
2026-08-13 22:44:13 +03:00
Bohdan Triapitsyn 50613bb170 chore: update unreleased changes 2026-08-13 22:01:54 +03:00
Bohdan Triapitsyn a9edc71e06 fix: bootstrap embedded chat prompting state and review read-only handling
Pass initial subagent prompting settings into embedded chat URLs and views
Prevent inactive embedded chats from stealing focus on load
Treat review sessions as independent conversations when resolving prompt read-only state
2026-08-13 22:01:11 +03:00
Serhii DziupinandSerhii Dziupin e99f6560be fix(scheduled-tasks): prevent dual-server double dispatch of daily tasks (#2713)
* fix(scheduled-tasks): claim schedule occurrences across server instances

Two OpenChamber servers sharing project config each armed timers and both
dispatched the same daily/weekly/cron/once slot (#2710). Claim the occurrence
in shared config under a cross-process write lock before creating a session.

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>

* fix(scheduled-tasks): harden occurrence claim failure and lock ownership

Address PR review blockers: release running-slot bookkeeping when claim
throws, avoid silently dropping an armed occurrence after a due-slack sync,
verify lock-file ownership on release, and cover real on-disk lock behavior.

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>

* fix(scheduled-tasks): always release running slot on state-write failures

Wrap runTask bookkeeping in finally so claim, manual-start, and completion
lock timeouts cannot stuck-run a task; drop the diskNext claim guard that
suppressed later occurrences; recover unparseable locks via mtime age.

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>

* fix(scheduled-tasks): stop re-arming past nextRunAt and clear stuck running

Only schedule future nextRunAt values so once-task losers and claim-failed
paths cannot spin delay-0 retries. Clear past once nextRunAt on claim, and on
completion-write failure retry terminal status so manual runNow still returns
the session instead of a hard 500 with lastStatus stuck running.

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>

* fix(scheduled-tasks): release write chain on lock acquire timeout

withProjectWriteLock left the in-process promise chain pending when
acquireProjectFileLock timed out, wedging every later project write and
stranding runTask before finally. Always release the chain; surface
persistError on run; record once claim failures in task state.

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>

---------

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
2026-08-13 16:14:42 +03:00
Serhii DziupinandSerhii Dziupin 86e6a2ae76 Remove verified dead declarations (#2714)
* chore: remove verified dead declarations

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>

* chore: narrow unused internal exports

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>

* chore: remove newly exposed dead helpers

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>

* chore: remove unused deep-link serializer

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>

* test: drop two tests that assert on copies of the code

mainLayoutMobileSidebarMount read MainLayout.tsx and SessionSidebar.tsx as
strings and asserted on source substrings down to exact indentation, so it
failed on formatting rather than behaviour. useProjectSessionSelection.test
reimplemented the hook's visitNodes logic inside the test file and asserted
against that copy, so it could not observe the hook at all.

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>

* test: repair sync suites that had rotted while unrunnable

No runner executed packages/ui, so these drifted from the source unnoticed:
two imported helpers that are no longer exported, one directory-store stub
predated the session field routeMessage reads, and the WebSocket fake missed
the mandatory url-token mint plus the close event the socket wrapper reads.

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>

* test: stop the web suite failing on timeouts and a hand-copied mock

The Git suites drive a real git binary, so the 5s default made a valid suite
fail differently per run. The gitApiHttp mock listed ~70 export names by hand
and fell behind the source; it now derives every stub from the real module,
which the added shared-UI aliases make resolvable.

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>

* test: run every suite from one command and in CI

packages/ui (232 files) and packages/vscode (22) had no test script at all, CI
ran neither, and 9 vscode files could never run because Node cannot resolve
their extensionless TypeScript imports. Three electron files sat outside every
script list, one of them importing vitest, which that package does not depend
on. A runner gives each file its own process, since these suites keep
module-level singletons and fail by load order when sharing one.

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>

* chore: delete a superseded repro harness and a completed plan

The issue-2638 harness needed lsof, overrode process.platform and spawned real
servers, and nothing referenced it; event-stream/rebind.test.js now covers the
same hub-pinned-to-the-old-port behaviour. The pairing v2 plan described relay
and the pairing UI as out of scope, both of which shipped.

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>

* docs: point at the theme tools and record the github barrel invariant

convert-vscode-theme and harmonize-theme were referenced nowhere, so the
theme-authoring reference now names them. The github barrel is loaded through
await import('./index.js') and destructured per route, which no static report
can see; documenting that is what stops the next cleanup from deleting it.

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>

* test: repair merge drift in bridge and route-registry mocks

upstream/main gained upsertProviderConfig on bridge-system-runtime and a
PATCH scheduled-task route after this branch forked. Their test doubles
were never updated to match:
- bridge-system-runtime.test.js: add upsertProviderConfig to the
  opencodeConfig mock so the import resolves.
- sse-routes.test.js: add app.patch to the route registry stub.

---------

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
2026-08-13 15:30:54 +03:00
Serhii Dziupin 61533ed881 fix(desktop): keep minimize on the taskbar and send only close to the tray (#2874)
With tray background mode on, the in-app minimize button hid the window,
so the taskbar entry disappeared while the native title-bar and taskbar
minimize still performed a normal minimize. Minimize now always minimizes;
the setting gates the close path only.

The persisted key stays `desktopMinimizeToTrayEnabled` so existing settings
keep working; the visible label becomes "Close to the system tray" in every
locale.

Closes #2857
2026-08-13 15:10:48 +03:00
Bohdan Triapitsyn 6a200e4622 fix(chat): preserve repeated shell prefixes 2026-08-13 14:05:03 +03:00
Bohdan Triapitsyn c3e2eae100 Merge pull request #2792 from RyderAsKing/fix/shell-command-entry-caret
Fix/shell command entry caret
2026-08-13 14:03:13 +03:00
Bohdan Triapitsyn 1a1170f9d2 fix: lazily load markdown gallery images 2026-08-13 14:01:26 +03:00
Bohdan Triapitsyn 4c80021296 Merge pull request #2863 from ChangeHow/codex/markdown-image-gallery
feat: add assistant Markdown image galleries
2026-08-13 14:00:05 +03:00
Bohdan Triapitsyn cf2e53b973 chore: update workspace lockfile versions 2026-08-13 13:57:56 +03:00
Bohdan Triapitsyn cc94c3c927 docs: refine agent skill guidance 2026-08-13 13:57:56 +03:00
Serhii Dziupin d3011a6247 fix(sessions): snapshot send target so a project switch cannot reroute a pending send (#2871)
Snapshot the new-session draft (and keep the existing-session target captured) at
submit time, then use that snapshot for draft materialization and routing instead
of re-reading live selection state after async preparation.

Fixes #2222
Fixes #2315
2026-08-13 12:31:33 +03:00
ChangeHow 5d29ef15d3 fix: reuse existing image preview for galleries 2026-08-13 16:19:06 +08:00
ChangeHow efba4f33a7 fix: scope markdown image previews to desktop 2026-08-13 16:19:06 +08:00
ChangeHow 61626db245 feat: improve mobile markdown image previews 2026-08-13 16:19:06 +08:00
ChangeHow f790b58d83 feat: add markdown image gallery previews 2026-08-13 16:19:06 +08:00
Serhii Dziupin 8a6eca5597 fix(sessions): select the active project using session ownership (#2865)
* fix(sessions): select the active project using session ownership

Keep a same-project worktree session while its rendered map is stale, but switch to the remembered or fallback session when the current session is known to belong to another project.

Fixes #2317

* test(sessions): pin project-switch ownership recovery in the selection hook
2026-08-13 10:51:40 +03:00
Bohdan Triapitsyn e7b864e9ae fix(mobile): tolerate transient connect failures without bouncing the user
A single fast probe (2.5s per transport) used to be the only chance a
connection got on cold launch and resume, so a just-woken network, a
WireGuard re-handshake, or a relay cold start (TLS + WS + E2EE) regularly
produced false "unreachable" verdicts that kicked the user to the connect
screen. Now:

- cold launch releases the splash on the fast verdict and retries once in
  the background with the full connect budget — a reachable instance
  reconnects on its own, and a manual connect started meanwhile wins;
- resume retries on a 4s/10s ladder, the last attempt with the full budget,
  before tearing the connection down; needs-login still disconnects
  immediately on every path;
- full-budget relay probes are capped at the shared 8s connect budget
  instead of inheriting the 15s relay session default, so a genuinely dead
  server does not pin the retry for 15 extra seconds.

Probe steps, budgets, and retry decisions all land in the connection log.
2026-08-13 00:07:00 +03:00
Bohdan Triapitsyn dc9c5f8e3e feat(mobile): hidden connection log panel for device-only diagnostics
Connection lifecycle events (probes, transport failures, resume decisions)
are mirrored into an in-memory trail that resets on every launch. A long
press on the connect-screen logo or the instances list opens a panel that
renders the trail with one-tap copy, so release builds can report the exact
probe sequence without a tethered debugger. Details reuse the already-masked
log payloads — no tokens or secrets are captured.
2026-08-13 00:06:51 +03:00