Upstream sync: v2 sidebar, recently viewed, workspace fixes#3498
Closed
MocA-Love wants to merge 897 commits into
Closed
Upstream sync: v2 sidebar, recently viewed, workspace fixes#3498MocA-Love wants to merge 897 commits into
MocA-Love wants to merge 897 commits into
Conversation
…#3347) * feat(desktop): add local v1/v2 version toggle in top bar When the v2 feature flag is enabled remotely, a segmented toggle appears in the top bar (next to resource consumption) that lets you switch between v1 and v2 locally without changing the PostHog flag. The preference persists in localStorage across app restarts. * lint
…ence (superset-sh#3346) * feat(desktop): port browser pane to v2 workspaces with global persistence - Port v1 browser pane (webview, URL toolbar, history, error overlay, new-window handler) into v2 workspace tree as a native implementation. Uses the v2 Workspace component's renderToolbar slot for a Chrome-style URL bar in the pane header. - Float-over webview: each <webview> lives at document.body under a fixed #browser-runtime-root, positioned via ResizeObserver on a per-pane placeholder div. Elements never reparent, so Electron's guest WebContents survives tab switches, pane drags, and workspace route remounts — no page reloads. - Keep-alive tab rendering in @superset/panes Workspace.tsx: tabs that have been visited stay mounted behind visibility:hidden so their React state (and persistent DOM like webviews) survives tab switches. Also benefits terminal scrollback, chat subscriptions, editor state. - BrowserRuntimeRegistry: module-level singleton keyed by paneId, modeled on terminalRuntimeRegistry. Owns webview lifecycle, state subscriptions via useSyncExternalStore, drag-passthrough listeners, equality-guarded setState to deduplicate webview event spam. - Single-pane-browser tabs show the page favicon + live page title in the tab bar via a new optional renderTabLabel prop on the panes library. - BrowserPane subscribes to the workspace store for activeTabId to drive webview visibility, so inactive-tab webviews don't paint on top of the active tab's content. - Destroy path: diff the set of browser pane ids across all tabs each render, destroying any that disappeared. Correctly handles tab closes, intra-tab split closes, and pane drags between tabs (moved panes stay in the set). Known limitation: dropping panes onto another browser pane's body doesn't register — the webview compositor layer intercepts drag events even with pointer-events:none/visibility:hidden. Drops on pane headers work. Deferred. * refactor(desktop): co-locate browser pane integration, remove keep-alive - Float-over webviews already preserve state across tab switches via the registry's attach/detach pair, so keep-alive tab rendering was redundant. Revert packages/panes Workspace.tsx to rendering only the active tab. - Move all browser-specific wiring from page.tsx into a new useBrowserPaneIntegration hook co-located with BrowserPane. page.tsx now consumes a single hook call instead of owning tab title derivation, tab label rendering, and the destroy diff effect. - Registry attach takes over the visibility flip directly; setVisibility method is no longer needed. Drop the rAF deferral — React useEffect fires after layout commit so getBoundingClientRect reads correct values synchronously. - BrowserPane no longer subscribes to the workspace store for isTabActive. * refactor(desktop): simplify browser pane integration, add onRemoved hook - Add PaneDefinition.onRemoved(pane) lifecycle hook to @superset/panes. Workspace.tsx tracks a flat snapshot of panes across all tabs and fires onRemoved with the pre-removal Pane object when an id disappears. Pane moves between tabs keep the same id in the current set so moves correctly don't fire onRemoved. - Wire browser cleanup declaratively via the new hook in usePaneRegistry.tsx: `onRemoved: (pane) => browserRuntimeRegistry.destroy(pane.id)`. Removes the need for useBrowserPaneDestroy in userland. - Persist faviconUrl on BrowserPaneData alongside pageTitle. The registry's persist callback fires from handleDidStopLoading AND handlePageFaviconUpdated via a shared firePersist helper. Favicons now survive app restart. - Replace renderTabLabel with renderTabIcon in @superset/panes. TabItem renders {icon}{title}{accessory} — icon leading, accessory trailing, native gap-2 from the parent button. Drop redundant `| null` from the ReactNode types. - Fix titleOverride precedence in Workspace.tsx: `tab.titleOverride ?? getTabTitle(tab) ?? tab.id`. Renaming a browser tab now actually sticks. - Empty tab rename clears titleOverride instead of being swallowed; thread `string | undefined` through TabItem → TabBar → Workspace so the derived title takes back over on clear. - Collapse useBrowserPaneIntegration.tsx and BrowserTabLabel component into BrowserPane.tsx as pure functions (getBrowserTabTitle, renderBrowserTabIcon). Favicon is now a plain <img> reading from persisted pane data — no more subscribing component just for one field. - page.tsx loses browser-specific imports, refs, effects, and callbacks. Just two pure helpers passed as props. * refactor(desktop): use native webview back/forward + tighten sanitizeUrl - Drop the custom history array and isHistoryNavigation flag. goBack/goForward now call webview.goBack()/goForward() directly, preserving scroll position, form state, and BFCache on back/forward navigation. - Add refreshNavState helper that reads webview.canGoBack()/canGoForward() and writes them into runtime state. Called from did-navigate, did-navigate-in-page, did-stop-loading, and on re-attach of existing entries. - The isHistoryNavigation guard was dead code: did-navigate fires before did-stop-loading, so the flag was always false by the time the guard ran, causing a redundant browserHistory.upsert IPC call on every back/forward nav. - Clear faviconUrl in handleDidStartLoading so stale favicons don't persist when navigating to a page with no favicon. - Tighten sanitizeUrl: reject dotted strings containing whitespace (e.g. "release v2.1") as URLs, trim input, tighten the localhost/127.0.0.1 regex to accept optional port and path. Dotted search queries now correctly fall through to Google search.
chore(upstream): PR8 - 新規upstream 8件取り込み
- Remove duplicate isV2CloudEnabled declaration in layout.tsx - Resolve conflict marker in usePaneRegistry browser pane renderer
Electronのwebviewはデフォルトでtransparent=trueのため、 supersetのダークテーマ背景が透けて見えていた。 v1/v2両方のBrowserPaneでwebpreferences="transparent=no"を設定。 closes #150
The dom-ready event can fire after the WebView has been detached from the DOM (isTrusted: false synthetic event), causing getWebContentsId() to throw. Add isConnected check and try-catch to prevent the crash. Fixes ELECTRON-19
Restructure the dom-ready handler so the pending-URL drain always runs, even when the WebView is temporarily disconnected from the DOM. This prevents queued navigations from getting stuck indefinitely when dom-ready fires during wrapper moves.
- New zustand store (useGitOperationDialogStore) for cross-component dialog state - New GitOperationDialog component rendered once at ChangesView level - classifyGitError helper maps stderr/error-message to structured kinds - showGitErrorDialog / showGitConfirmDialog helpers for call sites - CommitInput: commit/push/pull/sync/fetch errors now open the unified dialog with context-aware next actions (rebase+retry, stash+retry, copy, etc.) - PRButton: merge PR now requires a confirmation dialog (irreversible action); merge errors route through classifyGitError - ChangesView: bulk stage/unstage of >10 files now requires confirmation - useCreateOrOpenPR: behind-upstream flow replaces window.confirm with unified dialog; base-repo and reset errors route through showGitErrorDialog
…nd P2 errors Backend (apps/desktop/src/lib/trpc/routers/changes): - git-operation-types: new GitOperationWarning union + GitSyncStageError class - push/sync now return warnings[] instead of throwing for non-fatal follow-ups (auto-published-upstream, post-push-fetch-failed); sync wraps pull/push failures in GitSyncStageError so frontend can distinguish stages - createPR returns isExisting flag so frontend can show "open existing PR?" - commit accepts skipHooks to bypass pre-commit / commit-msg hooks - New forceUnlockIndex procedure to remove stale .git/index.lock Frontend: - gitWarningDialog: renders auto-repair notifications from response warnings - CommitInput push/sync onSuccess now show warning dialogs - ChangesHeader switchBranch routes index.lock through the unified dialog with forceUnlockIndex action; other non-BranchActionDialog branch errors route to showGitErrorDialog; fetch RefreshButton error too - ReviewPanel: Convert to draft now requires confirmation; Re-run all jobs requires confirmation (keeps a secondary "failed only" action) - RepositoryPanel: workflow_dispatch requires confirmation - ChangesView bulk discard now detects editor unsaved state and shows a warning dialog listing dirty document count - DiscardConfirmDialog + bulk discard prompts translated to Japanese for consistency with the rest of the git dialog surface - useCreateOrOpenPR: existing-PR detection opens a confirm dialog with an explicit "open existing" action instead of silently navigating
…ions Visual consistency fixes based on review feedback. - GitOperationDialog icon box now always uses bg-muted/text-muted-foreground, matching BranchActionDialog. Removed the amber/emerald/sky/red tone colors that were out of character for the rest of the app. Tone still drives the icon glyph (alert-triangle / circle-alert / circle-check / info / shield-alert) but no longer the background color. - Button variants narrowed to shadcn's primary / outline / ghost / destructive. Removed the custom "warn" / "ok" / "accent" variants that produced amber/emerald/sky buttons. "destructive" is reserved for truly irreversible actions (force push, force unlock, discard, abort rebase). - Removed flex-wrap on the footer so all dialogs render on a single row, matching the actual BranchActionDialog behavior. Button labels trimmed to fit: "修正して再 commit" -> "再試行", "フックを無視して commit" -> "フック無視で commit", "強制的に解除" -> "強制解除", "force push (lease)" -> "force push", "署名なしでこの commit を作る" -> "署名なしで commit". - Dropped the tertiary "出力をコピー" action on commit-hook-failed. The raw stderr is already shown in the details block inside the dialog, so a separate copy button was redundant and only contributed to the 4-button overflow. - Translated CreatePullRequestBaseRepoDialog (Choose -> "Pull Request の base リポジトリを選択"), its call sites in PRButton (Update / Save -> "PR base リポジトリを変更" / "保存"), and InitGitDialog (all Cancel / Initialize Git strings) to Japanese so the git dialog surface is uniform.
8 fixes from codex/coderabbit review on feat/git-dialog-unification. P1 — forceUnlockIndex now resolves the real git-dir via git rev-parse --git-dir before probing index.lock / HEAD.lock / shallow.lock. Linked worktrees have .git as a file pointing at .git/worktrees/<name>, so the old worktreePath/.git/*.lock probing always returned removed: false on that common layout. Critical — GitOperationDialog ActionButton now catches errors thrown by action.onClick instead of swallowing them via the unhandled try/finally. Mutation errors still route through their own onError handlers; this only catches unexpected throws so they land in the console rather than vanishing. Major — New dialogId token in the zustand store so that a late-running action's finally can only clear the dialog it originally opened. open() increments and returns the id, close(id?) no-ops when the current dialog has already been replaced. GitOperationDialog threads the id into ActionButton and the dismiss button. Major — GitOperationWarning is now re-exported from lib/trpc/routers/changes/git-operation-types instead of being duplicated in gitWarningDialog.ts; backend and renderer share a single source. Major — rerun-all-checks-confirm now makes "失敗分だけ再実行" the primary action and "全て再実行" the secondary, so a stray Enter keypress can no longer re-queue every job on the PR. P2 — CommitInput now passes retryWithoutHooks to showGitErrorDialog so the commit-hook-failed dialog actually exposes the "フック無視で commit" button that the backend's new skipHooks flag was added for. Minor — extractConflictFiles no longer drops filenames that contain spaces (git emits them literally in merge conflict output). Minor — ChangesHeader's forceUnlockIndex handler now awaits and catches the unlock mutation failure, surfacing it through showGitErrorDialog so a failed unlock is no longer silent.
Two follow-ups to the previous review batch. - CommitInput retry now reads the commit message from the mutation variables argument (the value that was actually submitted) instead of closing over the current textarea state. Editing the input after a failed commit previously silently changed what "retry" / "フック無視で commit" would send. - git-operation-dialog's setPending now takes an optional dialogId and only updates the store when it matches the current dialog, mirroring the close() guard. Without this, a late-running action's finally could flip pending=false on a dialog the user had opened in the meantime (for example when the action itself opens a subsequent error dialog). ActionButton now passes its captured dialogId to both setPending and close so a stale action cannot stomp on a newer dialog.
- Move GitOperationDialog mount from ChangesView to the authenticated layout (next to InitGitDialog). The dialog was previously only rendered while the Changes sidebar was open, so useCreateOrOpenPR prompts (behind-upstream confirm, error dialogs) invoked from workspace-level hotkey paths were silently invisible when the sidebar was closed. - forceUnlockIndex no longer swallows stat/unlink failures. Only ENOENT from the stat probe is treated as "file not present"; any other stat error and every unlink failure is surfaced through a TRPCError so the user can see EACCES/EPERM etc. instead of seeing removed: false with no explanation.
Six findings from the parallel rv-pr review (HIGH 2, MED 4).
HIGH — rerun-all-checks confirm had a conflicting title/primary pair
("全ての CI jobs を再実行しますか?" + primary "失敗分だけ再実行")
so a stray Enter press did the opposite of what the title suggested.
The title is now neutral ("CI jobs を再実行しますか?") and the copy
names the two options explicitly; the safer "failed only" stays as
the primary action.
HIGH — CommitInput's stashAndRetry recovery path now chains a stashPop
after the successful pull. Previously picking "stash してから pull"
from the pull-overwrite dialog stashed the user's local changes and
never popped them back, silently leaving them on the stash stack.
MED — classifyPushError's trailing `return context === "push" || ...
? null : null` was a no-op ternary; collapsed to `return null` and
dropped the now-unused context parameter.
MED — GitOperationDialog's ActionButton now forwards the mapped variant
directly to shadcn's <Button variant={...}> instead of hardcoding
variant="outline" and overriding with className. The previous approach
let outline borders and shadows bleed into the primary/destructive
renders.
MED — classifyGitError now consumes the [sync:pull] / [sync:push]
prefixes that GitSyncStageError plants in the message, so sync
failures are routed to the matching stage classifier (pull stage
errors no longer get tried against push patterns and vice versa).
MED — forceUnlockIndex now walks every candidate (index.lock /
HEAD.lock / shallow.lock) instead of returning after the first
successful removal, so a worktree with multiple stale locks can be
cleared in a single invocation.
CI lint caught five biome violations: - import sort in _authenticated/layout.tsx (my added GitOperationDialog import landed in the wrong alphabetical position) - import sort in _authenticated/_dashboard/layout.tsx (pre-existing) - trailing blank line in ChangesView.tsx after DiscardConfirmDialog - formatter whitespace in git-operations.ts (around forceUnlockIndex) - formatter line wrap in InitGitDialog.tsx Japanese text All auto-fixed by bun run lint:fix; no behavior change.
feat(desktop): unified Git operation dialog across Changes sidebar
fix(desktop): guard WebView getWebContentsId against detached DOM
…ep-alive, multi-select, findInPage) - Clone: stream git progress via tRPC observable, add cancel + UI with phase/bar/log - Diff viewer: reuse CodeEditorSearchOverlay at top-right with center-scroll on navigate - Tabs: keep file-viewer tabs mounted when inactive so scroll/search/cursor survive switching - Git sidebar: Shift/Cmd click multi-select + BulkActionBar for bulk stage/unstage - Browser: Cmd+F find-in-page via webContents.findInPage with right-top overlay - CodeEditor: diagnostic mousedown logging for drag-autoscroll investigation
P1: - projects: cleanup partial clonePath on git clone abort/failure so retry is not blocked by the existing-folder guard - projects: buffer clone progress events per cloneId with monotonic seq so subscribers established after the mutation starts do not miss early events; dedupe replay via seq - CodeMirrorDiffViewer: reset search state/refs on MergeView teardown to avoid pointing at a destroyed EditorView after original/modified/language change - CodeEditor: gate drag-autoscroll diagnostic logging behind localStorage.debug:code-editor-drag flag P2: - BrowserPane: hoist Cmd+F keydown capture to the pane root so the shortcut also fires when focus is in the toolbar / URL bar - BrowserFindOverlay: expose imperative focusInput handle; re-Cmd+F now refocuses the input even while overlay is already open - CloneRepoTab: only transition to "canceled" after cancelClone mutation confirms, otherwise leave status as cloning - CodeMirrorDiffViewer: sync overlay match count when focus moves between a/b sides
- projects: redact credentials from git URLs before logging so PATs / basic auth tokens embedded in the clone URL never reach the renderer via progress logs or error messages - CloneRepoTab: base the cloneProgress subscription lifetime on cloneId presence instead of status, so terminal log entries arriving after status flips in cloneRepo/cancelClone callbacks are still delivered
Previously `{type: "done"}` was emitted right after `git clone` returned,
so the renderer logged "Clone complete" even if getDefaultBranch / DB
insert / ensureProjectGitHubOwner / ensureMainWorkspace subsequently
failed. Move the terminal success event to after the project row and
workspace are fully created, and have the outer catch emit an error
event (when no terminal event has been produced yet) so post-clone
failures are still reported through the streaming channel.
- projects: use distributive Omit so CloneEventInput preserves the discriminated union shape; the previous Omit<Union, 'seq'> collapsed into the common intersection and broke emitCloneEvent callers that passed type-specific fields (message/stage/etc) - MultiSelectContext: re-order barrel exports per biome organizeImports
- CodeEditor: unconditionally log drag-autoscroll scrollableParents walk on mousedown (removed localStorage gate) so the race is visible in any session without setup - CodeEditor: add scrollSearchMatchToCenter to the overlay find handlers — the file viewer was missing center-scroll behaviour entirely (only the DiffViewer had it). Log head / scrollTop / matchCoordsY before + after the dispatch so we can see whether the effect is applied and where it lands - CodeMirrorDiffViewer: same before/after logging around the existing scrollIntoView center dispatch to investigate why navigation is not visibly centering
CM6's find commands dispatch `scrollIntoView: true` (y: "nearest") synchronously as part of the selection update. Dispatching a second `y: "center"` effect in the same tick causes CM to coalesce them and the nearest scroll wins — which is exactly what the diagnostic logs (matchCoordsY unchanged, small scrollTop deltas) showed for both the CodeEditor and CodeMirrorDiffViewer navigation paths. Schedule the center scroll in requestAnimationFrame so runFindNext's scroll has settled first, then dispatch `y: "center"` from the updated head position. Log scrollTop and coordsAtPos before + after in both frames so we can verify the effect applied and whether centering lands at the expected coordinate. Also widen the drag-autoscroll diagnostic: mousedown now attaches a scoped mousemove + scrollDOM scroll listener (both released on mouseup) so we can capture spurious scrolls that happen while dragging — the initial mousedown position consistently reports `nearEdgeAtStart: false` so the trigger must be in a subsequent mousemove inside the 6px edge band.
## drag-autoscroll spurious triggering
Diagnostic logs showed CM firing drag-select autoscroll at +8px/tick
(dragScrollSpeed's baseline) even while the pointer was hundreds of
pixels from any edge. Tracked the cause to the hidden search panel:
- `@codemirror/search` defaults `top: false`, so the hidden search panel
lives in the BOTTOM PanelGroup
- `PanelGroup.scrollMargin()` for a bottom group is
`min(innerHeight, scrollDOM.bottom) - panelDom.top`
- The previous `createHiddenSearchPanel` hid the container with
`display: none`, which makes `getBoundingClientRect()` return
`{top: 0, bottom: 0, ...}`
- That leaves `scrollMargin = scrollDOM.bottom - 0 ≈ scroller height`,
i.e. the drag autoscroll's "bottom edge" effectively collapses to
y=0 and every mousemove inside the viewport satisfies the edge check
Replace `display: none` with a zero-height in-flow collapse (height:0,
visibility:hidden, overflow:hidden). The panel stays at scroller.bottom
so scrollMargin resolves to ~0, and drag autoscroll only fires when
the pointer is genuinely within 6px of the scroller edge.
Same fix mirrored in CodeMirrorDiffViewer's local copy of
createHiddenSearchPanel.
## search center scroll
Follow-up `scrollIntoView({y: "center"})` dispatches remained flaky on
huge virtualized files — logs showed `delta: 43` and the match still at
clientY=-63 after the dispatch. `view.coordsAtPos(head)` returns
estimated coords for un-rendered lines, and CM's internal scroll math
uses those estimates, producing a near-noop instead of the large jump
needed to center a line tens of thousands of pixels away.
Replace the `scrollIntoView` effect with a manual `scrollDOM.scrollTop`
write computed from `view.lineBlockAt(head)`, which is backed by CM's
own doc-relative line-height cache (maintained by the measure cycle and
always accurate for `scrollTop` math). Same refactor in DiffViewer.
The root causes are now fixed (hidden search panel no longer uses display:none so PanelGroup.scrollMargin resolves correctly, and search navigation uses view.lineBlockAt + manual scrollTop to sidestep CM's virtualized-content coordsAtPos estimation). Strip the mousedown/ mousemove/scroll telemetry and before/after scrollIntoView logging — the functional fixes stay in place.
Each FileList variant re-sorts files internally — compact sorts by filename, grouped sorts by folder+name, tree builds a DFS-ordered tree with folders first. The MultiSelectProvider, however, was wrapping the list with the raw unordered `files` array, so `indexOf(anchor)` / `indexOf(clicked)` for shift-click range selection sliced the wrong positions and produced the "sparse / flickering" selections the user reported. Extract `orderFilesForViewMode` that mirrors each variant's sort (and flattens tree DFS) and thread the ordered arrays through `useOrderedSections` to the provider. FileList variants keep their own internal sort; the helper is the single source of truth for the visual order used by range selection. Tree mode approximates "all folders expanded" DFS order — collapsed folders still contribute their files to the range, which is acceptable until expand/collapse state is threaded through the context.
1. Hover / context-menu actions on a selected file apply to the whole
multi-selection.
- MultiSelectProvider now accepts onStageSelected / onUnstageSelected
/ onDiscardSelected and exposes them through the context.
- FileItem reads the context at action-invocation time: if the file
is part of a selection of 2+, it runs the bulk handler with
`ctx.selectedFiles` and clears the selection; otherwise it runs
the single-file handler. Clicking an action on a non-selected
file still targets only that file, matching VS Code.
- Context menu and hover labels reflect the bulk count
("Stage 5 files" etc.) when applicable.
- The standalone BulkActionBar component is removed — the
VS Code-native hover / context flow replaces it.
2. Shift-click without a prior anchor picks the first visible file as
the anchor so the range extends from the top of the list down to
the clicked item (VS Code fallback).
3. Range selection order is DOM-driven: FileItem carries a
`data-multi-select-path` attribute, and MultiSelectProvider wraps
children in a `display: contents` div that scopes
`querySelectorAll('[data-multi-select-path]')` to its subtree.
DOM order naturally reflects what the user sees — including tree
view's collapsed-folder filtering, which the previous static
`orderFilesForViewMode` helper couldn't handle. For virtualized
lists where the anchor has scrolled out of the DOM the resolver
falls back to the precomputed flat order so shift-click still
works across large change sets.
fix(desktop): vibrancy ON時にダイアログ/モーダル背景の透過を修正
VSCode Claude Code拡張のwebview/index.cssを直接解析し、本物と 同じ折りたたみUI+IN/OUTグリッドレイアウトに書き直した。 - <details>/<summary>ベースに変更。ツールコールはデフォルトで 折りたたまれ、summaryはbold太字ツール名+monospaceでlink-color の二次情報(ファイルパス等)の2行構成 - 本体(.rr)を開くとgrid-template-columns: max-content 1fr の grid-subgridレイアウトでIN/OUT表示(拡張の .ir/.lo/.tr と同等) - StreamViewの親をabsolute inset-0にして、カード圧縮問題を 修正(従来はflex-shrinkで履歴が潰れていた) - assistant_text/result/errorは枠線なしのborder-leftスタイルに 簡素化。system_initは1行アイコンバッジに - raw eventも<details>で折りたたみ プリセット拡張準備: - todoPromptPresetsテーブルに kind (system/description/goal) と workspaceId (null=global) を追加。migration 0055 生成 - zodスキーマとtRPC create/updateも対応
fix(desktop): TODO新規worktree作成時のgit worktree add競合を解消
fix(desktop): 単発TODOで介入送信が無視される問題を修正
fix(desktop): TODOのStopでclaudeが止まらない問題を修正
fix(desktop): TODOのシステムプロンプトテンプレートが効いていない問題を修正
feat(desktop): Start前のTODOのdescription/goalを編集可能に
fix(desktop): 選択したプリセットをAgentManagerの詳細に表示する
feat(desktop): AgentManagerライブストリームを折りたたみグループ化
Antigravity IDE方式。AgentManagerの 「新しい TODO」 クリックで 独立ダイアログを出さず、詳細ペインを TodoComposer に差し替える。 主な機能: - 対象プロジェクト をプルダウン選択(projects.getRecents) - 「新しい worktree を作成」 チェックボックス(デフォルトON) - OFF 時は そのプロジェクト内の既存 worktree 一覧から選択 - タイトル / やって欲しいこと / ゴール / verify コマンド - 「やって欲しいこと」「ゴール」欄それぞれに テンプレ ドロップ ダウン追加(kind でフィルタしてプロジェクトスコープのプリセット だけを候補表示) - システムプロンプトプリセット(kind=system) セレクタ - 作成後は自動でそのセッションを選択表示 preset.workspaceId は projectId を保持する形で再利用(マイグレー ション不要)。「default」 worktree が大量に並ぶ問題を解消
- 「自律 TODO セッションを横断表示」 サブテキストを削除 - TodoComposer の 「やって欲しいこと」 → 「タスク」 に変更
Issue #201 の対応。以下のgitエラー時にフレンドリーなダイアログが 出ず、生のエラーメッセージだけが表示されていた: error: cannot pull with rebase: You have unstaged changes. error: Please commit or stash them. 原因: classifyGitError のパターン 'please commit your changes or stash' は merge系のメッセージ用で、rebase系の別の文言に マッチしていなかった。 rebase系パターンを3つ追加: - 'cannot pull with rebase' - 'please commit or stash them' - 'you have unstaged changes' これで pull-overwrite 扱いになり、stash→pull / discard→pull の 選択肢付きダイアログが出る。 Closes #201
…s without restart Previously `getInitialWindowOptions` omitted the `vibrancy` property when the user had vibrancy disabled, so NSVisualEffectView was never attached at construction time. The first OFF→ON toggle then tried to attach it via `setVibrancy` on a live window, which on macOS doesn't fully take effect until the next app launch — users reported needing to restart the app to actually see transparency. Always pass a `vibrancy` kind at construction based on the saved `blurLevel`. The opaque `backgroundColor` returned by `computeBackgroundColor` when disabled fully covers the vibrancy layer, so OFF state is visually identical to before. Toggling ON now just lowers the backgroundColor alpha and takes effect immediately.
handleCreate実行中にヘッダーのキャンセルが押せたため、作成 完了は走るのにcomposerが閉じてonCreatedでセッション選択、という 'キャンセルしたのに作成された' 挙動になっていた。 ヘッダーのキャンセルボタンも submitting=true の間は disabled に して、フッターのキャンセルと挙動を揃えた。 Refs: Codex review on PR #202
…vibrancy Vibrancy overlay forces `--background` to `transparent` so the 166 `bg-background` surfaces pass through the window's vibrancy layer without stacking multiple solid tints. But a handful of components use `--background` as a non-surface value (tooltip text color, kbd inside tooltip, ring-background on run indicator, fill-background on status icons, from-background gradient, inverted-bg button text). For those, the transparent override made the color / ring / fill invisible — tooltips rendered an empty black pill with no readable text. Add a parallel `--background-solid` CSS variable that always mirrors the theme's opaque background, and migrate the 10 non-surface consumers to it: - desktop-only usages use the `text-background-solid` / `ring-background-solid` / `fill-background-solid` utilities exposed via `@theme inline`. - packages/ui usages use `var(--background-solid, var(--background))` so other apps without the variable still resolve to the old value. `applyUIColors` mirrors `colors.background` into `--background-solid` on every theme change so the variable tracks theme switches correctly.
code/pre/anchor タグが親幅を超えてもはみ出したままになっていた。 コンテナに overflow-hidden + 子孫に break-words/break-all を 強制して、長い識別子やURLでも折り返すようにした。
- placeholder: '次のターンに注入する介入指示' → 'メッセージを送信' - 送信ボタン: 'キュー' → '送信' - toast: '次のターンに介入指示を注入します' → 'メッセージを送信しました'
【レビュー対応】
- lint: 空span + noLabelWithoutControl 修正
- Shift+Enter 改行可能に (Input→Textarea化)
- iter ラベル抑制: verify なし or iter==1 では非表示。
単発タスクで "iter 1" が意味なく出ていた問題を解消
【resume時の情報保持 (supervisor)】
- claudeSessionId を持つセッションを resume するときは
stream バッファを clear しない → 過去ターンが残る
- "再開" セパレータイベントを追加して新ターン境界を明示
【テンプレート統一】
- "システムプロンプトプリセット" → "テンプレート"
- PresetsDialog:
* タブ名/toast/関連文言を 'テンプレート' に統一
* 種別(システム/タスク/ゴール) + 対象プロジェクト セレクタ追加
* 内容ラベルも選択中kindを表示
* リスト行に種別バッジ
- TodoComposer:
* 2カラム化(左=フォーム、右=TemplateBrowser)
* 右ペインに検索・種別フィルタ・プロジェクトフォルダで
見れるブラウザ。ワンクリックで適用(kindで自動ルーティング)
* 適用中のシステムテンプレートはフォーム下部にプレビュー表示
* 旧インラインプルダウン廃止
Closes #201 (cherry-picked earlier)
新機能: ImagePasteTextarea - onPaste / onDrop / onDragOver を処理 - 画像をFileReaderでbase64化 → todoAgent.saveAttachment で userData/todo-agent/attachments/ 配下に保存 - 保存後、キャレット位置にmarkdown画像参照  を 自動挿入 - ドラッグ中は ring-primary ハイライト - 10MB超過/非画像ファイルはtoastで拒否 Claudeは -p モードで Read tool を使えるので(bypassPermissions 許可済み)、markdown参照先のファイルを開いて画像として認識できる。 適用箇所: - TodoComposer のタスク欄 / ゴール欄 - SessionDetail の介入メッセージ欄 バックエンド: todoAgent.saveAttachment tRPC mutation 追加。 ファイル名のサニタイズ + 拡張子の自動補完 + 20MB上限。
userData/todo-agent/attachments/ にペーストされた画像は参照 カウントしていないため、放置すると溜まる一方だった。 app.whenReady() 直後に cleanupOldAttachments() を呼び、mtime が30日より古いファイルを削除。30日は長時間動くTODOでも画像参照 を失わないのに十分なバッファ。ディレクトリが存在しなければ noop。個別ファイルのエラーは無視してsweep続行。
長い絶対パスの  が textarea に出ると 読みにくかったので、UIでは短いトークン [image1], [image2] ... を表示するように変更。 - ImagePasteTextarea に attachments / onAttachmentsChange props を追加して controlled 管理 - 画像ペースト時は [imageN] を挿入し、別途 attachments 配列で token→path を保持 - textarea 上部にチップ(🖼 [imageN] filename ×) を表示して 視認性+解除ボタン - 手動でトークンを削った時は orphan-prune で添付リストから自動除去 - 送信直前に resolveAttachmentTokens() で  に展開 してClaudeに渡す - TodoComposer(desc/goal) + SessionDetail(intervention) 全てに適用
内部では [imageN] トークンを引き続き使い送信時に markdown 展開 するが、UI上のチップは 🖼アイコン + ファイル名 + × ボタンだけに 簡素化。 + a.html にアイコン候補8種(HiMiniPaperClip / HiMiniPhoto / HiMiniCamera / LuPaperclip / LuImage / LuFileImage / LuImageUp / LuImages) を並べたモックを追加
Chat PlusMenu で既に 「添付」 として使われているアイコンと 一貫性を合わせた。
composerOpen が true のままだとサイドバーから別のTODOを選んでも 詳細画面に切り替わらなかった。セッション選択時にcomposerOpenも falseにして詳細ペインに遷移するように修正。
【🟠 Major: supervisor.ts resume 機能が実際に動いていなかった】 runSession 先頭で claudeSessionId / finalAssistantText / totalCostUsd / totalNumTurns を無条件に null 初期化していた ため、done→再開時に --resume が使われず会話コンテキストが 失われていた。 isResumingPastRun の時は session0 の値を維持するように修正。 これで本当に --resume <id> で会話が継続される。 【🟠 Major: attachments-cleanup が活きてる添付も消す可能性】 mtime 30日だけで削除していたため、30日超のセッションを再開 した時に画像が欠損する恐れがあった。 todo_sessions の description / goal / pendingIntervention / customSystemPrompt / finalAssistantText / verdictReason を スキャンして、attachments/<filename> で参照されているファイル 名の集合を作り、参照されているものは年齢に関係なく保持する ように修正。スキャン失敗時は安全側に倒してクリーンアップ全体 をスキップ。 Refs: CodeRabbit review on PR #202
- 添付トークン生成を useRef ベースのシーケンスに変更。連続pasteで [imageN] 番号が衝突する問題を解消 - onAttachmentsChange を SetStateAction 形式にして rapid-paste 時の stale state を避ける - attachments-cleanup の参照検出をUUIDプレフィックスパターン正規 表現に厳密化。path.sep 依存・誤検出を回避、POSIX/Windows両対応 - saveAttachment のサイズ制限コメントを明確化 (クライアント10MB, サーバ~15MB raw / 20MB base64) - PresetsDialog の SelectTodoPromptPreset 型アサーション3箇所を 削除(スキーマが notNull default "system" で型に含まれる) - TodoComposer.handleCreate に finally で setSubmitting(false)。 onCreated throw時のボタン永続disable回避 - css-variables: clearThemeVariables で --background-solid も remove。vibrancy 切替後のstale値を防ぐ
feat(desktop): AgentManager内にインラインTODO作成を実装(プロジェクト+worktree選択)
# Conflicts: # apps/desktop/package.json # apps/desktop/src/renderer/routes/_authenticated/_dashboard/pending/$pendingId/page.tsx # apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/page.tsx # apps/desktop/src/renderer/screens/main/components/CommandPalette/CommandPalette.tsx # bun.lock # packages/host-service/src/trpc/router/workspace-creation/workspace-creation.ts
Contributor
|
Important Review skippedToo many files! This PR contains 300 files, which is 150 over the limit of 150. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (300)
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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概要
upstream/main から 5 コミットを取り込み。すべて desktop アプリ (v2 workspace) の変更。
取り込みコミット
ec45c78b3c2e96c37886e0170a7e4c1365f81b7cb9c96コンフリクト解消
package.jsonworkspace-creation.tsfullRef維持 + upstream のautoSetupRemote/baseブロック追加pending/$pendingId/page.tsxv2-workspace/$workspaceId/page.tsxCommandPalette.tsxbun.lockbun installで再生成フォーク適応
workspace-creation.ts: FORK NOTE 維持 —fullRef使用でリモートブランチ名の曖昧さを回避pending page: フォーク独自のsyncTimedOutリセット useEffect を upstream のprevPendingIdRefパターンに置換CommandPalette: フォーク側の SearchDialog アーキテクチャを維持。upstream の Recently Viewed UI は旧 CommandPrimitive ベースのため未統合(別タスクで対応予定)注意事項
useRecentlyViewedFileshook とFileResultItemコンポーネントは取り込み済みだが、SearchDialog への UI 統合は別タスクテストチェックリスト
Summary by cubic
Syncs with upstream v2 desktop: improves the Changes/Files sidebar, adds Quick Open “Recently Viewed”, reads the base branch from git config, and fixes the workspace transition flash. Also introduces new desktop services (databases, diagnostics, language services, VS Code extension host), Git/GitHub tooling, browser permissions, and CI/workflow guards for forks.
New Features
tsserver,yaml-language-server), Reference Graph, Vibrancy controls.Bug Fixes
superset-sh/superset.electron-updater→6.8.3with corrupt cache auto‑clear; add macOS camera permission text.Written for commit 3e5eab7. Summary will update on new commits.