Skip to content

fix: join soft-wrapped rows when copying terminal text - #6923

Merged
teamleaderleo merged 10 commits into
manaflow-ai:mainfrom
mvanhorn:feat/terminal-copy-reflow
Sep 26, 2026
Merged

teamleaderleo merged 10 commits into
manaflow-ai:mainfrom
mvanhorn:feat/terminal-copy-reflow

Conversation

@mvanhorn

@mvanhorn mvanhorn commented Jun 26, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Fixes the soft-wrap part of #3096, reworked into the smaller change @teamleaderleo suggested below. Copying a line Ghostty soft-wrapped now pastes as one line: on the current copy path, both the formatted representations and the plain-text write, rows Ghostty marks as wrapped are joined. Line breaks the program printed are kept. Option-drag rectangular selections are left alone, since joining their rows would merge columns.

Heuristic reflow of hard-wrapped text is behind a new Terminal setting, "Reflow Hard-Wrapped Text on Copy" (terminal.reflowHardWrapOnCopy), which is off by default.

Testing

  • TerminalSoftWrapCopyTests (new, CmuxTerminalCore): 15/15 via swift test, covering the soft-wrap join, blank lines, rectangular selections, and the setting on and off.
  • SettingCatalogTests: 10/10 with the new key.
  • Not built or run locally: the app target (GhosttyTerminalView.swift hook), so CI is the compile check there, and I haven't checked it in a tagged build.

Demo Video

  • None yet, I couldn't record the app for this change.

Checklist

  • Behavior changes have added or updated tests
  • Localization: the new setting strings use String(localized:) keys with English defaults; catalog entries are not added yet

Maintainer note

  • Localization: the four new keys are now in Resources/Localizable.xcstrings with all nine macOS locales.
  • Rich copies: when the join changes the text, only text/plain is rewritten. HTML and RTF pass through unchanged, since their row breaks can't be remapped without re-rendering Ghostty's styled output, and dropping them lost formatting in rich-text destinations.
  • Copy-on-select is out of scope here. It arrives through write_clipboard_cb, which also carries OSC 52 writes from programs and has no reliable way to tell them apart, so joining there could rewrite text an app put on the clipboard. It still copies rows as Ghostty emits them.

@vercel

vercel Bot commented Jun 26, 2026

Copy link
Copy Markdown

@mvanhorn is attempting to deploy a commit to the Manaflow Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Jun 26, 2026 •

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

We couldn't safely recover the incremental review. No full review was started, and the last reviewed checkpoint was preserved. Retry later, or explicitly request a full review by commenting @coderabbitai full review.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds terminal copy reflow through a new Swift package, configurable terminal.reflowCopy setting, raw-copy action, pasteboard rewriting, settings/search/localization wiring, project integration, and tests covering prose joining and structural preservation.

Changes

Terminal copy reflow

