Skip to content

Windows suite: from 289 failures to zero, plus image-to-pet creation - #15994

Open
Sylen00 wants to merge 111 commits into
stablyai:mainfrom
Sylen00:Sylen00/pet-overlay-animations
Open

Sylen00 wants to merge 111 commits into
stablyai:mainfrom
Sylen00:Sylen00/pet-overlay-animations

Conversation

@Sylen00

@Sylen00 Sylen00 commented Aug 22, 2026

Copy link
Copy Markdown

78 commits, two things: the Windows test suite goes from 289 failures to zero, and the image-to-pet creation feature this branch originally existed for.

The Windows work is the bulk of it. Full write-up, per-failure verdicts and reproduction steps live in docs/windows-test-suite-remediation-plan.md — this body is orientation, not a transcript.


The numbers

Before (2026-08-20) After (2026-08-22, post-merge)
Test files 99 failed | 5876 passed 0 failed | 6082 passed | 67 skipped
Tests 289 failed | 55257 passed 0 failed | 56571 passed | 926 skipped

Measured with a full vitest run on Windows 11 Pro (Node 24.16.0, Git 2.54.0.windows.1, pnpm 10.24.0). The 99/289 baseline was verified identical on main and on this branch — none of it came from the feature work; it was accumulated platform rot that had never been visible, because pr.yml ran the full suite only on ubuntu-latest and the one windows-2022 job ran seven hand-picked files.

What config/windows-suite-baseline.json = {} means for you

The baseline file records which Windows tests are expected to fail. It is now {}. Any Windows failure from here is a regression introduced by the change that caused it, not inherited rot you have to triage before you can tell whether your PR is at fault. That is the whole point of driving it to zero rather than to "fewer": a non-empty baseline is a list you have to read; an empty one is a gate.


Product bugs found and fixed

These are real defects in Orca, not test problems. The tests were right; production was wrong.

1. An NTFS inode is bigger than a safe integer — 7d2ae74, src/main/ai-vault/codex-session-root-dedup.ts

codexRolloutHardlinkIdentity rejected any stat whose ino failed Number.isSafeInteger. A Windows st_ino is the 64-bit NTFS file index and routinely exceeds 2^53 — measured on this host at 14073748837253212. The guard therefore returned null for every rollout, and pre-parse dual-root dedup was dead code on Windows entirely. Consequences beyond the failing test: bridged and backfilled aliases were never collapsed, so they ate the parse budget and pushed real sessions out of the listing, and the per-account resume repin never ran. dev and nlink keep the strict check; the composite alias key still pins the execution namespace and the session UUID, so the relaxation cannot cause a false merge.

2. A daemon respawn race — 0d64d92, src/main/daemon/client.ts

A DaemonClient connect against an already-dead endpoint could still be in flight when respawn published its replacement, and ensureConnected joined it unconditionally — so the retried spawn inherited the dead endpoint's connect ENOENT, which reads as isDaemonGoneError, which forked a second respawn. Generation checks alone don't catch it: the stale attempt starts after doRespawn's pre-respawn disconnect(), so it looks current. doRespawn now retires the in-flight attempt once respawnFn returns. The race is not Windows-specific — Windows only exposed it, because connecting to a missing named pipe fails far more slowly than to a missing unix socket, which widens the window. Fixed entirely in production; the test file is unchanged.

3. A tui-idle probe leaked its provider buffer when the waiter died — 557613c, src/main/runtime/orca-runtime.ts

The probe's retire timer (waiterMs - 1) raced the waiter's rejection timer (waiterMs). When the rejection won, readTerminal found the acquisition un-retired, took the unbounded return acquisition.promise path, and blocked on a capture whose only consumer had already given up — a 30 s hang. The 1 ms margin never guaranteed anything: Node stamps a timer's deadline from a libuv clock that advances mid-turn, so 0.1–1.7 ms of synchronous work between the two setTimeout calls consumes the entire margin whenever it crosses a millisecond boundary. The retire is now anchored to the waiter's timeout death — a causal event, not a timer. Full orca-runtime.test.ts under sweep-shaped load: 5/10 hangs before, 0/36 after.

Two independent static-analysis passes concluded this ordering was safe before instrumenting _idleStart refuted it. The rule that came out of it, recorded in the plan doc: a sub-millisecond timer margin is not a margin.

Test-portability fixes (the other ~90%)

Separate category, kept deliberately separate. These are tests that hardcoded POSIX assumptions while Orca itself was fine: path separators and volume roots, CRLF folding where a test reads source or a model's value, fixtures rooted somewhere Windows doesn't recognise, tests reading the developer's own shell, one asserting an NTFS directory enumeration order the command never promised.

Two rules were held throughout, and they are why this isn't a skipIf sweep:

  • it.skipIf(process.platform === 'win32') is not a fix unless the behaviour is POSIX-only by design. 61 symlink tests across 14 files were stranded by Windows refusing CreateSymbolicLink without elevation — they are gated on the detected capability, not the platform, precisely so they still run on an elevated CI runner. Most of that turned out to be a genuine fix rather than a gate: a junction needs no privilege, so every directory link now asks for one, recovering 26 tests outright.
  • Never change a production assertion to match Windows output without first proving the Windows output is correct.

What is not claimed here

test_windows still carries continue-on-error: true. This PR does not flip it, and you should not read the zero as "the gate is on".

The zero is measured on a developer machine. A GitHub runner differs in ways that move the numbers — most importantly it is elevated, so the ~61 symlink tests that skip locally will execute on the runner for the first time ever. This PR's test_windows run is the first real look at them. A follow-up flips continue-on-error off once the runner's own results have been read and anything it surfaces is closed. Turning it into a blocking gate on the strength of a local number would be asserting something nobody has measured.

For the same reason the job does no baseline comparison: the baseline is for local iteration, and the job reports what the runner itself sees.


Reproducing the zero locally — the node-pty precondition

If you run the suite on Windows and get four failures in the two .win32 job-object suites, this is why. A plain pnpm install will not produce the zero. node-pty prefers its upstream prebuild, which does not contain Orca's Windows job-object patch, and requiresPatchedNodePtySourceBuild() returns false on win32. You need:

npm_config_build_from_source=true corepack pnpm rebuild node-pty

This is documented in the "Reproduce" section of docs/windows-test-suite-remediation-plan.md, along with the corepack pnpm shim the sweep scripts need and the full-sweep command itself (~41 min). CI's Windows lane already builds from source, so this affects local reproduction only.

(Related, and left as upstream's to fix: because that predicate returns false on win32, a normal Windows install of Orca also runs an unpatched node-pty, so PTY teardown silently falls back to the pid-walk. Out of scope here — noted so it isn't lost.)


Also in this branch: image-to-pet creation

The feature the branch was opened for. A pet can now be built from an uploaded image: chroma-key cutout with halo fade and magenta-cast drain, character framing with a configurable background-removal amount, head-swap and leg-rigged build modes, a preview before saving, persistence over its own IPC channel, and a quality gate on uploaded cutouts. Alongside it, the pet overlay animation work — gravity drop and flick-throw with squash on landing, a walking leg cycle, topple-and-get-up on a real drop, a four-row pose sheet driven by agent state, and a user setting to turn pacing and drop-to-floor off.


Reviewing 78 commits

  • Commit subjects are prefixed by intent: fix(...) is a production change, test(windows): ... is portability, docs(windows): ... is the plan doc's running record, feat(pet): ... is the feature.
  • The three production fixes above are the ones that change runtime behaviour on all platforms.
  • Each commit message states its verdict — P (product bug), T (test portability), or C (capability gap) — and the reasoning, including the diagnoses that turned out to be wrong.

Sylen00 and others added 30 commits August 19, 2026 14:22
Bundled pets sat frozen at a persisted point. They now walk a lane
resting on the status bar, mirror on turn, and hang-sway while grabbed.

- pet-walk-lane.ts: pure pacing math — bounds, lane y, turn-at-edge.
  Collapses to a fixed point when the viewport is narrower than the pet,
  so coincident edges can't flip direction every frame.
- usePetWalkLane.ts: rAF driver, idle while dragging/hidden/reduced-motion.
- Facing lives on its own layer; bob and sway own `transform`, so a flip
  declared beside them would lose to the animation.
- Persist on drag end only — the walk moved position every frame, which
  would have hammered localStorage 60x/s.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Rendering the lane top while state kept a stale y hid the staleness until
you picked the pet up: the grab measures its offset against `position`,
so the pet jumped to the old y — 0 whenever the mount happened before the
window reported a height. Sync y into state instead, and drop the
render-time override.

Found by driving a real pointer drag against a dev build over CDP.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…landing

Releasing above the lane snapped the pet home instantly. It now falls.

Modelled on Shimeji's actions.xml rather than plain gravity:
- `Falling` pairs gravity with air resistance, so there is a terminal
  velocity. Pure acceleration reads as a stone, not a pet.
