upstream取り込み: コンフリクト解決10コミット (terminal/host-service/desktop)#391
upstream取り込み: コンフリクト解決10コミット (terminal/host-service/desktop)#391
Conversation
…uperset-sh#3565) Observability was enabled in superset-sh#1464 but dropped when the proxy was re-created from scratch in superset-sh#1867. Without it, every wrangler deploy reconciles Cloudflare back to logs/traces off, which is why the dashboard toggles kept reverting after each production deploy. Pin invocation_logs explicitly so future config drift can't silently disable it again. Audit logs are an account-level setting and still need to be re-enabled in the Cloudflare dashboard separately.
Without it, Chromium rejects https://localhost:* with ERR_CERT_AUTHORITY_INVALID on machines that never had Caddy's local root CA installed with trust flags (e.g. fresh machines, or where the prior `caddy run` sudo prompt was dismissed).
…3640) Co-authored-by: Sprite <noreply@sprites.dev>
…-sh#3599) * fix(workspace-client): preserve host path prefix in useWorkspaceWsUrl new URL(path, hostUrl) resolves absolute paths against the origin, dropping hostUrl's path component. For remote workspaces hostUrl is "https://relay.superset.sh/hosts/<hostId>"; building the terminal WS URL via new URL("/terminal/<id>", hostUrl) yielded "wss://relay.superset.sh/terminal/<id>", which the relay 404s (only /hosts/:hostId/* is routed). Swap to string concat so the prefix survives. * fix(relay): cap to one fly machine TunnelManager.tunnels is an in-process Map — with 2+ replicas a proxy request routed to the replica that doesn't own the tunnel returns 503 "Host not connected". Prod was running 2 machines and serving ~half of all /hosts/:hostId/* traffic as 503. Scaled down live; this commit codifies it so the next deploy doesn't recreate the second machine. Longer-term fix (shared tunnel state via Redis pub/sub) tracked in SUPER-427.
Captures the architecture plan for SUPER-427 (relay hardening) so phases can ship independently. Documents the fly-replay + Upstash directory approach (reusing the existing rate-limit instance), the truthful is_online story, streaming-proxy fix, graceful shutdown, observability, and data-model cleanups — with rejected alternatives recorded so we don't relitigate them.
* docs: consolidated weekly changelog — 2026-04-20 Supersedes superset-sh#3206 (2026-04-06) and superset-sh#3404 (2026-04-13), folding in this week's v2 workspace work so three weeks of shipped changes land in one post instead of three stale PRs. * docs(changelog): include chat UX overhaul (superset-sh#3039) in consolidated post * docs(changelog): add compressed chat-ux hero screenshot * docs(changelog): refresh chat-ux hero and add v2 file tree screenshot * docs(changelog): add brand refresh screenshot * docs(changelog): add v2 diff viewer screenshot * docs(changelog): v2 workspace framed as early access, add screenshot * docs(changelog): rename title to 'v2 early access' * docs(changelog): frame v2 as a cloud-aimed rebuild — terminal rewrite, IDE architecture * docs(changelog): drop articles in title * docs(changelog): light trim — drop redundant lead-ins and filler words
…t-sh#3590) Production Electric runs on Electric Cloud and local dev runs on Docker — the Fly.io `superset-electric` app no longer exists, so every deploy-electric run was failing on `flyctl secrets set --app superset-electric`. Remove the job, the preview Fly.io counterpart, and the root fly.toml. Point preview API at the shared ELECTRIC_URL/ELECTRIC_SECRET secrets.
…#3631) * chore(ci): pin third-party GitHub Actions to commit SHAs Replaces every mutable tag (`@v4`, `@v2`, `@master`, etc.) on third-party actions with the commit SHA they currently resolve to, with a trailing `# <tag>` comment so Dependabot/Renovate can keep them updated. Closes Tolmo findings 04e0e887, 3580d63d, 3ced71b1, 59691bf4, ce908e26, f7d7ab2e, 8bd4a7ba, 6ab1fc7e — all rooted in the unpinned `oven-sh/setup-bun@v2` (and other tags) reachable from `deploy-production.yml` and `build-desktop.yml`. 114 references pinned across 13 workflow files. No logic changes. * chore(ci): use specific release tags in pin comments Replaces major-tracking comments (`# v4`, `# v2`, `# master`) with the precise release tag the SHA points to (`# v4.3.1`, `# v2.2.0`, `# 1.6`). Same SHAs, more useful comments — Dependabot/Renovate can now show "v4.3.1 → v4.4.0" in the bump PR title instead of a no-op `v4 → v4`.
The Vercel-hosted `/api/electric/*` route is no longer used by supported desktop clients. Bumps minimum desktop version to 1.5.0 (the first release after 2026-04-10) so any lingering client on a pre-1.5.0 build is forced to update before it can heartbeat against an endpoint that's about to disappear. Drops the route, its env vars (ELECTRIC_URL/SECRET/SOURCE_*), `@electric-sql/client` dep, Electric CORS headers, and the matching env passthroughs in the Vercel deploy workflows. The Cloudflare worker (apps/electric-proxy) and Fly-hosted Electric instance stay intact.
…#3560) - drizzle-orm 0.45.1 → 0.45.2 (GHSA-gpj5-g38j-94v9 / CVE-2026-39356) - better-auth family 1.5.6 → 1.6.5 (GHSA-xr8f-h2gw-9xh6)
…superset-sh#3638) * feat(cli,trpc): organization override via header, no session mutation CLI sends `x-superset-organization-id` when `organizationId` is set in config. A new middleware on `protectedProcedure` validates membership and exposes `ctx.activeOrganizationId`, falling back to the session's active org when the header is absent. Router call sites migrate to the new ctx field; `requireActiveOrgId`/`requireActiveOrgMembership` take `ctx`. Adds `superset organization switch <idOrSlug>`; renames `commands/org/` to `commands/organization/`. `auth login` picks an org when the user has multiple memberships. * fix(cli): narrow login error swallowing + lazy sessionActive fetch - Scope the post-login try/catch to the non-essential user.me info line; let myOrganizations / writeConfig errors surface. - Skip myOrganization round-trip for single-org users; only fetch the session's active org when the multi-org selector needs it as a default. - Remove --organization from the global flags doc since it isn't wired as an actual global (use `organization switch` instead).
…ts (superset-sh#3562) Memory leak and CPU spiral root-caused to `staleTime: 0, gcTime: 0` + 60fps polling: React Query can't dedupe or GC anything, and the render path churns allocations every 16ms. Restoring the React Query defaults (5min gcTime) fixes the leak. Server poll rate is independent of perceived stream smoothness — StreamingMessageText already reveals text client-side at 60fps from whatever buffer the server delivers. 4fps polling keeps that buffer fed with plenty of headroom. Also removes the `isRunning` invalidation effect — redundant when the query is polling. Builds on and supersedes superset-sh#3170 by @thepathmakerz, which diagnosed the same root cause. This version takes the subtractive path (-21 lines) instead of adaptive polling (+36). Closes superset-sh#3049
…3642) * feat(desktop): render mermaid diagrams in markdown pane Wire the editable TipTap code-block node view to render a live mermaid preview above the source when the language is `mermaid`, using the same Streamdown plugin + theme handling as the read-only CodeBlock. The read-only v2 path already supported mermaid; this closes the gap for v1's editable rendered view. * feat(desktop): toggle between mermaid preview and source in markdown pane Default to rendered-only for mermaid code blocks with content; click the diagram or the toolbar toggle to reveal the editable source. Empty blocks open in source mode so users can type. The code element stays mounted (hidden) when the preview is showing so TipTap keeps tracking content. * fix(desktop): polish mermaid preview in markdown pane - Definitively hide the mermaid source via inline display:none so the raw code no longer shows below the preview. - Drop the extra bg/padding frame around the Streamdown viewer so zoom/expand controls aren't captured by a click-to-edit wrapper. - Unify hover toolbar as a single pill (rounded border + bg/80 + backdrop-blur) and move it to top-left in preview mode so it doesn't overlap Streamdown's own top-right toolbar. - Override Streamdown's min-h-28 to min-h-80 so the diagram canvas is taller by default. * fix(desktop): guard mermaid fence against backticks in source Open the synthetic markdown with 4 backticks instead of 3 so a stray triple-backtick inside the user's mermaid source can't close the fence early and leave Streamdown with malformed input.
…t-sh#3513) (superset-sh#3554) * fix(desktop): recover terminal from non-monospace font crash (superset-sh#3513) Setting the terminal font to a proportional family like "Inter" blanked the app on next launch — the bad value persisted in SQLite and xterm couldn't lay out cells on reload, leaving no way back into settings. - Sanitize the stored family on read: if the primary family isn't monospace (per canvas measurement), fall back to the default terminal font so a poisoned DB value can never blank the renderer. - Hide the "Other" group and custom free-form entry in the terminal font picker so new selections are restricted to monospace candidates. * fix(desktop): reject all-proportional generic terminal font stacks Follow-up on superset-sh#3554 review. sanitizeTerminalFontFamily previously passed any all-generic CSS value through untouched (e.g. "cursive", "sans-serif", "monospace, sans-serif") because parsePrimaryFontFamily returns null when no concrete family is present — same blank-window crash class as the "Inter" report. Refactor the sanitizer to inspect the full family list: when no concrete primary exists, only trust the value if every entry is a monospace generic; otherwise fall back to the default. Add regression tests. * refactor(desktop): append ", monospace" fallback + cleaner font preview - Always append "monospace" to the sanitized terminal font stack when it doesn't already end with one. Mirrors VS Code's behavior in src/vs/workbench/contrib/terminal/browser/terminalConfigurationService.ts so that if the configured primary isn't installed on this machine, the browser falls back to the OS monospace generic instead of a proportional default. - Swap the terminal font preview from a box-drawing layout (which rendered as broken in proportional fonts and used tofu glyphs) to a shell session that demonstrates column alignment naturally. - Drop a couple of narrating comments flagged in simplify review. * refactor(desktop): show Nerd Fonts in the editor picker too Nerd Fonts are monospace — the terminal-only gate was pre-existing special-casing and reviewers pointed out it hides a widely-used class of fonts from users picking an editor font. Drop the gate. * fix(desktop): validate the actual CSS primary font, not the first concrete entry Addresses the coderabbit review on b2e6a04. The sanitizer previously skipped leading generics when picking the primary to measure, so a value like `sans-serif, "JetBrains Mono"` passed validation because the later concrete entry was monospace — but CSS resolves the first generic (sans-serif) and the terminal still renders proportional. Switch to validating families[0] (the actual CSS primary): if it's a monospace generic, trust the stack; if it's a proportional generic, fall back; if it's concrete, canvas-measure it. Add regression tests.
…perset-sh#3581) * fix(desktop): restore terminal buffer after Unicode 11 activation The persisted xterm buffer was being replayed before the Unicode11Addon was loaded, so CJK, emoji, and ZWJ sequences got parsed with Unicode 6 cell widths. The wrong widths baked into the buffer, producing garbled glyphs on repaint — especially visible with many Claude Code tabs open and Chinese content (superset-sh#3572). Mirrors VS Code's pattern: load Unicode11Addon during terminal construction, before the first write. Also bumps @xterm/* to the versions VS Code ships (xterm 6.1.0-beta.197, webgl 0.20.0-beta.196). * docs: tighten Unicode 11 ordering comment
…d paste (superset-sh#3582) * fix(desktop): terminal paste auto-submits first line when bracketed paste is off Terminal's custom paste handler reimplemented xterm's `\r?\n → \r` normalization to enable a chunking path that turned out to be unnecessary. Without bracketed paste, the `\r` sequence makes the shell execute each pasted line as Enter, so a multi-line paste would run only the first line. Mirror VS Code's approach: delegate to `xterm.paste()` (which handles normalization + bracketed-paste wrapping correctly) and add a `shouldPasteTerminalText`-style confirmation dialog for multi-line pastes when the shell doesn't have bracketed paste mode enabled. * drop multi-line paste warning dialog, keep only paste-handler simplification * drop setupPasteHandler entirely, let xterm handle paste natively * Lint * restore minimal setupPasteHandler for Electron clipboard-event propagation * Revert "restore minimal setupPasteHandler for Electron clipboard-event propagation" This reverts commit f3fba94. * remove unused isBracketedPasteRef from useTerminalLifecycle
Rename TOGGLE_EXPAND_SIDEBAR to OPEN_DIFF_VIEWER (same binding). In v2, focus any existing diff pane or open one in a new tab, and flip the workspace sidebar to the Changes tab. V1 keeps its existing expand-sidebar behavior under the new ID.
…ebar (superset-sh#3619) * fix(desktop): place new v2 workspaces at top of their project in the sidebar New workspaces were inserted with tabOrder = max + 1, burying them at the bottom of the project's list. Prepend with min - 1 instead so freshly created workspaces surface at the top without disturbing existing order. * fix(desktop): seed empty-project prepend tabOrder at 1 to match reorder helpers
…h#3655) * fix(desktop): render pending workspaces at top of sidebar New workspaces are inserted with a prepend tabOrder (top), but the pending placeholder was pinned to MAX_SAFE_INTEGER (bottom), so the creating/failed indicator visually separated from the row it represents. Flip the constant to MIN_SAFE_INTEGER so the pending sits alongside the just-created workspace at the top. * chore(desktop): tighten PENDING_WORKSPACE_TAB_ORDER comment
superset-sh#3635) * feat(desktop): add Copy Branch Name to v1 and v2 sidebar context menus * chore(desktop): drop success toast from Copy Branch Name * chore(desktop): restore success toast on Copy Branch Name * fix(desktop): expose Copy Branch Name on collapsed v1 local-workspace The collapsed branch-workspace branch returned early with only a Tooltip, so right-click surfaced no menu. Wrap the button in a ContextMenu so Copy Branch Name is reachable. * style(desktop): biome auto-format collapsed branch context menu trigger
…h#3660) * feat(desktop): redesign v2-workspaces list as sortable Linear-style table Replace stacked card rows with a dense full-width table: Sidebar / Name / Host / Branch / Created columns that align across projects, sortable column headers, proper truncation on long workspace and host names, and hover-revealed row actions. * fix(desktop): address v2-workspaces review feedback - Sidebar column sort direction was inverted (default "desc" put non-sidebar items first); use a normal boolean comparator so descending means "in sidebar first". - Row onKeyDown was firing when Enter/Space bubbled from focused action buttons; ignore keyboard events originating from descendants. - Offline host cell regressed to a native `title` tooltip; wrap it in the shared `<Tooltip>` so the indicator is keyboard-accessible and styled consistently with the action buttons. - Extract SortableHeader into its own folder per repo conventions (one component per file) and move shared sort types into a types module.
…licks (superset-sh#3552) * fix(desktop): refresh v2 terminal link tooltip editor label + nudge plain clicks - LinkHoverTooltip fetched the default editor in a mount-only useEffect, so changing the default editor in settings left the modifier-shift label ("Open in Cursor", etc.) stale until the terminal pane unmounted. Refetch on every hover-start instead. - Plain (no-modifier) clicks on a detected file path in the v2 terminal were silent, which made the modifier-key affordance undiscoverable. On a plain file-link click, show a transient tooltip at the click position ("Hold ⌘ to open · ⌘⇧ for external", or Ctrl/Ctrl+Shift off-mac). Capped at two shows per renderer session via a module-level counter, and suppressed while the modifier-hover tooltip is already visible. Uses framer-motion's AnimatePresence for fade in/out. * refactor(desktop): simpler v2 terminal link tooltip labels - "Open in editor" → "Open in pane" for the ⌘-click file case (native in-app file pane is what actually happens). - Shift variant always says "Open in external editor" instead of interpolating the configured editor name. openFileInEditor uses the global settings defaultEditor (non-editor apps like Finder can't be set there), so the interpolated name could disagree with a user's per-project preference — the generic label never lies. - Drops the getDefaultEditor fetch, defaultEditor state, and getAppOption/ getAppLabel plumbing that went with it. * refactor(desktop): URL ⌘-click tooltip says "Open in pane" for consistency
…et-sh#3650) * fix(desktop): allowlist URL schemes before shell.openExternal The browser-pane context menu and `external.openUrl` tRPC procedure forwarded attacker-controlled URLs directly to `shell.openExternal`, letting a `file://` href right-clicked inside a pane launch arbitrary applications via OS URL handlers. Adds `main/lib/safe-url` with an `{http, https, mailto}` allowlist and routes both sinks through it. Rejects disallowed schemes on `openUrl` with BAD_REQUEST. * fix(desktop): catch openExternal rejections and redact URL logs Addresses two defense-in-depth findings from PR superset-sh#3650 review: - safeOpenExternal now try/catches shell.openExternal so fire-and-forget callers (browser-manager context menu) can't leak an unhandled rejection into the main process. - Log only the parsed URL scheme (via externalUrlLogLabel) instead of the raw untrusted URL in both sinks, avoiding path/email/token spill into electron-log files. --------- Co-authored-by: Satya Patel <satyapatel111@gmail.com>
…uperset-sh#3659) `safe-url.ts` imports `shell` from electron at the module top level, so bun's test runner can't load the file and the whole suite fails with `SyntaxError: Export named 'shell' not found`. Moves the pure URL helpers (`isSafeExternalUrl`, `externalUrlLogLabel`) to `scheme.ts` and has the test import from there. `safeOpenExternal` stays in `safe-url.ts` with the electron import; the barrel keeps the same public surface.
…rset-sh#3629) host.info was calling organization.getActiveFromJwt, which resolves to organizationIds[0] on the JWT regardless of which org the host-service is configured for. Users in multiple orgs saw the same (first) membership name for every Host Service tray entry. Adds organization.getByIdFromJwt and has host.info use ctx.organizationId so each per-org host-service reports its own org.
… + dev placeholders (superset-sh#3580) * fix(desktop): unblock AI branch/workspace naming for OAuth-only users + dev placeholders `getSmallModel` only resolved Anthropic credentials from `apikey:anthropic` in mastracode's auth.json. Users authed via Claude OAuth (the default Code flow) had no api-key entry, so it returned `null` silently and naming always fell back to a slugified prompt. A stale/dummy `ANTHROPIC_API_KEY` in `.env` (e.g. the `=dummy` placeholder) made it worse: the env path was preferred, the bad key 401'd, and the fallback toast hid the real reason. Resolution order is now: env api-key → stored api-key → OAuth → openai. Anthropic api-keys are validated to start with `sk-ant-api` and openai keys with `sk-` so dev placeholders fall through to OAuth instead of being sent to the API. OAuth is read directly from auth.json with refresh done via direct HTTP to console.anthropic.com — no mastracode import (it pulls in onnxruntime-node and broke electron-vite bundling, see superset-sh#3517). Also cap the workspace auto-rename prompt at "20 characters or less" so sidebar titles stay short. Diagnostic logs (`[get-small-model] using …` / refresh failures) are kept so future regressions surface in the dev terminal instead of silently producing the fallback toast. * review: address self-review feedback on small-model OAuth fix - Fix pre-existing OpenAI provider-id mismatch: mastracode stores keys at apikey:openai-codex, not apikey:openai. Settings-saved OpenAI keys now reach the small-model path. - Add length floor (30 chars) to api-key validation. Catches placeholders shorter than the prefix check would (e.g. bare "sk-ant-api"). - Drop success-path console.log calls. Keep the no-credentials warn so the silent-fallback regression stays visible if it ever returns. - Tighten writeAnthropicEntry comment to acknowledge the cross-provider race window and document the (rare) impact + escape hatch. - Hard-cap workspace auto-rename output at 20 chars server-side. Prompt asks for 20, but LLMs miscount; this guarantees the contract. - Add provenance comment for CLAUDE_CODE_OAUTH_CLIENT_ID. - Drop unused AnthropicOAuthHeaders type export; const is `as const` so callers get the same type inference. - Change getSmallModel return type from Promise<unknown | null> to Promise<unknown> (null is assignable to unknown). - Add unit tests: - isAnthropicApiKey / isOpenAIApiKey validation (rejects "dummy", rejects OAuth tokens sent as api keys, accepts real key shapes). - isOAuthEntry shape validation. - 20-char truncation behaviour in generateWorkspaceNameFromPrompt. * test(chat): add OAuth refresh integration tests with mocked fs + fetch Covers the previously-untested paths in anthropic-oauth.ts: - happy path: valid non-expired token returned without refresh - refresh: expired token + 200 → new entry persisted with refreshed access, refresh, and future expiry - refresh: response without refresh_token → original refresh token preserved - failure: 4xx, missing access_token, fetch throw → all return null without writing - cross-provider preservation: refreshing anthropic does not clobber the openai-codex slot (the race-window concern from the self-review) * review: address second-pass feedback on small-model OAuth fix - Fix data-loss in writeAnthropicEntry on parse failure: distinguish "file missing" from "parse error" in readAuthJson; refuse to overwrite auth.json when existing content is unparseable (would otherwise wipe every non-anthropic provider slot). - Cache the in-memory refreshed entry so we don't hammer Anthropic's OAuth endpoint when persistence keeps failing (read-only home dir, full disk). - Move provider-id constants to packages/chat/src/server/shared/ auth-provider-ids.ts; desktop re-exports for back-compat. getSmallModel now iterates OPENAI_AUTH_PROVIDER_IDS (covers both `openai-codex` and legacy `openai` slots) instead of hardcoding one. - Drop unused AuthJsonOAuthEntry export; only isOAuthEntry is consumed externally. - Comment the fs-mock isolation constraint in anthropic-oauth.test.ts. - Drop the workspace-title server-side .slice(0, 20). The prompt still says "20 characters or less"; LLMs miscount but the soft hint is good enough — hard truncation produced ugly mid-word cuts. - New tests: - data-loss prevention: corrupt auth.json → no write - expires_in default path (3600s) when response omits it - leeway boundary: token expiring within REFRESH_LEEWAY_MS triggers refresh - cache reuse: write failure once doesn't cause a second refresh fetch * review: address PR review-bot feedback - Fix EXDEV on Linux: writeAnthropicEntry now creates the temp file in the SAME directory as auth.json (renameSync across filesystems throws when /tmp is tmpfs and $HOME is on a different mount). mkdirSync the target dir first so initial writes on a fresh install succeed. Reported by greptile, coderabbitai, cubic (P1 each, independently). - Add 10s AbortController timeout around the OAuth refresh fetch so a stalled token endpoint can't hang AI naming indefinitely. Reported by coderabbitai. - Deduplicate getAuthJsonPath/readAuthJson: export from anthropic-oauth.ts and import in get-small-model.ts. getAnthropicOAuthCredential now takes an optional pre-parsed authData so getSmallModel doesn't read auth.json twice per call. Reported by greptile. - Tests: temp-file location + mkdirSync call, refresh-timeout abort. * fix(chat): isolate OAuth test fs mocking to prevent leakage to sibling tests CI failure root cause: anthropic-oauth.test.ts used `mock.module("node:fs", …)`, which is process-global in bun:test. When the chat suite ran all 19 test files in one process, mcp-overview.test.ts (which uses real fs to set up temp dirs) inherited my no-op mocks → 8 unrelated failures. Fix: extract auth-storage-io.ts (small dedicated I/O wrapper for auth.json) and add an injectable IO seam to anthropic-oauth.ts via __setIOForTests / __resetIOForTests. The OAuth test now passes a plain mock object instead of mocking node:fs at all. Production code keeps the same default behaviour. Bonus: auth.path is now an injectable parameter on readAuthJson/writeAuthJson, so auth-storage-io.test.ts can exercise real file I/O against a temp dir without touching the user's real auth.json. Verified: full chat suite 148/148 pass, ai-name 6/6 pass, live OAuth smoke test still produces a real title. * refactor(chat): use mastracode for OAuth instead of reimplementing The custom anthropic-oauth.ts + auth-storage-io.ts that this PR added were justified by a constraint that doesn't actually exist: mastracode is already externalized via runtime-dependencies.ts (so electron-vite doesn't try to bundle it) AND is already imported by 10+ other places in the codebase (chat-service, host-service's resolveAnthropicCredential, etc). There's no bundle-size or memory cost to importing it from get-small-model too. Mastracode's createAuthStorage().getApiKey(providerId) handles: - OAuth refresh via the Claude Code endpoint - Atomic write-back to auth.json (EXDEV-safe) - Refresh token rotation - All the auth.json schema details We were reimplementing all of it. ~830 lines deleted across 4 files; ~170-line get-small-model.ts replaces it. What we keep: - isAnthropicApiKey / isOpenAIApiKey validators (still needed for the ANTHROPIC_API_KEY=dummy fallthrough — the actual original bug) - ANTHROPIC_OAUTH_HEADERS constant (these go on the inference request, not the OAuth flow — mastracode doesn't help here) - auth-provider-ids.ts shared module - Memoized AuthStorage instance (matches chat-service.ts pattern) Verified: typecheck 25/25, full chat suite 123/123, ai-name 6/6, live OAuth smoke test still produces a real branch name with ANTHROPIC_API_KEY=dummy in the environment. * fix(chat): prefer apikey:<provider> slot over main slot in get-small-model If a user logs in with OAuth after saving an API key via Settings, the main `anthropic` (or `openai-codex`) slot flips to OAuth and the stored API key in `apikey:<provider>` becomes unreachable from the small-model path — even though the user explicitly added it. Check `getStoredApiKey()` first for both Anthropic and OpenAI before falling back to the main slot. Matches the precedence the previous custom implementation had and aligns with the docstring. * chore(branch-naming): nudge LLM toward 20 chars or less Branch names show up in compact UI surfaces (sidebar, tabs, status). The existing "2-4 words" guidance still leaves room for a 60-char branch when the words are long. Add an explicit char hint to keep them tight. Soft prompt only — no server-side truncation. Same approach as workspace title prompt.
…es with / (superset-sh#3232) * fix: fall back to FETCH_HEAD checkout when gh pr checkout fails for branch names with / Fixes superset-sh#3231 gh pr checkout internally runs `git checkout -b <branch> --track origin/<branch>`. When the branch name contains `/`, git cannot resolve the tracking ref inside a freshly created detached worktree, producing "starting point is not a branch". The fetch succeeds — only the tracking setup fails. Catch that specific error and fall back to `git checkout -b <localBranchName> --no-track FETCH_HEAD`. push.autoSetupRemote=true (already set after worktree creation) handles push tracking without needing --track. * fix: use -B flag to force-replace branch in FETCH_HEAD fallback checkout * fix: log fallback path when gh pr checkout fails with tracking error --------- Co-authored-by: Ruan Gustavo Araujo da Silveira <ruan.silveira@M4Pro.local>
…set-sh#3478) (superset-sh#3550) Cherry-picked from upstream with manual resolution: fork's write() retains the `options?.interactive` parameter signature for API compatibility, but now passes all writes through immediately (only dropping escape sequences during shell init), matching upstream behavior. FORK NOTE: preReadyStdinQueue removed; all non-escape writes pass through regardless of interactive flag.
…t-sh#3372) (superset-sh#3547) Cherry-picked from upstream: coalesces port scans, adds debounce, prevents orphan lsof processes. No fork conflicts in these files.
…aces (superset-sh#3625) Cherry-picked from upstream: adds upstream_ref field to workspace schema for correct cross-fork PR matching. Applied directly (no fork conflicts).
…mstat (superset-sh#3543) Cherry-picked from upstream: fixes git operations for v2 workspaces.
…h#3295) Cherry-picked from upstream: fixes GitHub status resolution.
…uperset-sh#3546 (superset-sh#3615) PR superset-sh#3546 swapped builtin terminal agent defaults to safer modes (claude acceptEdits, codex --full-auto, gemini auto_edit, copilot --allow-tool=write, cursor-agent without --yolo suffix). The v1 `terminalPresetsInitialized` guard and v2 migration marker preserved users' stored terminal-preset command strings, but the **agent-preset** resolution path (resolveAgentConfigs in packages/shared/src/agent-settings.ts) layers user overrides on top of the *current* builtin defaults — so any existing canary user who never customized claude/codex/gemini/copilot/cursor-agent silently had their resolved launch command swapped. Fix: one-shot backfill into agentPresetOverrides. New `agentPresetPermissionsMigratedAt` column in settings gates the migration to run exactly once per user. On first read of agent-preset overrides, if the user's stored `terminalPresets` row contains any of the 4 pre-superset-sh#3546 exact default command strings (meaning their seed happened on a pre-superset-sh#3546 build), we inject overrides for `command`/`promptCommand`/`promptCommandSuffix` carrying the legacy YOLO values, skipping any field the user has already customized. Fresh post-superset-sh#3546 installs have no legacy fingerprint, so the migration only stamps the timestamp and moves on.
…rset-sh#3621) `workspaceCleanup.destroy` can take 10–20s; the old loading toast sat there the whole time and the row stayed in the sidebar. Now the row hides optimistically on confirm and the toast is gone. On error (conflict / teardown-failed) the row reappears and the dialog reopens into the matching error pane for force-retry.
…#3596) * feat(desktop): v1 review comments open in a pane like v2 Clicking a review comment in v1's ReviewPanel now opens it as a full pane rendering the comment body (markdown, code blocks, tables), instead of opening the GitHub URL. The "Open on GitHub" action remains as a separate icon in the comment row. Adds a "comment" pane type to the v1 tabs store (shared types, createCommentPane/createCommentTabWithPane helpers, openCommentPane action that reuses an existing comment pane per workspace) and a new CommentPane view wired into TabView alongside file/chat/browser panes. * feat(desktop): comment pane toolbar shows avatar + GitHub link * fix(desktop): sync tab name when reusing comment pane + correct section comment
…ojectPickerPill styling (superset-sh#3593) The footer rendered two DevicePicker instances bound to the same draft state. Remove the right-hand duplicate and restyle the remaining one to use FormPickerTrigger so the Device/Project/Branch pickers read as one segmented control (same text size, color, icon size).
…superset-sh#3602) * fix(desktop): stop spurious folder picker on settings → dashboard nav The folder-first import flow was plumbed through a zustand counter plus a useEffect in AddRepositoryModals. The counter outlives component mounts, but the effect runs on every mount — so once a user ever clicked "Import existing folder," every subsequent remount of the dashboard layout (including the one that happens when navigating back from Settings) re-ran the effect and re-opened the native directory picker. Remove the indirection. DashboardSidebarHeader now owns useFolderFirstImport and renders FolderFirstImportModal itself; the dropdown item calls folderImport.start() directly on click. No store pulse, no effect. * fix(desktop): drop dead promise-rejection catch on folderImport.start
|
Important Review skippedToo many files! This PR contains 172 files, which is 22 over the limit of 150. ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (6)
📒 Files selected for processing (172)
You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d2704ccba4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| export { | ||
| ANTHROPIC_AUTH_PROVIDER_ID, | ||
| OPENAI_AUTH_PROVIDER_ID, | ||
| "openai", | ||
| ] as const; | ||
| OPENAI_AUTH_PROVIDER_IDS, | ||
| } from "../../shared/auth-provider-ids"; |
There was a problem hiding this comment.
Re-export INCEPTION auth provider ID
This module now re-exports only Anthropic/OpenAI IDs, but existing desktop auth code still imports INCEPTION_AUTH_PROVIDER_ID (for example in desktop/auth/inception.ts and desktop/chat-service/chat-service.ts). That makes the package fail type-check/module linking with missing-export errors and breaks Inception auth paths at build time. Please keep the Inception constant exported here (or migrate all consumers in the same commit).
Useful? React with 👍 / 👎.
| export async function getSmallModel(): Promise<unknown> { | ||
| const anthropic = await resolveAnthropic(); | ||
| if (anthropic?.kind === "apiKey") { | ||
| return createAnthropic({ apiKey: anthropic.key })(ANTHROPIC_SMALL_MODEL_ID); | ||
| } |
There was a problem hiding this comment.
Preserve small-model candidate exports for desktop callers
Changing this module to only expose the async getSmallModel API removed getSmallModelCandidates/related candidate types that are still re-exported from shared/small-model/index.ts and consumed by apps/desktop/src/lib/ai/call-small-model.ts. That creates missing-export failures and breaks the desktop small-model fallback path. Either keep compatibility exports or update every downstream import/re-export in this change.
Useful? React with 👍 / 👎.
| async function getProcessNameWindows( | ||
| pid: number, | ||
| signal?: AbortSignal, | ||
| ): Promise<string> { | ||
| try { |
There was a problem hiding this comment.
Keep process-name helpers exported after scanner refactor
The refactor leaves only internal Windows name lookup helpers in this file and removes the public getProcessName/getProcessCommand exports that browser-mcp-bridge/pane-resolver.ts still imports for Claude/Codex parent-process detection. That causes import/type-check breakage and disables PPID-to-pane resolution in desktop main. Restore those exports or migrate the resolver to the new API in the same commit.
Useful? React with 👍 / 👎.
|
PR1 (#388) にmergeしたためclose |
Summary
PR1 (#388) で取り込めなかったコンフリクトありコミット10件を手動解決して取り込み。PR1に依存。
取り込み内容
Terminal:
54ba07400unblock v1 terminal user input during shell init ([bug] Workspace freezes on missing Node version prompt (no way to answer y/N) superset-sh/superset#3478) (fix(desktop): unblock v1 terminal user input during shell init (#3478) superset-sh/superset#3550)write()はoptions?.interactiveを残すが、全非escape書き込みを即時通過に変更preReadyStdinQueue廃止f3c1e3178stop excessive lsof spawning from port scanner ([bug] lsof excessive use superset-sh/superset#3372) (fix(desktop): stop excessive lsof spawning from port scanner (#3372) superset-sh/superset#3547)Host-service:
a116bb2b3stop misattributing cross-fork PRs (fix(host-service): stop misattributing cross-fork PRs to local workspaces superset-sh/superset#3625)987b29c64v2 workspace git correctness (fix(host-service): v2 workspace git correctness (upstream, 3-dot, numstat) superset-sh/superset#3543)Desktop:
829161364resolve GitHub status for branch workspaces (fix(desktop): resolve GitHub status for branch workspaces superset-sh/superset#3295)5aaeb0f82backfill legacy permissions for canary users (fix(desktop): backfill legacy permissions for canary users exposed to #3546 superset-sh/superset#3615)3902e3b44hide v2 workspace rows while destroy is in flight (fix(desktop): hide v2 workspace rows while destroy is in flight superset-sh/superset#3621)2c000607ev1 review comments open in a pane like v2 (feat(desktop): v1 review comments open in a pane like v2 superset-sh/superset#3596)a8fe5ac73dedupe DevicePicker in new-workspace modal (fix(desktop): dedupe DevicePicker in new-workspace modal and match ProjectPickerPill styling superset-sh/superset#3593)d2704ccbastop spurious folder picker on settings → dashboard nav (fix(desktop): stop spurious folder picker on settings → dashboard nav superset-sh/superset#3602)Fork側のコンフリクト解決
session.ts: upstreamの「全書き込み即時通過」方針に追随。preReadyStdinQueueを削除。fork独自のoptions?.interactiveパラメータはAPI互換のため維持host-service/: upstream版を直接適用(fork未改造領域)DashboardSidebar*,layout.tsx: upstream版を採用(PR1のCopy Branch Name等と競合していた箇所)Test plan
bun installが正常に完了するbun run typecheckが通る