Skip to content

fix(commands): localize /undo feedback - #7121

Merged
Hmbown merged 1 commit into
codewhale-hq:mainfrom
Aboysky:fix/undo-localization
Oct 29, 2026
Merged

Hmbown merged 1 commit into
codewhale-hq:mainfrom
Aboysky:fix/undo-localization

Conversation

@Aboysky

@Aboysky Aboysky commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

What and why

/undo outcome messages were still hardcoded English — the remaining surface #7071 names after the /diff slice landed in 887a3c6 (#7101). This routes them through the presentation facet with translations in all 15 complete locale packs, following the exact /diff shape:

  • UndoCmd registration gains Caps::PRESENTATION
  • patch_result / conversation_result take a &dyn CommandPresentationContext; the internal reports return Result like diff_report
  • 29 CmdUndo* keys: catalog enum + ALL_MESSAGE_IDS in codewhale-localization, resolve arms in tui diagnostics_messages, values in en + 14 packs
  • the shared FILES_NOT_REVERTED_NOTE / NO_FILE_CHANGES_NOTE / SNAPSHOT_REPO_UNAVAILABLE_PREFIX consts became catalog keys (they had no other consumers)

English output is byte-identical to before: the exact-string assertions in operations_tests.rs and debug_mutation_host_tests.rs pass unchanged.

Not in this slice: /edit and /retry messages, the "Command capability unavailable" wiring errors, and host-provided RestoreBlocked text — the same surfaces /diff left unlocalized.

Issue

Refs #7071 (undo portion) — I claimed this slice in the issue. With this and #7101, both surfaces the issue names as remaining are covered; leaving the close call to you in case more surfaces belong to it.

How I tested it

scripts/dev-test.sh crates/commands undo     → test result: ok. 4 passed; 0 failed
scripts/dev-test.sh crates/commands          → test result: ok. 28 passed; 0 failed
scripts/dev-test.sh tui debug_mutation_host  → test result: ok. 38 passed; 0 failed
cargo test -p codewhale-localization --locked → test result: ok. 54 passed; 0 failed
python3 scripts/check-tui-locale-parity.py   → PASS (15 packs, 2673/2673 keys each)

Two red checks, both from main moving 28 commits past this branch's base (4b3053d) — the PR merge ref carries them, and neither file is touched here:

  • Lint — cargo fmt drift in crates/release/src/install.rs (from the install/uninstall work that landed on main after this branch was cut).
  • Test (ubuntu-latest) — exec_stream_drop_acceptance and two lifecycle_outbox_exec integration tests in crates/tui/tests/integration/; this PR touches none of those paths (commands-crate messages, locale catalogs, and the two test files listed above).

cargo fmt --all -- --check on the branch itself is clean apart from that main drift.

Checklist

  • One focused change, started from current main
  • Behavior-preserving localization; existing tests cover it and pass unchanged
  • No new user-facing feature, so no docs/features.toml row needed

Route /undo outcome messages through the presentation facet and provide
translations in all 15 complete locale packs, following the /diff
localization in 887a3c6. English output stays byte-identical: the
exact-string host tests pass unchanged.

Refs codewhale-hq#7071 (undo portion).

Signed-off-by: Boyce <aboyskyi@gmail.com>
@Aboysky
Aboysky requested a review from Hmbown as a code owner October 28, 2026 02:33

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

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@github-actions github-actions Bot added the contribution-gate Author not yet in .github/APPROVED_CONTRIBUTORS; a maintainer grants access with /lgtm label Oct 28, 2026
@Hmbown
Hmbown merged commit db0c1de into codewhale-hq:main Oct 29, 2026
24 of 26 checks passed
Hmbown pushed a commit that referenced this pull request Oct 29, 2026
…-7585)

Refs #7118. A save, fork, rename, title change or conversation rewind used to publish whichever Work Graph transaction was pending, whatever session it belonged to and whether or not a newer graph had arrived after the snapshot was built. Publication now carries the saved session's owner and graph (SavedWorkProjection) and the Work runtime refuses it, leaving the transaction pending for the next save, when either no longer matches (publish_pending_matching and publish_pending_sync_matching in work_graph/runtime.rs; the unconditional publish remains only under cfg(test)). Fork reports that parent and child were saved but the active session did not change when Work could not be published. A conversation rewind that applied but could not be saved or published now says so ("Conversation was rewound, but its save or Work update needs attention"), puts the replacement or retry prompt back where the user can copy it, and does not send the retry.

Does not close #7118: the reporter's cancelled-turn case and the /task list versus To-do tracker visibility mismatch are neither reproduced nor changed. Known limits from three independent read-only reviews, none a blocker: the Engine SyncSession checkpoint branch still fails the request after the checkpoint was queued when the Work projection errors (its message says so); build_session_snapshot can still fall back to the last known Work state under lock contention, which the refused publish now reports after the write; a busy To-do lock still fails publication even with nothing pending; the partial-success toast says "retry was not sent" for a plain /undo and the new strings are not in the locale catalog.