- `Thrown` seeds the drop with the cursor's velocity, so a flick arcs the
  pet sideways; it stops dead at the lane's walls instead of sliding out
  of reach.
- `Bouncing` is a two-pose blink, hence the 220ms landing squash pivoting
  on the floor rather than a long wobble.

Catching the pet mid-air cancels the drop; reduced motion keeps the snap.

Also adds the held-pose plumbing: `BundledPet.heldUrl` renders in place of
the idle art while the pet is in hand. No bundled pet ships one yet — the
three WebPs have no arms-up frame (verified by decoding all 96/73/73), and
the Codex bundle contract has no held row, so imported pets keep the sway
alone.

DetectedSpriteFrame moved to its own file to stay under max-lines.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Derived from each pet's own artwork rather than generated: the arm pixels
are isolated by palette (the vest/shirt/jeans fail the skin test), rotated
about the shoulder or elbow, and composited back. Identity is exact
because the pixels are the originals.

- Gremlin and OpenCode read clearly as hands-up at render size.
- Claudino's change is subtle and will stay that way: its canvas is
  320x180 with a small character, so the arms are ~4px on screen. Shipped
  for consistency — a pet that ignores being picked up while the others
  react is worse than a quiet reaction.

142KB for all three, against 2.2MB for the animated idles.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The pet slid along the lane as a static image. Each bundled pet now has a
four-frame walk cycle: its own legs, cut at the hem and swung about the
hip, with the body lifting on the passing poses.

Rides the existing `.codex-pet` sprite renderer rather than adding a
second animation path — a strip is just a one-row sheet, so
`walkSpriteFrom` adapts the descriptor and SpriteFrame steps it.

- The legs stop while the pet is held or falling; it isn't walking then.
- The CSS bob is suppressed for walk-strip pets: the cycle already lifts
  the body, and two vertical oscillations at different periods wobble.
- Swing is 20-24 degrees, far past anatomical. At the size the overlay
  renders (~141x180) a realistic 9 degrees was invisible.

227KB for three strips.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two faults in the walk strips, both from treating a front-on drawing as
if it had a side view hiding in it.

The pets stand with each foot splayed outward, which is right for an
idle front pose. Walking, that left the trailing foot pointing against
the direction of travel. One leg is now mirrored about its own content
centre — not the cut box, which would slide it sideways — so both feet
face the same way and the overlay's existing flip serves the other
direction.

The sinusoidal swing was also wrong: a stride has nothing to project
onto in a front view, and on half the frames the legs scissored through
each other. Replaced with alternating single-leg steps — one foot lifts
and tilts while the other stays planted, so they can never cross.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The previous cycle only lifted a foot in place, so the legs never moved
horizontally and stayed at the idle stance width the whole way round —
wider than anyone actually walks.

They now converge past each other on the contact frames and separate on
the passing ones, and which leg is drawn on top alternates so the
crossing reads as one leg in front of the other rather than a merge. A
constant inward pull closes the idle splay that made them look planted
apart.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Dropped from a height the pet now tips over as it falls, lands flat on
its back, lies there a beat, and pushes itself upright over 1.2s before
resuming its walk.

All transform, no new art: the body pivots on its feet so it falls over
backwards rather than spinning about its middle. A 90-degree turn about
that point would bury half the body under the lane, so the pose lifts by
half the rendered artwork width to lay it on the floor.

The fall hook grew a phase machine — falling, downed, rising — decided at
release rather than impact, since by the time it lands the height it fell
is no longer measurable. Drops under 80px keep the old quick squash; a
pet toppling over after a 5px stumble reads as broken, not hurt. The walk
holds through all three phases.

Also fixes the test harness: cancelAnimationFrame was a no-op, so
cancelled frames kept firing and hid the walk running while the pet was
supposed to be lying down.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two toggles in the status-bar pet menu, both on by default so nothing
changes for anyone who does not go looking.

- Walk around: off, the pet stands still with its walk strip frozen on a
  standing frame.
- Drop to the floor when released: off, the pet stays wherever you put
  it — no fall, no topple, and the lane stops owning y. It still paces,
  just along the height you left it at, so the two settings stay
  independent rather than one silently disabling the other.

Persisted alongside petVisible/petSize. The RPC schema gains two optional
booleans, which docs/reference/remote-wire-compatibility.md classifies as
safe for older clients; hydration defaults both to true so profiles
written before this land upright.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The bundled pets had one animation — a walk strip that played whatever
the pet was doing. They now carry a 4x4 sheet (idle breathing, the
crossing walk, an impatient toe tap, a hop) and pick the row from live
agent state, the way imported .codex-pet bundles already could.

Every pose is derived from each pet's own artwork by the same canvas
pipeline, so identity is exact and no image model was involved.

Two things fall out of having more than one row:

- Arbitration. Pacing and the agent-state row disagree: walking with a
  breathing row reads as gliding, and a waiting pose should park the pet.
  `arbitratePetPose` decides both at once, so the row on screen and
  whether the lane advances can never contradict. Hover now genuinely
  stops the pet instead of sliding it along mid-hop.
- Per-row timing. Breathing at running speed reads as panic, so each row
  carries its own frame hold rather than sharing the sheet fps.

Every PetAnimationName maps to a row, so SpriteFrame never silently falls
back — an unmapped state used to look like a stuck animation. The drag
rows share locomotion; `review` borrows the waiting pose.

Removes the walk strips and their one-row descriptor, now dead.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
From an independent review of the branch.

- A hard upward flick peaked ~1200px above the release point: the fall
  clamped x to the lane walls and y only at the floor. For the ~2s round
  trip the pet was off-screen and ungrabbable, with `busy` suppressing
  both the walk and the lane sync. It now stops at the ceiling and drops
  its upward velocity so gravity brings it straight back. Verified live:
  a hard flick now peaks at y=1 instead of leaving the window.

- Both rAF loops read the lane and pet size through refs, so a resize can
  no longer restart them. A restart drops the timestamp baseline and the
  tick after one only records, so a stream of them would stall the motion.
  The review flagged this as a resize stall; I could not reproduce the
  symptom, but a loop that restarts on value changes is wrong regardless.

- The supine lift fell back to half the overlay box for pets without a
  pose sheet, leaving a narrow custom sprite floating above the lane. It
  now reads the real frame from whichever descriptor is active.

- The settled position is persisted instead of the mid-air release point,
  which reappeared hanging on relaunch with the floor return off.

Also pins the behaviour the pose-sheet refactor already fixed: turning
"Walk around" off used to freeze the pet solid, because the paused strip
and the suppressed bob left no motion at all. It now breathes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The topple was a CSS rotation of the standing pose: the pet stayed on its
feet in every frame, just turned sideways, and the rise was a linear
interpolation back to zero. Both are now drawn rows on the pose sheet.

The sheet grows from four rows to seven — falling tips through four
angles with a slight air stretch, downed lies flat and breathes shallow,
and rising peels off the floor and over-rotates a few degrees onto its
feet before settling, which is the beat an interpolation cannot express.

Three things this needed:

- Tipping about the feet swings the body out past its cell, where the
  neighbouring frame clips it. Each tipped frame is measured against the
  artwork's own box and slid back to centre.
- `buildSpriteAnimationCss` grew a `loop` flag. Getting up must settle on
  its last frame; looping would drop the pet back on the floor. The rise
  row is also paced to span exactly PET_RISING_MS so playback and phase
  end together.
- The fall phase now enters pose arbitration ahead of everything else.
  Mid-air is mid-air: no agent state should stand the pet back up.

Pets without the rows — every imported `.codex-pet` bundle — keep the CSS
topple, so the fallback path stays intact and is still covered.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Groundwork for building pets from uploaded images.

The leg boxes, pivots and animation amplitudes for the three bundled pets
lived in environment variables of a throwaway script. They are now data in
the repo, shared by the sheet generator and the coming image pipeline so
the two cannot drift, plus a head slot per pet for the head-swap mode.

`assessCutout` refuses an upload whose background could not be separated,
rather than saving a pet that is visibly broken in every frame. Five
measured criteria, thresholds in one named place because they will need
tuning against real uploads: coverage too high or too low, a subject that
is mostly scattered specks, a full-bleed photo, and a silhouette too
uniform to be a character.

An image that arrived with its own alpha is never second-guessed — someone
already cut it out with more to work with than a corner fill.

The uniformity test replaced a head-detection heuristic I wrote first. Its
own test caught it: a rectangular slab has a full-width top band and so
passed as "has a head". Without face detection any head rule is a guess
that big-headed characters fail, while uniformity catches the real failure
— a rectangular chunk of background where no character is distinguishable.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Phase 2: the pipeline, no UI yet. `buildPetFromImage` takes an upload and
one of the three aesthetics and returns a seven-row sheet plus a manifest
shaped exactly like the one the bundle importer already validates — so a
generated pet and an imported one are the same thing downstream.