Layer / File(s) Summary
Reflow package and engine
Packages/macOS/CmuxCopyReflow/...
Adds the Swift package, configurable reflow engine, structural line classifier, terminal-width helpers, continuation heuristics, and Markdown table handling.
Reflow validation
Packages/macOS/CmuxCopyReflow/Tests/CmuxCopyReflowTests/*
Tests prose joining, structural boundaries, URLs, lists, whitespace, idempotency, Unicode widths, and large deterministic inputs.
Setting storage and UI
Packages/macOS/CmuxSettings/..., Sources/CmuxSettingsJSONPathSupport.swift, Sources/SettingsNavigation.swift, Sources/SettingsSearchAliases.swift, web/data/cmux.schema.json, web/messages/*.json, Resources/Localizable.xcstrings
Adds enabled-by-default terminal.reflowCopy persistence, schema descriptions, settings toggle, search indexing, aliases, and localized labels.
Clipboard integration
Sources/GhosttyTerminalView.swift, Packages/macOS/CmuxTerminal/...
Applies bounded reflow to eligible selections, preserves raw and rectangular copy paths, and rewrites plain-text pasteboard representations.
Raw copy and project wiring
Sources/KeyboardShortcutSettings.swift, Sources/AppDelegate.swift, cmux.xcodeproj/project.pbxproj, cmux.xcworkspace/contents.xcworkspacedata, .github/workflows/ci.yml
Adds the raw-copy shortcut and routing, registers the local package with Xcode and the workspace, and runs its Swift tests in CI.
Supporting test stubs and plan
Packages/macOS/CmuxTerminal/Tests/GhosttyRuntimeTestStubs/*, docs/plans/2026-06-26-001-feat-terminal-copy-reflow-plan.md
Expands Ghostty configuration stubs and documents the implementation design and verification plan.

Transport test timing

Layer / File(s) Summary
Admission test coordination
Packages/Shared/CmuxIrohTransport/Tests/CmuxIrohTransportTests/*
Admission tests gate completion before recording admitted connection events and reorder the related assertion.

Estimated code review effort: 5 (Critical) | ~100 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant GhosttyTerminalView
  participant CmuxCopyReflow
  participant TerminalPasteboardService
  participant SystemClipboard
  User->>GhosttyTerminalView: Copy terminal selection
  GhosttyTerminalView->>CmuxCopyReflow: Classify and reflow eligible text
  CmuxCopyReflow-->>GhosttyTerminalView: Reflowed text
  GhosttyTerminalView->>TerminalPasteboardService: Rewrite text representations
  TerminalPasteboardService->>SystemClipboard: Publish replacement pasteboard item
  User->>GhosttyTerminalView: Invoke Copy Raw
  GhosttyTerminalView->>SystemClipboard: Publish verbatim selection
Loading

Suggested reviewers: lawrencecchen


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 3 warnings)

Check name Status Explanation Resolution
Cmux No Ambient Global State ❌ Error LineKind.swift adds two new top-level internal helpers at lines 81 and 86; they’re module-global free functions, not private/fileprivate, so the diff adds ambient API surface. Move those helpers onto LineKind (e.g. static methods) or make them private/fileprivate within the file that owns the logic; keep file-scope helpers non-ambient.
Out of Scope Changes check ⚠️ Warning A few CmuxIrohTransport test edits appear unrelated to terminal copy reflow and fall outside the linked issue scope. Remove those CmuxIrohTransport test changes or split them into a separate PR unless they are required for this feature.
Docstring Coverage ⚠️ Warning Docstring coverage is 14.77% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ⚠️ Warning The description includes the required sections and testing details, but its core behavior and setting information conflicts with the changeset. It describes terminal.reflowHardWrapOnCopy as disabled… Update the description to match the implementation. Document terminal.reflowCopy, its default value of true, the reflow and raw-copy behavior, affected settings and shortcut wiring, localization status, and the complete test and CI stat…
✅ Passed checks (21 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes implement copy reflow, raw-copy fallback, setting wiring, and tests needed to fix soft-wrapped command pasting.
Cmux Swift Actor Isolation ✅ Passed No new actor-isolation regression found: new UI code stays on MainActor, and the added pasteboard service method sits on an existing lock-guarded Sendable service.
Cmux Swift Blocking Runtime ✅ Passed The new copy-reflow/copy-raw paths only rewrite strings and pasteboard contents; no new waits, sleeps, semaphores, main-syncs, or locks appear in the introduced code.
Cmux Browser Automation Off-Main ✅ Passed The PR doesn’t touch browser automation routing; wait-heavy browser.* methods are in socketWorkerMethods, routed off-main, with policy tests pinning them.
Cmux Expensive Synchronous Load ✅ Passed Touched hunks add pure reflow/text-copy wiring and settings UI only; no new RestorableAgentSessionIndex.load() or other agent-history load appears in the changed paths.
Cmux Cache Substitution Correctness ✅ Passed PASS: the copy/reflow path reads live Ghostty selection via ghostty_surface_read_selection and pasteboard contents directly; the rectangular flag is transient and reset on no selection.
Cmux No Hacky Sleeps ✅ Passed No covered TypeScript/JS/shell/runtime-script files changed; the only workflow file is CI YAML, which the rule explicitly excludes.
Cmux Algorithmic Complexity ✅ Passed PASS: CmuxCopyReflow is linear over copied lines; helper scans are per-line or fixed-size, with no nested rescans or hot-path sorts/filtering over scalable collections.
Cmux Swift Concurrency ✅ Passed The PR adds only synchronous copy/reflow wiring; the lone DispatchQueue.global UI-test path already exists on origin/main and isn’t expanded.
Cmux Swift @Concurrent ✅ Passed No new @concurrent/nonisolated-async misuse found; the added copy/reflow paths are synchronous and UI-bound, so the rule isn’t violated.
Cmux Swift Package Boundaries ✅ Passed Reusable reflow logic and tests live in the new CmuxCopyReflow SwiftPM package; app-target changes are limited to Ghostty/AppKit glue, settings, and shortcut wiring.
Cmux Swiftpm Lockfiles ✅ Passed No cmux-owned .gitignore changes, the new Swift package has no external deps, and the pbxproj diff only adds source refs—not package references needing root Package.resolved.
Cmux Swift Logging ✅ Passed Parent→HEAD Swift diff adds no print/debugPrint/dump/NSLog or new Logger writes; only preexisting log declarations surfaced in unchanged files.
Cmux User-Facing Error Privacy ✅ Passed No new user-facing error/alert/recovery text with hidden implementation details was added; the changes only add settings/help and Copy Raw labeling.
Cmux Full Internationalization ✅ Passed All new user-facing text is localized: Swift uses String(localized:defaultValue:), the 20 xcstrings locales are filled, and all 20 web message locales include reflowCopy.
Cmux Swiftui State Layout ✅ Passed The new TerminalSection state uses @Observable DefaultsValueModel in @State, with no new ObservableObject/@published or lazy-row store reference, and no render-time mutation.
Cmux Architecture Rethink ✅ Passed The only new mutable bridge is a documented Ghostty ABI workaround; copy/reflow is centralized in the package path, with no sleeps, polling, or split ownership added.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed Touched standalone windows already use stable cmux.* IDs and are listed in cmuxAuxiliaryWindowIdentifiers; no new unregistered auxiliary window appears.
Cmux Source Artifacts ✅ Passed All changed paths are intentional source/config/docs/localization/test files; no logs, build output, temp dirs, or other accidental artifacts appear in the diff.
Cmux No Test Or Debug Seam In Production Source ✅ Passed New production additions are feature code (copyRaw, reflowCopy); the new package files contain no #if DEBUG/ForTesting/TestHook seam.
Title check ✅ Passed The title clearly identifies the primary change: joining soft-wrapped terminal rows during copy.
Full details: Description check

Explanation

The description includes the required sections and testing details, but its core behavior and setting information conflicts with the changeset. It describes terminal.reflowHardWrapOnCopy as disabled by default and focuses on soft-wrap handling, while the implementation adds default-enabled terminal.reflowCopy, hard-wrap reflow, raw-copy shortcuts, settings UI, localization, and broader integration work.

Resolution

Update the description to match the implementation. Document terminal.reflowCopy, its default value of true, the reflow and raw-copy behavior, affected settings and shortcut wiring, localization status, and the complete test and CI status. Add the required demo video or explain the missing artifact according to repository policy. Mark completed checklist items accurately and remove stale soft-wrap-only details.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Jun 26, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a "clean copy" reflow transform that rejoins hard-wrapped terminal text on Cmd+C, while preserving code fences, tables, blockquotes, lists, and URLs. All reflow logic lives in a new pure, dependency-free CmuxCopyReflow SwiftPM package (49 unit tests), integrated into the copy path with a 256 KB / 4 000-line guard so main-thread work stays bounded.

  • New CmuxCopyReflow package — ReflowOptions.reflow(_:terminalWidth:) runs a two-pass classifier + paragraph joiner; heuristics are deliberately conservative and tested against real failing clipboard payloads.
  • UI integration — GhosttyNSView tracks activeSelectionMayBeRectangular on Option-drag to bypass reflow for columnar selections (best-effort); copyRaw action (Cmd+Shift+C + context-menu item) always copies verbatim; the terminal.reflowCopy setting (default true) controls the default behaviour.
  • Localization — all five new user-facing strings are translated across all 20 app locales in Localizable.xcstrings and all 20 web locales in web/messages/.

Confidence Score: 5/5

Safe to merge. The reflow transform is bounded, runs on the AppKit event thread where copy already occurs, and is guarded by a user-facing setting with a verbatim-copy escape hatch. Localization is complete across all 20 app and web locales.

All new production paths are bounded and conservative. The reflow engine lives in a well-tested, dependency-free package with 49 unit tests. The UI integration correctly gates reflow behind setting, line-count, and byte-count checks. No new blocking issues were found beyond what was already addressed in previous review threads.

No files require special attention. The most complex new file, CopyReflow.swift, is well-commented and has direct unit-test coverage for its edge cases.

Important Files Changed

Filename Overview
Packages/macOS/CmuxCopyReflow/Sources/CmuxCopyReflow/CopyReflow.swift Core two-pass reflow engine implemented as a method on ReflowOptions; conservative heuristics with bounded input guards. No issues found.
Packages/macOS/CmuxCopyReflow/Sources/CmuxCopyReflow/LineKind.swift Line classifier enum with proper cases; file-scope helpers are private or internal to the package. No issues found.
Packages/macOS/CmuxCopyReflow/Sources/CmuxCopyReflow/ReflowOptions.swift Public API is a method on a constructable, injectable ReflowOptions struct; static default is a let constant. Well-structured.
Packages/macOS/CmuxCopyReflow/Sources/CmuxCopyReflow/TerminalCellWidth.swift Heuristic terminal-column width using East Asian Wide ranges; intentionally approximate, conservative over-counting is safe for the wrap heuristic.
Sources/GhosttyTerminalView.swift Integration: activeSelectionMayBeRectangular heuristic, copyRaw action, reflowClipboardTextIfEligible; copy path is bounded (256 KB / 4 000 lines) and always runs on the AppKit event thread. Previously-raised concerns are verified/acknowledged in prior review threads.
Sources/AppDelegate.swift Adds copyRaw shortcut handler in sendEvent; correctly exempted from menu-backed shortcut guard.
Resources/Localizable.xcstrings All five new keys translated across all 20 app locales. Localization complete.
Packages/macOS/CmuxCopyReflow/Package.swift Standalone package with no external dependencies (Foundation only); no Package.resolved needed. Correctly registered in Xcode workspace and pbxproj.
Packages/macOS/CmuxSettings/Sources/CmuxSettings/Keys/TerminalCatalogSection.swift Adds reflowCopy DefaultsKey with default true; follows existing catalog key pattern.
Packages/macOS/CmuxTerminal/Sources/CmuxTerminal/Services/Pasteboard/TerminalPasteboardService+TextContents.swift Adds rewriteTextRepresentations; drops HTML/RTF/RTFD (intentional per comment), retains plain-text. Clean implementation.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant User
    participant AppDelegate
    participant GhosttyNSView
    participant Ghostty as libghostty
    participant NSPasteboard
    participant ReflowEngine as CmuxCopyReflow

    User->>AppDelegate: Cmd+C (copy)
    AppDelegate->>GhosttyNSView: copyKeyboardCopyModeSelectionToClipboard / copy(_:)
    GhosttyNSView->>GhosttyNSView: activeSelectionShouldBypassCopyReflow()
    GhosttyNSView->>Ghostty: ghostty_surface_selection_screen_rows()
    Ghostty-->>GhosttyNSView: (topRow, bottomRow) or nil
    GhosttyNSView->>Ghostty: performBindingAction(copy_to_clipboard)
    Ghostty->>NSPasteboard: write formatted text
    GhosttyNSView->>GhosttyNSView: reflowCopySettings.value(for: reflowCopyKey)
    alt reflow enabled and bounds present and within limits
        GhosttyNSView->>NSPasteboard: string(forType: .string)
        NSPasteboard-->>GhosttyNSView: original text
        GhosttyNSView->>ReflowEngine: ReflowOptions.default.reflow(text, terminalWidth:)
        ReflowEngine-->>GhosttyNSView: reflowed text
        GhosttyNSView->>NSPasteboard: rewriteTextRepresentations(reflowed)
    else reflow off / raw / rectangular / too large
        Note over GhosttyNSView,NSPasteboard: original text left on pasteboard
    end
    User->>AppDelegate: Cmd+Shift+C (Copy Raw)
    AppDelegate->>GhosttyNSView: copyRawSelectionToClipboard()
    GhosttyNSView->>Ghostty: performBindingAction(copy_to_clipboard)
    Note over GhosttyNSView: reflow=false, pasteboard unchanged
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant User
    participant AppDelegate
    participant GhosttyNSView
    participant Ghostty as libghostty
    participant NSPasteboard
    participant ReflowEngine as CmuxCopyReflow

    User->>AppDelegate: Cmd+C (copy)
    AppDelegate->>GhosttyNSView: copyKeyboardCopyModeSelectionToClipboard / copy(_:)
    GhosttyNSView->>GhosttyNSView: activeSelectionShouldBypassCopyReflow()
    GhosttyNSView->>Ghostty: ghostty_surface_selection_screen_rows()
    Ghostty-->>GhosttyNSView: (topRow, bottomRow) or nil
    GhosttyNSView->>Ghostty: performBindingAction(copy_to_clipboard)
    Ghostty->>NSPasteboard: write formatted text
    GhosttyNSView->>GhosttyNSView: reflowCopySettings.value(for: reflowCopyKey)
    alt reflow enabled and bounds present and within limits
        GhosttyNSView->>NSPasteboard: string(forType: .string)
        NSPasteboard-->>GhosttyNSView: original text
        GhosttyNSView->>ReflowEngine: ReflowOptions.default.reflow(text, terminalWidth:)
        ReflowEngine-->>GhosttyNSView: reflowed text
        GhosttyNSView->>NSPasteboard: rewriteTextRepresentations(reflowed)
    else reflow off / raw / rectangular / too large
        Note over GhosttyNSView,NSPasteboard: original text left on pasteboard
    end
    User->>AppDelegate: Cmd+Shift+C (Copy Raw)
    AppDelegate->>GhosttyNSView: copyRawSelectionToClipboard()
    GhosttyNSView->>Ghostty: performBindingAction(copy_to_clipboard)
    Note over GhosttyNSView: reflow=false, pasteboard unchanged
Loading

Reviews (35): Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." | Re-trigger Greptile

Comment thread Packages/macOS/CmuxCopyReflow/Sources/CmuxCopyReflow/CopyReflow.swift Outdated
Comment thread Sources/GhosttyTerminalView.swift Outdated
@mvanhorn mvanhorn closed this Jun 26, 2026
@mvanhorn mvanhorn reopened this Jun 26, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Packages/macOS/CmuxCopyReflow/Sources/CmuxCopyReflow/CopyReflow.swift`:
- Around line 139-142: The wrap-join logic in CopyReflow should not depend only
on startsLowercaseLetter(content), because that misses common command
continuations like --flag, /path, $VAR, or quoted tokens. Update the canJoin
decision in CopyReflow.swift to add a command/token continuation rule alongside
the existing s1, s3, and s4 checks, and keep the prevEndsTerminator guard
intact. Add a regression test covering a long wrapped command that continues
onto --another-option or /path to verify the hard newline is removed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2dd6cc20-140a-42e5-a64e-908e5be17d29

📥 Commits

Reviewing files that changed from the base of the PR and between 9ede031 and 1d3ce98.

📒 Files selected for processing (3)
  • Packages/macOS/CmuxCopyReflow/Sources/CmuxCopyReflow/CopyReflow.swift
  • Packages/macOS/CmuxCopyReflow/Tests/CmuxCopyReflowTests/ReflowParagraphTests.swift
  • Sources/GhosttyTerminalView.swift

Comment thread Packages/macOS/CmuxCopyReflow/Sources/CmuxCopyReflow/CopyReflow.swift Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 issues found across 24 files

You’re at about 99% of the monthly reviewed-line limit. You may want to disable incremental reviews to conserve quota. Reviews will continue until that limit is exceeded. If you need help avoiding interruptions, please contact contact@cubic.dev.

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread docs/plans/2026-06-26-001-feat-terminal-copy-reflow-plan.md Outdated
Comment thread Packages/macOS/CmuxCopyReflow/Sources/CmuxCopyReflow/ReflowOptions.swift Outdated
Comment thread Packages/macOS/CmuxCopyReflow/Sources/CmuxCopyReflow/LineKind.swift Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

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

⚠️ Outside diff range comments (2)
Sources/GhosttyTerminalView.swift (2)

4740-4789: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Reflow-decision logic is duplicated across three call sites.

The condition reflow && !activeSelectionMayBeRectangular && TerminalReflowCopySettings.isEnabled() (or an equivalent) is reimplemented three times: inline in the ghosttyWroteFormattedText branch via reflowClipboardTextIfEnabled (line 4749/4767), inline again in the raw-selection fallback (line 4757), and a third variant in copyKeyboardCopyModeSelectionToClipboard (line 4781) that intentionally omits the activeSelectionMayBeRectangular check. This is exactly the kind of "same behavior wired separately through multiple surfaces" the repo's shared-behavior policy calls out, and it's already drifted once (the third site has a different rule).

Consider extracting a single helper, e.g.:

private func shouldReflow(_ reflow: Bool, considerRectangular: Bool = true) -> Bool {
    guard reflow, TerminalReflowCopySettings.isEnabled() else { return false }
    return !considerRectangular || !activeSelectionMayBeRectangular
}

and call it from all three sites, so future changes to the eligibility rule can't silently diverge between entry points.

Based on learnings: repo's shared behavior policy states "When a behavior is exposed through multiple entrypoints... implement one shared action/model path... Do not patch one surface while leaving the others with duplicated logic."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Sources/GhosttyTerminalView.swift` around lines 4740 - 4789, The reflow
eligibility check is duplicated and already diverging across copy paths in
GhosttyTerminalView. Extract a single shared helper around the copy/reflow
decision in copyCurrentGhosttySelectionToClipboard and
copyKeyboardCopyModeSelectionToClipboard, then use it everywhere instead of
repeating TerminalReflowCopySettings.isEnabled(), reflow, and
activeSelectionMayBeRectangular checks inline. Keep the helper as the source of
truth for both the formatted pasteboard branch and the raw-selection fallback so
all entrypoints follow the same rule.

4740-4774: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Preserve Ghostty’s mixed clipboard payload Sources/GhosttyTerminalView.swift:4769-4773
copy_to_clipboard writes .mixed here, so pasteboard.clearContents() followed by setString(..., forType: .string) drops the HTML flavor and breaks rich-text paste fidelity. Reflow should rewrite the plain-text item without discarding the other pasteboard types.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Sources/GhosttyTerminalView.swift` around lines 4740 - 4774, The clipboard
reflow path in copyCurrentGhosttySelectionToClipboard /
reflowClipboardTextIfEnabled is replacing the whole pasteboard contents, which
drops Ghostty’s mixed payload and loses rich-text flavors. Update the reflow
logic to rewrite only the plain-text representation on the existing pasteboard
item after copy_to_clipboard, preserving any additional types such as HTML
instead of calling clearContents and resetting the pasteboard from scratch.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Packages/macOS/CmuxCopyReflow/Sources/CmuxCopyReflow/CopyReflow.swift`:
- Around line 117-176: The joiner in CopyReflow’s prose/url handling is using
the paragraph-level isURL flag, which can incorrectly suppress spaces after
URL-led lines that later continue as normal prose. Update the join logic in the
case .prose, .urlLine block to key the joiner off the per-iteration s3 signal
instead of p.isURL, so only true bare-URL fragment continuations use no
separator while s1/s4 prose continuations keep a space; add a regression test
covering a URL-prefixed line followed by multi-word continuation.

In `@Packages/macOS/CmuxCopyReflow/Sources/CmuxCopyReflow/LineKind.swift`:
- Around line 81-86: The current LineKind.isTableRow heuristic treats any line
containing a pipe as a table row, which causes shell commands with pipes to be
misclassified and hard-broken in CopyReflow.swift. Tighten the table detection
in isTableRow so it only returns true for likely markdown tables, such as when
the line is adjacent to a separator-like row or when the content has multiple
pipe delimiters, and keep shell command lines from being classified as
.tableRow.

In `@Sources/GhosttyTerminalView.swift`:
- Line 3539: The selection reflow logic is still relying on the mouse-driven
activeSelectionMayBeRectangular flag, which can become stale after non-mouse
selection changes. Update GhosttyTerminalView’s copy/reflow path to derive
whether a selection is rectangular from the selection payload’s rectangle shape
instead of shadow-tracking it via mouse modifiers, and make the Cmd+C handling
use that authoritative selection state.

---

Outside diff comments:
In `@Sources/GhosttyTerminalView.swift`:
- Around line 4740-4789: The reflow eligibility check is duplicated and already
diverging across copy paths in GhosttyTerminalView. Extract a single shared
helper around the copy/reflow decision in copyCurrentGhosttySelectionToClipboard
and copyKeyboardCopyModeSelectionToClipboard, then use it everywhere instead of
repeating TerminalReflowCopySettings.isEnabled(), reflow, and
activeSelectionMayBeRectangular checks inline. Keep the helper as the source of
truth for both the formatted pasteboard branch and the raw-selection fallback so
all entrypoints follow the same rule.
- Around line 4740-4774: The clipboard reflow path in
copyCurrentGhosttySelectionToClipboard / reflowClipboardTextIfEnabled is
replacing the whole pasteboard contents, which drops Ghostty’s mixed payload and
loses rich-text flavors. Update the reflow logic to rewrite only the plain-text
representation on the existing pasteboard item after copy_to_clipboard,
preserving any additional types such as HTML instead of calling clearContents
and resetting the pasteboard from scratch.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: dab798c3-a73a-45c4-be7d-b5e7a8318869

📥 Commits

Reviewing files that changed from the base of the PR and between b262e56 and 01fbff1.

⛔ Files ignored due to path filters (1)
  • .github/swift-file-length-budget.tsv is excluded by !**/*.tsv
📒 Files selected for processing (34)
  • Packages/macOS/CmuxCopyReflow/Sources/CmuxCopyReflow/CopyReflow.swift
  • Packages/macOS/CmuxCopyReflow/Sources/CmuxCopyReflow/LineKind.swift
  • Packages/macOS/CmuxCopyReflow/Sources/CmuxCopyReflow/ReflowOptions.swift
  • Packages/macOS/CmuxCopyReflow/Tests/CmuxCopyReflowTests/ClassifierTests.swift
  • Packages/macOS/CmuxCopyReflow/Tests/CmuxCopyReflowTests/ReflowParagraphTests.swift
  • Packages/macOS/CmuxCopyReflow/Tests/CmuxCopyReflowTests/ReflowStructureTests.swift
  • Packages/macOS/CmuxSettingsUI/Sources/CmuxSettingsUI/Navigation/CuratedSettingEntry+Default.swift
  • Packages/macOS/CmuxSettingsUI/Tests/CmuxSettingsUITests/SettingsSearchIndexTests.swift
  • Resources/Localizable.xcstrings
  • Sources/CmuxSettingsJSONPathSupport.swift
  • Sources/GhosttyTerminalView.swift
  • cmux.xcodeproj/project.pbxproj
  • docs/plans/2026-06-26-001-feat-terminal-copy-reflow-plan.md
  • web/data/cmux.schema.json
  • web/messages/ar.json
  • web/messages/bs.json
  • web/messages/da.json
  • web/messages/de.json
  • web/messages/en.json
  • web/messages/es.json
  • web/messages/fr.json
  • web/messages/it.json
  • web/messages/ja.json
  • web/messages/km.json
  • web/messages/ko.json
  • web/messages/no.json
  • web/messages/pl.json
  • web/messages/pt-BR.json
  • web/messages/ru.json
  • web/messages/th.json
  • web/messages/tr.json
  • web/messages/uk.json
  • web/messages/zh-CN.json
  • web/messages/zh-TW.json

