mirror of
https://github.com/stablyai/orca.git
synced 2026-09-27 08:02:35 +00:00
* fix(terminal): serialize only the visible width after a column shrink xterm does not reflow the alternate buffer (or a normal buffer under pre-21376 ConPTY), so after a shrink each line keeps its old length. SerializeAddon walked every non-final row to line.length, so any snapshot taken after a shrink carried stale right-hand cells that wrapped into extra rows on replay; restores repainted that garbage and a differential TUI such as OpenCode never cleared it. Clamp the row walk and the wrap-boundary lookups to the terminal's columns in Orca's addon-serialize source patch, and regenerate the bundles, maps and lockfile hash per docs/reference/xterm-patch-regeneration.md. * test(terminal): read shrink-snapshot fixtures through public APIs Drops the private-terminal casts the casting gate flags; the normal-buffer case now drives a plain pre-21376 ConPTY terminal and its SerializeAddon directly. * fix(terminal): blank a wide glyph clipped by a column shrink when serializing After a non-reflowing shrink a width-2 glyph can have its lead half in the last column and its trailing half past the grid. Serializing the lead half makes the replay wrap it to the next row and shift every row below, so serialize that cell as a blank and keep the row exactly the grid's width. A glyph ending exactly at the edge is unchanged. * test(mobile): move the session closure pin past the main agent status modules #22452 added src/shared/main-agent-status.ts and src/shared/agent-turn-outcome.ts, which agent-status-types.ts imports, so the session route's closure grew by two local modules (4218 -> 4220). That change was src/shared-only, so its own CI never ran this suite; main has been at 4220 since, and any PR that fires the mobile web app job fails on the stale pin. Measured on4064653740and on origin/main3ea15dd0a2. * test(terminal): differential serialize round-trip fuzz and transcript replay Seeded VT streams (text, CJK/emoji/combining, SGR, cursor/edit ops, scroll regions, DECAWM/IRM, alt-screen variants, DECSC, and shrink-heavy resizes) drive a source terminal in three modes: reflowing normal buffer, alternate buffer, and a non-reflowing pre-21376 ConPTY normal buffer. At each checkpoint every SerializeAddon build under test serializes it, and each output is replayed into a fresh terminal of the same size and compared cell by cell, plus cursor, active buffer and modes. CI runs 25 seeds per mode against a pinned list of pre-existing divergences, and replays the committed PTY transcripts (the existing agent fixtures plus new vim, less, pico, and OpenCode captures) under four resize schedules. Point ORCA_OLD_SERIALIZE_ADDON at a previous patched build to also check byte identity when no line is wider than the grid, and that no checkpoint regresses. * test(terminal): build the differential serialize baseline from any git ref config/scripts/build-serialize-addon-at-ref.mjs reverse-applies the patch that produced the installed @xterm/addon-serialize dist, applies the ref's patch, and verifies each step against the patches' blob hashes, so the fuzz can use origin/main (or any fix commit) as its baseline without a second install. ORCA_NEW_SERIALIZE_ADDON swaps in a built dist for the build under test, and a seed-pinned test replays the nine I3 regressions found against origin/main. * fix(terminal): serialize a clipped wide glyph as a width-1 blank The stand-in for a wide glyph clipped by a column shrink came from getNullCell(), whose width is 0. _nextCell skipped it as a wide trailer, and the row-end wrap check counted the width-0 _backgroundCell as content, so a soft wrap after the clipped column was taken as natural and replayed one column early (conpty seed 1149: `abcdefghi中WRAPPED` at 12 -> 10 cols replayed as `abcdefghiR`/`APPED`). Blank the cell in place instead: width 1, no codepoint, its own attributes, so it counts as one empty column and forces the wrap. Differential sweep vs origin/main, 7000 cases per mode: I1 0 byte diffs, seed 1149 fixed; the remaining I3 regressions are the trailing background-row seeds. * test(terminal): neutral paths in the serialize fixtures and usage comment The OpenCode transcript carried this machine's lane paths in its footer; replace them with same-length neutral paths so the recorded cursor layout is unchanged. * fix(terminal): keep trailing background-only rows when serializing Without scrollback, _serializeString trims rows after the last content cursor. A row made only of background-colored blanks emits its erase in _rowEnd but never moved that cursor, so two or more such rows at the bottom were dropped (4x3 `r1\r\n\e[48;5;157m\e[J\e[0m\e[3;1H` replayed with the last row blank). Track the erase separately and extend the kept rows to it, except when the cursor is wrap-pending: relative moves back from those rows cannot re-create that state, and doing so regressed normal 508, alt 1425/6647, conpty 4699. Harness: I1 now exempts checkpoints with a background row after the last text row, the one place this fix changes bytes on purpose (scope helpers move to serialize-grid-variant-scope.ts); conpty seed 5 leaves the pinned pre-existing list. Sweep vs origin/main, 7000 cases per mode: I1 0, I3 regressions 0; fixed/both-fail normal 967/3914, alt 2628/8316, conpty 6657/2937 (was 323/4558, 2296/8648, 5466/4128). * test(terminal): narrow the I1 carve-out to where the serializer keeps background rows Trailing background-only rows change bytes only when the serialized range has no scrollback (the trimming path) and the cursor is not wrap-pending; checkpoints with scrollback or a wrap-pending cursor are held to byte identity again. The 7000-per-mode sweep against origin/main stays at I1 0 and I3 0. * test(native-chat): pin that screen scrapers ignore kept background rows The serializer now keeps trailing background-only rows, so a painted TUI's screen read as text ends in \r\n\x1b[NX rows. Serialize the same frame with and without them and check the Claude option scrape, the empty-prompt check and the fork transcript read the same thing. * test(terminal): read xterm core internals through a checked parser, not Reflect.get The fuzz oracle reached xterm's private _core with Reflect.get, which the low-evidence gate rejects. Narrow _core, writeSync and the DECSTBM bounds with in/typeof checks into one named XtermCoreInternals shape instead. * test(terminal): keep captured serialize transcripts byte-exact on Windows checkouts
88 lines
4.5 KiB
Plaintext
88 lines
4.5 KiB
Plaintext
# A shebang plus CRLF makes vite's SSR transform emit a literal `#!` mid-module,
|
|
# so any suite importing the script dies at load with a SyntaxError. Pin the whole
|
|
# directory rather than the scripts that happen to have a test today.
|
|
/config/scripts/**/*.mjs text eol=lf
|
|
/skill-guides/*.md text eol=lf
|
|
/skill-stubs/*.md text eol=lf
|
|
/skill-stubs/_shared/*.md text eol=lf
|
|
/skills/*/SKILL.md text eol=lf
|
|
/src/cli/bundled-skill-guides.ts text eol=lf
|
|
# Bundled plugin trees are byte-hashed; CRLF checkout would break the pinned hash.
|
|
/resources/plugins/** text eol=lf
|
|
# Relay assets are copied verbatim into the bundle and hashed byte-for-byte into
|
|
# .version, which names the immutable remote install dir. A CRLF checkout makes a
|
|
# Windows-built client disagree with a mac/Linux-built one on the same release,
|
|
# so one host ends up with two relay trees (#17886 review).
|
|
/config/relay-assets/** text eol=lf
|
|
# Pin the bytes so a patch reads and diffs identically on every host. It is NOT
|
|
# what makes the hash right: pnpm hashes a patch LF-normalized, so a CRLF checkout
|
|
# cannot change it. Believing otherwise put a hand-computed raw digest in the
|
|
# lockfile twice and broke every install (#17886).
|
|
# These files are stored LF, which is not always the encoding they were written
|
|
# against -- @vscode/windows-process-tree ships CRLF sources -- so any code that
|
|
# runs `git apply` on one must force `-c core.autocrlf=input` rather than trust
|
|
# the host's setting. See config/scripts/windows-process-tree-gyp-rebuild.mjs.
|
|
/config/patches/*.patch -text
|
|
# Same reason, and pnpm parses these too: a CRLF checkout makes the mobile
|
|
# patches unparseable, so Windows packaging dies on ERR_PNPM_INVALID_PATCH.
|
|
/mobile/patches/*.patch -text
|
|
# The xterm bundle hunks also make a diff nobody can read; review the hand-written
|
|
# source patch under xterm-src/ instead. The sibling patches stay diffable.
|
|
/config/patches/@xterm__xterm@*.patch -diff
|
|
/config/patches/xterm-src/*.patch text eol=lf
|
|
# pnpm parses these unified diffs during Windows installs; keep checkout bytes stable.
|
|
/mobile/patches/*.patch -text
|
|
# Generated wrapper fixtures: collapse them in the PR diff so they stop drowning
|
|
# the reviewable change, and pin LF because they are compared byte-for-byte.
|
|
# Not -diff: the shell diff is the review surface when a wrapper does change.
|
|
/src/main/__fixtures__/shell-wrapper-snapshots/*.txt linguist-generated=true text eol=lf
|
|
# Captured agent PTY transcripts. -text, not `text eol=lf` like the wrapper snapshots above:
|
|
# these carry real CR and CRLF bytes as the terminal emitted them, and line-ending
|
|
# normalisation on a Windows checkout would rewrite the evidence the fixture exists to be.
|
|
/src/main/runtime/__fixtures__/*.txt -text
|
|
/src/main/daemon/__fixtures__/pty-transcripts/*.txt -text
|
|
# Generated runtime English subset: compared byte-for-byte by
|
|
# verify:localization-runtime-catalog, so a CRLF checkout would fail the gate.
|
|
/src/renderer/src/i18n/en-runtime-required.json linguist-generated=true text eol=lf
|
|
# Generated method->params catalog: compared byte-for-byte by
|
|
# verify:rpc-params-catalog, so a CRLF checkout would fail the gate.
|
|
/src/shared/rpc-contract/rpc-params-catalog.generated.ts linguist-generated=true text eol=lf
|
|
# Mobile web page source. Every text byte here is hashed into an asset digest and from
|
|
# there into buildId, so a CRLF Windows checkout would ship a different bundle id for
|
|
# identical source (91af2897 vs 9d78435e, measured on the bundle this replaced).
|
|
/mobile/src/** text eol=lf
|
|
/mobile/app/** text eol=lf
|
|
/mobile/web-entry/** text eol=lf
|
|
# The blanket pin above would mark a future binary as text; exempt the asset types an
|
|
# RN page actually carries.
|
|
/mobile/src/**/*.png -text
|
|
/mobile/src/**/*.jpg -text
|
|
/mobile/src/**/*.jpeg -text
|
|
/mobile/src/**/*.gif -text
|
|
/mobile/src/**/*.ico -text
|
|
/mobile/src/**/*.webp -text
|
|
/mobile/src/**/*.ttf -text
|
|
/mobile/src/**/*.otf -text
|
|
/mobile/src/**/*.woff -text
|
|
/mobile/src/**/*.woff2 -text
|
|
/mobile/app/**/*.png -text
|
|
/mobile/app/**/*.jpg -text
|
|
/mobile/app/**/*.jpeg -text
|
|
/mobile/app/**/*.gif -text
|
|
/mobile/app/**/*.ico -text
|
|
/mobile/app/**/*.webp -text
|
|
/mobile/app/**/*.ttf -text
|
|
/mobile/app/**/*.otf -text
|
|
/mobile/app/**/*.woff -text
|
|
/mobile/app/**/*.woff2 -text
|
|
/mobile/web-entry/**/*.png -text
|
|
/mobile/web-entry/**/*.jpg -text
|
|
/mobile/web-entry/**/*.jpeg -text
|
|
/mobile/web-entry/**/*.gif -text
|
|
/mobile/web-entry/**/*.ico -text
|
|
/mobile/web-entry/**/*.webp -text
|
|
/mobile/web-entry/**/*.ttf -text
|
|
/mobile/web-entry/**/*.otf -text
|
|
/mobile/web-entry/**/*.woff -text
|
|
/mobile/web-entry/**/*.woff2 -text
|