Skip to content

fix: keep New Tab drafts through update and quit - #26753

Open
teamleaderleo wants to merge 8 commits into
lane/nx-draft-persistencefrom
lane/nx-newtab-unsent-attachments
Open

teamleaderleo wants to merge 8 commits into
lane/nx-draft-persistencefrom
lane/nx-newtab-unsent-attachments

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes the New Tab draft loss Leo reported after an update/relaunch: "Also, when I updated, it removed my draft in one of the composer things."

New Tab drafts were only sent to the native unsent store from the replacement/unmount callback. A normal quit/update could close the WebView without that callback, and the store only carried text. This adds ordinary edit writes plus a pagehide fallback, stores text and attachment metadata together, and restores both through the native seed/handshake. Existing non-empty records are never replaced by an empty seed.

The red regression covers an ordinary New Tab edit before quit, then a build-A to build-B relaunch restoring text and attachment order and a later B write surviving another relaunch. Swift coverage also keeps the legacy text-only file format readable.

Non-goals: QuickComposer standalone drafts and local queued-message edits remain separate follow-ups.

Verification: git diff --check (pass). Fleet Swift and browser tests should run in CI; this GCP lane has no Swift or Bun toolchain.

agent-identity footer


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Fixes New Tab drafts being lost after an app update or quit, attachments included, for both the current and Classic New Tab. Drafts are now persisted on every edit and flushed on pagehide — reading the field's latest DOM value so a final keystroke and a cleared draft are captured — giving native quit a durable record even when the WebView closes without unmounting, and text and attachment metadata restore together through the native handshake.

  • A late-arriving native seed only fills an untouched composer field; a person's typing always wins, and a reconnect omitting the one-shot seed leaves restored state in place.
  • Text-only writes preserve the stored attachment list, so an attachment-aware write is never clobbered by a later text-only one.
  • Adopts older per-build text-only draft files and legacy daemon composerDraft fields without overwriting newer state.
  • Leaves QuickComposer standalone drafts and local queued-message edits as follow-ups.

Written for commit ca77c3f. Summary will update on new commits.

View guided diff Turn on auto-fix

@github-actions

github-actions Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review 51eaaef: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr26753 -f ref=lane/nx-newtab-unsent-attachments -f platform=macos -f backend_mode=local

Unclear: web / react-apps-check failed: no known signature; failed step: Check webview test shards.

CI failed on ca77c3f1a1 (run 40671505397 attempt 1): 3 code, 1 unknown.

Job Verdict Why
web / react-apps-base-check (2) code a web test failed
web / react-apps-base-check (3) code a web test failed
web / react-apps-base-check (4) code a web test failed
web / react-apps-check unknown no known signature; failed step: Check webview test shards

Failures:

  • seen on other PRs agent-pane-dock-gutters.test.ts chromium > the gutter beside every part of the stack scrolls the transcript, and the part keeps the ...: failed (job)
  • seen on other PRs agent-pane-dock-gutters.test.ts webkit > the gutter beside every part of the stack scrolls the transcript, and the part keeps the po...: failed (job)
  • seen on other PRs agent-pane-queue-steer.test.ts queued and steering prompts > the queue takes its own place in the stack: nothing is cut off or draw...: failed (job)
  • seen on other PRs changes-stage-hunk-keys.test.ts n then s stages the hunk n stopped at: failed (job)
  • seen on other PRs composer-footer-harness.test.ts with no harness installed the row still says Add harness: failed (job)
  • seen on other PRs composer-mention.test.ts @ then letters lists the chat's matching files and Return writes the path: failed (job)
  • seen on other PRs composer-permission-pill.test.ts claude: permission control keeps the shared capsule geometry: failed (job)
  • seen on other PRs composer-permission-pill.test.ts codex: permission control keeps the shared capsule geometry: failed (job)
  • seen on other PRs agent-pane-background-tasks.test.ts the summary card lists the chat's background tasks: running ones first, the finished folded: failed (job)
  • seen on other PRs agent-pane-chat-unavailable.test.ts loading never shows the unavailable text: a slow attach, then a machine still connecting: failed (job)
  • ... 14 more in the job logs
Matched log lines
web / react-apps-base-check (2): (fail) chromium > the gutter beside every part of the stack scrolls the transcript, and the part keeps the pointer [8702.31ms]
web / react-apps-base-check (3): (fail) the summary card lists the chat's background tasks: running ones first, the finished folded [1163.06ms]
web / react-apps-base-check (4): (fail) no orange or system accent and no opaque glass on the gallery stages [734509.35ms]

Not re-run automatically: web / react-apps-base-check (2), web / react-apps-base-check (3), web / react-apps-base-check (4), web / react-apps-check are not machine failures.

Written by scripts/ci/classify_failures.py (ci-failure-attribution.yml); signatures are its SIGNATURES table. A machine verdict is the runner's fault, not this PR's; yours means the failing file is one this PR changes, also red on main that main's latest full suite fails the same way, seen on other PRs that it failed on another pull request's run lately.

red: cmux-next checks (god files, concurrency, crash safety, l10n); NEW: red check: Main-thread concurrency (+1 more) is not red on the base 14efbd8; do not merge until green; see lane-rules
red: cmux-next crash ratchet; NEW: green on the base 14efbd8; do not merge until green; see lane-rules
red: web / react-apps-check; no finished base run on 14efbd8 to compare; do not merge until green; see lane-rules

CI fast guards failed on ca77c3f1a1 (https://github.com/manaflow-ai/cmux/actions/runs/40671505397). It does not block the merge; a red guard merged into main breaks it for every open PR.
The log named no failed step; see the run.

Agents: python3 scripts/ci/guard_attribution.py fix applies the mechanical fixes locally.

@github-actions github-actions Bot added the risk:high Risk tier (docs/ci/risk-tiers.md) label Oct 28, 2026
@cursor

cursor Bot commented Oct 28, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot uses usage-based billing for this team and requires on-demand usage to be enabled.

A team admin can enable on-demand usage in the Cursor dashboard.

@teamleaderleo
teamleaderleo changed the base branch from feat-cmux-next to lane/nx-draft-persistence October 28, 2026 07:11
@teamleaderleo
teamleaderleo force-pushed the lane/nx-newtab-unsent-attachments branch from 51eaaef to 06ab833 Compare October 28, 2026 07:11
@github-actions github-actions Bot added risk:normal Risk tier (docs/ci/risk-tiers.md) and removed risk:high Risk tier (docs/ci/risk-tiers.md) labels Oct 28, 2026
@blacksmith-sh

blacksmith-sh Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Found 141 test failures on Blacksmith runners:

Failures

Test View Logs
/tmp/tmp4v60ojuz/summary-missing.json (live):/summary-missing.json (live): View Logs
/tmp/tmplweckwsm/summary-fail.json (live):/summary-fail.json (live): View Logs
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows/
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows
View Logs
[new_workspaces] the window draws no frames/[new_workspaces] the window draws no frames View Logs
[tabs] debug.tab_switch timed 0 of 40 switches/
[tabs] debug.tab_switch timed 0 of 40 switches
View Logs
[tabs] the window draws no frames/[tabs] the window draws no frames View Logs
build_only must be a conjunctive exclusion on the helper, signing, and publication jobs
, and must not gate the unsigned app build/
build_only must be a conjunctive exclusion on the helper, signing, and publication jobs
, and must not gate the unsigned app build
View Logs
convention violations found (ERROR lines above)./
convention violations found (ERROR lines above).
View Logs
nightly.yml must derive the embedded key and sign every appcast through the helper/
nightly.yml must derive the embedded key and sign every appcast through the helper
View Logs
test/accent-glass-invariants.test.ts/accent-glass-invariants.test View Logs

...and 131 more test failures. View all on Blacksmith: run 40671505397, run 40648422062

Fix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

@teamleaderleo
teamleaderleo force-pushed the lane/nx-newtab-unsent-attachments branch from b9535ed to 31f83e5 Compare October 28, 2026 08:06
@teamleaderleo
teamleaderleo force-pushed the lane/nx-newtab-unsent-attachments branch from 31f83e5 to 29e6697 Compare October 28, 2026 08:44

This branch was previously deployed

1 inactive deployment
ci-routing-agent — ca77c3f1 Deployed Oct 28, 2026 by teamleaderleo via wait for same-key tree publisher #71290
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant