Fix close_tab corruption, active_panes routing, and blocking writes#2
Fix close_tab corruption, active_panes routing, and blocking writes#2
Conversation
…ient writes - Guard close_tab to reject closing the last tab before destroying pane state, preventing irreversible state corruption on a normal user command - Initialize active_panes for all existing tabs on client hello, and propagate new tab's focused pane to all clients to prevent cross-tab input misrouting - Make client sockets nonblocking (SOCK_NONBLOCK) and disconnect clients on write failure to prevent one stalled client from freezing the entire server Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
CodeAnt AI is reviewing your PR. |
|
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 5 minutes and 58 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 (3)
📝 WalkthroughWalkthroughGitHubアクション用のCI/CD ワークフロー(フォーマットチェック、ビルド、テスト、セキュリティ監査)を追加し、 Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 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 |
Up to standards ✅🟢 Issues
|
|
|
Overall Grade |
Security Reliability Complexity Hygiene |
Code Review Summary
| Analyzer | Status | Updated (UTC) | Details |
|---|---|---|---|
| Secrets | Apr 6, 2026 5:28p.m. | Review ↗ |
There was a problem hiding this comment.
Pull Request Overview
There is a major discrepancy between the PR title and the actual changes submitted. While the PR claims to fix session corruption, routing, and blocking writes, the implementation only contains GitHub Actions workflow updates (.github/workflows/ci.yml). Consequently, 5 out of 6 acceptance criteria regarding application logic are completely unaddressed. Additionally, the CI pipeline is configured to allow formatting failures, which undermines its utility as a quality gate. These gaps must be addressed before the PR can be considered for merging.
About this PR
- Critical Scope Mismatch: The PR is missing all application-level logic changes described in the title and description (tab management fixes, active_panes routing, and non-blocking socket implementation). Only CI workflow changes are present.
Test suggestions
- Verify that 'close_tab' logic rejects closing the last tab and preserves session stability.
- Verify that a new client receives correct 'active_panes' state for all tabs upon connection.
- Verify that creating a tab on one client correctly routes input and focus on other clients.
- Verify that a slow/stalled client (simulated via throttled socket) is disconnected without freezing the server.
- CI workflow triggers on push/pull_request and executes 'zig build test'.
Prompt proposal for missing tests
Consider implementing these tests if applicable:
1. Verify that 'close_tab' logic rejects closing the last tab and preserves session stability.
2. Verify that a new client receives correct 'active_panes' state for all tabs upon connection.
3. Verify that creating a tab on one client correctly routes input and focus on other clients.
4. Verify that a slow/stalled client (simulated via throttled socket) is disconnected without freezing the server.
🗒️ Improve review quality by adding custom instructions
| git diff --name-only "origin/$GH_BASE_REF" -- '*.zig' 2>/dev/null | while read -r file; do | ||
| [ -f "$file" ] || continue | ||
| grep -n "$pattern" "$file" 2>/dev/null | while IFS=: read -r line content; do | ||
| echo "::warning file=$file,line=$line::[$level] $label: $content" | ||
| done | ||
| done | ||
| fi |
There was a problem hiding this comment.
🟡 MEDIUM RISK
The audit function generates warnings for every occurrence of a pattern within any file touched by the PR, even on lines not modified. This results in 'ghost' warnings for legacy code.
Update the security-audit job to only emit warnings for pattern matches that appear within the added or modified lines of the current PR diff.
| - name: Format check | ||
| continue-on-error: true | ||
| run: zig fmt --check src/ |
There was a problem hiding this comment.
🟡 MEDIUM RISK
Suggestion: The 'continue-on-error' property should be removed to ensure that code formatting is strictly enforced across the codebase. CI formatting checks should be blocking to maintain consistent code style.
| - name: Format check | |
| continue-on-error: true | |
| run: zig fmt --check src/ | |
| run: zig fmt --check src/ |
| - name: Install Zig | ||
| run: | | ||
| curl -sL "https://ziglang.org/download/0.15.2/zig-x86_64-linux-0.15.2.tar.xz" | tar -xJ | ||
| echo "$PWD/zig-x86_64-linux-0.15.2" >> "$GITHUB_PATH" |
There was a problem hiding this comment.
⚪ LOW RISK
Suggestion: Consider using a dedicated Zig setup action for better reliability and easier version management instead of manual curl/tar commands.
Try running the following prompt in your IDE agent:
Replace the manual Zig installation steps in the 'check' job with the 'mlugg/setup-zig' action.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ef553e7ea0
ℹ️ 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".
| const w = posix.write(cs.fd, buf[sent..n]) catch |err| { | ||
| cs.write_failed = true; | ||
| return err; |
There was a problem hiding this comment.
Treat nonblocking backpressure as retryable
Because accepted client sockets are now nonblocking, posix.write can return error.WouldBlock under normal transient backpressure, but this code marks write_failed for any write error and the client is disconnected on the next composeAll sweep. That means a healthy but briefly slow client can be dropped during output bursts (for example, large render updates), even though the connection is still valid. WouldBlock should be handled as a retry/queue condition rather than immediate protocol corruption.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Code Review
This pull request introduces non-blocking socket handling for client connections and implements a mechanism to disconnect clients that encounter write errors, preventing protocol stream corruption. It also improves state synchronization by propagating active pane information to all clients during tab creation and initial connection. Feedback was provided regarding the aggressive handling of 'WouldBlock' errors on non-blocking writes, which could lead to unnecessary disconnections of slow clients, and the potential fragility of using a fixed-size stack array for client cleanup.
| const w = posix.write(cs.fd, buf[sent..n]) catch |err| { | ||
| cs.write_failed = true; | ||
| return err; | ||
| }; |
There was a problem hiding this comment.
The posix.write call on a non-blocking socket will return error.WouldBlock if the output buffer is full. While the intent is to disconnect stalled clients, treating WouldBlock as a fatal error in a tight while (sent < n) loop is very aggressive. If the client is only momentarily slow, this will disconnect them immediately. Consider if a partial write should be allowed to remain in a per-client buffer, or explicitly document that this server does not support buffering for slow clients and requires them to keep up with the render rate.
| fn sweepFailedClients(self: *Server) void { | ||
| var to_remove: [MAX_CLIENTS]u16 = undefined; | ||
| var count: u8 = 0; | ||
| var it = self.clients.iterator(); | ||
| while (it.next()) |entry| { | ||
| if (entry.value_ptr.*.write_failed) { | ||
| if (count < MAX_CLIENTS) { | ||
| to_remove[count] = entry.key_ptr.*; | ||
| count += 1; | ||
| } | ||
| } | ||
| } | ||
| for (to_remove[0..count]) |cid| { | ||
| self.disconnectClient(cid); | ||
| } | ||
| } |
There was a problem hiding this comment.
The sweepFailedClients function uses a fixed-size stack array to_remove of size MAX_CLIENTS. While MAX_CLIENTS is currently small (8), this pattern is fragile if the limit is increased in the future. Additionally, since self.clients is a HashMap, the iteration order is undefined. If count were to reach MAX_CLIENTS (which it shouldn't given the current architecture), some failed clients might be missed in one pass. A more robust approach would be to use an ArrayList or simply perform the removal in a way that doesn't invalidate the iterator if the language/library supports it.
References
- Adhere to safe memory management and avoid potential stack overflows or logic errors when scaling constants. (link)
src/server.zig
Outdated
| // Initialize active_panes for all existing tabs | ||
| for (self.tab_manager.tabs, 0..) |maybe_tab, i| { | ||
| if (maybe_tab) |t| { | ||
| cs.active_panes[@intCast(i)] = pane_mod.firstLeafId(t.pane_tree.root); | ||
| } |
There was a problem hiding this comment.
Suggestion: New clients still default to tab index 0, but tab slot 0 can be null after earlier tab closes. composeForClient later calls activeTab(cs.active_tab) and will unwrap null, crashing the server. Pick a valid open tab during .hello while initializing active_panes. [null pointer]
Severity Level: Critical 🚨
- ❌ Server crashes on second client attach after closing tab 0.
- ❌ All existing multiplexed terminal sessions are terminated.
- ⚠️ Multi-client workflows become unreliable after tab reorganization.| // Initialize active_panes for all existing tabs | |
| for (self.tab_manager.tabs, 0..) |maybe_tab, i| { | |
| if (maybe_tab) |t| { | |
| cs.active_panes[@intCast(i)] = pane_mod.firstLeafId(t.pane_tree.root); | |
| } | |
| // Initialize active_panes for all existing tabs and choose a valid active tab | |
| var first_open_tab: ?u8 = null; | |
| for (self.tab_manager.tabs, 0..) |maybe_tab, i| { | |
| if (maybe_tab) |t| { | |
| const tab_idx: u8 = @intCast(i); | |
| cs.active_panes[tab_idx] = pane_mod.firstLeafId(t.pane_tree.root); | |
| if (first_open_tab == null) first_open_tab = tab_idx; | |
| } | |
| } | |
| if (first_open_tab) |tab_idx| { | |
| cs.active_tab = tab_idx; |
Steps of Reproduction ✅
1. Start the server via `main.zig:185-188`, which calls `server.Server.init` and then
`srv.run()` (event loop in `server.zig:316-439`).
2. Attach client A using the CLI, which eventually calls `client.run` in
`client.zig:18-47`; this connects to the socket and sends a `.hello` frame
(`client.zig:35-46`), handled by `handleClientFrame` at `server.zig:443-462`, creating the
initial session with tab index 0.
3. From client A, open an additional tab and then close the original tab at index 0: the
`.new_tab` command is handled in `server.zig:561-573`, calling
`tab_mod.TabManager.createTab` (`tab.zig:70-95`), and `.close_tab` is handled in
`server.zig:575-589`, which calls `tab_mod.TabManager.closeTab` at `tab.zig:97-118`.
`closeTab` deinitializes the pane tree and sets `self.tabs[index] = null`
(`tab.zig:104-106`), so `self.tabs[0]` becomes null while another tab (e.g. index 1)
remains open.
4. Attach client B: `client.run` again sends `.hello` (`client.zig:35-46`), which is
handled by `handleClientFrame` at `server.zig:443-462`. The `.hello` handler initializes
`cs.active_panes` for non-null tabs (`server.zig:452-457`) but does not change
`cs.active_tab`, which remains its default value 0 (`ClientState.active_tab` initialized
at `server.zig:130`). Immediately after, `handleClientFrame` calls
`self.composeForClient(cs)` (`server.zig:461`), and `composeForClient` uses
`self.tab_manager.activeTab(cs.active_tab)` at `server.zig:913-915`. Since `cs.active_tab
== 0` and `self.tabs[0] == null` after the earlier close, `TabManager.activeTab`
unconditionally unwraps `self.tabs[active].?` (`tab.zig:145-146`), causing a runtime panic
(null unwrap) and crashing the entire server process when client B connects.Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** src/server.zig
**Line:** 452:456
**Comment:**
*Null Pointer: New clients still default to tab index `0`, but tab slot `0` can be null after earlier tab closes. `composeForClient` later calls `activeTab(cs.active_tab)` and will unwrap null, crashing the server. Pick a valid open tab during `.hello` while initializing `active_panes`.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.|
CodeAnt AI finished reviewing your PR. |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (1)
.github/workflows/ci.yml (1)
53-82:security-auditが Critical 検出時にも成功終了します現状は warning 出力のみで、Line 71 の
Criticalパターンが検出されてもジョブが落ちません。重大な安全性後退をブロックできるよう、終了コードを返す分岐を追加するのが安全です。修正案(Critical 件数で fail)
total=0 + critical_total=0 audit() { local pattern="$1" level="$2" label="$3" local count count=$(grep -rn --include='*.zig' -e "$pattern" src/ 2>/dev/null | wc -l) if [ "$count" -gt 0 ]; then echo "| \`$label\` | $count | $level |" >> "$GITHUB_STEP_SUMMARY" total=$((total + count)) + if [ "$level" = "Critical" ]; then + critical_total=$((critical_total + count)) + fi fi if [ "$GH_EVENT" = "pull_request" ] && [ -n "$GH_BASE_REF" ]; then git diff --name-only "origin/$GH_BASE_REF" -- '*.zig' 2>/dev/null | while read -r file; do [ -f "$file" ] || continue grep -n "$pattern" "$file" 2>/dev/null | while IFS=: read -r line content; do echo "::warning file=$file,line=$line::[$level] $label: $content" done done fi } @@ echo "" >> "$GITHUB_STEP_SUMMARY" echo "**Total: $total** patterns tracked" >> "$GITHUB_STEP_SUMMARY" echo "_Not bugs — areas requiring careful review during changes._" >> "$GITHUB_STEP_SUMMARY" + if [ "$critical_total" -gt 0 ]; then + echo "::error::Critical security patterns detected ($critical_total)." + exit 1 + fi🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/ci.yml around lines 53 - 82, The audit function currently logs matches but never fails the job for Critical patterns; update the audit function (named audit and invoked for '@setRuntimeSafety\(false\)' with level 'Critical') so that when level equals 'Critical' and count is greater than zero it records the summary as now and then causes the step to fail (e.g., set a non-zero exit status or call exit 1 after writing to GITHUB_STEP_SUMMARY); preserve existing per-file warning emission for pull_request diffs and ensure the exit happens after emitting those warnings so PR annotations are still produced.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/workflows/ci.yml:
- Around line 24-26: The CI currently ignores zig fmt failures because the
"Format check" step has continue-on-error: true; update the "Format check" step
by removing the continue-on-error: true (or set it to false) so that running
"zig fmt --check src/" fails the job on formatting violations; locate the
"Format check" step in .github/workflows/ci.yml (the step that runs the command
"zig fmt --check src/") and change the continue-on-error setting accordingly.
- Around line 19-23: The "Install Zig" GitHub Actions step currently streams the
tarball via `curl -sL
"https://ziglang.org/download/0.15.2/zig-x86_64-linux-0.15.2.tar.xz" | tar -xJ`
and appends the extracted path to `$GITHUB_PATH` without any integrity checks;
replace this with a secure installation that verifies authenticity — either
switch to the maintained setup action (e.g., use the setup-zig action in place
of the manual curl/tar step) or, if keeping manual download, fetch both the
tarball and its checksum/signature, verify the checksum/signature before
extracting, and only then append the extracted directory to `$GITHUB_PATH` to
ensure tamper detection.
In `@src/server.zig`:
- Around line 576-580: When closing a tab we currently destroy panes but do not
remove per-pane client state entries (scroll_offsets), causing stale offsets to
leak and later be applied to new panes; update the tab-close path so that after
calling destroyAllPanesInTab(closed_tab) (or inside that function) you iterate
the pane IDs belonging to closed_tab and remove their entries from the
scroll_offsets map (the same cleanup close_pane performs), ensuring
scroll_offsets no longer contains any pane_id from the closed tab before calling
tab_manager.closeTab or returning.
- Around line 838-839: 現在は write_failed の回収が composeAll()
経由のみで行われており、.hello/タブ切替/スクロール/初期送信などの composeForClient() 経路で失敗した client
が残るため、composeForClient() で送信した直後にも必ず sweepFailedClients() を呼ぶように修正してください;具体的には
composeForClient() を直接呼んでいる箇所(accept 直後の
hello_ack/初期送信、タブ切替やスクロール送信の呼び出し)を共通の送信ヘルパーにまとめ、単一送信後に self.sweepFailedClients()
を実行するか、各 composeForClient() 呼び出しの直後で必ず self.sweepFailedClients() を呼ぶ処理(関数名:
composeAll(), composeForClient(), self.sweepFailedClients() を参照)を追加してください。
---
Nitpick comments:
In @.github/workflows/ci.yml:
- Around line 53-82: The audit function currently logs matches but never fails
the job for Critical patterns; update the audit function (named audit and
invoked for '@setRuntimeSafety\(false\)' with level 'Critical') so that when
level equals 'Critical' and count is greater than zero it records the summary as
now and then causes the step to fail (e.g., set a non-zero exit status or call
exit 1 after writing to GITHUB_STEP_SUMMARY); preserve existing per-file warning
emission for pull_request diffs and ensure the exit happens after emitting those
warnings so PR annotations are still produced.
🪄 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: 95fb8c0d-e942-4308-8c10-729d045f26d7
📒 Files selected for processing (3)
.github/workflows/ci.ymlsrc/pane.zigsrc/server.zig
| - name: Install Zig | ||
| run: | | ||
| curl -sL "https://ziglang.org/download/0.15.2/zig-x86_64-linux-0.15.2.tar.xz" | tar -xJ | ||
| echo "$PWD/zig-x86_64-linux-0.15.2" >> "$GITHUB_PATH" | ||
|
|
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, check the actual .github/workflows/ci.yml file
cat -n .github/workflows/ci.yml | head -30Repository: midasdf/zplit
Length of output: 822
🏁 Script executed:
# Search for the Zig installation section
rg -A 5 -B 5 "Install Zig" .github/workflows/ci.ymlRepository: midasdf/zplit
Length of output: 368
🌐 Web query:
mlugg/setup-zig GitHub action Zig version 0.15.2
💡 Result:
To install Zig 0.15.2 with mlugg/setup-zig in GitHub Actions, set the action’s version input to 0.15.2:
- uses: mlugg/setup-zig@v2
with:
version: 0.15.2The action supports release versions like 0.13.0 (and thus 0.15.2), plus latest, master, and specific nightly build strings. (github.com)
Citations:
Zig バイナリ取得に整合性検証がなく、サプライチェーンリスクがあります
Lines 21-22 の curl | tar はチェックサムおよび署名検証なしで実行されています。配布物改ざんやMITM攻撃時に検知できない状態です。
修正案(setup-zigアクション利用)
- - name: Install Zig
- run: |
- curl -sL "https://ziglang.org/download/0.15.2/zig-x86_64-linux-0.15.2.tar.xz" | tar -xJ
- echo "$PWD/zig-x86_64-linux-0.15.2" >> "$GITHUB_PATH"
+ - name: Setup Zig
+ uses: mlugg/setup-zig@v2
+ with:
+ version: 0.15.2📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - name: Install Zig | |
| run: | | |
| curl -sL "https://ziglang.org/download/0.15.2/zig-x86_64-linux-0.15.2.tar.xz" | tar -xJ | |
| echo "$PWD/zig-x86_64-linux-0.15.2" >> "$GITHUB_PATH" | |
| - name: Setup Zig | |
| uses: mlugg/setup-zig@v2 | |
| with: | |
| version: 0.15.2 |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/ci.yml around lines 19 - 23, The "Install Zig" GitHub
Actions step currently streams the tarball via `curl -sL
"https://ziglang.org/download/0.15.2/zig-x86_64-linux-0.15.2.tar.xz" | tar -xJ`
and appends the extracted path to `$GITHUB_PATH` without any integrity checks;
replace this with a secure installation that verifies authenticity — either
switch to the maintained setup action (e.g., use the setup-zig action in place
of the manual curl/tar step) or, if keeping manual download, fetch both the
tarball and its checksum/signature, verify the checksum/signature before
extracting, and only then append the extracted directory to `$GITHUB_PATH` to
ensure tamper detection.
| - name: Format check | ||
| continue-on-error: true | ||
| run: zig fmt --check src/ |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n .github/workflows/ci.yml | head -60Repository: midasdf/zplit
Length of output: 2009
zig fmt の失敗をCI失敗として扱ってください
Line 25 の continue-on-error: true により、フォーマット違反でも check ジョブが成功扱いになります。Format check の目的と逆動作です。
修正案
- name: Format check
- continue-on-error: true
run: zig fmt --check src/📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - name: Format check | |
| continue-on-error: true | |
| run: zig fmt --check src/ | |
| - name: Format check | |
| run: zig fmt --check src/ |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/ci.yml around lines 24 - 26, The CI currently ignores zig
fmt failures because the "Format check" step has continue-on-error: true; update
the "Format check" step by removing the continue-on-error: true (or set it to
false) so that running "zig fmt --check src/" fails the job on formatting
violations; locate the "Format check" step in .github/workflows/ci.yml (the step
that runs the command "zig fmt --check src/") and change the continue-on-error
setting accordingly.
… WouldBlock - Set active_tab to first valid open tab on .hello (codeant-ai: crash if tab 0 was closed before new client attaches) - Clean up scroll_offsets for all panes when closing a tab (coderabbitai: stale entries leak and affect reused pane IDs) - Run sweepFailedClients after composeForClient, not just composeAll (coderabbitai: single-client render paths left failed clients connected) - Only mark write_failed on WouldBlock after partial frame send; transient backpressure with no bytes sent just skips the frame (codex/gemini: too aggressive disconnection of briefly slow clients) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e3bb33dac6
ℹ️ 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".
| if (cs.write_failed) { | ||
| self.sweepFailedClients(); |
There was a problem hiding this comment.
Remove in-loop client sweep from composeForClient
composeAll iterates self.clients via valueIterator() and calls composeForClient for each client, but this new block calls sweepFailedClients(), which disconnects/removes entries from the same hash map. Mutating std.AutoHashMap during an active iterator walk can invalidate the iterator, so a write failure in one client can cause skipped renders, incorrect iteration, or use-after-free behavior in that same compose pass. Since composeAll already performs a sweep after the loop, this per-client sweep should be deferred instead of running inside the iteration.
Useful? React with 👍 / 👎.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
User description
Summary
close_tabto reject closing the last tab before destroying pane state, preventing irreversible state corruptionactive_panesfor all existing tabs on client.hello, and propagate new tab's focused pane to all clients to prevent cross-tab input misroutingSOCK_NONBLOCK) and auto-disconnect stalled clients to prevent one slow client from freezing the entire server event loopTest plan
zig buildcompiles without errorszig build testpasses all testssocatwith throttle) — server stays responsive for other clients🤖 Generated with Claude Code
CodeAnt-AI Description
Add CI checks and prevent tab and client failures from breaking sessions
What Changed
Impact
✅ Fewer session-corruption cases when closing tabs✅ Fewer cross-client input mix-ups✅ Fewer freezes from slow or broken clients💡 Usage Guide
Checking Your Pull Request
Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.
Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.
Summary by CodeRabbit
リリースノート
バグ修正
改善
Chores