Four pure modules, none touching a DOM, so the whole path is unit-testable
and deterministic: the same image and style produce the same bytes, which
is what lets the preview a user approves be what actually gets written.

- `pet-image-cutout` separates subject from background. An image that
  arrived with alpha is used as-is; otherwise each corner floods against
  its own colour and gives up honestly on a busy photo rather than eating
  into the subject.
- `pet-image-resample` fits the subject to the chosen pet's frame, standing
  on its floor line. Nearest-neighbour and aspect-preserving: smoothing
  makes an upload read as a photo pasted onto a drawing, and squashing a
  face to fill the frame is worse than leaving air.
- `pet-raster-transform` does affine draws by inverse mapping, because the
  forward direction leaves holes wherever a transform stretches.
- `pet-sheet-composer` builds the seven rows. Whole-body mode has no limbs
  it can trust, so the walk row leans and bounces rather than claiming an
  anatomy the image may not have.

Two of my own test fixtures were wrong and the tests caught them. Four
uniform quadrants are perfectly floodable, so "corners disagree" removed
everything as it should — the real case is high-frequency noise. Both are
now checked end to end against the quality gate, which is where a bad
upload gets refused.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Phase 3. `pet:import` copies a file the user picked, so there was no way
to save bytes the app itself produced. `pet:createGenerated` takes the
sheet and manifest from the renderer and writes them with the same atomic
tmp-then-rename the bundle importer uses.

Two things the renderer must not control are pinned in main: where the
sheet lands, and what the manifest calls it. The caller's spritesheetPath
is replaced *before* validation rather than after — sanitising a path we
were never going to use would only hand the caller a way to fail the parse
with one we then discard.

Everything else goes through the same zod schema and the same geometry
checks an external `.codex-pet` faces, and that validation runs before the
rename, so a sheet that does not match its manifest never becomes a saved
pet. A test asserts nothing is left on disk when it does not.

Two bugs found while writing the tests, both mine:

- `Buffer.concat` returns a view into a shared pool, so `.buffer.slice(0)`
  handed the whole pool across the boundary instead of the sheet, and the
  WebP header parse failed on bytes that were fine.
- The manifest schema rejects `..` in a path, so overwriting the caller's
  path after parsing meant a traversal attempt failed validation instead
  of being ignored. Overwriting first is both simpler and what the comment
  already claimed was happening.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Phase 4 — the feature is now reachable. "Create pet from image…" in the
pet menu opens a dialog: pick a picture, pick one of the three aesthetics,
watch the result move, then save.

Nothing is written until the user confirms. The pipeline is deterministic,
so the preview they approve is byte-for-byte what lands on disk, and
switching aesthetic re-runs it from the decoded source rather than asking
for the file again.

A refused cutout never reaches a save button. The dialog shows what went
wrong AND what to do — "the background is too busy to separate from the
character, try a PNG with a transparent background" rather than "could not
import". A test asserts every failure reason has such a message and that
none of them leaks its internal code.

The preview tours the rows instead of showing one: a bad cutout reads as a
plausible blob standing still, and only gives itself away once it moves.

`pet-image-decode` is the canvas edge and is deliberately logic-free, so
everything that decides anything stays in the pure modules and testable
without a rasteriser. It caps source pixels — a small file can declare
enormous dimensions.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Selecting "Create pet from image…" called preventDefault, which is what
the toggles above it need — they are meant to be used several in a row —
but wrong here. The menu stayed open behind the dialog, and once the
dialog closed the next click on the trigger toggled the still-open menu
shut, so the menu looked like it had stopped working.

Found while validating the pipeline against real images, and diagnosed by
counting menu items rather than guessing: the dropdown had six items open
through the whole dialog lifetime.

Also adds the component test this file never had. It pins both halves —
the dialog item closes the menu, the toggles keep it open — so the two
cannot be "fixed" into each other later.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Phase 5, completing the three modes. Whole body remains the default and
the only one that works for any picture; the dialog now offers the other
two beside it.

Walking legs finds a rig in the upload's own silhouette, so a generated
pet can walk rather than glide. `detectLegs` is written to say no more
readily than yes — exactly two column runs, each wide and tall enough
relative to the subject — because a wrong rig tears a seam through the
middle of something that has no legs, while falling back merely looks
calm. When it declines, the build degrades to whole body and the dialog
says so; silently handing back a glide would read as the feature being
broken.

Head only composes the upload into the chosen pet's head slot, so the
aesthetic is exact — it IS the pet, wearing the user's face. It needs the
pet's artwork, and refuses with a message rather than quietly building
something else when that cannot be loaded.

`BUILD_PET_FAILURES` is now the source of `BuildPetFailure` rather than a
copy of it. Adding the head-swap failure exposed the gap: the type grew, a
hand-written test list did not, and only the compiler caught the missing
message. Now both the switch and the test walk the same list.

Verified in the app against real images: all three modes produce a
preview, the rig is genuinely detected on a legged silhouette, and a
legless blob degrades with the notice shown.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The three mode buttons shipped as bare English literals, which the
localization coverage check refuses — and rightly: every other string in
this dialog goes through translate().

They use getters rather than plain calls, matching pet-models: a
module-level translate() would run before i18n is ready and would not
follow a language change afterwards. The hover hints are translated too,
though the audit did not flag them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The magenta key promised antialiased edges would fade proportionally, but
the threshold and the multiplier together could never yield a score below
0.5, so every scored pixel was hard-cleared. Normalising across the band
above the threshold makes the partial-alpha path reachable. Extracted to
its own module so it can be tested without the blob cache.

The importer trusted the file extension alone, so an executable renamed
.png was copied into the pets directory unchallenged. Now the first bytes
have to agree with the name.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Fading alpha alone left the pixel magenta, so making the partial band
reachable would have turned a hard-cut edge into a visible pink fringe.
Red and blue now fall to green in step with the score, so the edge loses
the cast as it loses opacity.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two things the pipeline cannot work out on its own. Which of the things
in a picture is the character is a question only the person who chose it
can answer, so a drag on the source image now says it. And no single
flood tolerance suits both a flat studio backdrop and a gradient, so the
width of the fill is a slider rather than a constant.

Fixes a real defect found on the way: the corner fills shared one visited
set, and marked a pixel seen BEFORE testing it. The first corner's
refusals therefore stood for all four, stranding background the others
were well inside tolerance of — and walling off everything behind it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Removing a pet already deletes its files. This is for the times that
never ran: a crash between writing a bundle and persisting the list, or a
profile restored without it. Conservative by construction — an entry has
to be shaped like a pet id, unclaimed, and a full day old before it is
touched, because a pet reaches disk before it reaches the list.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…onse

React Doctor found three real defects in this branch. Refs were written
during render in four places; React may replay or discard a render, and a
ref written in one that never commits would feed the animation loop a
value the user never saw. They move to effects, which run after commit.

fetch resolves on 404 as readily as on 200, so head-swap handed the error
page to the decoder and failed talking about pixels. It now says what
actually went wrong.

The orphan sweep awaited one stat at a time; the stats are independent.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Node refuses to spawn a .cmd without a shell, so both gates threw
spawnSync EINVAL before oxlint or react-doctor ever started. On Windows
neither had been running at all. ensure-native-runtime already had the
fix; these two were missed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The Windows suite starts from 303 failures across 99 files. At that size
a phase cannot show it fixed its own cluster without disturbing another
by reading the output, so this records the per-file counts and compares
against them.

It fails only on files that got worse or newly started failing. Demanding
zero would make it useless until the very last phase, and offsetting
regressions against progress would let a phase that broke something
elsewhere read as a win.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Vite strips a shebang line-wise. A CRLF checkout leaves the stray CR
behind, and any .mjs a test imports then fails to parse with a
SyntaxError naming no file and no line. Node runs CRLF shebangs fine,
which is why three test files carried this for as long as they did.

The eight individual pins are subsumed by the blanket rule.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Pinning .mjs to LF let three test files parse for the first time, and one
of them then failed six ways — the SyntaxError had been hiding real bugs
in the script it covers.

Git quotes any pathname holding a character it must escape, so on Windows
every `git diff --no-index` header comes back as "a/C:\tmp\..." with the
separators doubled. The forward-slash prefix stripping never matched, and
the generator wrote absolute scratch paths into the patch.

The lockfile pattern matched a literal \n, so a checkout with autocrlf
made the script report a patchedDependencies entry as missing while it sat
right there. The test's own `git apply` needed the same neutralising.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`os.devNull` is `\.\nul` on Windows and Git rejects it outright — every
`git init` in worktree-shared-directories died on the config path rather
than on anything the test meant to exercise. A path that does not exist
reads as an empty config on every platform. `stdio: 'ignore'` had been
swallowing git's reason, so the failure said only "Command failed".

The oxlint plugin test spawned `.bin/oxlint.cmd`, which Node refuses to
launch without a shell. The shim only runs `node oxlint/bin/oxlint`, so
running that directly needs no shell and no argument has to survive
quoting.

lint-react-doctor-changed was the third quality gate carrying the same
.cmd defect, after the two fixed in a25372e. Fourteen developer-only
scripts still carry it; none is reachable from the suite and none can be
exercised here, so they are recorded rather than changed blind.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@coderabbitai coderabbitai 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.

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 7239ade8-3475-4282-a008-7b63c97d3dea

📥 Commits

Reviewing files that changed from the base of the PR and between ee5ac06 and 4586074.

📒 Files selected for processing (15)
  • src/main/ipc/pet-generated-write.ts
  • src/main/ipc/pet.test.ts
  • src/main/ipc/pet.ts
  • src/main/updater.ts
  • src/renderer/src/components/pet/pet-raster-transform.test.ts
  • src/renderer/src/components/pet/pet-raster-transform.ts
  • src/renderer/src/components/pet/pet-sheet-composer.test.ts
  • src/renderer/src/components/pet/pet-sheet-composer.ts
  • src/shared/file-mode-capability.test.ts
  • src/shared/file-mode-capability.ts
  • src/shared/posix-shell.test.ts
  • src/shared/posix-shell.ts
  • src/shared/probe-scratch-directory.ts
  • src/shared/symlink-capability.test.ts
  • src/shared/symlink-capability.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/updater.ts

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

Comment on lines +189 to +191
const scale = Math.min((hx1 - hx0) / sourceWidth, (hy1 - hy0) / sourceHeight)
const width = Math.round(sourceWidth * scale)
const height = Math.round(sourceHeight * scale)

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Keep a non-empty fitted head.

When an opaque upload has an extreme aspect ratio, the non-limiting dimension can round to 0. clearCell and drawTransformed then use an empty rectangle, so the composed sheet contains no uploaded head. Clamp both fitted dimensions to at least one pixel.

Proposed fix
-    const width = Math.round(sourceWidth * scale)
-    const height = Math.round(sourceHeight * scale)
+    const width = Math.max(1, Math.round(sourceWidth * scale))
+    const height = Math.max(1, Math.round(sourceHeight * scale))
📝 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.

Suggested change
const scale = Math.min((hx1 - hx0) / sourceWidth, (hy1 - hy0) / sourceHeight)
const width = Math.round(sourceWidth * scale)
const height = Math.round(sourceHeight * scale)
const scale = Math.min((hx1 - hx0) / sourceWidth, (hy1 - hy0) / sourceHeight)
const width = Math.max(1, Math.round(sourceWidth * scale))
const height = Math.max(1, Math.round(sourceHeight * scale))

Comment thread src/shared/posix-shell.ts
Comment on lines +15 to +17
/** Why not the 30s process default: up to five candidates are tried, and the
* probe runs at `describe.skipIf` scope — during collection, which vitest's
* `testTimeout` does not govern. A shell that has not answered in 2s is a "no". */

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.

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Keep rationale comments concise. Reduce these comments to one-line explanations of the non-obvious constraint; avoid restating implementation details or general commenting guidance.

📍 Affects 2 files
  • src/shared/posix-shell.ts#L15-L17 (this comment)
  • src/renderer/src/components/pet/pet-sheet-composer.ts#L192-L197

Source: Coding guidelines

Sylen00 and others added 23 commits August 23, 2026 16:25
… blob

Git classified the file as binary, so GitHub rendered "Binary file not
shown" for it in the PR.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R3oGCiyWVfKj1DXK2hTFTH
The click and result lines were scaffolding from bringing custom-pet
upload up; they fire on every use and print the imported model. The
warn/error paths stay — those still describe failures worth diagnosing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R3oGCiyWVfKj1DXK2hTFTH
The overlay plays `rising` once and pins its last frame (`loop={animationName
!== 'rising'}`); the preview left `buildSpriteAnimationCss`'s `loop` at its
default, so the tour's last stop showed the pet standing up over and over —
a motion the pet never makes in the app the user is previewing it for.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R3oGCiyWVfKj1DXK2hTFTH
…assing empty

Seven cases returned before their first assertion when the host lacked
the thing under test, so Windows counted them as passes. Three would
have stayed green with findPosixShell() regressed to null. runIf/skipIf
reports them as skips; on this host that exposes one more vacuous case
than expected -- findPosixShell() resolves the bare name 'sh', so the
PATH-precedence case was never asserting either.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R3oGCiyWVfKj1DXK2hTFTH
… zero

The comment still said the suite does not pass on Windows and promised
the flag would come off at zero. It is at zero. State the real reason
the flag stays: the runner's own results have never been read.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R3oGCiyWVfKj1DXK2hTFTH
…asked for

The generated manifest named only the seven physical rows, so `running-left`,
`running-right` and `review` fell through to the default row — a generated pet
played idle while being dragged and while a result waited for review. Alias
them onto the same rows `bundled-pet-pose-sprite.ts` uses, typed against
`PetAnimationName` so a new state cannot ship without one.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R3oGCiyWVfKj1DXK2hTFTH
The two overlay toggles drew a Check span inside a plain menuitem, so the
state was visible but unannounced; they are DropdownMenuCheckboxItem now
and carry aria-checked. Choosing a pet is a single choice over two lists,
so both lists move into one DropdownMenuRadioGroup.

The per-row delete was a <button> nested inside a role="menuitem" — invalid,
and unreachable by the arrow keys that drive a menu, so keyboard users had
no way to remove a custom pet at all. It becomes its own "Remove a pet"
submenu, shown only when there is something custom to remove.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R3oGCiyWVfKj1DXK2hTFTH
…d pet

A generated pet is written with `kind: 'bundle'`, and every bundle is
chroma-keyed by `keyMagenta` at load. The preview never ran that pass, so a
pink subject looked intact on the confirm screen and came back with 700k
pixels drained once saved — the dialog's byte-for-byte promise was false.

Run the pass at the end of the build instead of dropping the promise: the
user now sees what the overlay will render and can pick another image. The
pass is idempotent (a keyed pixel scores 0 on the next run), so the loader
repeating it changes nothing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R3oGCiyWVfKj1DXK2hTFTH
The comment called it a decompression-bomb guard, but the check runs after
`createImageBitmap` has already decoded the file. No renderer API reports an
image's dimensions without decoding it, so the check cannot move earlier; what
it really prevents is the RGBA heap copy and the O(pixels) passes after it. The
file comes from the user's own picker, so there is no adversary to defend from.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R3oGCiyWVfKj1DXK2hTFTH
The image dialog on this same branch uses <Slider> for the tolerance
control; the size control a few clicks away was a bare <input type="range">,
so two sliders in one feature read as two different products. The wrapper's
stopPropagation still keeps the menu open while the thumb is dragged.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R3oGCiyWVfKj1DXK2hTFTH
…andled

`loadCustomBlobUrl` was voided with a bare `.then`, so an IPC read that
rejected became an unhandled rejection. A freshly generated pet is never in
the blob cache, so it takes this path every time. The overlay already falls
back to the bundled default while the load is in flight; log and stay there.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R3oGCiyWVfKj1DXK2hTFTH
Style and build mode are one-of-N choices that were encoded only in a
Button `variant`, so which one is active was a colour and nothing else —
no role, no checked state. Both become ToggleGroup, whose items render as
radios with aria-checked.

The three modes differ in ways only `title` explained, and STYLEGUIDE lists
`title` under "Don't use": it never reaches keyboard or touch. The selected
mode's sentence now renders under the group and is wired to it with
aria-describedby.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R3oGCiyWVfKj1DXK2hTFTH
…eport it

`usePetFallToLane` already caps its integration step at 50ms with a comment
about teleporting through the lane; the walk passed the raw delta, so a
backgrounded window resuming after five seconds slid the pet 180px in one
frame. Same cap, same reason.

`PetOverlay.walk.test.tsx` drives a single 1000ms frame as shorthand for a
second of walking and now fails; the two step patterns that replace it are
pinned here so the overlay test can adopt them directly.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R3oGCiyWVfKj1DXK2hTFTH
…tried

The owner keeps this component mounted and only flips `open`, so every piece
of dialog state outlived the dialog: reopening after a save showed the last
picture, its framing, and its verdict. An effect on `open` clears them.

The file input kept the chosen path, so after a failure re-picking the same
file fired no change event and the user's only recourse was another file.

The decoded source moves from a ref to state: it sizes the crop surface
during render, and a ref read there is a value React never promised had been
committed — the anti-pattern 5c0c258 fixed on the writing side.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R3oGCiyWVfKj1DXK2hTFTH
…list

`customPets` is optional on the persisted UI state, and a corrupt state file
falls back to defaults where it is absent. `?? []` read that as "no pets are
known", handing the orphan sweep an empty keep-set: every pet folder past the
24h grace period deleted, with no undo.