Comment thread Packages/macOS/CmuxCopyReflow/Sources/CmuxCopyReflow/CopyReflow.swift Outdated
Comment thread Packages/macOS/CmuxCopyReflow/Sources/CmuxCopyReflow/LineKind.swift Outdated
Comment thread Sources/GhosttyTerminalView.swift Outdated
@vercel

vercel Bot commented Jul 3, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cmux Canceled Canceled Comment Jul 16, 2026 12:25am

@mvanhorn

Copy link
Copy Markdown
Contributor Author

Ping on this one @austinywang - thanks for the earlier look. The red checks (tests / activation-session) look like they just need a rebase, which I'm glad to push. Is there anything about the reflow behavior itself you'd want changed before it can go in?

@vercel

vercel Bot commented Jul 15, 2026

Copy link
Copy Markdown

Deployment failed with the following error:

The provided GitHub repository does not contain the requested branch or commit reference. Please ensure the repository is not empty.

@austinywang

Copy link
Copy Markdown
Contributor

@mvanhorn I’ve taken this through the maintainer-update pass and pushed the result to your fork branch. The reflow behavior itself is now in the shape I’d want before merge:

  • merged current origin/main without dropping any of the existing follow-up commits
  • added behavioral coverage for command/token continuations, URL-led prose, markdown-table detection, CJK terminators, and settings/shortcut wiring
  • centralized reflow eligibility across copy entrypoints
  • replaced the ambient static settings namespace with the typed CmuxSettings client/catalog path
  • preserved Ghostty clipboard flavor availability and, on reflow, now regenerates existing HTML/RTF from the transformed text so rich editors cannot paste stale hard-wrapped content
  • kept rectangular selections on the conservative verbatim path; Ghostty’s current C ABI does not expose the active selection shape, which was confirmed in the resolved review thread
  • linked the package/tests into the Xcode targets and retained the tracked lockfiles

All nine inline review threads are resolved. The branch is currently MERGEABLE; fresh CI and activation runs are in progress on 6de0da03ed. I’m continuing to watch those and the final automated review pass.

@austinywang

Copy link
Copy Markdown
Contributor

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 15, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Comment thread Sources/GhosttyTerminalView.swift Outdated
@austinywang

Copy link
Copy Markdown
Contributor

Addressing the remaining Greptile summary note: Swift already classifies U+00A0 (NO-BREAK SPACE) as whitespace on this PR's pinned toolchain. Verified directly with:

$ swift -e 'print(Character("\u{00A0}").isWhitespace)'
true

nextNonWhitespaceToken uses Character.isWhitespace, so it already treats decoded   / U+00A0 as a token boundary. The rich-text rewrite alignment therefore covers this case as written; no code change is needed.

@cursor

cursor Bot commented Jul 15, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

5 similar comments
@cursor

cursor Bot commented Jul 15, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@cursor

cursor Bot commented Jul 15, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@cursor

cursor Bot commented Jul 15, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@cursor

cursor Bot commented Jul 15, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@cursor

cursor Bot commented Jul 15, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@austinywang

Copy link
Copy Markdown
Contributor

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 15, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
Packages/macOS/CmuxCopyReflow/Sources/CmuxCopyReflow/CopyReflow.swift (1)

