Skip to content

fix(claude): let a Claude chat start again after its root exited with unverifiable descendants - #22802

Merged
brennanb2025 merged 8 commits into
mainfrom
brennanb2025/claude-reopen-after-root-exit
Sep 25, 2026
Merged

brennanb2025 merged 8 commits into
mainfrom
brennanb2025/claude-reopen-after-root-exit

Conversation

@brennanb2025

@brennanb2025 brennanb2025 commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 5 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​165 $\color{#cf222e}{\Huge{\mathbf{−}}}$​36 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​129
Prod 6 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​56 $\color{#cf222e}{\Huge{\mathbf{−}}}$​29 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​27

ELI5

Orca stops a Claude chat's background process after a while with nobody looking at it, and starts it again when you come back. When Claude's main process had exited but Orca couldn't confirm that every process it had started was gone, the chat could never be started again. Coming back showed "Could not load conversation", and every message failed until you restarted Orca. Now the chat starts again normally.

What Changed

  • Before: after an idle stop of a Claude chat where Claude's own process had exited but its child processes could not be verified, reopening the chat failed every time with agent_session_operation_invalid. The saved failure reads "provider close unproven". The pane showed "Could not load conversation", and sends failed too.
  • After: the chat re-attaches, resumes from its saved point, and works as before.
  • The same refusal had a second source: a Claude process that crashed with unverifiable child processes. The adapter told the host about a crash only once every child process was proven gone (or when startup failed), so this crash was never published: the chat stayed marked live, a message sent just before the crash never settled, every later send failed with the crash message, and nothing restarted Claude until the idle clock stopped the chat. The adapter kept the exit on record, and the next start of the chat checked it again and refused on the same "Claude itself exited" verdict. Now a crash whose own process was seen to exit is published like a proven one (observeClaudeSessionExit in claude-structured-session-exit-lifecycle.ts), so the host settles the turn, releases the chat and, while the chat is open, restarts Claude on its saved session at once. A crash during startup still waits for the next send, as before. A start that lands before that publication settles the recorded exit itself instead of refusing (resolveClaudeAcquisitionLaunch). Only an exit this host cannot vouch for (Claude's own process not confirmed gone) is still held back and still blocks the start.
  • A start that finds the chat's previous Claude process still recorded as live closes it first. If that close sees the root exit with unverifiable descendants, the session is now fully finalized before the verdict is reported, so the start goes ahead instead of failing once with "provider close unproven". Also in resolveClaudeAcquisitionLaunch.
  • Recovering from a failed journal write closes the Claude process too, and it read that same verdict as a failure while idle eviction read it as a stop. With the adapter now ending the session before it reports the verdict, that left the host holding a Claude process the adapter had already ended, so sends failed until the chat was evicted. One function, stopAgentSessionProviderRoot in structured-agent-session-adapter.ts, now reads a stop's result for idle eviction, journal-failure recovery and the adapter's own start over a still-recorded session, so they cannot disagree again. Only Claude reports this verdict from a close, so other agents are unaffected.
  • Mechanism, finalizeClaudePublishedSession in claude-structured-session-close.ts: when a close sees the root exit but cannot prove the descendants gone, the host already treats it as stopped. It releases the session's lease and forgets the session (fix(native-chat): release sessions after provider root exit #20502: the lease follows the provider root). The Claude adapter, however, returned early and kept its own session entry. Each later start of that chat first tried to close that stale entry again, got the same verdict, and threw. The close now finishes like a proven close: it saves the resume point, emits the end, and drops the entry, and it still reports the root-exit verdict to the caller. Only a genuinely unknown exit, where the root itself is unverified, stays indexed for a retry.

Why

The host and the adapter disagreed about whether the session was over. The host's rule is the deliberate one from #20502: seeing the provider root exit first-hand is enough to release a root-owned lease. The adapter was the side contradicting it, so the fix is to make the adapter agree, not to add a retry or a special case at re-attach.

Alternative considered: tolerate the root-exit verdict at re-attach and drop the stale entry there. That leaves the session half-finalized: no end event, no saved resume point, and a translator still bound. It also has to be repeated at every place that closes a stale session.

What this does not change: a Claude process the host has not seen exit, or one with a child process seen still running, still fails closed everywhere.

Linked Issue

No separate issue. Found in live QA of #22794 and #22801: the first chat the idle clock stopped on desktop could not be reopened. It is reachable on main today wherever the idle clock stops a Claude chat, for example after a phone leaves a chat. #22801 would make it reachable from every desktop chat you leave, so it must land before #22801.

Visual Proof

Live Electron QA on an isolated dev instance (hidden window, CDP), macOS, real Claude Code sessions. The idle window was shortened to 45 s in the QA build only. "Before" builds swap in one file set from main at a time and restart the app. Process liveness comes from ps on the provider pid the app spawned.

Before (this fix removed): stop, come back, send After: stop, come back
before after
  • Before: the provider was stopped at +60 s after leaving. On return, sending failed with "The provider stopped before it finished starting: provider close unproven." / "Claude couldn't restart: provider close unproven.", and no new provider process started. The first QA run on the stack without this fix also showed "Could not load conversation".
  • After: the provider was stopped at +60 s. On return the history is intact, the send is answered, and a new provider process is running.

Testing

  • claude-structured-session-close.test.ts: a close that sees the root exit with unverifiable descendants still rejects with the root-exit verdict. A second acquisition of the same chat then opens a new connection, and the old one is not closed again. Fails without the fix with "provider close unproven".

  • claude-structured-session-close.test.ts: a start over a still-recorded session whose close sees the root exit opens a new connection, and the old session ends exactly once. Fails without the start-side change with "provider close unproven", and without the close change because no end is emitted.

  • claude-structured-session-adapter.test.ts: a crash whose root exited with unverifiable descendants publishes its end to the host, and a later release reports the session stopped. A start made before that publication opens a new connection instead of refusing. Each fails without its change.

  • claude-structured-session-integration.test.ts: production-wired host. With the chat open and a message in flight, the same crash settles that message as "exited before acknowledgement", restarts Claude on the saved session, and the next send is accepted by the new process. Without the publication change the in-flight message never settles and the test times out.

  • structured-agent-session-surface-lifetime.test.ts: a failed journal write whose stop reports the root-exit verdict still settles the exit and releases the lease. Fails without the recovery change.

  • Each production change was reverted on its own and a test above failed for each. The eviction change only moves existing logic into the shared function, so reverting it stays green; removing the function's tolerance there fails the existing root-exit eviction test and the reopen test.

  • claude-structured-session-integration.test.ts: production-wired host and RPC. Create a Claude chat, stop it with that exit verdict, and hold it again as a returning chat surface does: a new provider connection starts and the session is back. Fails without the fix with agent_session_operation_invalid, the same failure seen in the live app.

  • The existing root-exit eviction test now asserts that the adapter agrees the session is over after eviction; it used to assert that the crash record was kept. The Claude adapter suites (including the real-CLI suite), the integration suite and all 113 structured-session host test files pass: 1880 tests. There are two exceptions. "leaves unlisted shell exports out when inheritance is off" fails identically without this change: my shell's own Anthropic key leaks into it. The real-CLI "proves a pre-minted session" test needs a local Claude CLI and fails on main too.

  • pnpm tc:node, oxlint and check:code-quality:changed are clean.

  • I manually tested these changes locally

  • Automated tests added/updated, or explained why not below

AI Disclosure

Review

Agent skill upstream boundary

  • Not applicable, or this change follows docs/reference/agent-skill-sharing-upstream-boundary.md and copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.

Notes

  • Quit: a Claude chat stopped this way no longer makes the adapter's shutdown report "could not prove every child stopped", because its entry is finalized on the first close.
  • Deviation from fix(native-chat): release sessions after provider root exit #20502: that PR noted "later cleanup still preserves that uncertainty" about descendants, and kept both a stopped session's entry and a crash's exit record to carry it. Neither is kept now. A later close of a kept record did re-run the process-tree check and signal any descendants it still found, but the only later closes were the idle stop, which released the lease on the root exit anyway, the next start of the chat, which it refused, and quitting Orca. The lease had already moved on with the root, so keeping the record traded a repeat of the check the first close already ran for a chat that could not start or recover.
  • SSH/WSL: this is execution-host adapter state. No wire change. Mobile benefits too.

Checklist

  • This PR is small and focused
  • I explained what changed and why (ELI5, the user-facing before/after, the mechanism, and why over the alternatives)
  • Before/after screenshots or videos attached for UI changes, or N/A with reason
  • Self-reviewed for correctness, security, and performance
  • Cross-platform, SSH/remote, and path/shortcut impact considered (or N/A)
  • pnpm lint, pnpm typecheck, pnpm test, and pnpm build pass (or CI will cover; local preferred)

…gain

When the idle release clock stopped a Claude chat whose root process exited but whose descendants could not be verified, the host released the lease and forgot the session, as designed. The adapter, though, kept its session indexed as not yet closed. Every later start of that chat first tried to close the stale session again, got the same verdict, and was refused with "provider close unproven". The chat then read as "Could not load conversation" until the app restarted.

A proven root exit or processless close now finalizes the adapter session like a proven close: it persists the resume point, emits the end, and drops the entry, and it still reports the verdict to the caller. Only a genuinely unknown exit stays indexed for a retry.
…rt again

The same refusal had a second emitter. A Claude root that crashed with unverifiable descendants stays recorded as an exit, and the next start of the chat re-checked that exit and refused on the root-exit verdict, although that verdict is what let the host release the lease. The start now proceeds and settles the recorded exit; only an exit this host cannot vouch for still blocks it.
@brennanb2025 brennanb2025 changed the title fix(claude): let a chat stopped with unverifiable descendants start again fix(claude): let a Claude chat start again after its root exited with unverifiable descendants Sep 25, 2026
… exit go ahead

Closing the previous session finalizes it before reporting the root-exit verdict, so the start
that closed it must not fail on that verdict, the same as a retained root exit.
…op site

Idle eviction already treated a stop whose provider root was seen to exit as a stop, but handing a chat to the terminal and recovering from a journal write failure treated the same verdict as a failure. Now that the Claude adapter finalizes the session before reporting that verdict, those two paths left the host holding a child the adapter had already ended: the first hand-off failed with "provider close unproven" and sends failed until the chat was evicted.

One function now reads a stop's result for eviction, hand-off, sink-failure recovery and the adapter's own start-over-a-live-session path.
…nts went unverified

A Claude crash was published to the host only once its whole process tree was proven gone, or when it failed during startup. A crash whose root was seen to exit but whose descendants could not be verified was held back, so the chat stayed marked live: sends failed with the crash message and nothing restarted Claude until the idle clock stopped the chat. The owner already releases the lease on a first-hand root exit, so the crash now publishes like a proven one and the host reconciles and recovers at once.
…ants went unverified

The crash-publication test only asserted the lease was released, so nothing showed the restart the fix exists for. It now holds the chat as an open surface does and asserts Claude comes back on the saved session with a live lease.
…ss a root-exit crash restart

The restart test now also covers the sends around the crash: a message Claude took but never echoed settles as exited before acknowledgement instead of waiting forever, and a send after the restart is accepted by the new process.
@brennanb2025

Copy link
Copy Markdown
Contributor Author

Review status

The chat-reopen bug is fixed and verified in automated tests. Code review found no remaining problems. Live Electron QA is still outstanding: screenshots will be attached from the separate QA run.

What the PR fixes

  • Idle stop, then reopen: a Claude chat that Orca had stopped, where Claude's own process had exited but its child processes could not be verified, could never be started again. Reopening it showed "Could not load conversation" until Orca was restarted. It now resumes from its saved point.
  • Crash while the chat is open: a crash of the same kind is now reported straight away. The in-flight message settles as "the provider stopped while this response was in progress". Claude restarts on the saved session, and the next message is delivered. Before, the in-flight message never settled, and every send failed until the chat was idle-stopped.
  • Handoff and recovery: handing the chat to the terminal, and recovering from a journal write failure, now treat that same stop as finished instead of failing.

What review changed

  • The Claude adapter now fully ends a session (saves the resume point, emits the end event, drops its record) before it reports that Claude's own process exited. Before, it reported first and kept the record, so every later start was refused.
  • Starting a session over an old one, whether still live or crashed, now proceeds on this verdict.
  • One host function, stopAgentSessionProviderRoot, now reads a stop's result for idle eviction, terminal handoff, journal-failure recovery and start. Before, eviction had its own copy of this check, and handoff and recovery were missing it.
  • A crash where Claude's own process exited is now reported to the host even when its child processes can't be verified. This drops the rule, older than fix(native-chat): release sessions after provider root exit #20502, that kept such crashes on record, a record nothing could ever clear. The PR body records the deviation from fix(native-chat): release sessions after provider root exit #20502.
  • The tests now cover each of these. With any one production change removed, a test fails. The one exception is the eviction change, which only moves existing logic into the shared function.

Deliberate behavior change

Child processes that couldn't be verified at the first cleanup are not signalled again later. A leftover background command can keep running while the restarted Claude works. That was already the case after an idle stop followed by a reopen.

Validation

  • Across all Claude structured-session and session-host test files (real-CLI suites excluded), 1,860 tests pass. The shell-exports test, which fails on main too because of a local environment leak, was checked separately.
  • pnpm tc:node, oxlint and check:code-quality:changed are clean. The PR adds no new files.
  • Readiness checklist, run at the start and end of the review: every item passed.
  • Not covered by this review: live Electron QA, which runs separately. CI on the latest head was still running when this was posted.

Known gaps, left for a follow-up PR

The follow-up makes a stop return its result as a value instead of throwing an error after it succeeds. That closes two narrow windows:

  • A retry while a previous start is still shutting down can be refused with "exit unproven".
  • Closing a kept crash record reports the result before cleaning up.

Older issues, not caused by this PR

  • There is no limit on automatic restarts after a crash that follows a successful startup. This PR puts the new crash case on the same path as other crashes.

@brennanb2025

Copy link
Copy Markdown
Contributor Author

Live Electron QA (whole stack)

Isolated dev instance (hidden window, driven over CDP), macOS, real Claude Code sessions. The idle window was shortened to 45 s in the QA build only. A "before" build swaps one fix's files back to main and restarts the app. Liveness is ps on the provider pid the app spawned. Screenshots are in each PR's Visual Proof.

Scenario Build Result
Leave a finished chat (switch worktree) stack head 2c7ab9991b provider ALIVE +30 s, DEAD +60 s. On return: history intact, new provider starts, the next send is answered. Pass
Same without #22801 provider still ALIVE at +30/+60/+90/+150 s (never released). Old behavior reproduced
Background sleep 150 left running, then leave stack head 2c7ab9991b provider ALIVE +30…+150 s while the command runs. Command finishes, provider DEAD by +180 s. On return: task done, new send answered. Pass
Same without #22794 provider and sleep both DEAD at +60 s. Chat shows "Background task stopped · didn't finish before the previous session ended". Old bug reproduced
Leave, idle stop, come back without #22802 "Claude couldn't restart: provider close unproven" and no new provider. An earlier run showed "Could not load conversation". Old bug reproduced

The scenario that crashes Claude mid-chat was not driven live; the #22802 integration tests cover it. Windows, Linux and SSH were not run live: the changes are host-side and not platform-specific, and no wire format changed.

@brennanb2025
brennanb2025 marked this pull request as ready for review September 25, 2026 11:20

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

  • Adapter now agrees a root-exit close is final (claude-structured-session-close.ts): finalizeClaudePublishedSession persists the resume cursor, emits ended, and drops the session entry when the close returned false with a root-exit-observed or processless verdict, then re-throws the verdict; only a genuinely unknown exit stays indexed. A later close short-circuits on closeFinalized, so the stale entry no longer refuses every subsequent start.
  • Start proceeds over a stopped/released session (claude-structured-acquisition-launch.ts): the launch wraps close with stopAgentSessionProviderRoot, and a retained exit that cannot be proven is settled instead of throwing unless the verdict is genuinely unproven.
  • Crash with unverifiable descendants is published (claude-structured-session-exit-lifecycle.ts): dropping the startupFailed qualifier means any first-hand root exit settles the in-flight turn and restarts an open chat; startup crashes keep startupUnproven and still wait for the next send.
  • One normalized stop reading (structured-agent-session-adapter.ts): new stopAgentSessionProviderRoot treats root-exit/processless as stopped and rethrows everything else (known-live descendants stay unproven), wired into idle eviction, terminal hand-off, journal-sink recovery, and the adapter's own start.
  • Tests: adapter, close, root-exit eviction, surface-lifetime, and integration suites cover the reopen, hand-off, crash-restart, and journal-failure paths.

Verification performed in this review

  • pnpm test on the five changed test files: 83 passed.
  • pnpm tc:node: clean.
  • Reverted the observeClaudeSessionExit change in isolation and re-ran the adapter + integration suites: 5 tests failed, confirming the new tests actually pin the publication behavior.

The only noteworthy tradeoff — a retained root-exit record is no longer kept, so a later close no longer re-runs the tree check on leftover descendants — is deliberate and documented in the PR body. tree: 'live' still fails closed at every site.

Pullfrog  | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

@coderabbitai

coderabbitai Bot commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: c9974a0e-ded7-492c-b364-27e0fb5090c7

📥 Commits

Reviewing files that changed from the base of the PR and between f5d2ce5 and 7b41824.

📒 Files selected for processing (12)
  • src/main/claude/claude-structured-acquisition-launch.ts
  • src/main/claude/claude-structured-session-adapter.test.ts
  • src/main/claude/claude-structured-session-close.test.ts
  • src/main/claude/claude-structured-session-close.ts
  • src/main/claude/claude-structured-session-exit-lifecycle.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-adapter.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-claude-root-exit.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-event-recovery.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-eviction.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-host-handoff.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-surface-lifetime.test.ts
  • src/main/runtime/claude-structured-session-integration.test.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

A shared helper now interprets provider-root stop results across eviction, event recovery, and host handoff. Claude session closing retains proven root-exit or processless verdicts until finalization completes. Observed root exits can settle as unexpected exits even when descendant closure is unproven. Tests cover reacquisition, session handoff, journal-sink recovery, and recovery after a crash during send.

Priority: ➖ Normal

Merge Risk: ⚪ Minimal · up to 7b418

The changed exit handling supports restarting Claude after a confirmed root exit, and no merge-blocking issue remains identified.

Security Architecture Review

Security architecture risk: 🟡 Moderate · up to 7b418

A chat can now restart or hand off after Claude’s main process exits even when its other processes cannot be verified. A known-running child still blocks release, but the remaining processes’ access in the unverifiable case has not been established.

Retained concerns

  • Medium · security · inferred: An observed provider-root exit can now lead to automatic recovery or handoff while descendants remain unverifiable. If a descendant survives with workspace or account authority, the replacement owner may operate alongside it; descendant containment at that transition is not proven.
Security review details

Security Blast Radius

  • inferred — The plausible independently affected scope is a local Claude session, its workspace, and its selected account—not an evidenced new service-wide or cross-tenant entrypoint. Whether user-influenced background processes can retain those capabilities after root exit is unresolved.

Security Findings and Attack Paths

  • inferred — If a provider descendant survives an unverifiable verdict with independent workspace or account access, automatic release and reacquisition could overlap its activity with a replacement provider. The inspected evidence establishes the ownership transition, not an actual surviving descendant or exploitable credential path.

Trust Boundaries and Controls

  • observed — The reaper requires a snapshot taken while the root was alive and revalidates descendant identity before signaling on POSIX. An absent post-exit snapshot remains unverifiable; the shared stop helper does not treat known-live or otherwise unproven root outcomes as success.

Resilience and Maintainability Implications

  • observed — Session finalization settles pending permission prompts and dispatch waiters, persists the resume point, and emits an ended event. Host recovery serializes replacement and checks its recovery ticket, limiting stale host events even though these controls do not prove descendant containment.

Hardening Proposals

  • proposed — Establish whether a surviving Claude descendant can retain account, workspace, or tool authority after root exit. If it can, contain or revoke that authority before treating an unverifiable-tree verdict as sufficient for replacement or handoff.
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 10 functions across 12 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ⚠️ Warning The description explains the user impact, mechanism, rationale, testing, visual proof, and cross-platform considerations. However, the required Linked Issue section does not provide a linked issue in … Add the issue reference that this pull request fixes, using the required Fixes #<issue-number> format. Confirm the final CI status or explain which checklist commands CI will cover.
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly identifies the main fix: allowing Claude chats to restart after the root process exits while descendant processes remain unverifiable.
Full details: Description check

Explanation

The description explains the user impact, mechanism, rationale, testing, visual proof, and cross-platform considerations. However, the required Linked Issue section does not provide a linked issue in the required Fixes #... form.

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Main removed the terminal handoff (#22783), so its root-exit stop reading and the
handoff integration test are dropped with it.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

Since the prior pullfrog review, this PR merged origin/main (d443320), which removed the terminal handoff subsystem (#22783). The net change to this PR is a scope reduction: the stopAgentSessionProviderRoot wiring at the now-deleted terminal hand-off suspendNative site and its handoff integration test are dropped.

  • Dropped the obsolete hand-off stop site (structured-agent-session-host-handoff.ts): the file is gone upstream, so its stopAgentSessionProviderRoot wiring went with it. The three remaining production stop sites — idle eviction, journal-sink failure recovery, and the adapter's own start — still route through the shared helper.
  • Dropped the corresponding integration test (structured-agent-session-surface-lifetime.test.ts): the "hands a chat to the terminal…" case exercised the removed suspend path; nothing replaces it because the path no longer exists.

All other production and test changes are byte-for-byte identical to the version already reviewed and approved. The merge did not silently drop any intended change, and the newly-added tests still compile and pass against the merged tree.

One stale-prose note for whoever edits the description: the PR body still lists structured-agent-session-host-handoff.ts suspendNative as one of the wired stop sites. Code and tests are correct; only the prose needs the bullet removed.

Verification performed in this review

  • pnpm test on the five changed test files: 80 passed.
  • pnpm tc:node: clean.

Pullfrog  | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant