chore: open PR 11 件をまとめて取り込み (#216 〜 #236)#239
Conversation
- ReplyDialog の返信元プレビューが getCommentPreviewText でプレーンテキスト化されていたため、画像・リンク・コードブロック等が表示されていなかった - ReviewPanel 内の CommentBody をコンポーネント化し、ReplyDialog でも再利用することで GFM/リンク/コードハイライト/GitHub blockquote alert を含むフルレンダリングに統一 - リンククリックは ReviewPanel の handleOpenUrl を経由し、ブラウザタブで開く挙動を維持
max-w-2xl (672px) から max-w-5xl (1024px) に拡大し、狭い画面にも対応できるよう w-[92vw] を併用。 2カラムレイアウトの各列がフォーム入力に十分な幅を確保できるようにする。
PresetsDialog を DialogContent の外側(Dialog の兄弟)に置いていたため、 Radix の DismissableLayer が兄弟同士のネストを認識できず、設定ダイアログ 内のクリックが「外側クリック」と判定されて Agent Manager が閉じていた。 正しく動作している ScheduleEditorDialog と同じく DialogContent 内部で 描画するよう修正した。 Closes #217
Claude Code の ScheduleWakeup (/loop 動的モード) が呼ばれたあと子 プロセスが一旦終了する。supervisor はそれを「処理完了」とみなして セッションを done にしてしまうため、再開待ちの間も並列実行数の カウントから外れ、UI では完了済みとして誤表示されていた。 - 新しい status "waiting" と waitingUntil / waitingReason カラムを 追加し、Claude の tool_use ストリームから ScheduleWakeup を検知 したときに done ではなく waiting に遷移させる - scheduler の tick で waitingUntil を過ぎたセッションをアトミック にキューへ戻して自動再開する - isSessionActive と TodoButton/TodoManager の表示を waiting に対応 させ、同時実行数・バッジ・ドットで並列中として扱う - trpc start を waiting からの再開にも対応させ、手動「即時起動」を 許可する
Claude の assistant メッセージに `text` と `ScheduleWakeup` tool_use が同じ `message.content` 配列で来る場合、text で早期 return してしまい ScheduleWakeup が落ちて done 誤遷移していた。`classifyStreamJson` の `type === "assistant"` 分岐で text/tool/wakeup を前段で揃えてから返し、 どちらのイベントでも `scheduledWakeup` を propagate するよう修正。
`claimWaitingForResume` で status を queued に進めた後で supervisor.start が失敗すると、waiting のタイマーも消えているため scheduler tick の次回以降 でも取り戻せず、セッションが永続的に queued のまま取り残されていた。 catch 内で現在の status を確認し、まだ queued(=我々が claim したまま)の 場合に限り failed へ遷移させ、原因メッセージを verdictReason に残すように した。
supervisor がシングルスロット (`active: ActiveRun | undefined`) だったため、 設定の `maxConcurrentTasks` が完全に無視され、常に 1 セッションしか走らず 残りは永久キュー待ちになっていた。加えて設定変更時に supervisor へ通知が 飛ばないので、ユーザーが 1→2 に上げても pending のまま動き出さなかった。 - `active` を `Map<string, ActiveRun>` に変更し、複数同時実行を可能に - `start()` をキュー登録 + `drain()` 呼び出しに変更 - 各 runSession の `finally` で slot を解放し `drain()` を再実行 - `handleSettingsChanged()` を追加し、settings.update のミューテーションから呼ぶ - abort() も Map ベースに書き換え、対象セッションだけを停止
- スケジュールタブに検索機能を追加 - タスクタブにスケジュールと同じ形式の「新規」ボタンを追加 - 「新しい TODO」押下時の Composer をインライン表示から Dialog 表示に変更
Issue #226。 - `git log startHeadSha..HEAD` は HEAD が startHeadSha の子孫でない場合 (ブランチ切替・reset・rebase)無音で0件を返し、`gitOut` が例外を 握りつぶしていたため「新規コミット無し」と「開始点が失われた」を 区別できなかった。`gitRevExists` で解決可能性を確認し、 `startHeadUnreachable` としてUIへ通知する。 - `git diff --name-status -z startHeadSha HEAD` で2コミット間のファイル 差分を `sessionFiles` として追加。divergent な履歴でも累積デルタを 表示できるようにした。 - ChangesSidebar に「セッション全体」セクションと、開始HEAD喪失時の 注意表示を追加。選択中スコープのラベル切替も session / commit を 考慮する。 - supervisor: resume のたびに `startHeadSha` を上書きすると初回ランの コミットが埋もれてしまうため、既に記録済みの場合は維持する。
`git diff <start>..HEAD -- <path>` は削除ファイルでも有効な patch を 返すため、「セッション全体」セクションでは `code === "D"` を無効化 せず、削除の差分も閲覧できるようにする。ワーキングツリー側の `D` 無効化はファイルが worktree から既に失われているため維持する。
AgentManager のタスク詳細画面では「やってほしいこと」「ゴール」 フィールドが whitespace-pre-wrap の素テキストだったため、添付画像が `` という長い マークダウン文字列のまま剥き出しで見えていた。コンポーザ (`ImagePasteTextarea`) のチップ UI と詳細表示の体験を揃える。 - `todoAgent.readAttachment` tRPC procedure を追加。 `userData/todo-agent/attachments/` 配下のパスのみ読み取りを許可し、 base64 + MIME を返す。それ以外のパスは FORBIDDEN で拒否。 - 添付参照を抽出する `extractAttachmentRefs` / `stripAttachmentRefs` ユーティリティを追加(POSIX/Windows 両対応、UUID プリフィックス除去)。 - `AttachmentChips`(読み取り専用 chip 一覧)と `AttachmentPreviewDialog` (ネスト Dialog で画像表示)を追加。 - SessionDetail の description / goal 表示を、本文(strip 済み) + チップ列にレイアウト。チップクリックでプレビューを開く。 AgentManager ダイアログは閉じない(ネスト Dialog として動作)。
Running / Queued / Failed / Paused を色分けされた独立したバッジとして 並べて表示し、Manager を開かなくても各ステータスの件数を把握できる ようにする。配色は TodoManager の StatusDot と揃えた。 Closes #230
`preparing` は supervisor が Claude プロセスを spawn する前の 準備状態で、この時点での編集は `prepareArtifacts` が goal.md を 書き直すため安全に反映される。キュー待ちで `preparing` 停滞中の セッションも編集できるようにする。 キュー待ちセッションの番が回ってきて編集中に `running` / `verifying` に遷移した場合は、フロント側の useEffect で編集モードを自動解除し toast で通知する。バックエンドも `queued` / `preparing` / `failed` / `aborted` / `escalated` のみ許可する二重ガードを維持。 Closes #232
#234 — AgentManager の TODO 詳細で、Claude Code のサブエージェント (Task/Agent ツール) の tool_use/tool_result が親 Agent ブロック外にフラット表示される 不具合を修正し、併せて全体のビジュアルを改善する。 - supervisor: stream-json の `parent_tool_use_id` と tool_use/tool_result ブロックの id を抽出して TodoStreamEvent に `parentToolUseId` / `toolUseId` として伝搬。 - types: TodoStreamEvent に optional な id フィールドを追加。旧 jsonl (id 無し) は renderer 側の legacy 位置ペアリングで従来通り動作する。 - renderer: pairStreamEvents を id ベース + 親子ツリー化した buildStreamTree に差し替え。ToolCallCard はツリー再帰表示・ lucide-react のツール別アイコン/パレット・実行中 ShinyText シマー・ 子件数バッジを持つカード型に刷新。子がいる場合は初回に自動展開。 - globals.css: pure CSS の `.animate-shine` キーフレームを追加 (currentColor + --shine-peak で theme 対応)。
PR #219 で追加された `waiting` ステータス (ScheduleWakeup で一時停止中) が本 PR の新インジケーターで拾えていないため、queued バケットに追加する。 scheduler が waitingUntil 経過後に自動で queued に戻す挙動から、slot を 占有している扱いとして queued と同じバッジで集計する。
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 45 minutes and 27 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (5)
📝 WalkthroughWalkthroughTODO タスクにおける待機状態管理、添付ファイルのレンダリング、並行実行制御の新機能を実装しました。セッションの自動再開、ScheduleWakeup による自己ペース制御、git変更ファイルの表示、添付画像のプレビュー、ストリームイベントツリー構造化などが追加されました。 Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
|
@codex review |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e836a730d4
ℹ️ 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".
…ult 重複描画 - supervisor.start: 直前 abort で active から脱落途中の場合、 以前の早期 return で再開リクエストが捨てられ session が preparing で固着する問題を修正。abort 済みなら queue に積み、 drain で再起動する。 - TodoManager canEditFields: waiting (ScheduleWakeup 待機) を 除外。バックエンド updateFields が waiting を許可せず保存時 に PRECONDITION_FAILED で確定失敗する不整合を解消。 - buildStreamTree: イベントが順序逆転して tool_result が先に 到着した場合、standalone とツリー両方に出てしまう重複を排除。 事前パスで tool_use の id 集合も収集し、同じ id を持つ tool_result は standalone レンダリングをスキップする。
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/desktop/src/renderer/features/todo-agent/TodoManager/SchedulesSection/SchedulesSection.tsx (1)
73-96:⚠️ Potential issue | 🟡 Minorヘッダー件数とプレースホルダーのズレ
- Line 75-77: ヘッダーの
〜 件のスケジュールは常にschedules?.length(全件)を表示しており、絞り込み中でも件数が変わりません。フィルタリング時はfilteredSchedules.length / schedules.lengthのように一致件数を併記した方が UX として分かりやすいです。- Line 93: プレースホルダーは
名前 / タイトル / プロジェクトですが、実際はdescriptionとワークスペース名もマッチ対象に含まれています(Line 54-55)。案内文と実装を揃えるか、プレースホルダーを名前 / タイトル / 説明 / ワークスペース / プロジェクト等へ更新することを検討してください。💡 提案例
- <span className="text-xs text-muted-foreground"> - {(schedules?.length ?? 0) > 0 - ? `${schedules?.length} 件のスケジュール` - : "スケジュールなし"} - </span> + <span className="text-xs text-muted-foreground"> + {(schedules?.length ?? 0) === 0 + ? "スケジュールなし" + : filter.trim() + ? `${filteredSchedules.length} / ${schedules?.length} 件` + : `${schedules?.length} 件のスケジュール`} + </span>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/desktop/src/renderer/features/todo-agent/TodoManager/SchedulesSection/SchedulesSection.tsx` around lines 73 - 96, Update the header count to reflect filtering: in SchedulesSection replace the hard-coded display of schedules?.length with a conditional that shows filteredSchedules.length and the total (e.g. "X / Y 件のスケジュール" or just "Y 件のスケジュール" when no filter) so the header matches the current filtered list (use the existing filteredSchedules and schedules variables and the filter state to decide format). Also update the Input placeholder text in the same component to accurately list searchable fields (include "説明" and "ワークスペース" so it reads like "名前 / タイトル / 説明 / ワークスペース / プロジェクト") so the UI guidance matches the matching logic referenced around filteredSchedules.
🧹 Nitpick comments (5)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/RightSidebar/ChangesView/components/ReviewPanel/components/ReplyDialog/ReplyDialog.tsx (1)
93-118: プレビュー領域の Markdown 化は妥当、ただし長文コメントの縦方向占有に注意
getCommentPreviewTextによる 1 行プレビューからCommentBodyによるフル Markdown 描画へ切り替え、高さ上限をmax-h-48に広げた変更は、返信時の文脈確認という観点で良い改善です。一方で、コードブロックや表を含む長いコメントだとmax-h-48(約 12rem)でも内部スクロールが頻発し、返信テキストエリアが画面下に押し込まれるケースがあり得ます。実機で長大なレビューコメントに対する返信ダイアログを確認し、Textarea が隠れないか軽く触れておくと安心です。🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/desktop/src/renderer/screens/main/components/WorkspaceView/RightSidebar/ChangesView/components/ReviewPanel/components/ReplyDialog/ReplyDialog.tsx` around lines 93 - 118, The preview area now renders full Markdown via CommentBody inside the div with class "max-h-48 overflow-y-auto..." which can push the reply Textarea off-screen for very long comments; reduce the preview's vertical impact by either lowering the hard cap (e.g. change max-h-48 to a smaller max height), or make the preview collapsible/expandable (show first line or getCommentPreviewText by default with a "Show more" toggle that expands to render CommentBody), and ensure the dialog/container uses a flex-column layout that allows the reply Textarea to stay visible (use flex, flex-col and allow the preview to overflow-y-auto while giving the Textarea a stable min-height) so the ReplyDialog layout (the preview div and the reply Textarea) never hides the input.apps/desktop/src/renderer/screens/main/components/WorkspaceView/RightSidebar/ChangesView/components/ReviewPanel/components/CommentBody/CommentBody.tsx (1)
24-35:onOpenUrl未指定時にリンクの既定ナビゲーションが発生する
onClickでonOpenUrl?.(href, e)を呼ぶだけなので、onOpenUrlが未指定だとpreventDefaultが走らず、<a href>の既定動作で Electron のレンダラ内ナビゲーションが起きる恐れがあります(ワークスペース状態を丸ごと失う典型的な足元の罠)。現状の呼び出し元では常にhandleOpenUrlを渡しているので実害はないですが、将来の利用で破綻しないよう、コールバック未指定時はtarget="_blank" rel="noopener noreferrer"相当にフォールバックするか、常にe.preventDefault()してから任意でコールバックを呼ぶ形が安全です。♻️ 防御的な修正例
- a: ({ href, children }) => - href ? ( - <a - href={href} - className="text-primary underline" - onClick={(e) => onOpenUrl?.(href, e)} - > - {children} - </a> - ) : ( - <span>{children}</span> - ), + a: ({ href, children }) => + href ? ( + <a + href={href} + className="text-primary underline" + target="_blank" + rel="noopener noreferrer" + onClick={(e) => { + if (onOpenUrl) { + e.preventDefault(); + onOpenUrl(href, e); + } + }} + > + {children} + </a> + ) : ( + <span>{children}</span> + ),🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/desktop/src/renderer/screens/main/components/WorkspaceView/RightSidebar/ChangesView/components/ReviewPanel/components/CommentBody/CommentBody.tsx` around lines 24 - 35, The anchor in CommentBody's custom renderer can trigger default navigation when onOpenUrl is undefined; update the onClick for the <a> in CommentBody.tsx to always call e.preventDefault(), then if onOpenUrl exists call onOpenUrl(href, e), otherwise open the URL safely as an external window (e.g. window.open(href, '_blank') with noopener/noreferrer) and also add target="_blank" rel="noopener noreferrer" as a defensive fallback attribute so unidentified callers cannot cause renderer navigation.packages/local-db/src/schema/todo-sessions.ts (1)
95-102:waitingUntilへのインデックス検討(運用アドバイス)
session-store.ts#listWaitingDueは scheduler tick から定期的に呼ばれ、status = "waiting" AND waiting_until <= nowで走査されます。現状はtodo_sessions_status_idxの前方一致でフィルタ後にメモリ上で絞り込まれる形ですが、waiting セッションが増えても O(waiting件数) で済みます。当面は問題ありませんが、waiting セッションが多数になる運用が見込まれる場合は(status, waiting_until)の複合インデックスを追加するとスキャン範囲をさらに絞れます。現段階では必須ではありません。🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/local-db/src/schema/todo-sessions.ts` around lines 95 - 102, The current schema defines waitingUntil (waiting_until) but lacks a composite index with status; to optimize session-store.ts#listWaitingDue queries that filter WHERE status = 'waiting' AND waiting_until <= now, add a composite DB index on (status, waiting_until) (e.g., create or declare an index named todo_sessions_status_waiting_until_idx) so the database can use the index for both predicates instead of scanning all waiting rows; update the schema definition in todo-sessions.ts to declare that composite index and run migrations or adjust the table/index creation accordingly.apps/desktop/src/renderer/features/todo-agent/TodoManager/ChangesSidebar/ChangesSidebar.tsx (1)
477-488:scopeLabelの網羅性について
DiffScopeの 4 ケースすべてを switch で返しており、TypeScript の flow analysis により末尾 return 不要で成立します。将来DiffScopeに値が追加された際は本関数で TS エラーが出るため、現状のままで網羅性チェックが効きます。必要に応じてdefault: const _exhaustive: never = scope; return _exhaustive;を追加するとさらに明示的になりますが、必須ではありません。🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/desktop/src/renderer/features/todo-agent/TodoManager/ChangesSidebar/ChangesSidebar.tsx` around lines 477 - 488, The switch in scopeLabel(scope: DiffScope) currently covers all known DiffScope cases but to make exhaustiveness explicit and cause a compile error if DiffScope grows, add a default branch that asserts never (e.g., assign scope to a never-typed variable and return it) so the compiler will catch any unhandled new variants; update the switch in function scopeLabel to include this exhaustive check referencing the symbol scope (and function scopeLabel / type DiffScope) so future additions to DiffScope produce a type error until handled.apps/desktop/src/renderer/features/todo-agent/TodoManager/TodoManager.tsx (1)
2234-2254: サイドバー行の残り時間表示はリアルタイムに更新されません(任意)。
SessionDetail側には 1 秒おきのsetTickがありますが、SessionRow側では再レンダの起点がlistAllの 2 秒ポーリングだけなので、waiting行に表示される「N 秒後 / N 分後」が最大 2 秒ラグで跳ねて見えます。秒単位表示が目立つケースはそれほど多くないので急ぎの実害はないですが、「残りが少ないほど表示もカクつく」印象は気になる人もいるかもしれません。気になるようなら
SessionRowでsession.status === "waiting"のときだけ短周期の再レンダ Hook を足す手があります。🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/desktop/src/renderer/features/todo-agent/TodoManager/TodoManager.tsx` around lines 2234 - 2254, Sidebar "waiting" rows use listAll's 2s poll so formatWaitingRemaining (used in SessionRow) can lag; add a short-interval re-render only when session.status === "waiting". In the SessionRow component, create a local tick (e.g. useState or useReducer) and useEffect that sets a setInterval at ~1s when session.status === "waiting" and clears it on status change/unmount; ensure the effect depends on session.status and session.waitingUntil so formatWaitingRemaining(session.waitingUntil) updates in real time, and keep SessionDetail/listAll unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/desktop/src/main/todo-agent/scheduler.ts`:
- Around line 226-244: The catch on supervisor.start() is dead code because
TodoSupervisor.start (supervisor.start) never rejects; either make start
legitimately throw on validation failures so this catch is reachable or remove
the catch and centralize stranding-handling in the drain/runSession path.
Concretely: either modify TodoSupervisor.start (the async function referenced as
supervisor.start) to validate session existence/state (using
sessionStore.get/session id checks) and throw a descriptive Error on invalid
conditions, or delete the .catch block in scheduler.ts and ensure
runSession()/drain() performs the same sessionStore.update(...) to mark
failed/stranded sessions; keep references to supervisor.start,
TodoSupervisor.start, runSession, drain, sessionStore.get, and
sessionStore.update to locate places to change.
In `@apps/desktop/src/main/todo-agent/supervisor.ts`:
- Around line 1363-1369: The code currently clamps delaySeconds into clamped and
waits, which contradicts the comment that out-of-range values are malformed;
change the behavior to follow the comment: in the ScheduleWakeup handling
(variables delaySeconds, reason, currently using clamped) validate that
delaySeconds is finite and inside [60, 3600] and if it is outside that range
treat it as malformed (continue/return null) instead of clamping; preserve the
reason extraction logic (typeof inp.reason === "string") and, when valid, return
delayMs computed from Math.floor(delaySeconds) * 1000; also update the
surrounding comment to clearly state that out-of-range values are rejected as
malformed.
In `@apps/desktop/src/renderer/globals.css`:
- Around line 533-559: In the .animate-shine rule, add a blank line immediately
before the background-image declaration to satisfy
declaration-empty-line-before, and replace all occurrences of the CSS keyword
currentColor with lowercase currentcolor (e.g., in background-image stops) to
satisfy value-keyword-case; target the .animate-shine selector and its
background-image value updates (and any other uses of currentColor inside that
rule) to make these changes.
In
`@apps/desktop/src/renderer/screens/main/components/WorkspaceView/RightSidebar/ChangesView/components/ReviewPanel/components/CommentBody/CommentBody.tsx`:
- Around line 21-22: The remarkAlert output classes are being stripped by
rehypeSanitize's default schema; update CommentBody.tsx to pass a custom
sanitize schema to rehypeSanitize that preserves the alert classes. Import the
default schema from rehype-sanitize (or clone its object) then extend its
attributes to allow className values like "markdown-alert",
"markdown-alert-title", and "markdown-alert-content" (assign these to the '*' or
to relevant elements such as 'div'/'p') and pass the extended schema into
rehypeSanitize(...) in the rehypePlugins array so the alert markup keeps its
classes and the existing CSS (.review-comment-body .markdown-alert...) applies.
In `@README.md`:
- Line 93: The date in the README table row for "**TODO 詳細の添付画像 chip 化+プレビュー**"
is inconsistent (shows 2026-04-17); update that cell to match the PR creation
date 2026-04-16 (same as PR `#239` and `#229`) so all rows use the same JST PR date;
locate the table row text "**TODO 詳細の添付画像 chip 化+プレビュー**" and replace the date
value to 2026-04-16.
---
Outside diff comments:
In
`@apps/desktop/src/renderer/features/todo-agent/TodoManager/SchedulesSection/SchedulesSection.tsx`:
- Around line 73-96: Update the header count to reflect filtering: in
SchedulesSection replace the hard-coded display of schedules?.length with a
conditional that shows filteredSchedules.length and the total (e.g. "X / Y
件のスケジュール" or just "Y 件のスケジュール" when no filter) so the header matches the current
filtered list (use the existing filteredSchedules and schedules variables and
the filter state to decide format). Also update the Input placeholder text in
the same component to accurately list searchable fields (include "説明" and
"ワークスペース" so it reads like "名前 / タイトル / 説明 / ワークスペース / プロジェクト") so the UI
guidance matches the matching logic referenced around filteredSchedules.
---
Nitpick comments:
In
`@apps/desktop/src/renderer/features/todo-agent/TodoManager/ChangesSidebar/ChangesSidebar.tsx`:
- Around line 477-488: The switch in scopeLabel(scope: DiffScope) currently
covers all known DiffScope cases but to make exhaustiveness explicit and cause a
compile error if DiffScope grows, add a default branch that asserts never (e.g.,
assign scope to a never-typed variable and return it) so the compiler will catch
any unhandled new variants; update the switch in function scopeLabel to include
this exhaustive check referencing the symbol scope (and function scopeLabel /
type DiffScope) so future additions to DiffScope produce a type error until
handled.
In `@apps/desktop/src/renderer/features/todo-agent/TodoManager/TodoManager.tsx`:
- Around line 2234-2254: Sidebar "waiting" rows use listAll's 2s poll so
formatWaitingRemaining (used in SessionRow) can lag; add a short-interval
re-render only when session.status === "waiting". In the SessionRow component,
create a local tick (e.g. useState or useReducer) and useEffect that sets a
setInterval at ~1s when session.status === "waiting" and clears it on status
change/unmount; ensure the effect depends on session.status and
session.waitingUntil so formatWaitingRemaining(session.waitingUntil) updates in
real time, and keep SessionDetail/listAll unchanged.
In
`@apps/desktop/src/renderer/screens/main/components/WorkspaceView/RightSidebar/ChangesView/components/ReviewPanel/components/CommentBody/CommentBody.tsx`:
- Around line 24-35: The anchor in CommentBody's custom renderer can trigger
default navigation when onOpenUrl is undefined; update the onClick for the <a>
in CommentBody.tsx to always call e.preventDefault(), then if onOpenUrl exists
call onOpenUrl(href, e), otherwise open the URL safely as an external window
(e.g. window.open(href, '_blank') with noopener/noreferrer) and also add
target="_blank" rel="noopener noreferrer" as a defensive fallback attribute so
unidentified callers cannot cause renderer navigation.
In
`@apps/desktop/src/renderer/screens/main/components/WorkspaceView/RightSidebar/ChangesView/components/ReviewPanel/components/ReplyDialog/ReplyDialog.tsx`:
- Around line 93-118: The preview area now renders full Markdown via CommentBody
inside the div with class "max-h-48 overflow-y-auto..." which can push the reply
Textarea off-screen for very long comments; reduce the preview's vertical impact
by either lowering the hard cap (e.g. change max-h-48 to a smaller max height),
or make the preview collapsible/expandable (show first line or
getCommentPreviewText by default with a "Show more" toggle that expands to
render CommentBody), and ensure the dialog/container uses a flex-column layout
that allows the reply Textarea to stay visible (use flex, flex-col and allow the
preview to overflow-y-auto while giving the Textarea a stable min-height) so the
ReplyDialog layout (the preview div and the reply Textarea) never hides the
input.
In `@packages/local-db/src/schema/todo-sessions.ts`:
- Around line 95-102: The current schema defines waitingUntil (waiting_until)
but lacks a composite index with status; to optimize
session-store.ts#listWaitingDue queries that filter WHERE status = 'waiting' AND
waiting_until <= now, add a composite DB index on (status, waiting_until) (e.g.,
create or declare an index named todo_sessions_status_waiting_until_idx) so the
database can use the index for both predicates instead of scanning all waiting
rows; update the schema definition in todo-sessions.ts to declare that composite
index and run migrations or adjust the table/index creation accordingly.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 1dc41012-d760-46ae-b277-140b5509d911
📒 Files selected for processing (27)
README.mdapps/desktop/src/main/todo-agent/git-status.tsapps/desktop/src/main/todo-agent/scheduler.tsapps/desktop/src/main/todo-agent/session-store.tsapps/desktop/src/main/todo-agent/supervisor.tsapps/desktop/src/main/todo-agent/trpc-router.tsapps/desktop/src/main/todo-agent/types.tsapps/desktop/src/renderer/features/todo-agent/TodoButton/TodoButton.tsxapps/desktop/src/renderer/features/todo-agent/TodoManager/ChangesSidebar/ChangesSidebar.tsxapps/desktop/src/renderer/features/todo-agent/TodoManager/SchedulesSection/SchedulesSection.tsxapps/desktop/src/renderer/features/todo-agent/TodoManager/SchedulesSection/components/ScheduleEditorDialog/ScheduleEditorDialog.tsxapps/desktop/src/renderer/features/todo-agent/TodoManager/TodoManager.tsxapps/desktop/src/renderer/features/todo-agent/TodoManager/components/AttachmentChips/AttachmentChips.tsxapps/desktop/src/renderer/features/todo-agent/TodoManager/components/AttachmentChips/index.tsapps/desktop/src/renderer/features/todo-agent/TodoManager/components/AttachmentPreviewDialog/AttachmentPreviewDialog.tsxapps/desktop/src/renderer/features/todo-agent/TodoManager/components/AttachmentPreviewDialog/index.tsapps/desktop/src/renderer/features/todo-agent/TodoManager/utils/attachmentRefs/attachmentRefs.tsapps/desktop/src/renderer/features/todo-agent/TodoManager/utils/attachmentRefs/index.tsapps/desktop/src/renderer/globals.cssapps/desktop/src/renderer/screens/main/components/WorkspaceView/RightSidebar/ChangesView/components/ReviewPanel/ReviewPanel.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/RightSidebar/ChangesView/components/ReviewPanel/components/CommentBody/CommentBody.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/RightSidebar/ChangesView/components/ReviewPanel/components/CommentBody/index.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/RightSidebar/ChangesView/components/ReviewPanel/components/ReplyDialog/ReplyDialog.tsxpackages/local-db/drizzle/0057_todo_session_waiting.sqlpackages/local-db/drizzle/meta/0057_snapshot.jsonpackages/local-db/drizzle/meta/_journal.jsonpackages/local-db/src/schema/todo-sessions.ts
- scheduler.ts: supervisor.start は同期 wrap で実際には reject しない ため、'.catch で failed に倒す' という docstring が嘘だった。docstring を実態(不慮の throw を console に出すだけの保護的 catch)に合わせ、 status 書き換え経路は drain 側の責務に一本化。 - supervisor.ts (extractScheduledWakeup): 範囲外の delaySeconds を silent clamp していたが、Claude が想定した再開時刻と実際の再開が ずれて挙動が読めなくなる。コメント通り malformed 扱いで wait に 遷移させない(done の通常終了に倒す)よう修正。 - globals.css (.animate-shine): Stylelint の declaration-empty-line-before と value-keyword-case を解消(currentColor → currentcolor、宣言前空行)。 - CommentBody.tsx: rehype-sanitize の defaultSchema が className を 剥がして remark-github-blockquote-alert の markdown-alert スタイル が当たらない問題を修正。markdown-alert / markdown-alert-title / octicon クラスのみ明示許可するカスタムスキーマを渡す。 - README.md: #229 の追加日 2026-04-17 → 2026-04-16(他行と同じ PR 作成日 UTC 基準)に揃える。
概要
現時点で MocA-Love/superset に open している 11 件の PR をひとつのブランチに統合しました。
それぞれの機能・修正は維持したまま、merge commit ベースで時系列順に取り込んでいます。
個別 PR をひとつずつマージする手間を省くためのまとめ PR です。マージ後に各元 PR は不要になります。
取り込んだ PR
fix/reply-dialog-markdown-renderingfix/215-schedule-dialog-widthfix/217-agent-manager-settings-dialogfix/todo-waiting-statusfix/todo-max-concurrent-tasksmagenta-spectroscopefix/agent-manager-changes-sidebarfeat/todo-attachment-chip-previewfix/todo-button-status-indicatorsfix/todo-preparing-editablefeat/todo-live-stream-revampコンフリクト解消メモ
3 箇所でコンフリクトを解消しました(merge commit message にも記録)。
TodoManager.tsx) — fix(desktop): Agent Manager の タスク/スケジュール タブの UI 統一 (#222) #225 が新設した composer Dialog を、fix(desktop): Agent Manager 設定ダイアログでマネージャが閉じる問題を修正 (#217) #221 が確立した「Manager のDialogContentの内側にネストして外側 Dialog を閉じさせない」パターンに合わせて DialogContent 内へ配置。TodoButton.tsx) — fix(desktop): TODOボタンのインジケーターをステータス別に表示 #231 のステータス別バッジ実装が fix(desktop): Todo セッションに ScheduleWakeup 待機ステータスを追加 (#219) #223 のrunning + queued + waitingカウンターを完全に包含しており、waitingも同等扱いで集計するため fix(desktop): TODOボタンのインジケーターをステータス別に表示 #231 側を採用。supervisor.ts) — feat(desktop): TODO ライブストリームをサブエージェント入れ子 + スタイリッシュ UI に刷新 (#234) #236 が追加したparentToolUseId/toolUseIdなどのイベントフィールドと、fix(desktop): Todo セッションに ScheduleWakeup 待機ステータスを追加 (#219) #223 のextractScheduledWakeupによる waiting 状態検出を両立。リネームされたextractToolResultDetailsも維持しつつ、extractScheduledWakeupヘルパーを残した。検証
bun run typecheck✅bun run lint✅(rg不在によるcheck-git-ref-strings.shの警告のみで biome 本体は pass)マージ後タスク
Summary by CodeRabbit
リリースノート
新機能
改善