3bd785a10af1889afecf569dce520cd2f82fa238
3
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
c703db2745 |
fix: stop forwarding client auth to OpenCode and harden home/session state
Packaged desktop showed no sessions in 1.12.4. Root cause: the sanitized session-list proxy path added in #1538 forwarded the renderer's "authorization" header (the OpenChamber UI client token) to the managed OpenCode upstream alongside the managed "Authorization" credential. OpenCode does not recognize UI client tokens, so every session-list request answered 401 — only in the packaged app, because only its renderer (openchamber-ui:// origin) attaches a bearer token; dev web and dev Electron run same-origin without one. The legacy http-proxy path overwrote the header correctly, which is why everything except session lists kept working. Proxy fix: - proxy-headers: filter the client "authorization" header out of forwarded request headers; the OpenCode upstream must only ever see its own managed credentials. Covered by tests. Desktop cwd: - electron: launch the managed OpenCode CLI from the user home instead of app userData, matching upstream desktop behavior. userData-as-cwd made OpenCode treat the app-data folder as a separate empty workspace. Home directory poisoning loop: - directoryPersistence: stop replaying localStorage homeDirectory through synchronizeHomeDirectory on boot/auth resync. The persisted value is only a boot-time cache; replaying it re-wrote stale values (e.g. a project path) into desktop settings on every start, overriding the authoritative /api/fs/home resolution. - persistence: never overwrite an injected window.__OPENCHAMBER_HOME__ with a persisted value. - useDirectoryStore: host switches happen in place (no reload), so re-resolve home from the new runtime's /api/fs/home on endpoint change instead of keeping the previous host's value. - opencode client: only short-circuit to the injected desktop home when the active runtime is local; remote runtimes ask /api/fs/home. Settings hygiene: - persistSettings: log field names only — change payloads can carry credentials (UI password, client tokens, tunnel tokens) that must not reach the log file; drop step-by-step log chatter. - validateProjectEntries: only stat project paths when the incoming update actually touches the projects list, not on every settings save. - remove the write-only approvedDirectories setting everywhere and add a migration that strips the stale key from persisted settings. Tests: - usePluginsStore.test: register an own runtime-fetch module mock so the suite is independent of process-global mock.module leakage from other files, and restore globalThis.fetch after the suite. - persistence.test: clean up the window global created for the suite. |
||
|
|
2031e3b4a8 |
Decouple bundled UI from runtime API and add remote instance tooling (#1228)
Add a packaged-client runtime boundary so the shared UI can talk to local, desktop, remote, and VS Code runtimes through the right transport instead of assuming one same-origin web server. Centralize OpenChamber-owned API access behind RuntimeAPIs, runtimeFetch, and runtime URL helpers, while keeping official OpenCode traffic on the SDK path. Support runtime switching, remote host selection, desktop client credentials, and headless connection links for pairing packaged clients with remote OpenChamber servers. Harden the new auth model by moving long-lived client tokens out of browser URLs, introducing short-lived scoped URL tokens for browser-owned transports, restricting URL-token access to explicit readable/realtime routes, and making client-token management session-scoped or self-scoped as appropriate. Update browser-owned assets and preview proxy flows to work with the split runtime model, including authenticated project icons, preview token propagation, CSP-safe preview bridge injection, and preview proxy auth that survives short-lived URL-token expiry. Tighten Electron security boundaries for packaged clients by gating privileged preload state to trusted origins and requiring explicit confirmation before connect deep-links import or switch remote runtimes. Also refresh agent guidance and project skills so future runtime/API, auth, preview, UI, CLI, settings, locale, and drag-to-reorder work follows the new architecture. |
||
|
|
2b47d899c6 |
feat: plugin settings (#1375)
* feat(settings): add opencode plugins page Manage opencode `plugin` array entries (npm, scoped npm, versioned, local paths) and auto-loaded plugin files in `~/.config/opencode/plugins/` and `<project>/.opencode/plugins/`. Mirrors MCP CRUD pattern. - Server: `plugins.js` data layer + `plugin-routes.js` REST routes - UI: PluginsSidebar / PluginsPage / AddPluginDialog - Store: usePluginsStore (cache TTL, in-flight dedup, narrow selectors) - i18n: 41 keys across 7 locales Whitelist /api/config/plugins in JSON body-parser so POST/PATCH bodies parse; opencode plugin specs runtime-resolve OPENCODE_CONFIG dir so parallel test files do not cross-pollute module-frozen consts. * feat(settings/plugins): hook npm registry for update + invalid-version detection Plugins page now consults registry.npmjs.org with a 1h server cache. Sidebar rows show an update badge with the latest version, group headers show how many updates are available, the kebab adds an "Update to latest" action that reuses the existing PATCH+restart flow, and the editor surfaces a banner for update-available / missing-version / missing-package / malformed / missing-path / unreadable-path / offline-registry states. A refresh button in the sidebar header forces a cache bypass. - Server: `npm-registry.js` (cache + in-flight dedup + 5s timeout, 404 cached, network failures NOT cached) + `plugin-spec.js` (parser + exact semver detection) + `GET /api/config/plugins/registry?specs=...&refresh=` - Routes accept up to 100 specs/request, dedup by npm package name before fetching, classify each result by kind, never propagate network failure as 500. - Client: `registryInfo` slice + `loadRegistryInfo` (fire-and-forget after loadPlugins, refreshes on mutations) + `updateToLatest(id)`. - UI: `RegistryBadge` per-row + `RegistryBanner` per-entry editor, both use theme tokens (text-only color, no new bg/border tokens) and the shared Icon sprite. Per-spec subscriptions only. - i18n: 24 new keys (incl. split singular/plural for "N update(s) available" because the runtime does not parse ICU plural format). * fix(settings/plugins): keep registry badge visible for long specs Sidebar entry row used `inline-flex` with `truncate` only on the spec text. With long npm specs the badge could be pushed past the row edge and clipped by the parent overflow. Switch to `flex` with spec `flex-1 min-w-0 truncate` and add `shrink-0` to the badge wrapper so the update indicator stays anchored to the right of the row. * fix(settings/plugins): use code-box icon to distinguish from MCP Plugins nav entry used 'plug' which is visually too close to MCP's 'plug-2' icon. Swap to 'code-box' for clearer differentiation in the Settings nav list. * Update packages/ui/src/components/sections/plugins/PluginsPage.tsx Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Signed-off-by: Quat3rnion <81202811+Quat3rnion@users.noreply.github.com> * Update packages/ui/src/stores/usePluginsStore.ts Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Signed-off-by: Quat3rnion <81202811+Quat3rnion@users.noreply.github.com> * fix(settings/plugins): validate registry directory + surface save errors - registry endpoint: return 400 on invalid directory query (was silently falling back to homedir, breaking relative path specs) - save failure toast: prefer result.message over generic 'Reload failed' * fix(settings/plugins): address review follow-ups --------- Signed-off-by: Quat3rnion <81202811+Quat3rnion@users.noreply.github.com> Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com> |