269-288: 🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win

Advance past rows already promoted to avoid quadratic table scanning.

Each separator scans the remaining candidate rows, but those promoted .tableRow entries are processed again as separators. A 20,000-line separator-shaped selection therefore performs O(n²) work on the interactive copy path.

Proposed single-pass fix
-        for i in lines.indices {
-            guard isPromotableTableKind(lineKinds[i]),
-                  lineKindIsMarkdownTableSeparatorRow(lines[i]) else { continue }
+        var i = lines.startIndex
+        while i < lines.endIndex {
+            guard isPromotableTableKind(lineKinds[i]),
+                  lineKindIsMarkdownTableSeparatorRow(lines[i]) else {
+                i += 1
+                continue
+            }
 
             lineKinds[i] = .tableRow
             ...
             while bodyIndex < lines.count,
                   isPromotableTableKind(lineKinds[bodyIndex]),
                   lineKindIsMarkdownTableCandidateRow(lines[bodyIndex]) {
                 lineKinds[bodyIndex] = .tableRow
                 bodyIndex += 1
             }
+            i = bodyIndex
         }

Add an adversarial large separator-row regression or benchmark. As per path instructions, prefer single-pass reducers over repeated scans of scalable collections.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Packages/macOS/CmuxCopyReflow/Sources/CmuxCopyReflow/CopyReflow.swift` around
lines 269 - 288, Update the table-promotion loop around isPromotableTableKind
and lineKindIsMarkdownTableSeparatorRow so advancing through a separator’s body
skips already-promoted .tableRow entries and does not reprocess them as
separators. Preserve promotion of the header and contiguous candidate body rows
while making the traversal single-pass, and add an adversarial large
separator-row regression or benchmark covering the interactive copy path.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@Packages/macOS/CmuxCopyReflow/Tests/CmuxCopyReflowTests/ReflowParagraphTests.swift`:
- Around line 359-375: Remove the wall-clock timing and scaling assertion from
nearLimitSelectionReflowsWithLinearScaling, including its timedReflow, seconds,
and ContinuousClock usage. Replace it with a deterministic large-input
correctness assertion using the existing reflow expectations; move performance
scaling coverage to the benchmark harness rather than this correctness suite.

---

Outside diff comments:
In `@Packages/macOS/CmuxCopyReflow/Sources/CmuxCopyReflow/CopyReflow.swift`:
- Around line 269-288: Update the table-promotion loop around
isPromotableTableKind and lineKindIsMarkdownTableSeparatorRow so advancing
through a separator’s body skips already-promoted .tableRow entries and does not
reprocess them as separators. Preserve promotion of the header and contiguous
candidate body rows while making the traversal single-pass, and add an
adversarial large separator-row regression or benchmark covering the interactive
copy path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 913e0b04-f5b4-47d5-b78f-d6e23b19a3c6

📥 Commits

Reviewing files that changed from the base of the PR and between 6de0da0 and ffda7c3.

📒 Files selected for processing (18)
  • .github/workflows/ci.yml
  • Packages/macOS/CmuxCopyReflow/Sources/CmuxCopyReflow/CopyReflow.swift
  • Packages/macOS/CmuxCopyReflow/Sources/CmuxCopyReflow/LineKind.swift
  • Packages/macOS/CmuxCopyReflow/Sources/CmuxCopyReflow/ReflowOptions+ContinuationEvidence.swift
  • Packages/macOS/CmuxCopyReflow/Sources/CmuxCopyReflow/TerminalCellWidth.swift
  • Packages/macOS/CmuxCopyReflow/Tests/CmuxCopyReflowTests/ClassifierTests.swift
  • Packages/macOS/CmuxCopyReflow/Tests/CmuxCopyReflowTests/ReflowParagraphTests.swift
  • Packages/macOS/CmuxCopyReflow/Tests/CmuxCopyReflowTests/ReflowStructureTests.swift
  • Packages/macOS/CmuxSettings/Sources/CmuxSettings/Keys/TerminalCatalogSection.swift
  • Packages/macOS/CmuxSettingsUI/Sources/CmuxSettingsUI/Navigation/CuratedSettingEntry+Default.swift
  • Packages/macOS/CmuxSettingsUI/Sources/CmuxSettingsUI/Sections/TerminalSection.swift
  • Packages/macOS/CmuxSettingsUI/Tests/CmuxSettingsUITests/SettingsRowAnchorResolutionTests.swift
  • Packages/macOS/CmuxTerminal/Sources/CmuxTerminal/Services/Pasteboard/TerminalPasteboardService+TextContents.swift
  • Packages/macOS/CmuxTerminal/Tests/CmuxTerminalTests/Services/TerminalPasteboardServiceTests.swift
  • Resources/Localizable.xcstrings
  • Sources/AppDelegate.swift
  • Sources/GhosttyTerminalView.swift
  • cmux.xcodeproj/project.pbxproj
💤 Files with no reviewable changes (1)
  • Packages/macOS/CmuxCopyReflow/Sources/CmuxCopyReflow/LineKind.swift

@cursor

cursor Bot commented Jul 15, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@austinywang

Copy link
Copy Markdown
Contributor

Final review reconciliation on the current branch:

  • Fixed the wall-clock correctness-test finding in 29d3909; the 4,000-row case is now deterministic.
  • Fixed the outside-diff quadratic Markdown-table scan finding in 6856132; promotion is single-pass and has 4,000-row stress coverage.
  • The stale lockfile warning does not apply: CmuxCopyReflow is a dependency-free local package, and scripts/check-package-resolved-policy.py passes.
  • The stale ambient-global warning is already resolved: table promotion is scoped to ReflowOptions and terminal-cell helpers are private to their file.
  • Merged current main again in 9b1f4a2. Static Swift checks and the cmux policy gate are clean.

@mvanhorn

Copy link
Copy Markdown
Contributor Author

Appreciate you carrying this all the way to mergeable @austinywang - the continuation/table/CJK coverage covers the edges I was unsure about. Let me know if you need anything from me before it lands.

@teamleaderleo

Copy link
Copy Markdown
Collaborator

Thanks for all the work here, and sorry it sat so long. The soft-wrap part of #3096 is a real bug, and people hit it constantly.

I'm not going to merge this as-is, for two reasons:

  • The default behavior. It makes heuristic reflow of hard-wrapped text the default for Cmd+C. That goes well beyond the soft-wrap bug, and it's a product call we'd want to make on purpose.
  • Main has moved. The copy path in GhosttyTerminalView (configuredCopyToClipboardAction, captureNextStandardClipboardRepresentations) and mouse-up handling were rewritten, so the hook would need re-plumbing across about 10 files.

If you're up for it, a smaller PR would be easy to land: just fix soft-wrapped lines (join rows Ghostty marks as wrapped) on the current copy path, with hard-wrap reflow behind a setting that's off by default. Please leave out the plan doc, the ci.yml edit and the CmxIrohEndpointServerTests reorder. I'll review it quickly :)

@mvanhorn
mvanhorn force-pushed the feat/terminal-copy-reflow branch from 1516fc0 to b83f771 Compare September 25, 2026 22:55
@cursor

cursor Bot commented Sep 25, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@github-actions

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@mvanhorn mvanhorn changed the title feat: reflow wrapped text on terminal copy (fixes #3096) fix: join soft-wrapped rows when copying terminal text Sep 25, 2026
@mvanhorn

Copy link
Copy Markdown
Contributor Author

Thanks @teamleaderleo, took you up on the smaller version and reworked this PR in place rather than opening another (b83f771, one commit on current main).

It now only joins rows Ghostty marks as soft-wrapped, on the current copy path, and leaves rectangular selections alone. Hard-wrap reflow is behind a Terminal setting that's off by default. The plan doc, the ci.yml edit and the test reorder are gone. The description has the testing details, including what I couldn't verify locally.

teamleaderleo and others added 3 commits September 26, 2026 04:11
joinedCopyText read "terminal.reflowHardWrapOnCopy" as a raw UserDefaults
string. Read it through TerminalCatalogSection so the catalog stays the one
definition of the key, its type, and its default.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When the soft-wrap join changed the plain text, representationsJoiningSoftWraps
dropped every non-plain representation, so a copy that used to paste styled
HTML or RTF into Notes, Mail, or a document editor pasted unstyled text instead.

Keep the rich representations unchanged and rewrite only text/plain. Their row
breaks live inside styled markup and cannot be remapped from the plain text
without re-rendering Ghostty's formatter output, so regenerating them is not a
small change. This is the least surprising split: plain-text destinations
(terminals, editors, chat inputs) get the joined line, and rich destinations
paste exactly what they did before this PR rather than losing formatting.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add settings.terminal.reflowHardWrapOnCopy, its subtitleOn and subtitleOff
variants, and the settings.search.alias.setting.terminal.reflow-hard-wrap-on-copy
search alias to Resources/Localizable.xcstrings with all nine required macOS
locales, next to the copy-on-select entries they sit beside in Settings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@teamleaderleo

Copy link
Copy Markdown
Collaborator

Thanks for this! I pushed the localization entries plus a few small fixes (catalog key read, keeping rich clipboard formats) to your branch :)

teamleaderleo and others added 6 commits September 26, 2026 04:21
The package conventions lint rejects all-static namespace enums. The copy
builder now carries its hard-wrap settings as stored properties, and the
call sites and tests construct it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Ghostty's copy already unwraps soft wraps, so a logical line wider than
the grid was being joined onto the next line. Also narrow the wide-cell
table to East Asian Wide/Fullwidth and emoji so punctuation and box
drawing count as one cell.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…pOnCopy

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@teamleaderleo
teamleaderleo merged commit 1dfd0e6 into manaflow-ai:main Sep 26, 2026
80 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

Merge receipt for ed0f1ca73a: every check was green at merge (33 verified; 19 skipped by policy). Full suite runs on main after merge.

@teamleaderleo

Copy link
Copy Markdown
Collaborator

Merged, thanks @mvanhorn :)

rustybret pushed a commit to rustybret/bmux that referenced this pull request Sep 26, 2026
9bae42b Show one settings section at a time (manaflow-ai#12993)
1dfd0e6 fix: join soft-wrapped rows when copying terminal text (manaflow-ai#6923)
8ae8f01 ci: build the nightly app on cmux15's trusted runner first, Blacksmith as fallback (manaflow-ai#14821)
977148c Add command palette entries for shortcut-only actions (manaflow-ai#14815)
659fc76 Keep Claude NODE_OPTIONS restore preload out of TMPDIR (manaflow-ai#14814)
749a2f8 test(simulator): bound the interactive frame wait by the idle interval, not 250 ms (manaflow-ai#14820)

# Conflicts:
#	.github/workflows/ci-health-report.yml
#	.github/workflows/ci-owned-pool-rescue.yml
#	.github/workflows/ci-repo-variables.yml
#	.github/workflows/nightly.yml
@mvanhorn

Copy link
Copy Markdown
Contributor Author

Thanks for the review and merge @teamleaderleo!

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.

3 participants