Skip to content

Attach to an already-running detachable Lich session - #2

Open
kahlen-tech wants to merge 12 commits into
elanthia-online:mainfrom
kahlen-tech:attach-mode
Open

Attach to an already-running detachable Lich session#2
kahlen-tech wants to merge 12 commits into
elanthia-online:mainfrom
kahlen-tech:attach-mode

Conversation

@kahlen-tech

Copy link
Copy Markdown

Attach to an already-running detachable Lich session

What this adds

A third connection mode beside Lich-launch and Direct: attach to a Lich that
is already running and logged in
— one started as
lich --login Char --headless 8001, or with any --detachable-client= flag.

A ⇋ Attach button in the launcher top bar opens a three-field modal
(character / host / port). No account, no password, no Ruby or Lich paths:
headless Lich authenticated itself from its own saved entry, and its listener
takes a bare TCP connection.

Why it is worth having, as a player: closing Lichborne currently means logging
out. With attach, a session survives the client — close the window and reopen
it without losing your place, recover from a front-end crash without losing
the login, pick the same session up from another machine, or watch it from a
second front-end alongside the first.

Why the Lich side is already done

Everything needed exists in current lich-5 — verified in source, not assumed:

  • --headless PORT normalizes to --without-frontend --detachable-client=PORT
    (lib/main/arg_normalization.rb). The listener accepts a plain TCP
    connection: no auth, no handshake (docs/runtime-io.md,
    lib/main/main.rb detachable_client_thread).
  • On accept, Lich pushes a state resync — vitals, prepared spell, indicators,
    compass (lib/global_defs.rb detachable_client_send_init) — then the live
    stream. Game output reaches attached clients through send_to_client
    (lib/games.rb), so the feed is the same one a normal front-end sees.
  • Multiple front-ends may attach at once, and a detachable client dropping does
    not end the session (docs/runtime-io.md).
  • The sharp edge: a user-exit command from an attached client runs a full
    orderly shutdown of the whole session
    (lib/main/user_exit_dispatch.rb#dispatch_detachable_client) — which dictates
    the disconnect semantics below.

The hard constraint also lives in Lich: only an attachably-started Lich can be
attached to. A normally-launched one accepted its single front-end and closed
its listener, so this cannot (and does not try to) attach to those.

What the patch does

Twelve commits, ~1210 insertions across 18 files. The transport is small; most
of it is fitting the session lifecycle.

  • AttachConnection (new) — the transport. Free of electron imports so a
    plain-node harness can exercise the protocol. Never sends a login key or
    FE:WRAYTH line (either would be dispatched to the game as a command), and
    never QUIT. TCP keepalive at 30s: an attach target is often not loopback,
    and an idle connection through NAT gets reaped by intermediaries that tell
    neither end.
  • ConnectionManager — mode 'attach', connectAttach() with an
    ECONNREFUSED → "start Lich attachably" translation and a post-attach look
    (Lich's resync covers everything except the room). gracefulDisconnect
    detaches in this mode: half-close, no QUIT, for both the in-tab
    Disconnect and app shutdown. Typing exit stays the deliberate log-out.
  • main.tsCH.LOGIN_ATTACH mirroring CH.LOGIN's lifecycle, including
    the hold-for-replay (the attach-time resync would otherwise be flushed into a
    window with no GameWindow subscriber). useLich: true keeps the Lich Scripts
    panel and the rest of the Lich-only surface alive. Auto re-attach on an
    unclean drop, backoff 2/4/8/15/30s then a 30s heartbeat, reconnecting in
    place
    so the tab, scrollback and panels survive.
  • Target persistenceCharacterProfile grows an optional launcher-owned
    attach?: { host, port }, written on each successful attach via the
    setCharacterGame-style read-modify-write. It drives a tile ⋯ menu entry, the
    modal's prefill, an attach-first tile Connect button (falling back to a normal
    login when nothing is listening and the tile has a real account), the tab's
    Reconnect, and the bulk paths. planReconnect gains an attach branch that
    bypasses the account arithmetic — those rules protect a login from DR's
    one-per-account law, and an attach starts no login.
  • RendererAttachModal reuses the cne-* modal chrome; the launcher
    button threads through LauncherTopBar. Account and game resolve from the
    character's existing profile when there is one, so the roster, the
    one-per-account planner and the ambient profile export stay truthful.

Two changes worth your specific attention

1. The one shared-code change. GameWindow's status handler cleared its
dropped flag only on s.connected && s.message === 'Connected' — so the
connected flag was decorative and a human-readable string was load-bearing.
Attach sends 'Attached' / 'Re-attached', so the tab stayed greyed out while
game text streamed into it. Now keyed on s.connected alone, which is safe by
construction: main sends connected: true only from a genuine connect, because
every progress line goes out as connected: false. The mirror-image
!s.connected && s.message === 'Disconnected' check is deliberately left alone
— there the string does real work, separating a final drop from the progress
lines before a successful connect. This is arguably a latent fix for any future
connect path, but it is the change most likely to surprise you, so it is its own
commit.

2. A DR-specific vitals-resync fix. Lich's init hardcodes value='0' and
puts the numbers only in text — and in DR that text is health 100/, with no
max. Lich derives max_health by scanning numbers out of DR's own bar text,
DR sends a percentage (text='mana 86%', captured live), one number is found,
and the nil interpolates to empty. GS sends health 100/100, so the shape only
bites DR. The parser now takes the first number and treats a missing/zero max as
100, gated on value === 0 so live bars are untouched. You may prefer to fix
the nil upstream in Lich instead
— this handles both either way.

Verification

  • tsc on both tsconfigs: no new errors vs. v0.19.2 (main matches the stock
    baseline exactly, including its one pre-existing error; renderer clean).
    npm run build passes.
  • Four machine-local harnesses, in the style CLAUDE.md describes for
    reconnectPlan:
    • the transport against a fake detachable-Lich listener — no unprompted
      bytes on attach
      , zero bytes on detach (no QUIT), re-attach accepted;
    • drop/recovery: the listener killed mid-session and restarted, covering drop
      detection, repeated refused attempts, a fresh resync, and no spliced partial
      line across sockets;
    • planReconnect's attach branch, with regression cases pinning the
      login-mode dedup / already-on / conflict-row rules unchanged;
    • the vitals resync against both the DR and GS forms, plus live-bar,
      customText-label and zero-vital regressions.
  • Live play on DragonRealms — several attached characters at once, local
    and over the network, through ordinary play including combat. Every bug fixed
    after the first commit was found that way, not by reading code.

Known edges, left for your call

  • An attach-only character (never added through the wizard) gets a minimal stub
    profile under an attach placeholder account, so it has a tile to reconnect
    from. Reasonable, but it is a design choice.
  • A --genie-flavoured headless Lich sends no attach-time resync at all (Lich
    skips init for genie sessions) and suppresses stream tags, since genie is
    registered without the streams capability. Plain --headless is the shape
    to recommend.
  • Auto re-attach has no attempt cap by design: the session outlives the client,
    so the view keeps trying for as long as the tab is left open, and a cap would
    mean giving up exactly when the player wanted it back. Easy to put behind a
    setting if you would rather it were opt-in.
  • Attach targets could be auto-discovered from Lich's session descriptor files
    ({name, host, port} JSON written per character when detachable), which would
    remove even the first-time host/port entry and the risk of mislabelling a tab
    by typing the wrong name. Deliberately not attempted here.
  • Unrelated, spotted in passing: Edit Profile… has the same latent z-index bug
    the Attach modal had — opened from the compact launcher inside the Add
    Character modal, it renders behind the backdrop. Left alone as pre-existing.

Housekeeping

Built AI-assisted (Claude) against CLAUDE.md's conventions — the one-list IPC,
the hold-for-replay pattern, cne-* modal chrome, read-modify-write profile
writes, and comment provenance. Happy to rework naming, placement, the
Tracker.md / CLAUDE.md entries, or anything else to fit — or for you to take the
patch and reshape it however you like.

claude added 12 commits August 29, 2026 23:57
A third connection mode beside Lich-launch and Direct: point a tab at the
listener of a Lich started attachably (lich --login Char --headless PORT,
or any --detachable-client= launch) and render the session that is already
logged in. No SGE, no password, no spawn — Lich's detachable listener takes
a bare TCP connect (no auth, no handshake; lich-5 main.rb
detachable_client_thread → global_defs.rb handle_detachable_client), pushes
a Stormfront-XML state resync (vitals / spell / indicators / compass), and
treats every line we write as typed client input.

- AttachConnection: the transport. Electron-free on purpose so the protocol
  is exercisable by a plain-node harness against a fake listener. Never
  sends a login key or FE:WRAYTH line (they would dispatch to the game as
  commands), and never QUIT.
- ConnectionManager: mode 'attach', connectAttach() with a friendly
  ECONNREFUSED translation and a post-attach `look` nudge (Lich's resync
  covers everything except the room). gracefulDisconnect DETACHES in this
  mode — half-close, no QUIT — because from an attached client Lich runs a
  user exit as full-session shutdown for every attached front-end. Typing
  `exit` in the tab remains the deliberate log-out path.
- main: CH.LOGIN_ATTACH mirrors CH.LOGIN's lifecycle (hold-for-replay so
  the attach-time resync isn't dropped before the GameWindow mounts,
  roster, progress mirroring). useLich=true keeps the Lich Scripts panel
  and the rest of the Lich-only surface alive for attached tabs.
- renderer: '⇋ Attach' in the launcher top bar → a three-field modal
  (character / host / port). Account+game resolve from the character's
  existing profile YAML when one exists, so the roster, the one-per-account
  conflict planner, and the ambient profile export stay truthful; the
  per-character profile (layout, highlights, macros, theme) loads exactly
  as on a normal connect.

Known draft edges, deliberately out of scope: the tab menu's Reconnect
runs a full relaunch login rather than a re-attach; an attach-only
character's ambient profile save creates a tile under the 'attach'
placeholder account; a headless Lich started with --genie sends no
attach-time resync (Lich skips init for genie-identity sessions).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RES15zXfaUZZjD8PVz9ixy
… one-click and in-tab re-attach

The first cut attached but forgot: closing a tab (or the app) left no way
back except retyping host/port. Now the target is remembered and every
reconnect surface re-attaches:

- CharacterProfile grows a launcher-owned `attach` field ({host, port}),
  written on every successful attach via saveCharacterAttach — the same
  read-modify-write shape as setCharacterGame (buildCharacterProfile would
  wipe a non-active character's state). For an attach-only character it
  creates a minimal stub profile, whose tile IS the reconnect surface.
  exportCharacterProfile's preserve list learns the field so ambient saves
  can't strip it.
- Tile ⋯ menu gains "⇋ Attach (host:port)" when a saved target exists.
- The Attach modal opens prefilled with the last successful attach
  (lichborne.attach.last) and autofills host/port when a typed name matches
  a profile-saved target.
- The tab's Reconnect re-ATTACHES for attach sessions instead of relaunching
  a login (which would spawn a second Lich against an account whose headless
  session is still logged in — DR bounces one of them). Identity is pinned
  from the session record so the revived tab keeps its characterId and
  replaces itself rather than opening a second tab.
- The attach target rides main's session meta and the roster, so a
  decoupled / re-homed window inherits the re-attach path.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RES15zXfaUZZjD8PVz9ixy
…back

Clicking Connect on a tile that carries a saved attach target used to run
the normal login flow — which for an attach-only stub tile can only dead-end
in the Add Account wizard asking for a password that doesn't exist. Connect
now means "put me in that running session" for these tiles:

- handleCardConnect branches before the same-account conflict modal: that
  guard protects a NEW login against DR's one-per-account law, but an attach
  joins a session that's already on — and stub tiles all share the 'attach'
  placeholder account, so it would cross-flag unrelated characters.
- Per-character handling replaces it (prepareTileAttach, shared with the ⋯
  menu path): a connected tab for the character is focused instead of
  double-attached (the protocol allows it; the characterId replace would
  orphan the live record), a dead one is torn down so the revived session
  replaces it cleanly.
- When NOTHING is listening at the target, the click still means "get me in
  the game": a real account falls through to the normal launch-and-login
  flow; a stub tile surfaces the banner (no login to fall back to).
- The card button says what it does — "⇋ Attach" with the target in the
  tooltip — and the 1.5s grace/Cancel overlay works for attach too (a cancel
  that loses the race destroys the landed session, which for attach mode is
  a detach: the running Lich is untouched).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RES15zXfaUZZjD8PVz9ixy
Reconnect Last ran every saved character through the login flow, so an
attach tile died on "No saved password" (a stub has none) — and even a real
account would have been starting a SECOND Lich against a headless session
still logged in. Two fixes, one in the pure planner and one in the batch:

- planReconnect: an attach pick bypasses the account arithmetic. All three
  account rules exist to protect a LOGIN from DR's one-per-account law; an
  attach starts no login, so no conflict row and no one-per-account batch
  dedup. The dedup was load-bearing, not cosmetic: every attach-only stub
  shares the 'attach' placeholder account, so it dropped all but the FIRST
  and "Reconnect Last (3)" revived one character. Attach picks still skip
  when already on, matched by CHARACTER (a stub's placeholder account never
  matches a real roster account). Login-mode rules are unchanged and
  regression-locked by the harness.
- runBulkConnect: saved-target characters route through the new shared
  tryAttachPick — also used by the tile Connect button, so the "nothing is
  listening" fallback judgement (log in normally when the tile has a real
  account; a clear failure when it doesn't) cannot drift between the two
  entry points. Attached sessions honour "open each in its own window" like
  any other; a focused already-open tab reports no sessionId, so nothing the
  player already had open gets moved.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RES15zXfaUZZjD8PVz9ixy
Attaching a SECOND character while one was connected was impossible without
closing every open session first — the modal you get from the `+` tab had no
Attach control, and even wiring one in would not have worked. Two separate
faults:

1. NO ENTRY POINT. LauncherTopBar (which holds "⇋ Attach") renders only when
   !compact, and the Add Character modal renders the launcher compact. The
   onAttach prop was passed and silently dropped. Compact now gets
   CompactAttachRow — one button, not the whole bar, since compact
   deliberately sheds the logo/headings/chrome. A tile with a saved target
   was already attachable there via its own Connect button; what was missing
   is attaching a character Lichborne has never seen.

2. WRONG STACKING CONTEXT. AttachModal reuses CharacterNotesEditor's cne-*
   chrome and inherited its z-index of 100 — below .add-character-modal
   (1000). Opened from inside that modal it rendered BEHIND the backdrop, so
   the new button would have looked dead. `attach-backdrop` lifts it to 1600:
   above the launcher-connecting overlay (1500), below QuickSend (2000).
   Precisely the bug .launcher-connecting already documents, so the fix
   matches it. Edit Profile… has the same latent bug from the same
   inheritance; left alone as pre-existing and unrelated.

Verified the compiled bundle carries both rules.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RES15zXfaUZZjD8PVz9ixy
Reported as "not saving a connection tile for attached accounts" — the tile
WAS saved. Launcher account sections default to COLLAPSED for multi-account
users, and an attach-only character's stub profile is filed under the
'attach' placeholder account, i.e. a brand-new section the player had never
opened. Correct YAML on disk, correct card from loadCharacterCards, nothing
on screen: indistinguishable from the feature doing nothing.

AddCharacterWizard already solves exactly this for wizard-created tiles by
adding the new account to lichborne.launcher.expandedAccounts before bumping
refreshKey. Attach creates tiles too, so it now does the same — including
the wizard's 1→2 transition guard, since a player with one account sees it
expanded by the single-account rule and would otherwise watch it collapse
the moment 'attach' became the second.

Only on stub CREATION; re-expanding on every attach would fight a player who
deliberately collapsed the section.

Also: a failed profile write now raises a toast instead of a console line.
It produced the identical symptom — no tile, no reason — and the attach
itself has succeeded by that point, so it is a toast, not an error banner.

Verified end-to-end by bundling the real Launcher functions against the real
main-process profile store (harness in the proposal bundle): profile
written, card produced, section expanded, prior account preserved.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RES15zXfaUZZjD8PVz9ixy
Reported as "only one of my attached accounts shows a tile". The tiles were
never the problem — the second attach was silently landing on the FIRST
character.

The modal prefilled the character name from the last successful attach. But
this modal exists precisely to attach a character that has no tile yet (one
with a saved target attaches from its own Connect button), so the common case
is a DIFFERENT character than last time. A player who changed only the port
attached under the previous name — which SUCCEEDS, because the detachable
protocol neither sends nor checks a character name — mislabelling the tab,
overwriting that character's saved target, replacing its session record via
addSession's characterId match (orphaning the real session in main), and
producing no second tile.

- The name field now always starts empty, and says what it must match: the
  character that Lich session logged in as.
- Host still prefills (stable across sessions, and wrong values fail loudly).
  The PORT no longer does — every headless Lich listens on its own, so last
  time's port belongs to someone else. It still fills in from the saved
  target once a known name is typed.
- The modal path gains the per-character guard the tile paths already had:
  typing a name that is already attached switches to that tab and says so,
  instead of replacing a live session.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RES15zXfaUZZjD8PVz9ixy
Evidence from Kahlen's install: three attached characters, three saved
targets, one visible tile. Nothing was lost — they were filed under three
DIFFERENT accounts (Ethun→lenairk6, Tranon→lenairk21, Remu→the 'attach'
placeholder, since only Remu lacked a prior profile), and only the section
that got created was auto-expanded. The other two sat in collapsed sections,
so counting tiles under 'attach' found exactly one and looked like the other
attaches had not saved.

Keeping a known character on its REAL account stays correct — it is on that
account, and after detaching the player may want a normal login — so the fix
is visibility, not filing. expandAccountOnce now runs on EVERY successful
attach, including when the target is unchanged and nothing is written.

This reverses the previous commit's "only on stub creation, or we fight a
deliberate collapse" reasoning, which the evidence contradicts: a player who
just attached a character wants to see that character, and this fires once
per attach rather than persistently overriding their choice.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RES15zXfaUZZjD8PVz9ixy
The attach-time resync was arriving and being parsed — and setting every
vital to 0.

Lich's detachable_client_send_init builds the init string by hand and
hardcodes value='0' on all four bars, carrying the real numbers ONLY in the
text attribute:

    <progressBar id='health' value='0' text='health 100/100'/>

Lichborne's progressBar handler reads `value` and assumes max=100, which is
right for DR's own bars (value IS the percentage) but turns Lich's resync
into health/mana/spirit/stamina all at zero. Worse than blank: a zeroed bar
looks like live data and reads as one hit from dead.

The parser now falls back to the text attribute's cur/max pair, deliberately
narrowly — ONLY when value is 0 AND the text carries a non-zero current. DR's
live bars send a correct value, so they take exactly the path they always
did; a genuinely-zero vital still reports zero from either source; and
customText bars ('inner fire 59%', no slash) still fall back to value.
Widening it to "always prefer text" would change the numbers every existing
player sees, which is not this patch's business.

Verified against the exact init string lich-5 emits: 7/7, including
regression cases for live bars, zero health, and customText labels.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RES15zXfaUZZjD8PVz9ixy
The previous fix read the text attribute as a cur/max PAIR. In DragonRealms
there is no max, so it never matched and every bar still fell back to
value='0'.

Why the max is missing, from Kahlen's live capture plus lich-5:

  DR sends   <progressBar id='mana' value='86' text='mana 86%' customText='t'/>
  Lich reads @health, @max_health = text.scan(/-?\d+/)   (xmlparser.rb)

A percentage yields ONE number, so max_health stays nil. The init then
interpolates "#{XMLData.health}/#{XMLData.max_health}" into a trailing-slash
string — text='health 100/'. GS sends 'health 100/100', so the pair regex
worked there and hid the gap; DR is the shape that matters here.

So take the FIRST number in the text and treat a missing or zero max as 100,
which is correct for DR because these vitals ARE percentages. GS's real max
(118/120) is still honoured when a second number is present.

Still only when value === 0, so DR's live bars — which carry a correct value,
86 in that capture — and customText labels take exactly the path they always
did. Harness covers both shapes plus live-bar, label, zero-vital and
no-number regressions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RES15zXfaUZZjD8PVz9ixy
An attach target is often not loopback — another machine on the network, or
one reached over a VPN — so the socket crosses a link that sleeps, roams and
re-handshakes. Two gaps made that hurt more than it had to:

- NO KEEPALIVE. An idle TCP connection through NAT gets reaped by
  intermediaries that tell neither end. Lichborne held a socket it believed
  was live, showed the tab as connected, and found out only when the player
  typed something. DR sessions are legitimately silent for minutes, so 'idle'
  is normal and cannot be treated as suspicious. Now: probes every 30s, which
  keeps the path warm AND turns a dead peer into a real 'close'. Also
  setNoDelay — vitals and prompts are small and latency-sensitive.

- NO RECOVERY. A dropped attach left the tab stranded until the player
  noticed and reconnected by hand, which defeats the point of a mode whose
  whole promise is that the session outlives the client.

Auto re-attach is safe HERE in a way it would never be for a login: it starts
no SGE auth, claims no account slot, spawns no Lich, and cannot bounce anyone
from the game. The character never left — Lich still holds the game
connection — so a dropped socket is a lost VIEW, and restoring a view is
idempotent.

Backoff 2/4/8/15/30s then a 30s heartbeat, INDEFINITELY while the tab is
open. No attempt cap on purpose: the whole point of attach mode is that the
session outlives the client, so the view should keep trying for as long as
the tab is left open — a cap would guarantee that the one time the player
wanted it back is the time it had quietly given up. Reconnection happens IN
PLACE on the same session, so the tab, its scrollback and its panels survive;
Lich re-sends its resync per attach, so vitals repopulate.

Never after a CLEAN disconnect (tab closed, `exit` typed), and an explicit
Disconnect or a session teardown cancels a pending attempt — otherwise a tab
the player just closed springs back to life.

Harness kills the fake listener mid-session and restarts it: 5/5, covering
drop detection, repeated refused attempts, a fresh resync on re-attach, and
no spliced partial line across sockets.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RES15zXfaUZZjD8PVz9ixy
After an auto re-attach the game feed was live and streaming into the window
while the tab stayed greyed out and the toolbar still offered Login.

GameWindow's status handler cleared its `dropped` flag only on

    s.connected && s.message === 'Connected'

— so the connected FLAG was decorative and a human-readable STRING was
load-bearing. Attach mode sends 'Attached' and 'Re-attached', neither of
which matches, so the flag said connected, the socket was connected, text was
arriving, and the UI insisted otherwise.

Now keyed on `s.connected` alone. That is safe by construction: main sends
connected:true only from a genuine connect/attach, because wireSession's
status handler pushes every progress line as connected:false. The message is
free to say something useful, and the session log records what it said rather
than a hardcoded 'Connected'.

The mirror-image check below it — `!s.connected && s.message ===
'Disconnected'` — is deliberately left alone: there the string is doing real
work, separating a final drop from the connected:false progress lines that
precede a successful connect.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RES15zXfaUZZjD8PVz9ixy
@coderabbitai

coderabbitai Bot commented Aug 30, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 957046fa-b0a0-4c67-8aaf-958a23eeaf1a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

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.

2 participants