fix(cli): preserve trailing newline in forward output - #232
Conversation
34a7c50 to
4e9c137
Compare
4e9c137 to
4d98a34
Compare
PR #232 (@LunaMeerkats) fixed the same defect independently and carried explicit tests that already-terminated content — CRLF included — survives byte-for-byte. The behavior was already guaranteed here (`endsWith('\n')` is true for `\r\n`), but the pin is worth keeping; adopted with credit. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…266) * fix(forward): terminate resynced lecture files with a newline (#116) The translator trims every model response and nothing on the forward path put a terminator back, so each resynced file was written with its last line unterminated — `\ No newline at end of file` in all 69 Track B PR diffs on lecture-python.zh-cn, dirtying the next edit's diff on each file and tripping POSIX-minded tooling. The newline is added in `finalizeResyncContent`, which already returns the exact bytes that get written (the structural-parity guard runs on its output), so the local write and the --github commit both inherit it from one place rather than each write site remembering. --test mode terminates its mock the same way so the smoke path exercises the same bytes. Narrow by construction: already-terminated content is byte-identical, trailing blank lines are preserved rather than collapsed, and empty content stays empty so it remains falsy and still skips the write. Not fixed here: `translate init` writes `injectHeadingMap(applyTypography(…))` of the same trimmed model output and carries the same defect — out of #116's scope, recorded in the .dev log entry as a sibling worth filing. The action's sync path was never affected (`reconstructDocument` has always ended with `.trim() + '\n'`), and forward's state files come from `yaml.dump`, which terminates. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * style: prettier the new finalize tests `format:check` is a separate CI step from `lint`; the new #116 test's multi-line call fits on one line under the repo's print width. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * test(forward): adopt #232's LF/CRLF byte-for-byte preservation cases PR #232 (@LunaMeerkats) fixed the same defect independently and carried explicit tests that already-terminated content — CRLF included — survives byte-for-byte. The behavior was already guaranteed here (`endsWith('\n')` is true for `\r\n`), but the pin is worth keeping; adopted with credit. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Thanks so much for this contribution, @LunaMeerkats — and apologies that it sat without review for two weeks. You diagnosed #116 correctly and fixed it cleanly, and the validation notes (especially the careful Windows baselining) were genuinely helpful when comparing approaches. The fix ended up landing via #266, which places the newline append inside Your LF/CRLF byte-for-byte preservation tests outlived the comparison, though: they pin a stronger contract than the property assertions #266 originally carried (any silent byte rewrite on the write path fails them, not just a missing terminator), so they were adopted into #266 with credit — see the Thanks again for taking on a |
Fixes #116.
What changed
forwardoutput once before the local and--githubpaths split.[Unreleased]heading after rebasing onto current main,retaining the entries added by PRs 246 and 247.
Reproduction
Before the fix, the focused
forward.test.tssuite failed the two new local andGitHub-path assertions (
2 failed, 9 passed): both outputs returnedendsWith("\n") === false.Validation
npm run lint: passed.--stdin-filepath.npm run check-dev-refs: 133 references passed.npm run build: passed; the committed Action bundle was byte-identical because this is aCLI-only path.
npm audit --omit=dev: one moderateundiciadvisory on both the branch and exact currentmain
842528b; this PR changes no dependency.current main
842528bproduced the identical 11 failing suites and 23 failing tests(1,430/1,453 passed). Those shared failures are pre-existing CRLF, Windows path-separator,
and symlink-permission incompatibilities; this branch adds exactly two passing tests.
A direct final-worktree Prettier check reports the Windows
core.autocrlfcheckout of the twotracked TypeScript files; the committed LF blobs pass the exact formatting oracle above.
Provenance
Authored and submitted by OpenAI Codex operating autonomously under a user-configured public
open-source contribution workflow. No human pre-submission review is claimed.