An empty array is a real answer and still sweeps — that is the crashed-import
case the sweep exists for. An absent one is not an answer; skip, and let the
next launch that hydrates a list do the housekeeping.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R3oGCiyWVfKj1DXK2hTFTH
…_CROP

The shipped pose sheets are 4x7 (claude-poses is 1280x1260 at a 320x180 cell;
the other two are 1008x2240 at 252x320), not the four rows the comment claimed
— the fall rows were missing from the list.

FULL_CROP had no caller but its own test; the identity fast path it exercised
is worth keeping, so the test states the rectangle inline.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R3oGCiyWVfKj1DXK2hTFTH
The resample wrote 255 for every drawn pixel, so an upload that arrived with a
hand-made soft cutout came out with a hard edge — the one thing that makes a
subject read as pasted onto the pet art rather than drawn with it. Pixels below
the mask threshold are still skipped, so this only touches the feathered band.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R3oGCiyWVfKj1DXK2hTFTH
Dragging the tolerance slider ran the whole pipeline on every pointer
sample — a test drag queues three — and each run is a flood fill, a
connected-components pass, a resample and 28 full-sheet transforms on the
renderer's own thread. The thumb still tracks the drag; the build now waits
for onValueCommit, so a gesture costs one build. Arrow keys commit per
press, so the keyboard rebuilds immediately as before.

Overlapping runs also had no ordering: an older one finishing last replaced
the newer sheet, and the first `finally` cleared the spinner while another
build was still going. A run counter gates setDraft, setError and setBusy,
and the reset-on-open bumps it so nothing in flight can repopulate a dialog
that was just cleared.

Not moved off the main thread: with one build per gesture the stall is a
single hitch inside a dialog that already shows a spinner, and a worker
would mean a new build entry, structured-cloning sheets both ways, and a
second path to the bundled artwork.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R3oGCiyWVfKj1DXK2hTFTH
The surface was a bare div with pointer handlers: no role, no tabIndex, no
name, no keyboard path at all, so framing — the one thing the pipeline
cannot derive — was mouse-only. It is now a focusable role="application"
region (the arrows are the whole interaction; a browse cursor would eat
them) with the arrow keys moving the frame, Shift with them resizing it,
and a centred box appearing on the first press when nothing is framed yet.

Committing on keyup rather than keydown is the same bargain the drag makes
by committing on pointerup: an autorepeating arrow is one framing and one
rebuild, not one per repeat.

A gesture the OS takes away sends no pointerup, so pointercancel and
lostpointercapture now clear the drag instead of leaving the rectangle
stuck mid-drag.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R3oGCiyWVfKj1DXK2hTFTH
The reset added in a6829c9 was an effect keyed on `open`, which React
Doctor flags for the reason it is worth flagging: it clears the last
picture a frame after the dialog is already on screen. Radix unmounts
DialogContent on close, so moving the picking state into a form component
rendered underneath it makes every reopen a fresh mount and the effect
unnecessary.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R3oGCiyWVfKj1DXK2hTFTH
Three cases drove a single 1000ms frame as shorthand for a second of walking.
The walk now clamps a frame to 50ms, so that shorthand advances the pet 1.8px
instead of 36px. `stepWalkFrames` carries the reason at its definition, so the
loop does not read as an arbitrary elaboration of two calls.

The edge-turn case stops at 600ms on purpose: twelve clamped frames cover the
20px to the right edge, and a thirteenth is the pet already walking back.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R3oGCiyWVfKj1DXK2hTFTH
…nimations

# Conflicts:
#	src/main/runtime/agent-prompt-submission-runtime.test.ts
Four clusters, all introduced by the origin/main merge:

- config/scripts/vitest-host-ports-setup.ts left 28 suites failing on
  rmSync EPERM. POSIX lets an open file be unlinked; Windows does not, and
  a suite that keeps an OrchestrationDb open owns a handle in that scratch
  dir. Scratch cleanup under tmpdir must not fail a suite that passed.
