docs/plans/2026-04-11-toast-default-wrap-width-sync.md
For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
Goal: Add a persisted global defaultWrapWidth setting, make Toast.show(..., wrapWidth: nil) fall back to it, and expose the same value in the Toast debug panel so UI and runtime behavior stay in sync.
Architecture: Store the default wrap width in ToastStorage as a sanitized numeric value where 0 means single-line mode. Route wrapWidth: nil through that stored default inside the toast presentation path, and add a debug-panel control that edits the same stored value and uses it for test toasts unless a call site explicitly overrides wrapWidth.
Tech Stack: Swift, AppKit, UserDefaults, existing toast regression harness in tools/toast_regression_tests.swift
Files:
tools/toast_regression_tests.swiftStep 1: Write the failing test
Add tests asserting:
ToastStorage.defaultWrapWidth defaults to 00Step 2: Run test to verify it fails
Run: swiftc -module-cache-path /tmp/mos-toast-tests-cache -o /tmp/mos-toast-tests-bin tools/toast_regression_tests.swift Mos/Components/Toast/ToastLayout.swift Mos/Components/Toast/ToastVisibilityRules.swift Mos/Components/Toast/ToastContentView.swift Mos/Components/Toast/ToastStorage.swift && /tmp/mos-toast-tests-bin
Expected: FAIL because ToastStorage does not yet expose defaultWrapWidth.
Files:
Mos/Components/Toast/ToastStorage.swiftMos/Components/Toast/ToastManager.swiftStep 1: Write minimal implementation
Add defaultWrapWidth to ToastStorage with default 0 and sanitize negative values to 0. When ToastManager.present(..., wrapWidth: nil) is called, resolve it to ToastStorage.shared.defaultWrapWidth before creating ToastContentView.
Step 2: Run test to verify it passes
Run the same regression command as Task 1.
Expected: PASS for the new storage behavior.
Files:
Mos/Components/Toast/ToastPanel.swiftMos/Localizable.xcstringsStep 1: Add a numeric control
Add a Wrap Width configuration row to the debug panel. Bind it to ToastStorage.shared.defaultWrapWidth, display 0 as single-line mode, and refresh it when the panel opens.
Step 2: Use the stored value when firing panel toasts
Make debug-panel toasts pass wrapWidth: ToastStorage.shared.defaultWrapWidth.
Step 3: Run verification
Run:
swiftc -module-cache-path /tmp/mos-toast-tests-cache -o /tmp/mos-toast-tests-bin tools/toast_regression_tests.swift Mos/Components/Toast/ToastLayout.swift Mos/Components/Toast/ToastVisibilityRules.swift Mos/Components/Toast/ToastContentView.swift Mos/Components/Toast/ToastStorage.swift && /tmp/mos-toast-tests-binxcodebuild -project Mos.xcodeproj -scheme Debug -configuration Debug -sdk macosx build CODE_SIGNING_ALLOWED=NOExpected: regression tests pass and build succeeds.