Conversation
…et-sh#3811) * fix(host-service): isolate subsystem crashes from main thread Subsystem throws (timer callbacks, EventEmitter listeners, pty data/exit handlers, harness subscribe callback) used to escape into the process and could take the whole host-service down. Now they're contained per-subsystem and a process-level safety net catches anything that still slips through. - Add safety.ts with installProcessSafetyNet (uncaughtException + unhandledRejection log without exiting) and safeSync/safeAsync helpers for wrapping callbacks. - Wrap hot async entry points in EventBus, GitWatcher, PullRequestRuntimeManager, ChatRuntimeManager, and terminal PTY callbacks. - Surface the previously-silent malformed-message swallow in EventBus.parseClientMessage. Startup exit on init failure is intentionally preserved so the coordinator / external supervisor can restart with a clean process. * refactor(host-service): address review feedback on safety wrappers - Install process safety net only after server is listening so startup throws still reach main().catch and exit non-zero. - Rename misleading `safeSync` local in pull-requests.ts to `runBranchSync`/`runProjectRefresh` — it wraps an async fn. - Hoist `safeSync(event-bus:send, sendMessage)` to module scope to avoid per-broadcast-per-socket closure allocation. - Use `safeAsync` in git-watcher rescan for consistency with the pull-requests interval pattern. - Drop low-value `promise` field from unhandledRejection log. * refactor(host-service): simplify crash isolation to process-net + fan-out guards Drop safeSync/safeAsync wrappers entirely. The Node process-level handlers already catch throws from setInterval/setTimeout bodies, EventEmitter listeners, native pty callbacks, and orphaned promise continuations — so wrapping each one individually was redundant. The two cases that genuinely need inline error handling are loops over multiple subscribers, where a throw skips the rest of the iteration: - EventBus.broadcast — wrap per-socket send and drop dead sockets, matching the opencode pty fan-out pattern. Converts "log forever per broadcast" into "one log + clean state". - GitWatcher.scheduleFlush listener loop — inline try/catch so one bad subscriber can't skip siblings. Aligns with the field norm (opencode, tabby, hyper, mastra-code-ui all rely on process-level handlers + targeted inline guards rather than per-seam wrappers). Net -68 lines. * chore(host-service): drop redundant label arg, restore one-liner setInterval - installProcessSafetyNet had a default label arg that both call sites passed identically; drop the param and inline "host-service" in the logs. - git-watcher.ts start() reverts to its original setInterval one-liner shape (the multi-line form was leftover from an earlier refactor).
…d git status (superset-sh#3838) * fix(desktop): make file tree resilient to slow directory loads - Time out listDirectory after 5s and retry up to 3x with linear backoff - Abort in-flight requests on unmount and workspace/root change - Show a loading spinner in FilesTab while the workspace query resolves - Enable abortOnUnmount globally on the workspace tRPC client * refactor(desktop): simplify useFileTree cancellation, drop FilesTab workspace name - Use AbortController membership in the active set as the "still relevant" check, replacing isMountedRef + activeContextRef + isRequestCurrent - Inline single-use helpers (markDirectoryLoading, clearDirectoryLoading, shouldRetryListDirectory, getListDirectoryRetryDelayMs) - Drop the workspaceName prop from FilesTab/WorkspaceSidebar/WorkspaceContent; the files header is just "Explorer" * fix(desktop): only show files-tab spinner on initial load, not refetches * feat(host-service): plumb AbortSignal through listDirectory When the renderer aborts a listDirectory query (timeout or workspace switch), the host-service was running fs.readdir + per-symlink fs.stat to completion and discarding the result. Node's fs API doesn't honor AbortSignal, but we can short-circuit between operations — useful in symlink-heavy directories (node_modules) where the per-entry stat loop dominates. * refactor(host-service): batch listDirectory stat calls for cancellable abort Process per-entry symlink stats in batches of 16 with a signal check between batches. With Promise.all-over-everything, all stats kick off in the same microtask and an in-flight abort can't interrupt any of them. Batching bounds the zombie work to one batch (~16 stats) per abort. * feat(host-service): tRPC query timeout middleware + retry on TIMEOUT Hung host-service IPC (slow git, slow filesystem ops) was leaving the renderer spinning indefinitely. Replace the bespoke per-hook retry/timeout in useFileTree with a single server-side middleware that bounds every query procedure. Server (queryProcedure builder + middleware): - t.middleware races next() against a per-procedure timeout, rejecting with a TRPCError({ code: "TIMEOUT" }). Default 5s, override via `.meta({ timeoutMs })` on procedures that legitimately take longer (search, listCommits, getDiff, getStatus, getBranchSyncStatus, getPullRequestThreads, readFile). - Switch all query procedures in filesystem and git routers to queryProcedure; mutations remain on protectedProcedure. Client (workspace-client QueryClient): - defaultOptions.queries.retry retries TIMEOUT errors up to 2 times with linear backoff (300ms, 600ms). Other errors keep the previous single retry. useFileTree: - Drop withAbortableTimeout, ListDirectoryTimeoutError, retry-timer set, retry recursion, loadDirectoryRef, activeLoadAbortControllersRef. - Just await utils.filesystem.listDirectory.fetch(input). React Query's retry policy handles TIMEOUT; abortOnUnmount cancels in-flight on unmount/workspace switch. ~120 lines removed. Side benefit: git.getStatus / listBranches / listCommits etc. all gain hung-IPC protection automatically. The Changes tab no longer spins forever on a slow `git status`. * docs(host-service): add QUERY_TIMEOUTS.md reference Documents the queryProcedure / timeoutMiddleware pattern: where it lives, how to set per-procedure budgets via .meta({ timeoutMs }), the current budget table, and what timeouts do (and don't) interrupt.
…erset-sh#3884) * fix(host-service): dedupe PR refresh calls with repo-keyed cache Multiple projects targeting the same GitHub repo each fired their own GraphQL query every 10s, and force=true paths bypassed the per-project debounce entirely. Replace with a single repo-keyed response cache so N projects on the same repo collapse to 1 call, branch-sync/tRPC bursts share the in-flight promise, and the polling cadence drops to 20s. * fix(host-service): cache PR detail fetches to skip repeat gh pr view The PR detail panel re-invokes `gh pr view` on every mount, so re-renders, tab switches, and click-back patterns each shell out fresh. Wrap the procedure in a 30s TTL cache keyed on `owner/name#prNumber`, sharing the in-flight promise across concurrent callers and evicting on failure so transient errors don't poison subsequent reads. * fix(host-service): bypass repo cache for explicit PR refreshes The branch-sync follow-up and the `refreshByWorkspaces` tRPC mutation both fire when external state has just changed (local SHA moved, or a PR was just merged) — exactly the case where the 10s settled cache returns stale data. Thread a bypassCache option from those call sites down to the cache lookup so explicit refreshes always fetch fresh while the polling tick keeps deduping. Bypass paths still write to the cache so subsequent polls benefit.
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ 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 (21)
✨ 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 |
🧹 Preview Cleanup CompleteThe following preview resources have been cleaned up:
Thank you for your contribution! 🎉 |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bae304fd1c
ℹ️ 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".
Recorded as integrated via -s ours after batch PRs #455-#464. Taken via individual PRs: - PR 1 (#455): v2 polish 前半 safe set (9 commits) - PR 2 (#456): v2/host-service polish 中盤 (12 commits) - PR 3 (#457): sidebar polish + jwt API (5 commits) - PR 4 (#458): host-service tRPC retry/cache/timeout (3 commits) - PR 5 (#459): v2 diff pane / file pane polish (2 commits) - PR 7 (#462): host-service v2 canonical workspace.create + attachment store (PR1 superset-sh#3893 + PR2 superset-sh#3916) - PR 11 (#463): agents API + onboarding (7 commits + 1 cleanup) - PR 12 (#464): v1→v2 import flow rewrite (11 commits + 2 follow-ups) - PR 13 (#460): host-service shell env probe + typo (2 commits) - PR 16 (#461): marketplace 19 themes (1 commit) Skipped / deferred (recorded as integrated for behind=0): - PR 6: CLI v1 launch (superset-sh#3898 + 30+ CLI/SDK followups) — defer to dedicated migration - PR 9: v2 PR3 (superset-sh#3940) + revert (superset-sh#4017) — net-zero pair - PR 10: pty-daemon (superset-sh#3896, superset-sh#3971, superset-sh#4054) — fork keeps its terminal-host - PR 14: Slack MCP-v2 (superset-sh#4197, superset-sh#4208) — depends on mcp-v2/sdk divergence - PR 15: onboarding remaining (superset-sh#4115, superset-sh#4125, superset-sh#4214, superset-sh#4213, superset-sh#4222, superset-sh#4225) — depends on fork's deleted setup pages Behind: 0 after this merge.
Summary
upstream 同期バッチ第 4 弾。host-service tRPC retry/cache/timeout (3 commits)。
進捗: PR 1 (9) + PR 2 (12) + PR 3 (5) + PR 4 (3) = 29 / 223。
取り込み内容
Fork 側のコンフリクト解決
packages/host-service/src/trpc/router/git/git.ts(feat(host-service): tRPC query timeout + retry, fix hung file tree and git status superset-sh/superset#3838): fork のlistBranchesが持つsortOrder/pinDefault入力を維持しつつ、procedure をprotectedProcedure→queryProcedureに切替(timeout middleware 適用)packages/host-service/src/trpc/router/filesystem/filesystem.ts(feat(host-service): tRPC query timeout + retry, fix hung file tree and git status superset-sh/superset#3838): fork 独自のwarmupSearchIndex: protectedProcedureを維持。upstream のsearchContent: protectedProcedure → queryProcedure + meta({ timeoutMs: 60_000 })を fork の searchContent (line 331) にも適用apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/page.tsx(feat(host-service): tRPC query timeout + retry, fix hung file tree and git status superset-sh/superset#3838):WorkspaceSidebar周りの構造変更ではなく fork のWorkspace<PaneViewerData>を維持workspaceNameprop を fork 側でも以下から削除:<WorkspaceSidebar>呼び出し<CommandPalette>呼び出し(CommandPalette 側でworkspaceName?: stringの optional のため省略 OK)除外した commits
Fork 固有機能ヘルスチェック
githubExtendedprocedure 健在sortOrder/pinDefault維持Test plan
bun install成功bun run typecheck全 task greenbun run lintexit 0次の PR
PR 5: v2 diff pane polish (superset-sh#3899, superset-sh#3911)