- core.longpaths=true (stablyai#15866) is prefixed to worktree add on Windows, so
  argv literals in three suites could only be right on one platform; they
  now derive the prefix from windowsLongPathGitArgs.
- status-submodule-path-cache matched argv[0] for the subcommand, which is
  '-c' once that prefix is there.
- The new Hermes skills-root cases used drive-less path literals; the file
  already has a VOLUME constant for exactly that.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R3oGCiyWVfKj1DXK2hTFTH
@coderabbitai

coderabbitai Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🧹 Nitpick comments (3)
src/renderer/src/components/status-bar/PetStatusSegment.tsx (1)

90-103: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Reuse choosePet in the pet-registration paths. handleGeneratedPet, handleImport, and handleImportPetBundle repeat the same show-then-select sequence that choosePet already implements.

♻️ Proposed refactor
   const handleGeneratedPet = (model: Parameters<typeof addCustomPet>[0]): void => {
     addCustomPet(model)
-    if (!petVisible) {
-      setPetVisible(true)
-    }
-    setPetId(model.id)
+    choosePet(model.id)
   }
src/relay/skill-upload-multi-relay.integration.test.ts (1)

94-99: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Shorten the retire comment.

Keep the cross-platform reason, but reduce this six-line JSDoc to one sentence.

Proposed change
-/** Ends a relay the way both platforms support.
- *
- *  Why not `kill('SIGTERM')`: Windows has no signal delivery, so `kill` is a
- *  TerminateProcess and the relay's SIGTERM handler -- the thing that disposes
- *  its staging directory -- never runs. Closing stdin reaches the same
- *  `shutdown()` on every host; the short idle grace is what makes it prompt. */
+/** Close stdin so relay cleanup runs on Windows and POSIX. */

As per coding guidelines: “Comments must be concise, non-obvious, and brief—prefer one line.”

Source: Coding guidelines

src/main/git/status-branch-line-total-exec-contract.test.ts (1)

146-148: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Reduce the changed explanatory comments.

Replace each multi-line walkthrough with one concise comment that states only the non-obvious constraint.

  • src/main/git/status-branch-line-total-exec-contract.test.ts#L146-L148: reduce the cleanup rationale to one line.
  • src/main/git/status-shared-symlinks.test.ts#L16-L19: reduce the capability-gating rationale to one line.
  • src/main/git/worktree-shared-directories.test.ts#L26-L28: reduce the Git config-path rationale to one line.
  • src/main/git/worktree-shared-directories.test.ts#L34-L35: reduce the stderr rationale to one line.
  • src/main/ipc/filesystem-list-files-git-fallback-real.test.ts#L68-L72: reduce the cleanup rationale to one line.
  • src/main/ipc/filesystem-list-files-git-fallback-real.test.ts#L165-L167: reduce the assertion rationale to one line.
  • src/main/ssh/ssh-remote-commands.test.ts#L299-L303: reduce the ordering rationale to one line.
  • src/main/ssh/ssh-remote-node-resolution.test.ts#L189-L192: reduce the capability rationale to one line.
  • src/main/text-generation/commit-message-text-generation-model-discovery.test.ts#L37-L42: reduce the helper documentation to one concise comment.
  • src/main/text-generation/commit-message-text-generation-model-discovery.test.ts#L45-L46: reduce the environment-restoration rationale to one line.

As per coding guidelines: “Comments must be concise, non-obvious, and brief—prefer one line; do not explain obvious behavior or walk through code.”

Source: Coding guidelines


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 611db604-3b17-465a-82ab-38ad9496dd11

📥 Commits

Reviewing files that changed from the base of the PR and between c3a1694 and 7a27ce4.

📒 Files selected for processing (230)
  • .gitattributes
  • .github/workflows/pr.yml
  • .gitignore
  • config/scripts/check-changed-code-quality.mjs
  • config/scripts/check-react-doctor-changed.mjs
  • config/scripts/ensure-native-runtime.test.mjs
  • config/scripts/lint-react-doctor-changed.mjs
  • config/scripts/mobile-pairing-qrcode-import-plugin.test.mjs
  • config/scripts/pr-workflow-parallelism.test.mjs
  • config/scripts/rebuild-native-deps.test.mjs
  • config/scripts/regenerate-xterm-patches.mjs
  • config/scripts/regenerate-xterm-patches.test.mjs
  • config/scripts/run-ai-vault-typing-bench.mjs
  • config/scripts/verify-skills-cli-runtime.test.mjs
  • config/scripts/vitest-host-ports-setup.ts
  • config/scripts/windows-suite-baseline.mjs
  • config/scripts/windows-suite-baseline.test.mjs
  • config/windows-suite-baseline.json
  • docs/windows-test-suite-remediation-plan.md
  • resources/claude-held.webp
  • resources/claude-poses.webp
  • resources/gremlin-held.webp
  • resources/gremlin-poses.webp
  • resources/opencode-held.webp
  • resources/opencode-poses.webp
  • src/main/agent-hooks/installer-utils.test.ts
  • src/main/agent-hooks/managed-hook-stdin-lifecycle.test.ts
  • src/main/ai-vault/codex-session-root-dedup.ts
  • src/main/ai-vault/session-delete-target.test.ts
  • src/main/ai-vault/session-delete.test.ts
  • src/main/ai-vault/session-scanner-codex-dual-root.test.ts
  • src/main/ai-vault/session-scanner-opencode-sources-wsl-stall.test.ts
  • src/main/ai-vault/session-scanner-values.test.ts
  • src/main/ai-vault/session-scanner-values.ts
  • src/main/ai-vault/session-scanner.test.ts
  • src/main/artifacts/artifact-create-intent-store.test.ts
  • src/main/bitbucket/credential-store.test.ts
  • src/main/claude-accounts/runtime-auth-service-materialization.test.ts
  • src/main/cli/linux-bare-orca-dispatcher.test.ts
  • src/main/cli/linux-terminal-orca-cli-shim.test.ts
  • src/main/codex-accounts/runtime-home-mirrored-status-home.test.ts
  • src/main/codex-accounts/runtime-home-service-per-account-migration.test.ts
  • src/main/codex/codex-session-resume-home.test.ts
  • src/main/codex/codex-session-resume-preparation.test.ts
  • src/main/daemon/client.ts
  • src/main/daemon/daemon-client-connect-attempt.test.ts
  • src/main/daemon/daemon-client-connect-attempt.ts
  • src/main/daemon/daemon-preflight-client-replacement.test.ts
  • src/main/daemon/daemon-pty-adapter.ts
  • src/main/daemon/pty-subprocess-cwd-cancel-identity.test.ts
  • src/main/daemon/pty-subprocess-env-inheritance.test.ts
  • src/main/daemon/pty-subprocess-foreground-identity.test.ts
  • src/main/daemon/pty-subprocess-foreground-scan-cadence.test.ts
  • src/main/daemon/pty-subprocess-handle-lifecycle.test.ts
  • src/main/daemon/pty-subprocess-wsl-launch.test.ts
  • src/main/daemon/pty-subprocess.test.ts
  • src/main/devin/hook-service.test.ts
  • src/main/durable-file-write-syscall-proof.test.ts
  • src/main/ephemeral-vm-runtime-service.test.ts
  • src/main/git/porcelain-v1-records.test.ts
  • src/main/git/repo-detection.test.ts
  • src/main/git/status-branch-line-total-exec-contract.test.ts
  • src/main/git/status-shared-symlinks.test.ts
  • src/main/git/status-submodule-path-cache.test.ts
  • src/main/git/worktree-add-local-base-refresh.test.ts
  • src/main/git/worktree-add-local-base-suggestion.test.ts
  • src/main/git/worktree-deferred-removal-real-git.test.ts
  • src/main/git/worktree-include-file.test.ts
  • src/main/git/worktree-shared-directories.test.ts
  • src/main/ipc/ephemeral-vm.test.ts
  • src/main/ipc/filesystem-list-files-git-fallback-real.test.ts
  • src/main/ipc/filesystem-watcher-local-unsubscribe.test.ts
  • src/main/ipc/folder-repo-git-upgrade.test.ts
  • src/main/ipc/local-network-connection-test.test.ts
  • src/main/ipc/native-chat.test.ts
  • src/main/ipc/pet-generated-write.ts
  • src/main/ipc/pet-image-signature.test.ts
  • src/main/ipc/pet-image-signature.ts
  • src/main/ipc/pet-orphan-sweep-disk.test.ts
  • src/main/ipc/pet-orphan-sweep.test.ts
  • src/main/ipc/pet-orphan-sweep.ts
  • src/main/ipc/pet.test.ts
  • src/main/ipc/pet.ts
  • src/main/ipc/pty-codex-account-attribution.test.ts
  • src/main/ipc/pty-daemon-spawn-wsl-runtime.test.ts
  • src/main/ipc/pty-login-shell-startup-commands.test.ts
  • src/main/ipc/pty-spawn-env-codex-resume-provenance.test.ts
  • src/main/ipc/pty-wsl-cwd-validation.test.ts
  • src/main/ipc/register-core-handlers.test.ts
  • src/main/ipc/register-core-handlers.ts
  • src/main/ipc/worktree-base-directory-event-filter.test.ts
  • src/main/ipc/worktree-base-directory-watcher.test.ts
  • src/main/ipc/worktree-symlinks.test.ts
  • src/main/ipc/worktree-symlinks.ts
  • src/main/kimi/hook-service.test.ts
  • src/main/local-builds/local-build-candidate.test.ts
  • src/main/local-downloaded-folder-promotion.test.ts
  • src/main/native-chat/transcript-read-cache.test.ts
  • src/main/native-chat/transcript-watch-error.test.ts
  • src/main/providers/local-pty-shell-ready-wrapper-generation.test.ts
  • src/main/pty/codex-shell-launch-preflight.test.ts
  • src/main/rate-limits/codex-fetcher.test.ts
  • src/main/rate-limits/service-account-target-selection.test.ts
  • src/main/rate-limits/service-inactive-account-previews.test.ts
  • src/main/rate-limits/service-refresh-orchestration.test.ts
  • src/main/runtime/agent-session-claim-identity.test.ts
  • src/main/runtime/exit-provenance-audit.test.ts
  • src/main/runtime/orca-runtime-files-terminal-artifact-grants.test.ts
  • src/main/runtime/orca-runtime-files-terminal-artifact-io.test.ts
  • src/main/runtime/orca-runtime-files-terminal-link-host-translation.test.ts
  • src/main/runtime/orca-runtime.test.ts
  • src/main/runtime/orca-runtime.ts
  • src/main/runtime/rpc/methods/ai-vault.test.ts
  • src/main/runtime/rpc/methods/client-ui-schemas.ts
  • src/main/skills/skill-bundle-creation.test.ts
  • src/main/skills/skill-bundle-creation.ts
  • src/main/skills/skill-provider-runtime-roots.test.ts
  • src/main/source-control/hosted-review-creation-shared-symlinks.test.ts
  • src/main/ssh/ssh-g-config-resolution.test.ts
  • src/main/ssh/ssh-relay-upload-stage-commands.test.ts
  • src/main/ssh/ssh-remote-commands.test.ts
  • src/main/ssh/ssh-remote-node-resolution.test.ts
  • src/main/ssh/ssh-system-fallback.test.ts
  • src/main/ssh/system-ssh-forward-process.test.ts
  • src/main/text-generation/commit-message-text-generation-model-discovery.test.ts
  • src/main/updater-test-harness.ts
  • src/main/updater.build-channel-selection.test.ts
  • src/main/updater.check-preflight.test.ts
  • src/main/updater.check-settlement.test.ts
  • src/main/updater.linux-root-package-install.test.ts
  • src/main/updater.nudge-campaign.test.ts
  • src/main/updater.prerelease-fallback.test.ts
  • src/main/updater.publishing-window-feed.test.ts
  • src/main/updater.quit-and-install.test.ts
  • src/main/updater.silent-settle.test.ts
  • src/main/updater.startup-scheduling.test.ts
  • src/main/updater.timer-disposal.test.ts
  • src/main/updater.ts
  • src/main/window/clipboard-file-copy.test.ts
  • src/preload/api/pet-api.ts
  • src/preload/index.ts
  • src/relay/ai-vault-handler.test.ts
  • src/relay/ai-vault-service-client.test.ts
  • src/relay/fs-handler-mock-dispatcher.ts
  • src/relay/fs-handler.test.ts
  • src/relay/git-handler-worktree-provisioning.test.ts
  • src/relay/rotating-log-writer.test.ts
  • src/relay/skill-upload-multi-relay.integration.test.ts
  • src/relay/subprocess.test.ts
  • src/relay/terminal-history-wsl.test.ts
  • src/renderer/src/app-startup-routing.test.ts
  • src/renderer/src/components/editor/monaco-content-sync.undo-history.test.ts
  • src/renderer/src/components/pet/DetectedSpriteFrame.tsx
  • src/renderer/src/components/pet/PetFromImageDialog.test.tsx
  • src/renderer/src/components/pet/PetFromImageDialog.tsx
  • src/renderer/src/components/pet/PetOverlay.held-pose.test.tsx
  • src/renderer/src/components/pet/PetOverlay.tsx
  • src/renderer/src/components/pet/PetOverlay.walk.test.tsx
  • src/renderer/src/components/pet/PetSheetPreview.test.tsx
  • src/renderer/src/components/pet/PetSheetPreview.tsx
  • src/renderer/src/components/pet/PetSourceCrop.test.tsx
  • src/renderer/src/components/pet/PetSourceCrop.tsx
  • src/renderer/src/components/pet/bundled-pet-pose-sprite.test.ts
  • src/renderer/src/components/pet/bundled-pet-pose-sprite.ts
  • src/renderer/src/components/pet/pet-agent-state.ts
  • src/renderer/src/components/pet/pet-blob-cache.ts
  • src/renderer/src/components/pet/pet-body-motion-css.test.ts
  • src/renderer/src/components/pet/pet-body-motion-css.ts
  • src/renderer/src/components/pet/pet-crop-drag.test.ts
  • src/renderer/src/components/pet/pet-crop-drag.ts
  • src/renderer/src/components/pet/pet-cutout-quality.test.ts
  • src/renderer/src/components/pet/pet-cutout-quality.ts
  • src/renderer/src/components/pet/pet-fall-physics.test.ts
  • src/renderer/src/components/pet/pet-fall-physics.ts
  • src/renderer/src/components/pet/pet-from-image-message.test.ts
  • src/renderer/src/components/pet/pet-from-image-message.ts
  • src/renderer/src/components/pet/pet-from-image.test.ts
  • src/renderer/src/components/pet/pet-from-image.ts
  • src/renderer/src/components/pet/pet-image-crop.test.ts
  • src/renderer/src/components/pet/pet-image-crop.ts
  • src/renderer/src/components/pet/pet-image-cutout.test.ts
  • src/renderer/src/components/pet/pet-image-cutout.ts
  • src/renderer/src/components/pet/pet-image-decode.ts
  • src/renderer/src/components/pet/pet-image-resample.test.ts
  • src/renderer/src/components/pet/pet-image-resample.ts
  • src/renderer/src/components/pet/pet-magenta-key.test.ts
  • src/renderer/src/components/pet/pet-magenta-key.ts
  • src/renderer/src/components/pet/pet-models.test.ts
  • src/renderer/src/components/pet/pet-models.ts
  • src/renderer/src/components/pet/pet-pose-arbitration.test.ts
  • src/renderer/src/components/pet/pet-pose-arbitration.ts
  • src/renderer/src/components/pet/pet-raster-transform.test.ts
  • src/renderer/src/components/pet/pet-raster-transform.ts
  • src/renderer/src/components/pet/pet-rig-detection.test.ts
  • src/renderer/src/components/pet/pet-rig-detection.ts
  • src/renderer/src/components/pet/pet-rigs.test.ts
  • src/renderer/src/components/pet/pet-rigs.ts
  • src/renderer/src/components/pet/pet-sheet-composer.test.ts
  • src/renderer/src/components/pet/pet-sheet-composer.ts
  • src/renderer/src/components/pet/pet-walk-lane.test.ts
  • src/renderer/src/components/pet/pet-walk-lane.ts
  • src/renderer/src/components/pet/sprite-animation-css.test.ts
  • src/renderer/src/components/pet/sprite-animation-css.ts
  • src/renderer/src/components/pet/usePetFallToLane.ts
  • src/renderer/src/components/pet/usePetPointerInteraction.test.ts
  • src/renderer/src/components/pet/usePetPointerInteraction.ts
  • src/renderer/src/components/pet/usePetUrl.load-failure.test.ts
  • src/renderer/src/components/pet/usePetUrl.ts
  • src/renderer/src/components/pet/usePetWalkLane.test.ts
  • src/renderer/src/components/pet/usePetWalkLane.ts
  • src/renderer/src/components/pull-request-page-host-boundary.test.ts
  • src/renderer/src/components/right-sidebar/SourceControl.host-context-boundary.test.ts
  • src/renderer/src/components/status-bar/PetStatusSegment.test.tsx
  • src/renderer/src/components/status-bar/PetStatusSegment.tsx
  • src/renderer/src/components/terminal/initial-terminal-wiring.test.ts
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/store/slices/ui-hydration-workspace-preferences.test.ts
  • src/renderer/src/store/slices/ui.ts
  • src/shared/file-mode-capability.test.ts
  • src/shared/file-mode-capability.ts
  • src/shared/node-markdown-document-discovery.test.ts
  • src/shared/persisted-ui-state-types.ts
  • src/shared/posix-shell.test.ts
  • src/shared/posix-shell.ts
  • src/shared/probe-scratch-directory.ts
  • src/shared/symlink-capability.test.ts
  • src/shared/symlink-capability.ts
  • src/shared/wsl-login-shell-command.test.ts
  • tests/e2e/cross-version-wire/release-checkout.ts
  • tests/e2e/helpers/nested-runtime-proxy-jump-fixture.unit.test.ts
💤 Files with no reviewable changes (1)
  • src/main/ipc/worktree-symlinks.ts
🚧 Files skipped from review as they are similar to previous changes (181)
  • src/preload/index.ts
  • src/main/updater.check-settlement.test.ts
  • src/main/updater.nudge-campaign.test.ts
  • src/relay/subprocess.test.ts
  • src/main/rate-limits/codex-fetcher.test.ts
  • src/main/local-builds/local-build-candidate.test.ts
  • src/main/ipc/pty-daemon-spawn-wsl-runtime.test.ts
  • src/main/daemon/daemon-pty-adapter.ts
  • src/main/ai-vault/session-scanner-codex-dual-root.test.ts
  • src/renderer/src/components/right-sidebar/SourceControl.host-context-boundary.test.ts
  • src/main/runtime/agent-session-claim-identity.test.ts
  • src/renderer/src/app-startup-routing.test.ts
  • src/renderer/src/components/pet/pet-models.test.ts
  • src/main/ipc/pet-orphan-sweep.test.ts
  • src/main/updater.prerelease-fallback.test.ts
  • src/main/ipc/folder-repo-git-upgrade.test.ts
  • src/main/rate-limits/service-refresh-orchestration.test.ts
  • .gitattributes
  • tests/e2e/helpers/nested-runtime-proxy-jump-fixture.unit.test.ts
  • src/renderer/src/components/pet/pet-magenta-key.test.ts
  • config/windows-suite-baseline.json
  • src/renderer/src/components/pet/pet-raster-transform.ts
  • src/main/daemon/pty-subprocess-foreground-identity.test.ts
  • config/scripts/pr-workflow-parallelism.test.mjs
  • src/shared/probe-scratch-directory.ts
  • config/scripts/windows-suite-baseline.test.mjs
  • src/main/ipc/pet-image-signature.ts
  • src/relay/rotating-log-writer.test.ts
  • src/renderer/src/components/pet/pet-image-resample.ts
  • src/renderer/src/components/pull-request-page-host-boundary.test.ts
  • src/main/ai-vault/codex-session-root-dedup.ts
  • src/main/agent-hooks/installer-utils.test.ts
  • src/main/updater.check-preflight.test.ts
  • src/main/claude-accounts/runtime-auth-service-materialization.test.ts
  • src/main/codex-accounts/runtime-home-service-per-account-migration.test.ts
  • src/main/daemon/daemon-preflight-client-replacement.test.ts
  • src/main/cli/linux-terminal-orca-cli-shim.test.ts
  • src/main/ephemeral-vm-runtime-service.test.ts
  • src/main/updater.timer-disposal.test.ts
  • src/main/agent-hooks/managed-hook-stdin-lifecycle.test.ts
  • src/main/runtime/orca-runtime-files-terminal-link-host-translation.test.ts
  • config/scripts/check-react-doctor-changed.mjs
  • config/scripts/run-ai-vault-typing-bench.mjs
  • src/main/kimi/hook-service.test.ts
  • src/main/ipc/pty-spawn-env-codex-resume-provenance.test.ts
  • src/renderer/src/components/pet/pet-rig-detection.test.ts
  • src/main/providers/local-pty-shell-ready-wrapper-generation.test.ts
  • src/main/ai-vault/session-scanner-values.ts
  • src/renderer/src/components/pet/pet-blob-cache.ts
  • src/renderer/src/components/pet/pet-pose-arbitration.test.ts
  • src/main/updater.silent-settle.test.ts
  • src/main/git/worktree-include-file.test.ts
  • src/renderer/src/components/pet/DetectedSpriteFrame.tsx
  • src/renderer/src/components/pet/pet-agent-state.ts
  • src/shared/file-mode-capability.ts
  • src/main/ai-vault/session-scanner-opencode-sources-wsl-stall.test.ts
  • src/renderer/src/components/pet/pet-walk-lane.test.ts
  • src/main/updater.linux-root-package-install.test.ts
  • src/shared/node-markdown-document-discovery.test.ts
  • src/main/updater.publishing-window-feed.test.ts
  • src/main/runtime/orca-runtime-files-terminal-artifact-io.test.ts
  • src/relay/ai-vault-service-client.test.ts
  • src/renderer/src/components/editor/monaco-content-sync.undo-history.test.ts
  • src/relay/ai-vault-handler.test.ts
  • src/renderer/src/components/pet/pet-from-image-message.test.ts
  • src/main/cli/linux-bare-orca-dispatcher.test.ts
  • config/scripts/check-changed-code-quality.mjs
  • src/main/ai-vault/session-scanner.test.ts
  • src/main/runtime/exit-provenance-audit.test.ts
  • src/main/ipc/register-core-handlers.ts
  • src/renderer/src/components/terminal/initial-terminal-wiring.test.ts
  • src/main/codex-accounts/runtime-home-mirrored-status-home.test.ts
  • src/main/devin/hook-service.test.ts
  • src/main/skills/skill-bundle-creation.test.ts
  • src/main/ipc/ephemeral-vm.test.ts
  • src/renderer/src/components/pet/pet-fall-physics.test.ts
  • src/main/runtime/orca-runtime.test.ts
  • src/renderer/src/components/pet/pet-crop-drag.test.ts
  • src/relay/terminal-history-wsl.test.ts
  • config/scripts/verify-skills-cli-runtime.test.mjs
  • src/renderer/src/store/slices/ui-hydration-workspace-preferences.test.ts
  • src/main/daemon/pty-subprocess.test.ts
  • src/preload/api/pet-api.ts
  • src/main/pty/codex-shell-launch-preflight.test.ts
  • src/main/ai-vault/session-scanner-values.test.ts
  • src/main/durable-file-write-syscall-proof.test.ts
  • src/main/source-control/hosted-review-creation-shared-symlinks.test.ts
  • src/renderer/src/components/pet/bundled-pet-pose-sprite.test.ts
  • src/renderer/src/components/pet/pet-sheet-composer.test.ts
  • src/main/updater.quit-and-install.test.ts
  • src/main/daemon/pty-subprocess-foreground-scan-cadence.test.ts
  • src/main/rate-limits/service-inactive-account-previews.test.ts
  • src/main/ipc/pet-orphan-sweep-disk.test.ts
  • src/main/window/clipboard-file-copy.test.ts
  • src/main/daemon/pty-subprocess-env-inheritance.test.ts
  • config/scripts/lint-react-doctor-changed.mjs
  • src/renderer/src/components/pet/pet-rigs.test.ts
  • src/main/daemon/pty-subprocess-cwd-cancel-identity.test.ts
  • src/main/updater.startup-scheduling.test.ts
  • config/scripts/regenerate-xterm-patches.mjs
  • config/scripts/ensure-native-runtime.test.mjs
  • src/main/runtime/rpc/methods/client-ui-schemas.ts
  • src/renderer/src/components/pet/pet-body-motion-css.test.ts
  • src/main/ssh/ssh-system-fallback.test.ts
  • src/main/daemon/daemon-client-connect-attempt.ts
  • src/renderer/src/components/pet/pet-models.ts
  • src/renderer/src/components/pet/pet-from-image-message.ts
  • src/renderer/src/components/pet/pet-crop-drag.ts
  • src/renderer/src/components/pet/sprite-animation-css.test.ts
  • config/scripts/mobile-pairing-qrcode-import-plugin.test.mjs
  • src/main/daemon/pty-subprocess-wsl-launch.test.ts
  • src/main/native-chat/transcript-read-cache.test.ts
  • src/renderer/src/components/pet/pet-image-crop.test.ts
  • src/renderer/src/components/pet/pet-pose-arbitration.ts
  • src/renderer/src/components/pet/pet-raster-transform.test.ts
  • src/main/ai-vault/session-delete.test.ts
  • src/main/git/worktree-deferred-removal-real-git.test.ts
  • config/scripts/regenerate-xterm-patches.test.mjs
  • src/main/ipc/native-chat.test.ts
  • .gitignore
  • src/shared/symlink-capability.ts
  • src/main/ipc/pty-codex-account-attribution.test.ts
  • src/main/codex/codex-session-resume-preparation.test.ts
  • src/renderer/src/i18n/locales/en.json
  • config/scripts/rebuild-native-deps.test.mjs
  • src/main/bitbucket/credential-store.test.ts
  • src/main/ipc/pet-generated-write.ts
  • src/main/runtime/orca-runtime-files-terminal-artifact-grants.test.ts
  • src/main/runtime/orca-runtime.ts
  • src/main/ipc/worktree-base-directory-event-filter.test.ts
  • src/renderer/src/components/pet/usePetPointerInteraction.ts
  • src/main/rate-limits/service-account-target-selection.test.ts
  • src/renderer/src/components/pet/PetOverlay.walk.test.tsx
  • src/renderer/src/components/pet/sprite-animation-css.ts
  • src/renderer/src/components/pet/pet-fall-physics.ts
  • src/renderer/src/components/pet/pet-image-cutout.test.ts
  • src/main/skills/skill-bundle-creation.ts
  • src/renderer/src/components/pet/usePetPointerInteraction.test.ts
  • src/main/ai-vault/session-delete-target.test.ts
  • src/renderer/src/components/pet/pet-walk-lane.ts
  • src/main/updater-test-harness.ts
  • src/main/ipc/worktree-base-directory-watcher.test.ts
  • src/main/updater.ts
  • src/renderer/src/components/pet/pet-image-resample.test.ts
  • src/main/daemon/client.ts
  • src/renderer/src/components/pet/usePetFallToLane.ts
  • src/shared/persisted-ui-state-types.ts
  • config/scripts/windows-suite-baseline.mjs
  • src/main/updater.build-channel-selection.test.ts
  • src/renderer/src/components/pet/pet-cutout-quality.ts
  • src/main/local-downloaded-folder-promotion.test.ts
  • src/shared/file-mode-capability.test.ts
  • src/renderer/src/components/pet/bundled-pet-pose-sprite.ts
  • src/renderer/src/components/pet/pet-image-decode.ts
  • src/renderer/src/components/pet/pet-magenta-key.ts
  • src/shared/posix-shell.ts
  • src/main/native-chat/transcript-watch-error.test.ts
  • src/main/ssh/ssh-g-config-resolution.test.ts
  • src/main/daemon/pty-subprocess-handle-lifecycle.test.ts
  • src/main/ipc/pty-login-shell-startup-commands.test.ts
  • src/renderer/src/components/pet/pet-rig-detection.ts
  • src/main/ipc/pet-orphan-sweep.ts
  • src/renderer/src/components/pet/pet-rigs.ts
  • src/renderer/src/components/pet/pet-image-cutout.ts
  • src/main/ipc/local-network-connection-test.test.ts
  • src/renderer/src/components/pet/PetOverlay.held-pose.test.tsx
  • src/renderer/src/components/pet/pet-body-motion-css.ts
  • src/main/codex/codex-session-resume-home.test.ts
  • src/main/ipc/pet.test.ts
  • src/renderer/src/store/slices/ui.ts
  • src/renderer/src/components/pet/PetSheetPreview.tsx
  • src/renderer/src/components/pet/pet-sheet-composer.ts
  • src/main/runtime/rpc/methods/ai-vault.test.ts
  • src/main/ipc/worktree-symlinks.test.ts
  • src/main/ipc/pty-wsl-cwd-validation.test.ts
  • .github/workflows/pr.yml
  • src/renderer/src/components/pet/usePetUrl.ts
  • src/renderer/src/components/pet/PetOverlay.tsx
  • src/main/ssh/system-ssh-forward-process.test.ts
  • src/main/ipc/filesystem-watcher-local-unsubscribe.test.ts
  • src/renderer/src/components/pet/pet-from-image.ts

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

Comment on lines +452 to +456
1. Write `config/scripts/windows-suite-baseline.mjs` that runs the suite,
strips ANSI, and emits a sorted `file → failing-test-count` JSON.
2. Commit the current output as `docs/reference/windows-suite-baseline.json`.
3. Add a `compare` mode that diffs a fresh run against the committed baseline
and exits non-zero **only on files that got worse or are newly failing**.

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.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Correct the baseline artifact path.

This plan directs contributors to docs/reference/windows-suite-baseline.json, but this PR stores the baseline at config/windows-suite-baseline.json. Updating the documented path would leave the actual comparison input stale. Update this reference and the final checklist reference at Line 686.

…nimations

# Conflicts:
#	src/main/runtime/orca-runtime.ts

@coderabbitai coderabbitai 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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/runtime/orca-runtime.ts (1)

13422-13466: 🩺 Stability & Availability | 🟠 Major

Forward ProviderSnapshotReadOptions through readVisibleTerminalState

The adopted-PTY path calls readVisibleTerminalState(ptyId) without the probe options. Thus, onAcquisition does not populate waiter.probedAcquisition, and timeout retirement cannot run for this path. Pass the options through, or narrow the probe documentation to the fallback paths that support retirement. [medium_effort_and_high_reward]

🧹 Nitpick comments (1)
src/main/runtime/orca-runtime.test.ts (1)

20864-20967: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Document the non-mode-switch tail exclusion.

Add one short comment to the stale-snapshot tests. Provider frames are discarded when live output advances snapshot.seq; live mode transitions instead use the headless emulator.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: df0fffb7-2b09-4d98-b605-cc6adae52e59

📥 Commits

Reviewing files that changed from the base of the PR and between 7a27ce4 and f464f8a.

📒 Files selected for processing (2)
  • src/main/runtime/orca-runtime.test.ts
  • src/main/runtime/orca-runtime.ts

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

This branch has not been deployed

No deployments
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