Validation: Git-free export of origin/main 4d600ea plus this change, #7126, #7130, #7127, #7121 and the #7126 redraw follow-up, built and run on a Mac. cargo fmt --all -- --check clean. codewhale-tui lib focused run 281 passed, 0 failed (work_graph:: 43, session_snapshot_ 11, conversation_undo 3, undo_retry_apply_path 1, remote_control 90, phase_strip 43, paste 74, vim 3, composer_history 15) with RUST_MIN_STACK=16 MiB, the value CI and scripts/dev-test.sh export; at the default 2 MiB test stack the isolated undo lifecycle test overflows its stack in a debug build. Not run: the rest of the lib suite, Windows, hosted CI.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Hmbown pushed a commit that referenced this pull request Oct 29, 2026
Follow-up to #7126. The held-key flush runs after the event that triggered it has already drawn, so a Normal-mode key that changes the composer without setting needs_redraw (history recall with k, for one) left the old text on screen until the next terminal event. The flush now marks the frame dirty after dispatching the key.

Validation: Linux tmux PTY replay of a stack build (origin/main 4d600ea plus the Work Graph packet, #7126, #7130, #7127, #7121 and this change) with composer_vim_mode = "vim" and a seeded two-entry history, TERM_PROGRAM unset and iTerm.app: after Esc and k the composer showed the second seeded prompt at +150 ms and again after 1.15 s idle, k k showed the first, j the second again; i hello world Esc 0 x w x d d emptied the draft at 120 ms and 30 ms spacing; G moved to the end of the line; v q G Esc A left the draft unchanged. A single-write burst of Normal keys on an untrusted terminal is still inserted as text, as #7126 discloses. Not shown: the stale frame without this line (no #7126-only binary was built; the claim rests on history_up not setting needs_redraw). Not run: Windows, macOS terminals.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Hmbown pushed a commit that referenced this pull request Oct 29, 2026
…calized

Follow-up to #7121. /undo restores the files and truncates the App history before the portable handler sees the Restored outcome, and the Engine only learns about it through the SyncSession action that handler returns. The localized summary was built with ? on eight catalog lookups before that action, so a catalog that lacked one key turned a completed restore into a plain error result with no action, leaving the Engine's model context ahead of the files and history. The report is now built by restored_summary, and when it fails restored_fallback writes an English report from the outcome fields alone; is_error stays false and the SyncSession action is always returned. The shipped catalogs contain all 29 keys, so this is a guard, not a fix for a shipped failure.

Validation: codewhale-commands unit tests in a Git-free export on a Mac. The existing undo_reports_the_request_each_file_and_the_conversation, extended with a presentation context that fails one key, fails against the unrepaired code (the result was "Error: catalog lacks cmd_undo_action_restored" with no action) and passes after: 28 passed, 0 failed for the undo and debug filters. cargo fmt --all -- --check clean. Not run: the codewhale-tui lib tests that call the command, hosted CI.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Hmbown pushed a commit that referenced this pull request Oct 29, 2026
…do, TSX and Work fixes

Adds the Unreleased entries for #7126/#7130 (vim Normal mode), #7127 (rc start failures), #7121 (undo localization and its sync guard), #7140 (TSX language id), the Work Graph publication fence (#7118, with its open limit stated) and the #7095 session entries: the status-line hint, retained and listed interrupted checkpoints, and the signal-exit flush (#7122). Credits @Ricardo-M-L on docs/CONTRIBUTORS.md and web/lib/release-credits.ts and extends the @Lstarsky0, @laozidabo and @Aboysky lines. crates/tui/CHANGELOG.md is regenerated by scripts/sync-changelog.sh. The three web/ generated files were stale at HEAD (missing crates account-cli and plugins, two features, and the GUIDE.md digests that #7127 changed); they are regenerated from HEAD plus only these edits in a scratch export, so they carry none of the uncommitted DSH work.

Validation: sync-changelog --check, check-contributor-credit.py v0.10.2 (9 contributors, all credited on all three surfaces), check-versions.sh and check-facts.mjs pass on the scratch export; check-facts.mjs was red at HEAD before this. Not run: web build or hosted CI.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Hmbown pushed a commit that referenced this pull request Oct 29, 2026
The notices printed for a foreign-workspace checkpoint tell people to run `codewhale sessions`, but the command listed only saved sessions and so never showed a session that an interrupted turn had advanced past its last save. It now uses SessionManager::list_sessions_with_recovery, the call the resume picker already uses: a session with a newer checkpoint, or only a checkpoint, appears with that checkpoint's message count and an `interrupted` mark, and a recovery warning goes to stderr instead of failing the listing. `--search` still searches saved sessions only, and `codewhale resume` without an id still numbers saved sessions only; both are unchanged.

Validation: Linux Boat VM, debug build of a stack of origin/main 4d600ea plus the Work Graph change, #7126/#7130/#7127/#7121 and the uninstall slice, then this patch (sha256 d8dbb185…), with a loopback mock model inside an unshare -rn network namespace and a synthetic home. One saved session and one session killed by SIGTERM mid-stream: before, `sessions` showed the interrupted one as "New Session | 0 msgs"; after, "New Session | 1 msgs | interrupted"; `--limit 1` shows the newest row and "1 more session(s)"; `sessions list --limit 5` matches; cargo fmt --all -- --check clean. The row keeps the saved title, so it still reads "New Session". Not run: a session that exists only as a checkpoint (no saved file), the lib test suite (no test covers fn list_sessions in lib.rs), Windows, macOS.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@Aboysky
Aboysky deleted the fix/undo-localization branch October 29, 2026 07:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contribution-gate Author not yet in .github/APPROVED_CONTRIBUTORS; a maintainer grants access with /lgtm

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants