feat(mobile): plan mode (legacy) toggle with cross-client sync - #6614

Closed
amanthanvi wants to merge 29 commits into
pingdotgg:mainfrom
amanthanvi:t3code/feat-6401
Closed

feat(mobile): plan mode (legacy) toggle with cross-client sync#6614
amanthanvi wants to merge 29 commits into
pingdotgg:mainfrom
amanthanvi:t3code/feat-6401

Conversation

@amanthanvi

@amanthanviamanthanvi commented Aug 14, 2026

Copy link
Copy Markdown

Mobile had no way to see or control Plan Mode: /plan and /default were always-on slash commands with no toggle, no submit-time parsing, and no relationship to the web/desktop "Plan mode (legacy)" setting. This adds the toggle to mobile's Legacy settings section (default off), gates every send path the way web does (composer, new-task composer, queued outbox — including mid-drain preference changes), adds submit-time parsing and new-task slash support, and introduces per-environment synced client preferences (event-sourced server projection with an additive migration, incremental shell-stream updates, LWW with clock-skew clamping) so the toggle follows the user across web, desktop, and mobile, with offline device-local fallback.

Closes#6401

BeforeAfter
Mobile Legacy section with only Legacy Thread ListMobile Legacy section with Plan Mode toggle
Slash menu always showing /planSlash menu with /plan hidden while toggle off

Enabled state and new-task composer: slash menu enabled · new-task slash popover. Verified end-to-end on the iOS simulator (toggle gating both ways, literal /plan send while disabled, plan-mode thread creation).

Implemented by GPT-5.6 Sol (xhigh) via the Codex CLI, orchestrated and reviewed by Claude Fable 5 (Claude Code), with Claude Opus 5 run monitoring.


Note

Medium Risk
Touches interaction mode on every send/outbox path and adds multi-environment LWW reconciliation; mistakes could mis-route turns or briefly block submission until prefs hydrate.

Overview
Adds cross-client Plan Mode (legacy) on mobile: Settings exposes a toggle (default off) wired through synced client preferences with per-field LWW stamps, environment reconciliation, and patches to connected servers via syncedClientPreferences.patch.

A root SyncedClientPreferencesWorker keeps device cache and remote environments in sync; preference reconciliation readiness now gates when plan mode is considered loaded, so sends wait until hydration finishes.

Composer behavior is centralized in legacy-plan-mode helpers: /plan and /default appear only when enabled; standalone submit switches mode instead of sending; outgoing turns and queued work are forced to default when disabled. New-task and thread composers get slash popovers, safer trigger replacement, and shared submit eligibility; the outbox drain re-reads plan mode at delivery time.

Mobile preferences persist sync stamps, merge reconciled patches safely, and fan toggles to all patchable environments with retry and stale-ack handling.

Reviewed by Cursor Bugbot for commit e8f7a72. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add plan mode (legacy) toggle with cross-client preference sync

  • Introduces a client-preferences aggregate with event sourcing: a new client-preferences.patch command, client-preferences.patched event, projector (projector.ts), and DB migration 041 creating projection_synced_client_preferences with per-field LWW semantics
  • Adds WebSocket RPC syncedClientPreferences.patch requiring AuthOrchestrationOperateScope, and extends shell stream with client-preferences-updated items gated by clientPreferencesStreamItem opt-in so legacy clients are unaffected
  • Mobile composer gains /plan and /default slash commands, a command popover, submit-time mode parsing, and submission gating on preference load (legacy-plan-mode.ts, NewTaskDraftScreen.tsx, ThreadComposer.tsx)
  • Web settings coordinate plan mode hydration across environments with adopt/seed logic, pending write tracking, and serialized local persistence (useSettings.ts, synced-plan-mode.ts)
  • Risk: REQUIRED_SNAPSHOT_PROJECTORS now includes syncedClientPreferences, so snapshot readiness checks will wait for the new projector; canonicalizeClientCommandTimestamps clamps client-preferences.patchupdatedAt to server receive time if more than 5 minutes ahead

Macroscope summarized e8f7a72.

CopilotAI lite review requested due to automatic review settings August 14, 2026 14:59
@coderabbitai

coderabbitaiBot commented Aug 14, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: fd862178-6d5e-4cc2-8512-79c939d2d484

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

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Aug 14, 2026
Comment threadapps/web/src/hooks/useSettings.ts
Comment threadpackages/contracts/src/syncedClientPreferences.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/use-thread-outbox-drain.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences.ts Outdated

CopilotAI 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.

Pull request overview

Adds a cross-client “Plan Mode (Legacy)” preference that syncs per-environment via the server’s event log, and wires mobile’s UI + send paths to gate /plan / /default and interaction mode the same way web/desktop do.

Changes:

  • Introduces a new synced client preferences contract + WS RPCs (syncedClientPreferences.get/patch) and threads it through orchestration shell snapshots/stream items.
  • Implements a server-side client-preferences aggregate with LWW stamping (incl. future-skew clamping), SQLite projection, migration, and incremental shell-stream updates.
  • Adds mobile Plan Mode (Legacy) toggle + plan-mode helpers, submit-time parsing, outbox drain gating, and a background reconciler that converges preferences across connected environments with offline cache fallback.

Reviewed changes

Copilot reviewed 54 out of 54 changed files in this pull request and generated 2 comments.

Show a summary per file
FileDescription
packages/contracts/src/syncedClientPreferences.tsNew schema/types for synced client preferences + patch/request payloads.
packages/contracts/src/settings.test.tsAdds contract tests validating synced preference schema behavior.
packages/contracts/src/rpc.tsAdds WS method names + RPC definitions for get/patch synced preferences.
packages/contracts/src/orchestration.tsExtends read/shell models + shell stream union for synced preferences and adds command/event wiring.
packages/contracts/src/orchestration.test.tsEnsures generic command parsing rejects unknown-only patches; verifies legacy shell decoding tolerance.
packages/contracts/src/index.tsRe-exports synced client preferences module.
packages/client-runtime/src/state/shellReducer.tsApplies client-preferences-updated shell stream items into shell snapshots.
packages/client-runtime/src/state/shellReducer.test.tsTests reducer handling of synced preference updates.
packages/client-runtime/src/state/server.tsAdds environment RPC command for patching synced client preferences.
docs/user/plan-mode.mdNew user doc for enabling Plan Mode (Legacy) and sync behavior.
apps/web/src/hooks/useSettings.tsMerges server/client settings with synced prefs override; adds hydration/seed/write logic.
apps/web/src/hooks/useSettings.test.tsAdds extensive tests for synced plan-mode hydration controller + atom slicing behavior.
apps/server/src/ws.tsStreams incremental client-preferences-updated items; adds RPC handlers for get/patch.
apps/server/src/serverRuntimeStartup.test.tsUpdates test seams for new snapshot query method.
apps/server/src/server.test.tsAdds regression test ensuring preference patch streams incrementally (no full shell reload).
apps/server/src/provider/Layers/ProviderSessionReaper.test.tsUpdates test seam to include new snapshot query method.
apps/server/src/project/ProjectSetupScriptRunner.test.tsUpdates test seam to include new snapshot query method.
apps/server/src/persistence/Services/OrchestrationCommandReceipts.tsExtends receipt schema aggregate-id union to include client-preferences singleton.
apps/server/src/persistence/Migrations/041_ProjectionSyncedClientPreferences.tsNew migration creating synced preference projection table + projector cursor seeding.
apps/server/src/persistence/Migrations/041_ProjectionSyncedClientPreferences.test.tsTests migration behavior and idempotence.
apps/server/src/persistence/Migrations.tsRegisters migration 041.
apps/server/src/persistence/Layers/OrchestrationEventStore.tsExtends persisted event schemas to include client-preferences stream/aggregate IDs.
apps/server/src/orchestration/Services/ProjectionSnapshotQuery.tsAdds getSyncedClientPreferences to snapshot query interface.
apps/server/src/orchestration/projector.tsProjects client-preferences.patched events into the in-memory read model with LWW logic.
apps/server/src/orchestration/Normalizer.tsClamps excessively future-skewed preference stamps to server receive time.
apps/server/src/orchestration/Normalizer.test.tsTests preference-stamp skew clamping behavior.
apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.tsReads synced preference singleton projection into snapshots; includes in updatedAt computation.
apps/server/src/orchestration/Layers/ProjectionPipeline.tsAdds projector to upsert synced preferences into SQLite projection with LWW guard.
apps/server/src/orchestration/Layers/ProjectionPipeline.test.tsTests deterministic rebuild and idempotence for synced preferences projection.
apps/server/src/orchestration/Layers/OrchestrationEngine.tsRoutes client-preferences.patch commands to the client-preferences aggregate ref.
apps/server/src/orchestration/Layers/OrchestrationEngine.test.tsVerifies receipts + LWW behavior for preference patches and shell projection results.
apps/server/src/orchestration/decider.tsEmits client-preferences.patched events for patch commands.
apps/server/src/checkpointing/CheckpointDiffQuery.test.tsUpdates test seams to ensure diff query doesn’t request new snapshot query method.
apps/server/src/auth/RpcAuthorization.tsRequires read/operate scopes for synced preference get/patch RPCs.
apps/mobile/src/state/use-thread-outbox-drain.tsForces default interaction mode when plan mode disabled; re-reads preference at drain-time.
apps/mobile/src/state/use-thread-composer-state.tsGates interaction mode derived from draft/thread via plan-mode helper.
apps/mobile/src/state/thread-outbox.test.tsAdds tests for drain-time gating and queued settings behavior vs preference changes.
apps/mobile/src/state/thread-outbox-model.tsAdds plan-mode-aware queued settings resolution + send decision helper.
apps/mobile/src/state/synced-client-preferences.tsAdds background worker to reconcile device cache with connected environments + update hook.
apps/mobile/src/state/synced-client-preferences.test.tsAdds tests for reconciliation, fan-out, stamping, and pending settlement behavior.
apps/mobile/src/state/synced-client-preferences-model.tsImplements LWW reconciliation + stamp generation + fan-out helpers for mobile.
apps/mobile/src/Stack.tsxMounts the synced client preferences worker alongside outbox drain worker.
apps/mobile/src/persistence/mobile-preferences.tsTreats planModeEnabled as synced/offline-cache; validates canonical updatedAt stamp.
apps/mobile/src/lib/storage.test.tsAdds coverage for loading legacy prefs and dropping non-canonical synced stamps.
apps/mobile/src/features/threads/use-plan-mode-enabled.tsAdds hook to read plan mode preference + loaded state from mobile preferences atom.
apps/mobile/src/features/threads/ThreadComposer.tsxAdds plan-mode gating of slash commands, submit-time parsing, and safer trigger replacement.
apps/mobile/src/features/threads/plan-mode.tsNew shared helper logic for gating, submit parsing, and trigger replacement.
apps/mobile/src/features/threads/plan-mode.test.tsTests plan-mode gating, submit parsing, and trigger replacement semantics.
apps/mobile/src/features/threads/NewTaskDraftScreen.tsxAdds new-task slash popover + submit-time parsing + eligibility refactor and locking.
apps/mobile/src/features/threads/new-task-submit.tsNew helpers for submission eligibility, selection resetting, and command interpretation gating.
apps/mobile/src/features/threads/new-task-submit.test.tsTests new-task submit eligibility + selection reset behavior.
apps/mobile/src/features/threads/new-task-flow-provider.tsxSwitches to synced plan mode preference state and applies plan-mode interaction gating.
apps/mobile/src/features/settings/SettingsRouteScreen.tsxAdds “Plan Mode (Legacy)” toggle to mobile Legacy section and wires to synced update hook.
apps/mobile/src/components/AppSymbol.tsxAdds Android mapping for hammer icon used by the new setting row.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment threaddocs/user/plan-mode.md Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
@macroscopeapp

macroscopeappBot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Skipped

Macroscope did not run approvability analysis for this PR. Diff is too large for automated approval analysis, so this PR cannot be approved automatically.

You can add or adjust custom eligibility rules. Learn more.

Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/use-thread-outbox-drain.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences.ts
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts
Comment threadapps/mobile/src/state/synced-client-preferences.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
Comment threadapps/web/src/hooks/synced-plan-mode.ts
Aman Thanvi added 6 commits August 15, 2026 10:40
Adds a Plan Mode (Legacy) toggle to mobile Settings (default off) that
gates the /plan and /default slash commands and forces outgoing turns to
default mode when off, mirroring web semantics across every send path
(composer, new task, queued outbox). Adds submit-time parsing and slash
support on the new-task composer. Introduces per-environment synced
client preferences (contracts schema, event-sourced server projection
with additive migration, incremental shell stream item) consumed by web
and mobile with LWW reconciliation, clock-skew clamping, and offline
device-local fallback.
Closespingdotgg#6401
- Preserve offline web plan-mode writes
- Reject impossible preference timestamps
- Retry failed web preference patches
- Order rapid web toggles monotonically
- Re-read plan mode before queued mobile delivery
- Route environment-scoped preference writes correctly
- Ignore stale mobile preference acknowledgements
- Document the mobile Legacy settings location
- Use Hermes-compatible reconciliation sorting
- Bound mobile synced-preference stamps to the canonical future-skew window.
- Gate thread-composer enqueue mode selection on preference hydration.
- Preserve newer local Plan Mode intent in read-only mobile and web sessions.
- Add Plan Mode to the user-docs index.
Comment threadapps/mobile/src/features/threads/ThreadComposer.tsx
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated

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

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 5a02ceb. Configure here.

Comment threadapps/mobile/src/state/preferences.ts
@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

Closing this PR after an automated pass over open pull requests. Mobile already supports Plan Mode. The proposal adds an unnecessary cross-client preference rewrite.

@t3dotggt3dotgg closed this Aug 23, 2026
@amanthanvi
amanthanvi deleted the t3code/feat-6401 branch August 26, 2026 23:09
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Mobile: add the Legacy features menu (Plan mode toggle) for parity with web/desktop

3 participants

@amanthanvi@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat(mobile): plan mode (legacy) toggle with cross-client sync - #6614

Closed
amanthanvi wants to merge 29 commits into
pingdotgg:mainfrom
amanthanvi:t3code/feat-6401
Closed

feat(mobile): plan mode (legacy) toggle with cross-client sync#6614
amanthanvi wants to merge 29 commits into
pingdotgg:mainfrom
amanthanvi:t3code/feat-6401

Conversation

@amanthanvi

@amanthanviamanthanvi commented Aug 14, 2026

Copy link
Copy Markdown

Mobile had no way to see or control Plan Mode: /plan and /default were always-on slash commands with no toggle, no submit-time parsing, and no relationship to the web/desktop "Plan mode (legacy)" setting. This adds the toggle to mobile's Legacy settings section (default off), gates every send path the way web does (composer, new-task composer, queued outbox — including mid-drain preference changes), adds submit-time parsing and new-task slash support, and introduces per-environment synced client preferences (event-sourced server projection with an additive migration, incremental shell-stream updates, LWW with clock-skew clamping) so the toggle follows the user across web, desktop, and mobile, with offline device-local fallback.

Closes#6401

BeforeAfter
Mobile Legacy section with only Legacy Thread ListMobile Legacy section with Plan Mode toggle
Slash menu always showing /planSlash menu with /plan hidden while toggle off

Enabled state and new-task composer: slash menu enabled · new-task slash popover. Verified end-to-end on the iOS simulator (toggle gating both ways, literal /plan send while disabled, plan-mode thread creation).

Implemented by GPT-5.6 Sol (xhigh) via the Codex CLI, orchestrated and reviewed by Claude Fable 5 (Claude Code), with Claude Opus 5 run monitoring.


Note

Medium Risk
Touches interaction mode on every send/outbox path and adds multi-environment LWW reconciliation; mistakes could mis-route turns or briefly block submission until prefs hydrate.

Overview
Adds cross-client Plan Mode (legacy) on mobile: Settings exposes a toggle (default off) wired through synced client preferences with per-field LWW stamps, environment reconciliation, and patches to connected servers via syncedClientPreferences.patch.

A root SyncedClientPreferencesWorker keeps device cache and remote environments in sync; preference reconciliation readiness now gates when plan mode is considered loaded, so sends wait until hydration finishes.

Composer behavior is centralized in legacy-plan-mode helpers: /plan and /default appear only when enabled; standalone submit switches mode instead of sending; outgoing turns and queued work are forced to default when disabled. New-task and thread composers get slash popovers, safer trigger replacement, and shared submit eligibility; the outbox drain re-reads plan mode at delivery time.

Mobile preferences persist sync stamps, merge reconciled patches safely, and fan toggles to all patchable environments with retry and stale-ack handling.

Reviewed by Cursor Bugbot for commit e8f7a72. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add plan mode (legacy) toggle with cross-client preference sync

  • Introduces a client-preferences aggregate with event sourcing: a new client-preferences.patch command, client-preferences.patched event, projector (projector.ts), and DB migration 041 creating projection_synced_client_preferences with per-field LWW semantics
  • Adds WebSocket RPC syncedClientPreferences.patch requiring AuthOrchestrationOperateScope, and extends shell stream with client-preferences-updated items gated by clientPreferencesStreamItem opt-in so legacy clients are unaffected
  • Mobile composer gains /plan and /default slash commands, a command popover, submit-time mode parsing, and submission gating on preference load (legacy-plan-mode.ts, NewTaskDraftScreen.tsx, ThreadComposer.tsx)
  • Web settings coordinate plan mode hydration across environments with adopt/seed logic, pending write tracking, and serialized local persistence (useSettings.ts, synced-plan-mode.ts)
  • Risk: REQUIRED_SNAPSHOT_PROJECTORS now includes syncedClientPreferences, so snapshot readiness checks will wait for the new projector; canonicalizeClientCommandTimestamps clamps client-preferences.patchupdatedAt to server receive time if more than 5 minutes ahead

Macroscope summarized e8f7a72.

CopilotAI lite review requested due to automatic review settings August 14, 2026 14:59
@coderabbitai

coderabbitaiBot commented Aug 14, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: fd862178-6d5e-4cc2-8512-79c939d2d484

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

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Aug 14, 2026
Comment threadapps/web/src/hooks/useSettings.ts
Comment threadpackages/contracts/src/syncedClientPreferences.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/use-thread-outbox-drain.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences.ts Outdated

CopilotAI 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.

Pull request overview

Adds a cross-client “Plan Mode (Legacy)” preference that syncs per-environment via the server’s event log, and wires mobile’s UI + send paths to gate /plan / /default and interaction mode the same way web/desktop do.

Changes:

  • Introduces a new synced client preferences contract + WS RPCs (syncedClientPreferences.get/patch) and threads it through orchestration shell snapshots/stream items.
  • Implements a server-side client-preferences aggregate with LWW stamping (incl. future-skew clamping), SQLite projection, migration, and incremental shell-stream updates.
  • Adds mobile Plan Mode (Legacy) toggle + plan-mode helpers, submit-time parsing, outbox drain gating, and a background reconciler that converges preferences across connected environments with offline cache fallback.

Reviewed changes

Copilot reviewed 54 out of 54 changed files in this pull request and generated 2 comments.

Show a summary per file
FileDescription
packages/contracts/src/syncedClientPreferences.tsNew schema/types for synced client preferences + patch/request payloads.
packages/contracts/src/settings.test.tsAdds contract tests validating synced preference schema behavior.
packages/contracts/src/rpc.tsAdds WS method names + RPC definitions for get/patch synced preferences.
packages/contracts/src/orchestration.tsExtends read/shell models + shell stream union for synced preferences and adds command/event wiring.
packages/contracts/src/orchestration.test.tsEnsures generic command parsing rejects unknown-only patches; verifies legacy shell decoding tolerance.
packages/contracts/src/index.tsRe-exports synced client preferences module.
packages/client-runtime/src/state/shellReducer.tsApplies client-preferences-updated shell stream items into shell snapshots.
packages/client-runtime/src/state/shellReducer.test.tsTests reducer handling of synced preference updates.
packages/client-runtime/src/state/server.tsAdds environment RPC command for patching synced client preferences.
docs/user/plan-mode.mdNew user doc for enabling Plan Mode (Legacy) and sync behavior.
apps/web/src/hooks/useSettings.tsMerges server/client settings with synced prefs override; adds hydration/seed/write logic.
apps/web/src/hooks/useSettings.test.tsAdds extensive tests for synced plan-mode hydration controller + atom slicing behavior.
apps/server/src/ws.tsStreams incremental client-preferences-updated items; adds RPC handlers for get/patch.
apps/server/src/serverRuntimeStartup.test.tsUpdates test seams for new snapshot query method.
apps/server/src/server.test.tsAdds regression test ensuring preference patch streams incrementally (no full shell reload).
apps/server/src/provider/Layers/ProviderSessionReaper.test.tsUpdates test seam to include new snapshot query method.
apps/server/src/project/ProjectSetupScriptRunner.test.tsUpdates test seam to include new snapshot query method.
apps/server/src/persistence/Services/OrchestrationCommandReceipts.tsExtends receipt schema aggregate-id union to include client-preferences singleton.
apps/server/src/persistence/Migrations/041_ProjectionSyncedClientPreferences.tsNew migration creating synced preference projection table + projector cursor seeding.
apps/server/src/persistence/Migrations/041_ProjectionSyncedClientPreferences.test.tsTests migration behavior and idempotence.
apps/server/src/persistence/Migrations.tsRegisters migration 041.
apps/server/src/persistence/Layers/OrchestrationEventStore.tsExtends persisted event schemas to include client-preferences stream/aggregate IDs.
apps/server/src/orchestration/Services/ProjectionSnapshotQuery.tsAdds getSyncedClientPreferences to snapshot query interface.
apps/server/src/orchestration/projector.tsProjects client-preferences.patched events into the in-memory read model with LWW logic.
apps/server/src/orchestration/Normalizer.tsClamps excessively future-skewed preference stamps to server receive time.
apps/server/src/orchestration/Normalizer.test.tsTests preference-stamp skew clamping behavior.
apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.tsReads synced preference singleton projection into snapshots; includes in updatedAt computation.
apps/server/src/orchestration/Layers/ProjectionPipeline.tsAdds projector to upsert synced preferences into SQLite projection with LWW guard.
apps/server/src/orchestration/Layers/ProjectionPipeline.test.tsTests deterministic rebuild and idempotence for synced preferences projection.
apps/server/src/orchestration/Layers/OrchestrationEngine.tsRoutes client-preferences.patch commands to the client-preferences aggregate ref.
apps/server/src/orchestration/Layers/OrchestrationEngine.test.tsVerifies receipts + LWW behavior for preference patches and shell projection results.
apps/server/src/orchestration/decider.tsEmits client-preferences.patched events for patch commands.
apps/server/src/checkpointing/CheckpointDiffQuery.test.tsUpdates test seams to ensure diff query doesn’t request new snapshot query method.
apps/server/src/auth/RpcAuthorization.tsRequires read/operate scopes for synced preference get/patch RPCs.
apps/mobile/src/state/use-thread-outbox-drain.tsForces default interaction mode when plan mode disabled; re-reads preference at drain-time.
apps/mobile/src/state/use-thread-composer-state.tsGates interaction mode derived from draft/thread via plan-mode helper.
apps/mobile/src/state/thread-outbox.test.tsAdds tests for drain-time gating and queued settings behavior vs preference changes.
apps/mobile/src/state/thread-outbox-model.tsAdds plan-mode-aware queued settings resolution + send decision helper.
apps/mobile/src/state/synced-client-preferences.tsAdds background worker to reconcile device cache with connected environments + update hook.
apps/mobile/src/state/synced-client-preferences.test.tsAdds tests for reconciliation, fan-out, stamping, and pending settlement behavior.
apps/mobile/src/state/synced-client-preferences-model.tsImplements LWW reconciliation + stamp generation + fan-out helpers for mobile.
apps/mobile/src/Stack.tsxMounts the synced client preferences worker alongside outbox drain worker.
apps/mobile/src/persistence/mobile-preferences.tsTreats planModeEnabled as synced/offline-cache; validates canonical updatedAt stamp.
apps/mobile/src/lib/storage.test.tsAdds coverage for loading legacy prefs and dropping non-canonical synced stamps.
apps/mobile/src/features/threads/use-plan-mode-enabled.tsAdds hook to read plan mode preference + loaded state from mobile preferences atom.
apps/mobile/src/features/threads/ThreadComposer.tsxAdds plan-mode gating of slash commands, submit-time parsing, and safer trigger replacement.
apps/mobile/src/features/threads/plan-mode.tsNew shared helper logic for gating, submit parsing, and trigger replacement.
apps/mobile/src/features/threads/plan-mode.test.tsTests plan-mode gating, submit parsing, and trigger replacement semantics.
apps/mobile/src/features/threads/NewTaskDraftScreen.tsxAdds new-task slash popover + submit-time parsing + eligibility refactor and locking.
apps/mobile/src/features/threads/new-task-submit.tsNew helpers for submission eligibility, selection resetting, and command interpretation gating.
apps/mobile/src/features/threads/new-task-submit.test.tsTests new-task submit eligibility + selection reset behavior.
apps/mobile/src/features/threads/new-task-flow-provider.tsxSwitches to synced plan mode preference state and applies plan-mode interaction gating.
apps/mobile/src/features/settings/SettingsRouteScreen.tsxAdds “Plan Mode (Legacy)” toggle to mobile Legacy section and wires to synced update hook.
apps/mobile/src/components/AppSymbol.tsxAdds Android mapping for hammer icon used by the new setting row.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment threaddocs/user/plan-mode.md Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
@macroscopeapp

macroscopeappBot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Skipped

Macroscope did not run approvability analysis for this PR. Diff is too large for automated approval analysis, so this PR cannot be approved automatically.

You can add or adjust custom eligibility rules. Learn more.

Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/use-thread-outbox-drain.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences.ts
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts
Comment threadapps/mobile/src/state/synced-client-preferences.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
Comment threadapps/web/src/hooks/synced-plan-mode.ts
Aman Thanvi added 6 commits August 15, 2026 10:40
Adds a Plan Mode (Legacy) toggle to mobile Settings (default off) that
gates the /plan and /default slash commands and forces outgoing turns to
default mode when off, mirroring web semantics across every send path
(composer, new task, queued outbox). Adds submit-time parsing and slash
support on the new-task composer. Introduces per-environment synced
client preferences (contracts schema, event-sourced server projection
with additive migration, incremental shell stream item) consumed by web
and mobile with LWW reconciliation, clock-skew clamping, and offline
device-local fallback.
Closespingdotgg#6401
- Preserve offline web plan-mode writes
- Reject impossible preference timestamps
- Retry failed web preference patches
- Order rapid web toggles monotonically
- Re-read plan mode before queued mobile delivery
- Route environment-scoped preference writes correctly
- Ignore stale mobile preference acknowledgements
- Document the mobile Legacy settings location
- Use Hermes-compatible reconciliation sorting
- Bound mobile synced-preference stamps to the canonical future-skew window.
- Gate thread-composer enqueue mode selection on preference hydration.
- Preserve newer local Plan Mode intent in read-only mobile and web sessions.
- Add Plan Mode to the user-docs index.
Comment threadapps/mobile/src/features/threads/ThreadComposer.tsx
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated

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

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 5a02ceb. Configure here.

Comment threadapps/mobile/src/state/preferences.ts
@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

Closing this PR after an automated pass over open pull requests. Mobile already supports Plan Mode. The proposal adds an unnecessary cross-client preference rewrite.

@t3dotggt3dotgg closed this Aug 23, 2026
@amanthanvi
amanthanvi deleted the t3code/feat-6401 branch August 26, 2026 23:09
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Mobile: add the Legacy features menu (Plan mode toggle) for parity with web/desktop

3 participants

@amanthanvi@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(mobile): plan mode (legacy) toggle with cross-client sync - #6614

Closed
amanthanvi wants to merge 29 commits into
pingdotgg:mainfrom
amanthanvi:t3code/feat-6401
Closed

feat(mobile): plan mode (legacy) toggle with cross-client sync#6614
amanthanvi wants to merge 29 commits into
pingdotgg:mainfrom
amanthanvi:t3code/feat-6401

Conversation

@amanthanvi

@amanthanviamanthanvi commented Aug 14, 2026

Copy link
Copy Markdown

Mobile had no way to see or control Plan Mode: /plan and /default were always-on slash commands with no toggle, no submit-time parsing, and no relationship to the web/desktop "Plan mode (legacy)" setting. This adds the toggle to mobile's Legacy settings section (default off), gates every send path the way web does (composer, new-task composer, queued outbox — including mid-drain preference changes), adds submit-time parsing and new-task slash support, and introduces per-environment synced client preferences (event-sourced server projection with an additive migration, incremental shell-stream updates, LWW with clock-skew clamping) so the toggle follows the user across web, desktop, and mobile, with offline device-local fallback.

Closes#6401

BeforeAfter
Mobile Legacy section with only Legacy Thread ListMobile Legacy section with Plan Mode toggle
Slash menu always showing /planSlash menu with /plan hidden while toggle off

Enabled state and new-task composer: slash menu enabled · new-task slash popover. Verified end-to-end on the iOS simulator (toggle gating both ways, literal /plan send while disabled, plan-mode thread creation).

Implemented by GPT-5.6 Sol (xhigh) via the Codex CLI, orchestrated and reviewed by Claude Fable 5 (Claude Code), with Claude Opus 5 run monitoring.


Note

Medium Risk
Touches interaction mode on every send/outbox path and adds multi-environment LWW reconciliation; mistakes could mis-route turns or briefly block submission until prefs hydrate.

Overview
Adds cross-client Plan Mode (legacy) on mobile: Settings exposes a toggle (default off) wired through synced client preferences with per-field LWW stamps, environment reconciliation, and patches to connected servers via syncedClientPreferences.patch.

A root SyncedClientPreferencesWorker keeps device cache and remote environments in sync; preference reconciliation readiness now gates when plan mode is considered loaded, so sends wait until hydration finishes.

Composer behavior is centralized in legacy-plan-mode helpers: /plan and /default appear only when enabled; standalone submit switches mode instead of sending; outgoing turns and queued work are forced to default when disabled. New-task and thread composers get slash popovers, safer trigger replacement, and shared submit eligibility; the outbox drain re-reads plan mode at delivery time.

Mobile preferences persist sync stamps, merge reconciled patches safely, and fan toggles to all patchable environments with retry and stale-ack handling.

Reviewed by Cursor Bugbot for commit e8f7a72. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add plan mode (legacy) toggle with cross-client preference sync

  • Introduces a client-preferences aggregate with event sourcing: a new client-preferences.patch command, client-preferences.patched event, projector (projector.ts), and DB migration 041 creating projection_synced_client_preferences with per-field LWW semantics
  • Adds WebSocket RPC syncedClientPreferences.patch requiring AuthOrchestrationOperateScope, and extends shell stream with client-preferences-updated items gated by clientPreferencesStreamItem opt-in so legacy clients are unaffected
  • Mobile composer gains /plan and /default slash commands, a command popover, submit-time mode parsing, and submission gating on preference load (legacy-plan-mode.ts, NewTaskDraftScreen.tsx, ThreadComposer.tsx)
  • Web settings coordinate plan mode hydration across environments with adopt/seed logic, pending write tracking, and serialized local persistence (useSettings.ts, synced-plan-mode.ts)
  • Risk: REQUIRED_SNAPSHOT_PROJECTORS now includes syncedClientPreferences, so snapshot readiness checks will wait for the new projector; canonicalizeClientCommandTimestamps clamps client-preferences.patchupdatedAt to server receive time if more than 5 minutes ahead

Macroscope summarized e8f7a72.

CopilotAI lite review requested due to automatic review settings August 14, 2026 14:59
@coderabbitai

coderabbitaiBot commented Aug 14, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: fd862178-6d5e-4cc2-8512-79c939d2d484

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

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Aug 14, 2026
Comment threadapps/web/src/hooks/useSettings.ts
Comment threadpackages/contracts/src/syncedClientPreferences.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/use-thread-outbox-drain.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences.ts Outdated

CopilotAI 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.

Pull request overview

Adds a cross-client “Plan Mode (Legacy)” preference that syncs per-environment via the server’s event log, and wires mobile’s UI + send paths to gate /plan / /default and interaction mode the same way web/desktop do.

Changes:

  • Introduces a new synced client preferences contract + WS RPCs (syncedClientPreferences.get/patch) and threads it through orchestration shell snapshots/stream items.
  • Implements a server-side client-preferences aggregate with LWW stamping (incl. future-skew clamping), SQLite projection, migration, and incremental shell-stream updates.
  • Adds mobile Plan Mode (Legacy) toggle + plan-mode helpers, submit-time parsing, outbox drain gating, and a background reconciler that converges preferences across connected environments with offline cache fallback.

Reviewed changes

Copilot reviewed 54 out of 54 changed files in this pull request and generated 2 comments.

Show a summary per file
FileDescription
packages/contracts/src/syncedClientPreferences.tsNew schema/types for synced client preferences + patch/request payloads.
packages/contracts/src/settings.test.tsAdds contract tests validating synced preference schema behavior.
packages/contracts/src/rpc.tsAdds WS method names + RPC definitions for get/patch synced preferences.
packages/contracts/src/orchestration.tsExtends read/shell models + shell stream union for synced preferences and adds command/event wiring.
packages/contracts/src/orchestration.test.tsEnsures generic command parsing rejects unknown-only patches; verifies legacy shell decoding tolerance.
packages/contracts/src/index.tsRe-exports synced client preferences module.
packages/client-runtime/src/state/shellReducer.tsApplies client-preferences-updated shell stream items into shell snapshots.
packages/client-runtime/src/state/shellReducer.test.tsTests reducer handling of synced preference updates.
packages/client-runtime/src/state/server.tsAdds environment RPC command for patching synced client preferences.
docs/user/plan-mode.mdNew user doc for enabling Plan Mode (Legacy) and sync behavior.
apps/web/src/hooks/useSettings.tsMerges server/client settings with synced prefs override; adds hydration/seed/write logic.
apps/web/src/hooks/useSettings.test.tsAdds extensive tests for synced plan-mode hydration controller + atom slicing behavior.
apps/server/src/ws.tsStreams incremental client-preferences-updated items; adds RPC handlers for get/patch.
apps/server/src/serverRuntimeStartup.test.tsUpdates test seams for new snapshot query method.
apps/server/src/server.test.tsAdds regression test ensuring preference patch streams incrementally (no full shell reload).
apps/server/src/provider/Layers/ProviderSessionReaper.test.tsUpdates test seam to include new snapshot query method.
apps/server/src/project/ProjectSetupScriptRunner.test.tsUpdates test seam to include new snapshot query method.
apps/server/src/persistence/Services/OrchestrationCommandReceipts.tsExtends receipt schema aggregate-id union to include client-preferences singleton.
apps/server/src/persistence/Migrations/041_ProjectionSyncedClientPreferences.tsNew migration creating synced preference projection table + projector cursor seeding.
apps/server/src/persistence/Migrations/041_ProjectionSyncedClientPreferences.test.tsTests migration behavior and idempotence.
apps/server/src/persistence/Migrations.tsRegisters migration 041.
apps/server/src/persistence/Layers/OrchestrationEventStore.tsExtends persisted event schemas to include client-preferences stream/aggregate IDs.
apps/server/src/orchestration/Services/ProjectionSnapshotQuery.tsAdds getSyncedClientPreferences to snapshot query interface.
apps/server/src/orchestration/projector.tsProjects client-preferences.patched events into the in-memory read model with LWW logic.
apps/server/src/orchestration/Normalizer.tsClamps excessively future-skewed preference stamps to server receive time.
apps/server/src/orchestration/Normalizer.test.tsTests preference-stamp skew clamping behavior.
apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.tsReads synced preference singleton projection into snapshots; includes in updatedAt computation.
apps/server/src/orchestration/Layers/ProjectionPipeline.tsAdds projector to upsert synced preferences into SQLite projection with LWW guard.
apps/server/src/orchestration/Layers/ProjectionPipeline.test.tsTests deterministic rebuild and idempotence for synced preferences projection.
apps/server/src/orchestration/Layers/OrchestrationEngine.tsRoutes client-preferences.patch commands to the client-preferences aggregate ref.
apps/server/src/orchestration/Layers/OrchestrationEngine.test.tsVerifies receipts + LWW behavior for preference patches and shell projection results.
apps/server/src/orchestration/decider.tsEmits client-preferences.patched events for patch commands.
apps/server/src/checkpointing/CheckpointDiffQuery.test.tsUpdates test seams to ensure diff query doesn’t request new snapshot query method.
apps/server/src/auth/RpcAuthorization.tsRequires read/operate scopes for synced preference get/patch RPCs.
apps/mobile/src/state/use-thread-outbox-drain.tsForces default interaction mode when plan mode disabled; re-reads preference at drain-time.
apps/mobile/src/state/use-thread-composer-state.tsGates interaction mode derived from draft/thread via plan-mode helper.
apps/mobile/src/state/thread-outbox.test.tsAdds tests for drain-time gating and queued settings behavior vs preference changes.
apps/mobile/src/state/thread-outbox-model.tsAdds plan-mode-aware queued settings resolution + send decision helper.
apps/mobile/src/state/synced-client-preferences.tsAdds background worker to reconcile device cache with connected environments + update hook.
apps/mobile/src/state/synced-client-preferences.test.tsAdds tests for reconciliation, fan-out, stamping, and pending settlement behavior.
apps/mobile/src/state/synced-client-preferences-model.tsImplements LWW reconciliation + stamp generation + fan-out helpers for mobile.
apps/mobile/src/Stack.tsxMounts the synced client preferences worker alongside outbox drain worker.
apps/mobile/src/persistence/mobile-preferences.tsTreats planModeEnabled as synced/offline-cache; validates canonical updatedAt stamp.
apps/mobile/src/lib/storage.test.tsAdds coverage for loading legacy prefs and dropping non-canonical synced stamps.
apps/mobile/src/features/threads/use-plan-mode-enabled.tsAdds hook to read plan mode preference + loaded state from mobile preferences atom.
apps/mobile/src/features/threads/ThreadComposer.tsxAdds plan-mode gating of slash commands, submit-time parsing, and safer trigger replacement.
apps/mobile/src/features/threads/plan-mode.tsNew shared helper logic for gating, submit parsing, and trigger replacement.
apps/mobile/src/features/threads/plan-mode.test.tsTests plan-mode gating, submit parsing, and trigger replacement semantics.
apps/mobile/src/features/threads/NewTaskDraftScreen.tsxAdds new-task slash popover + submit-time parsing + eligibility refactor and locking.
apps/mobile/src/features/threads/new-task-submit.tsNew helpers for submission eligibility, selection resetting, and command interpretation gating.
apps/mobile/src/features/threads/new-task-submit.test.tsTests new-task submit eligibility + selection reset behavior.
apps/mobile/src/features/threads/new-task-flow-provider.tsxSwitches to synced plan mode preference state and applies plan-mode interaction gating.
apps/mobile/src/features/settings/SettingsRouteScreen.tsxAdds “Plan Mode (Legacy)” toggle to mobile Legacy section and wires to synced update hook.
apps/mobile/src/components/AppSymbol.tsxAdds Android mapping for hammer icon used by the new setting row.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment threaddocs/user/plan-mode.md Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
@macroscopeapp

macroscopeappBot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Skipped

Macroscope did not run approvability analysis for this PR. Diff is too large for automated approval analysis, so this PR cannot be approved automatically.

You can add or adjust custom eligibility rules. Learn more.

Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/use-thread-outbox-drain.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences.ts
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts
Comment threadapps/mobile/src/state/synced-client-preferences.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
Comment threadapps/web/src/hooks/synced-plan-mode.ts
Aman Thanvi added 6 commits August 15, 2026 10:40
Adds a Plan Mode (Legacy) toggle to mobile Settings (default off) that
gates the /plan and /default slash commands and forces outgoing turns to
default mode when off, mirroring web semantics across every send path
(composer, new task, queued outbox). Adds submit-time parsing and slash
support on the new-task composer. Introduces per-environment synced
client preferences (contracts schema, event-sourced server projection
with additive migration, incremental shell stream item) consumed by web
and mobile with LWW reconciliation, clock-skew clamping, and offline
device-local fallback.
Closespingdotgg#6401
- Preserve offline web plan-mode writes
- Reject impossible preference timestamps
- Retry failed web preference patches
- Order rapid web toggles monotonically
- Re-read plan mode before queued mobile delivery
- Route environment-scoped preference writes correctly
- Ignore stale mobile preference acknowledgements
- Document the mobile Legacy settings location
- Use Hermes-compatible reconciliation sorting
- Bound mobile synced-preference stamps to the canonical future-skew window.
- Gate thread-composer enqueue mode selection on preference hydration.
- Preserve newer local Plan Mode intent in read-only mobile and web sessions.
- Add Plan Mode to the user-docs index.
Comment threadapps/mobile/src/features/threads/ThreadComposer.tsx
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated

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

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 5a02ceb. Configure here.

Comment threadapps/mobile/src/state/preferences.ts
@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

Closing this PR after an automated pass over open pull requests. Mobile already supports Plan Mode. The proposal adds an unnecessary cross-client preference rewrite.

@t3dotggt3dotgg closed this Aug 23, 2026
@amanthanvi
amanthanvi deleted the t3code/feat-6401 branch August 26, 2026 23:09
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Mobile: add the Legacy features menu (Plan mode toggle) for parity with web/desktop

3 participants

@amanthanvi@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(mobile): plan mode (legacy) toggle with cross-client sync - #6614

Closed
amanthanvi wants to merge 29 commits into
pingdotgg:mainfrom
amanthanvi:t3code/feat-6401
Closed

feat(mobile): plan mode (legacy) toggle with cross-client sync#6614
amanthanvi wants to merge 29 commits into
pingdotgg:mainfrom
amanthanvi:t3code/feat-6401

Conversation

@amanthanvi

@amanthanviamanthanvi commented Aug 14, 2026

Copy link
Copy Markdown

Mobile had no way to see or control Plan Mode: /plan and /default were always-on slash commands with no toggle, no submit-time parsing, and no relationship to the web/desktop "Plan mode (legacy)" setting. This adds the toggle to mobile's Legacy settings section (default off), gates every send path the way web does (composer, new-task composer, queued outbox — including mid-drain preference changes), adds submit-time parsing and new-task slash support, and introduces per-environment synced client preferences (event-sourced server projection with an additive migration, incremental shell-stream updates, LWW with clock-skew clamping) so the toggle follows the user across web, desktop, and mobile, with offline device-local fallback.

Closes#6401

BeforeAfter
Mobile Legacy section with only Legacy Thread ListMobile Legacy section with Plan Mode toggle
Slash menu always showing /planSlash menu with /plan hidden while toggle off

Enabled state and new-task composer: slash menu enabled · new-task slash popover. Verified end-to-end on the iOS simulator (toggle gating both ways, literal /plan send while disabled, plan-mode thread creation).

Implemented by GPT-5.6 Sol (xhigh) via the Codex CLI, orchestrated and reviewed by Claude Fable 5 (Claude Code), with Claude Opus 5 run monitoring.


Note

Medium Risk
Touches interaction mode on every send/outbox path and adds multi-environment LWW reconciliation; mistakes could mis-route turns or briefly block submission until prefs hydrate.

Overview
Adds cross-client Plan Mode (legacy) on mobile: Settings exposes a toggle (default off) wired through synced client preferences with per-field LWW stamps, environment reconciliation, and patches to connected servers via syncedClientPreferences.patch.

A root SyncedClientPreferencesWorker keeps device cache and remote environments in sync; preference reconciliation readiness now gates when plan mode is considered loaded, so sends wait until hydration finishes.

Composer behavior is centralized in legacy-plan-mode helpers: /plan and /default appear only when enabled; standalone submit switches mode instead of sending; outgoing turns and queued work are forced to default when disabled. New-task and thread composers get slash popovers, safer trigger replacement, and shared submit eligibility; the outbox drain re-reads plan mode at delivery time.

Mobile preferences persist sync stamps, merge reconciled patches safely, and fan toggles to all patchable environments with retry and stale-ack handling.

Reviewed by Cursor Bugbot for commit e8f7a72. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add plan mode (legacy) toggle with cross-client preference sync

  • Introduces a client-preferences aggregate with event sourcing: a new client-preferences.patch command, client-preferences.patched event, projector (projector.ts), and DB migration 041 creating projection_synced_client_preferences with per-field LWW semantics
  • Adds WebSocket RPC syncedClientPreferences.patch requiring AuthOrchestrationOperateScope, and extends shell stream with client-preferences-updated items gated by clientPreferencesStreamItem opt-in so legacy clients are unaffected
  • Mobile composer gains /plan and /default slash commands, a command popover, submit-time mode parsing, and submission gating on preference load (legacy-plan-mode.ts, NewTaskDraftScreen.tsx, ThreadComposer.tsx)
  • Web settings coordinate plan mode hydration across environments with adopt/seed logic, pending write tracking, and serialized local persistence (useSettings.ts, synced-plan-mode.ts)
  • Risk: REQUIRED_SNAPSHOT_PROJECTORS now includes syncedClientPreferences, so snapshot readiness checks will wait for the new projector; canonicalizeClientCommandTimestamps clamps client-preferences.patchupdatedAt to server receive time if more than 5 minutes ahead

Macroscope summarized e8f7a72.

CopilotAI lite review requested due to automatic review settings August 14, 2026 14:59
@coderabbitai

coderabbitaiBot commented Aug 14, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: fd862178-6d5e-4cc2-8512-79c939d2d484

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

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Aug 14, 2026
Comment threadapps/web/src/hooks/useSettings.ts
Comment threadpackages/contracts/src/syncedClientPreferences.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/use-thread-outbox-drain.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences.ts Outdated

CopilotAI 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.

Pull request overview

Adds a cross-client “Plan Mode (Legacy)” preference that syncs per-environment via the server’s event log, and wires mobile’s UI + send paths to gate /plan / /default and interaction mode the same way web/desktop do.

Changes:

  • Introduces a new synced client preferences contract + WS RPCs (syncedClientPreferences.get/patch) and threads it through orchestration shell snapshots/stream items.
  • Implements a server-side client-preferences aggregate with LWW stamping (incl. future-skew clamping), SQLite projection, migration, and incremental shell-stream updates.
  • Adds mobile Plan Mode (Legacy) toggle + plan-mode helpers, submit-time parsing, outbox drain gating, and a background reconciler that converges preferences across connected environments with offline cache fallback.

Reviewed changes

Copilot reviewed 54 out of 54 changed files in this pull request and generated 2 comments.

Show a summary per file
FileDescription
packages/contracts/src/syncedClientPreferences.tsNew schema/types for synced client preferences + patch/request payloads.
packages/contracts/src/settings.test.tsAdds contract tests validating synced preference schema behavior.
packages/contracts/src/rpc.tsAdds WS method names + RPC definitions for get/patch synced preferences.
packages/contracts/src/orchestration.tsExtends read/shell models + shell stream union for synced preferences and adds command/event wiring.
packages/contracts/src/orchestration.test.tsEnsures generic command parsing rejects unknown-only patches; verifies legacy shell decoding tolerance.
packages/contracts/src/index.tsRe-exports synced client preferences module.
packages/client-runtime/src/state/shellReducer.tsApplies client-preferences-updated shell stream items into shell snapshots.
packages/client-runtime/src/state/shellReducer.test.tsTests reducer handling of synced preference updates.
packages/client-runtime/src/state/server.tsAdds environment RPC command for patching synced client preferences.
docs/user/plan-mode.mdNew user doc for enabling Plan Mode (Legacy) and sync behavior.
apps/web/src/hooks/useSettings.tsMerges server/client settings with synced prefs override; adds hydration/seed/write logic.
apps/web/src/hooks/useSettings.test.tsAdds extensive tests for synced plan-mode hydration controller + atom slicing behavior.
apps/server/src/ws.tsStreams incremental client-preferences-updated items; adds RPC handlers for get/patch.
apps/server/src/serverRuntimeStartup.test.tsUpdates test seams for new snapshot query method.
apps/server/src/server.test.tsAdds regression test ensuring preference patch streams incrementally (no full shell reload).
apps/server/src/provider/Layers/ProviderSessionReaper.test.tsUpdates test seam to include new snapshot query method.
apps/server/src/project/ProjectSetupScriptRunner.test.tsUpdates test seam to include new snapshot query method.
apps/server/src/persistence/Services/OrchestrationCommandReceipts.tsExtends receipt schema aggregate-id union to include client-preferences singleton.
apps/server/src/persistence/Migrations/041_ProjectionSyncedClientPreferences.tsNew migration creating synced preference projection table + projector cursor seeding.
apps/server/src/persistence/Migrations/041_ProjectionSyncedClientPreferences.test.tsTests migration behavior and idempotence.
apps/server/src/persistence/Migrations.tsRegisters migration 041.
apps/server/src/persistence/Layers/OrchestrationEventStore.tsExtends persisted event schemas to include client-preferences stream/aggregate IDs.
apps/server/src/orchestration/Services/ProjectionSnapshotQuery.tsAdds getSyncedClientPreferences to snapshot query interface.
apps/server/src/orchestration/projector.tsProjects client-preferences.patched events into the in-memory read model with LWW logic.
apps/server/src/orchestration/Normalizer.tsClamps excessively future-skewed preference stamps to server receive time.
apps/server/src/orchestration/Normalizer.test.tsTests preference-stamp skew clamping behavior.
apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.tsReads synced preference singleton projection into snapshots; includes in updatedAt computation.
apps/server/src/orchestration/Layers/ProjectionPipeline.tsAdds projector to upsert synced preferences into SQLite projection with LWW guard.
apps/server/src/orchestration/Layers/ProjectionPipeline.test.tsTests deterministic rebuild and idempotence for synced preferences projection.
apps/server/src/orchestration/Layers/OrchestrationEngine.tsRoutes client-preferences.patch commands to the client-preferences aggregate ref.
apps/server/src/orchestration/Layers/OrchestrationEngine.test.tsVerifies receipts + LWW behavior for preference patches and shell projection results.
apps/server/src/orchestration/decider.tsEmits client-preferences.patched events for patch commands.
apps/server/src/checkpointing/CheckpointDiffQuery.test.tsUpdates test seams to ensure diff query doesn’t request new snapshot query method.
apps/server/src/auth/RpcAuthorization.tsRequires read/operate scopes for synced preference get/patch RPCs.
apps/mobile/src/state/use-thread-outbox-drain.tsForces default interaction mode when plan mode disabled; re-reads preference at drain-time.
apps/mobile/src/state/use-thread-composer-state.tsGates interaction mode derived from draft/thread via plan-mode helper.
apps/mobile/src/state/thread-outbox.test.tsAdds tests for drain-time gating and queued settings behavior vs preference changes.
apps/mobile/src/state/thread-outbox-model.tsAdds plan-mode-aware queued settings resolution + send decision helper.
apps/mobile/src/state/synced-client-preferences.tsAdds background worker to reconcile device cache with connected environments + update hook.
apps/mobile/src/state/synced-client-preferences.test.tsAdds tests for reconciliation, fan-out, stamping, and pending settlement behavior.
apps/mobile/src/state/synced-client-preferences-model.tsImplements LWW reconciliation + stamp generation + fan-out helpers for mobile.
apps/mobile/src/Stack.tsxMounts the synced client preferences worker alongside outbox drain worker.
apps/mobile/src/persistence/mobile-preferences.tsTreats planModeEnabled as synced/offline-cache; validates canonical updatedAt stamp.
apps/mobile/src/lib/storage.test.tsAdds coverage for loading legacy prefs and dropping non-canonical synced stamps.
apps/mobile/src/features/threads/use-plan-mode-enabled.tsAdds hook to read plan mode preference + loaded state from mobile preferences atom.
apps/mobile/src/features/threads/ThreadComposer.tsxAdds plan-mode gating of slash commands, submit-time parsing, and safer trigger replacement.
apps/mobile/src/features/threads/plan-mode.tsNew shared helper logic for gating, submit parsing, and trigger replacement.
apps/mobile/src/features/threads/plan-mode.test.tsTests plan-mode gating, submit parsing, and trigger replacement semantics.
apps/mobile/src/features/threads/NewTaskDraftScreen.tsxAdds new-task slash popover + submit-time parsing + eligibility refactor and locking.
apps/mobile/src/features/threads/new-task-submit.tsNew helpers for submission eligibility, selection resetting, and command interpretation gating.
apps/mobile/src/features/threads/new-task-submit.test.tsTests new-task submit eligibility + selection reset behavior.
apps/mobile/src/features/threads/new-task-flow-provider.tsxSwitches to synced plan mode preference state and applies plan-mode interaction gating.
apps/mobile/src/features/settings/SettingsRouteScreen.tsxAdds “Plan Mode (Legacy)” toggle to mobile Legacy section and wires to synced update hook.
apps/mobile/src/components/AppSymbol.tsxAdds Android mapping for hammer icon used by the new setting row.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment threaddocs/user/plan-mode.md Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
@macroscopeapp

macroscopeappBot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Skipped

Macroscope did not run approvability analysis for this PR. Diff is too large for automated approval analysis, so this PR cannot be approved automatically.

You can add or adjust custom eligibility rules. Learn more.

Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/use-thread-outbox-drain.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences.ts
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts
Comment threadapps/mobile/src/state/synced-client-preferences.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
Comment threadapps/web/src/hooks/synced-plan-mode.ts
Aman Thanvi added 6 commits August 15, 2026 10:40
Adds a Plan Mode (Legacy) toggle to mobile Settings (default off) that
gates the /plan and /default slash commands and forces outgoing turns to
default mode when off, mirroring web semantics across every send path
(composer, new task, queued outbox). Adds submit-time parsing and slash
support on the new-task composer. Introduces per-environment synced
client preferences (contracts schema, event-sourced server projection
with additive migration, incremental shell stream item) consumed by web
and mobile with LWW reconciliation, clock-skew clamping, and offline
device-local fallback.
Closespingdotgg#6401
- Preserve offline web plan-mode writes
- Reject impossible preference timestamps
- Retry failed web preference patches
- Order rapid web toggles monotonically
- Re-read plan mode before queued mobile delivery
- Route environment-scoped preference writes correctly
- Ignore stale mobile preference acknowledgements
- Document the mobile Legacy settings location
- Use Hermes-compatible reconciliation sorting
- Bound mobile synced-preference stamps to the canonical future-skew window.
- Gate thread-composer enqueue mode selection on preference hydration.
- Preserve newer local Plan Mode intent in read-only mobile and web sessions.
- Add Plan Mode to the user-docs index.
Comment threadapps/mobile/src/features/threads/ThreadComposer.tsx
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated

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

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 5a02ceb. Configure here.

Comment threadapps/mobile/src/state/preferences.ts
@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

Closing this PR after an automated pass over open pull requests. Mobile already supports Plan Mode. The proposal adds an unnecessary cross-client preference rewrite.

@t3dotggt3dotgg closed this Aug 23, 2026
@amanthanvi
amanthanvi deleted the t3code/feat-6401 branch August 26, 2026 23:09
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Mobile: add the Legacy features menu (Plan mode toggle) for parity with web/desktop

3 participants

@amanthanvi@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat(mobile): plan mode (legacy) toggle with cross-client sync - #6614

Closed
amanthanvi wants to merge 29 commits into
pingdotgg:mainfrom
amanthanvi:t3code/feat-6401
Closed

feat(mobile): plan mode (legacy) toggle with cross-client sync#6614
amanthanvi wants to merge 29 commits into
pingdotgg:mainfrom
amanthanvi:t3code/feat-6401

Conversation

@amanthanvi

@amanthanviamanthanvi commented Aug 14, 2026

Copy link
Copy Markdown

Mobile had no way to see or control Plan Mode: /plan and /default were always-on slash commands with no toggle, no submit-time parsing, and no relationship to the web/desktop "Plan mode (legacy)" setting. This adds the toggle to mobile's Legacy settings section (default off), gates every send path the way web does (composer, new-task composer, queued outbox — including mid-drain preference changes), adds submit-time parsing and new-task slash support, and introduces per-environment synced client preferences (event-sourced server projection with an additive migration, incremental shell-stream updates, LWW with clock-skew clamping) so the toggle follows the user across web, desktop, and mobile, with offline device-local fallback.

Closes#6401

BeforeAfter
Mobile Legacy section with only Legacy Thread ListMobile Legacy section with Plan Mode toggle
Slash menu always showing /planSlash menu with /plan hidden while toggle off

Enabled state and new-task composer: slash menu enabled · new-task slash popover. Verified end-to-end on the iOS simulator (toggle gating both ways, literal /plan send while disabled, plan-mode thread creation).

Implemented by GPT-5.6 Sol (xhigh) via the Codex CLI, orchestrated and reviewed by Claude Fable 5 (Claude Code), with Claude Opus 5 run monitoring.


Note

Medium Risk
Touches interaction mode on every send/outbox path and adds multi-environment LWW reconciliation; mistakes could mis-route turns or briefly block submission until prefs hydrate.

Overview
Adds cross-client Plan Mode (legacy) on mobile: Settings exposes a toggle (default off) wired through synced client preferences with per-field LWW stamps, environment reconciliation, and patches to connected servers via syncedClientPreferences.patch.

A root SyncedClientPreferencesWorker keeps device cache and remote environments in sync; preference reconciliation readiness now gates when plan mode is considered loaded, so sends wait until hydration finishes.

Composer behavior is centralized in legacy-plan-mode helpers: /plan and /default appear only when enabled; standalone submit switches mode instead of sending; outgoing turns and queued work are forced to default when disabled. New-task and thread composers get slash popovers, safer trigger replacement, and shared submit eligibility; the outbox drain re-reads plan mode at delivery time.

Mobile preferences persist sync stamps, merge reconciled patches safely, and fan toggles to all patchable environments with retry and stale-ack handling.

Reviewed by Cursor Bugbot for commit e8f7a72. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add plan mode (legacy) toggle with cross-client preference sync

  • Introduces a client-preferences aggregate with event sourcing: a new client-preferences.patch command, client-preferences.patched event, projector (projector.ts), and DB migration 041 creating projection_synced_client_preferences with per-field LWW semantics
  • Adds WebSocket RPC syncedClientPreferences.patch requiring AuthOrchestrationOperateScope, and extends shell stream with client-preferences-updated items gated by clientPreferencesStreamItem opt-in so legacy clients are unaffected
  • Mobile composer gains /plan and /default slash commands, a command popover, submit-time mode parsing, and submission gating on preference load (legacy-plan-mode.ts, NewTaskDraftScreen.tsx, ThreadComposer.tsx)
  • Web settings coordinate plan mode hydration across environments with adopt/seed logic, pending write tracking, and serialized local persistence (useSettings.ts, synced-plan-mode.ts)
  • Risk: REQUIRED_SNAPSHOT_PROJECTORS now includes syncedClientPreferences, so snapshot readiness checks will wait for the new projector; canonicalizeClientCommandTimestamps clamps client-preferences.patchupdatedAt to server receive time if more than 5 minutes ahead

Macroscope summarized e8f7a72.

CopilotAI lite review requested due to automatic review settings August 14, 2026 14:59
@coderabbitai

coderabbitaiBot commented Aug 14, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: fd862178-6d5e-4cc2-8512-79c939d2d484

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

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Aug 14, 2026
Comment threadapps/web/src/hooks/useSettings.ts
Comment threadpackages/contracts/src/syncedClientPreferences.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/use-thread-outbox-drain.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences.ts Outdated

CopilotAI 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.

Pull request overview

Adds a cross-client “Plan Mode (Legacy)” preference that syncs per-environment via the server’s event log, and wires mobile’s UI + send paths to gate /plan / /default and interaction mode the same way web/desktop do.

Changes:

  • Introduces a new synced client preferences contract + WS RPCs (syncedClientPreferences.get/patch) and threads it through orchestration shell snapshots/stream items.
  • Implements a server-side client-preferences aggregate with LWW stamping (incl. future-skew clamping), SQLite projection, migration, and incremental shell-stream updates.
  • Adds mobile Plan Mode (Legacy) toggle + plan-mode helpers, submit-time parsing, outbox drain gating, and a background reconciler that converges preferences across connected environments with offline cache fallback.

Reviewed changes

Copilot reviewed 54 out of 54 changed files in this pull request and generated 2 comments.

Show a summary per file
FileDescription
packages/contracts/src/syncedClientPreferences.tsNew schema/types for synced client preferences + patch/request payloads.
packages/contracts/src/settings.test.tsAdds contract tests validating synced preference schema behavior.
packages/contracts/src/rpc.tsAdds WS method names + RPC definitions for get/patch synced preferences.
packages/contracts/src/orchestration.tsExtends read/shell models + shell stream union for synced preferences and adds command/event wiring.
packages/contracts/src/orchestration.test.tsEnsures generic command parsing rejects unknown-only patches; verifies legacy shell decoding tolerance.
packages/contracts/src/index.tsRe-exports synced client preferences module.
packages/client-runtime/src/state/shellReducer.tsApplies client-preferences-updated shell stream items into shell snapshots.
packages/client-runtime/src/state/shellReducer.test.tsTests reducer handling of synced preference updates.
packages/client-runtime/src/state/server.tsAdds environment RPC command for patching synced client preferences.
docs/user/plan-mode.mdNew user doc for enabling Plan Mode (Legacy) and sync behavior.
apps/web/src/hooks/useSettings.tsMerges server/client settings with synced prefs override; adds hydration/seed/write logic.
apps/web/src/hooks/useSettings.test.tsAdds extensive tests for synced plan-mode hydration controller + atom slicing behavior.
apps/server/src/ws.tsStreams incremental client-preferences-updated items; adds RPC handlers for get/patch.
apps/server/src/serverRuntimeStartup.test.tsUpdates test seams for new snapshot query method.
apps/server/src/server.test.tsAdds regression test ensuring preference patch streams incrementally (no full shell reload).
apps/server/src/provider/Layers/ProviderSessionReaper.test.tsUpdates test seam to include new snapshot query method.
apps/server/src/project/ProjectSetupScriptRunner.test.tsUpdates test seam to include new snapshot query method.
apps/server/src/persistence/Services/OrchestrationCommandReceipts.tsExtends receipt schema aggregate-id union to include client-preferences singleton.
apps/server/src/persistence/Migrations/041_ProjectionSyncedClientPreferences.tsNew migration creating synced preference projection table + projector cursor seeding.
apps/server/src/persistence/Migrations/041_ProjectionSyncedClientPreferences.test.tsTests migration behavior and idempotence.
apps/server/src/persistence/Migrations.tsRegisters migration 041.
apps/server/src/persistence/Layers/OrchestrationEventStore.tsExtends persisted event schemas to include client-preferences stream/aggregate IDs.
apps/server/src/orchestration/Services/ProjectionSnapshotQuery.tsAdds getSyncedClientPreferences to snapshot query interface.
apps/server/src/orchestration/projector.tsProjects client-preferences.patched events into the in-memory read model with LWW logic.
apps/server/src/orchestration/Normalizer.tsClamps excessively future-skewed preference stamps to server receive time.
apps/server/src/orchestration/Normalizer.test.tsTests preference-stamp skew clamping behavior.
apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.tsReads synced preference singleton projection into snapshots; includes in updatedAt computation.
apps/server/src/orchestration/Layers/ProjectionPipeline.tsAdds projector to upsert synced preferences into SQLite projection with LWW guard.
apps/server/src/orchestration/Layers/ProjectionPipeline.test.tsTests deterministic rebuild and idempotence for synced preferences projection.
apps/server/src/orchestration/Layers/OrchestrationEngine.tsRoutes client-preferences.patch commands to the client-preferences aggregate ref.
apps/server/src/orchestration/Layers/OrchestrationEngine.test.tsVerifies receipts + LWW behavior for preference patches and shell projection results.
apps/server/src/orchestration/decider.tsEmits client-preferences.patched events for patch commands.
apps/server/src/checkpointing/CheckpointDiffQuery.test.tsUpdates test seams to ensure diff query doesn’t request new snapshot query method.
apps/server/src/auth/RpcAuthorization.tsRequires read/operate scopes for synced preference get/patch RPCs.
apps/mobile/src/state/use-thread-outbox-drain.tsForces default interaction mode when plan mode disabled; re-reads preference at drain-time.
apps/mobile/src/state/use-thread-composer-state.tsGates interaction mode derived from draft/thread via plan-mode helper.
apps/mobile/src/state/thread-outbox.test.tsAdds tests for drain-time gating and queued settings behavior vs preference changes.
apps/mobile/src/state/thread-outbox-model.tsAdds plan-mode-aware queued settings resolution + send decision helper.
apps/mobile/src/state/synced-client-preferences.tsAdds background worker to reconcile device cache with connected environments + update hook.
apps/mobile/src/state/synced-client-preferences.test.tsAdds tests for reconciliation, fan-out, stamping, and pending settlement behavior.
apps/mobile/src/state/synced-client-preferences-model.tsImplements LWW reconciliation + stamp generation + fan-out helpers for mobile.
apps/mobile/src/Stack.tsxMounts the synced client preferences worker alongside outbox drain worker.
apps/mobile/src/persistence/mobile-preferences.tsTreats planModeEnabled as synced/offline-cache; validates canonical updatedAt stamp.
apps/mobile/src/lib/storage.test.tsAdds coverage for loading legacy prefs and dropping non-canonical synced stamps.
apps/mobile/src/features/threads/use-plan-mode-enabled.tsAdds hook to read plan mode preference + loaded state from mobile preferences atom.
apps/mobile/src/features/threads/ThreadComposer.tsxAdds plan-mode gating of slash commands, submit-time parsing, and safer trigger replacement.
apps/mobile/src/features/threads/plan-mode.tsNew shared helper logic for gating, submit parsing, and trigger replacement.
apps/mobile/src/features/threads/plan-mode.test.tsTests plan-mode gating, submit parsing, and trigger replacement semantics.
apps/mobile/src/features/threads/NewTaskDraftScreen.tsxAdds new-task slash popover + submit-time parsing + eligibility refactor and locking.
apps/mobile/src/features/threads/new-task-submit.tsNew helpers for submission eligibility, selection resetting, and command interpretation gating.
apps/mobile/src/features/threads/new-task-submit.test.tsTests new-task submit eligibility + selection reset behavior.
apps/mobile/src/features/threads/new-task-flow-provider.tsxSwitches to synced plan mode preference state and applies plan-mode interaction gating.
apps/mobile/src/features/settings/SettingsRouteScreen.tsxAdds “Plan Mode (Legacy)” toggle to mobile Legacy section and wires to synced update hook.
apps/mobile/src/components/AppSymbol.tsxAdds Android mapping for hammer icon used by the new setting row.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment threaddocs/user/plan-mode.md Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
@macroscopeapp

macroscopeappBot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Skipped

Macroscope did not run approvability analysis for this PR. Diff is too large for automated approval analysis, so this PR cannot be approved automatically.

You can add or adjust custom eligibility rules. Learn more.

Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/use-thread-outbox-drain.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences.ts
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts
Comment threadapps/mobile/src/state/synced-client-preferences.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
Comment threadapps/web/src/hooks/synced-plan-mode.ts
Aman Thanvi added 6 commits August 15, 2026 10:40
Adds a Plan Mode (Legacy) toggle to mobile Settings (default off) that
gates the /plan and /default slash commands and forces outgoing turns to
default mode when off, mirroring web semantics across every send path
(composer, new task, queued outbox). Adds submit-time parsing and slash
support on the new-task composer. Introduces per-environment synced
client preferences (contracts schema, event-sourced server projection
with additive migration, incremental shell stream item) consumed by web
and mobile with LWW reconciliation, clock-skew clamping, and offline
device-local fallback.
Closespingdotgg#6401
- Preserve offline web plan-mode writes
- Reject impossible preference timestamps
- Retry failed web preference patches
- Order rapid web toggles monotonically
- Re-read plan mode before queued mobile delivery
- Route environment-scoped preference writes correctly
- Ignore stale mobile preference acknowledgements
- Document the mobile Legacy settings location
- Use Hermes-compatible reconciliation sorting
- Bound mobile synced-preference stamps to the canonical future-skew window.
- Gate thread-composer enqueue mode selection on preference hydration.
- Preserve newer local Plan Mode intent in read-only mobile and web sessions.
- Add Plan Mode to the user-docs index.
Comment threadapps/mobile/src/features/threads/ThreadComposer.tsx
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated

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

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 5a02ceb. Configure here.

Comment threadapps/mobile/src/state/preferences.ts
@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

Closing this PR after an automated pass over open pull requests. Mobile already supports Plan Mode. The proposal adds an unnecessary cross-client preference rewrite.

@t3dotggt3dotgg closed this Aug 23, 2026
@amanthanvi
amanthanvi deleted the t3code/feat-6401 branch August 26, 2026 23:09
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Mobile: add the Legacy features menu (Plan mode toggle) for parity with web/desktop

3 participants

@amanthanvi@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(mobile): plan mode (legacy) toggle with cross-client sync - #6614

Closed
amanthanvi wants to merge 29 commits into
pingdotgg:mainfrom
amanthanvi:t3code/feat-6401
Closed

feat(mobile): plan mode (legacy) toggle with cross-client sync#6614
amanthanvi wants to merge 29 commits into
pingdotgg:mainfrom
amanthanvi:t3code/feat-6401

Conversation

@amanthanvi

@amanthanviamanthanvi commented Aug 14, 2026

Copy link
Copy Markdown

Mobile had no way to see or control Plan Mode: /plan and /default were always-on slash commands with no toggle, no submit-time parsing, and no relationship to the web/desktop "Plan mode (legacy)" setting. This adds the toggle to mobile's Legacy settings section (default off), gates every send path the way web does (composer, new-task composer, queued outbox — including mid-drain preference changes), adds submit-time parsing and new-task slash support, and introduces per-environment synced client preferences (event-sourced server projection with an additive migration, incremental shell-stream updates, LWW with clock-skew clamping) so the toggle follows the user across web, desktop, and mobile, with offline device-local fallback.

Closes#6401

BeforeAfter
Mobile Legacy section with only Legacy Thread ListMobile Legacy section with Plan Mode toggle
Slash menu always showing /planSlash menu with /plan hidden while toggle off

Enabled state and new-task composer: slash menu enabled · new-task slash popover. Verified end-to-end on the iOS simulator (toggle gating both ways, literal /plan send while disabled, plan-mode thread creation).

Implemented by GPT-5.6 Sol (xhigh) via the Codex CLI, orchestrated and reviewed by Claude Fable 5 (Claude Code), with Claude Opus 5 run monitoring.


Note

Medium Risk
Touches interaction mode on every send/outbox path and adds multi-environment LWW reconciliation; mistakes could mis-route turns or briefly block submission until prefs hydrate.

Overview
Adds cross-client Plan Mode (legacy) on mobile: Settings exposes a toggle (default off) wired through synced client preferences with per-field LWW stamps, environment reconciliation, and patches to connected servers via syncedClientPreferences.patch.

A root SyncedClientPreferencesWorker keeps device cache and remote environments in sync; preference reconciliation readiness now gates when plan mode is considered loaded, so sends wait until hydration finishes.

Composer behavior is centralized in legacy-plan-mode helpers: /plan and /default appear only when enabled; standalone submit switches mode instead of sending; outgoing turns and queued work are forced to default when disabled. New-task and thread composers get slash popovers, safer trigger replacement, and shared submit eligibility; the outbox drain re-reads plan mode at delivery time.

Mobile preferences persist sync stamps, merge reconciled patches safely, and fan toggles to all patchable environments with retry and stale-ack handling.

Reviewed by Cursor Bugbot for commit e8f7a72. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add plan mode (legacy) toggle with cross-client preference sync

  • Introduces a client-preferences aggregate with event sourcing: a new client-preferences.patch command, client-preferences.patched event, projector (projector.ts), and DB migration 041 creating projection_synced_client_preferences with per-field LWW semantics
  • Adds WebSocket RPC syncedClientPreferences.patch requiring AuthOrchestrationOperateScope, and extends shell stream with client-preferences-updated items gated by clientPreferencesStreamItem opt-in so legacy clients are unaffected
  • Mobile composer gains /plan and /default slash commands, a command popover, submit-time mode parsing, and submission gating on preference load (legacy-plan-mode.ts, NewTaskDraftScreen.tsx, ThreadComposer.tsx)
  • Web settings coordinate plan mode hydration across environments with adopt/seed logic, pending write tracking, and serialized local persistence (useSettings.ts, synced-plan-mode.ts)
  • Risk: REQUIRED_SNAPSHOT_PROJECTORS now includes syncedClientPreferences, so snapshot readiness checks will wait for the new projector; canonicalizeClientCommandTimestamps clamps client-preferences.patchupdatedAt to server receive time if more than 5 minutes ahead

Macroscope summarized e8f7a72.

CopilotAI lite review requested due to automatic review settings August 14, 2026 14:59
@coderabbitai

coderabbitaiBot commented Aug 14, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: fd862178-6d5e-4cc2-8512-79c939d2d484

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

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Aug 14, 2026
Comment threadapps/web/src/hooks/useSettings.ts
Comment threadpackages/contracts/src/syncedClientPreferences.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/use-thread-outbox-drain.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences.ts Outdated

CopilotAI 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.

Pull request overview

Adds a cross-client “Plan Mode (Legacy)” preference that syncs per-environment via the server’s event log, and wires mobile’s UI + send paths to gate /plan / /default and interaction mode the same way web/desktop do.

Changes:

  • Introduces a new synced client preferences contract + WS RPCs (syncedClientPreferences.get/patch) and threads it through orchestration shell snapshots/stream items.
  • Implements a server-side client-preferences aggregate with LWW stamping (incl. future-skew clamping), SQLite projection, migration, and incremental shell-stream updates.
  • Adds mobile Plan Mode (Legacy) toggle + plan-mode helpers, submit-time parsing, outbox drain gating, and a background reconciler that converges preferences across connected environments with offline cache fallback.

Reviewed changes

Copilot reviewed 54 out of 54 changed files in this pull request and generated 2 comments.

Show a summary per file
FileDescription
packages/contracts/src/syncedClientPreferences.tsNew schema/types for synced client preferences + patch/request payloads.
packages/contracts/src/settings.test.tsAdds contract tests validating synced preference schema behavior.
packages/contracts/src/rpc.tsAdds WS method names + RPC definitions for get/patch synced preferences.
packages/contracts/src/orchestration.tsExtends read/shell models + shell stream union for synced preferences and adds command/event wiring.
packages/contracts/src/orchestration.test.tsEnsures generic command parsing rejects unknown-only patches; verifies legacy shell decoding tolerance.
packages/contracts/src/index.tsRe-exports synced client preferences module.
packages/client-runtime/src/state/shellReducer.tsApplies client-preferences-updated shell stream items into shell snapshots.
packages/client-runtime/src/state/shellReducer.test.tsTests reducer handling of synced preference updates.
packages/client-runtime/src/state/server.tsAdds environment RPC command for patching synced client preferences.
docs/user/plan-mode.mdNew user doc for enabling Plan Mode (Legacy) and sync behavior.
apps/web/src/hooks/useSettings.tsMerges server/client settings with synced prefs override; adds hydration/seed/write logic.
apps/web/src/hooks/useSettings.test.tsAdds extensive tests for synced plan-mode hydration controller + atom slicing behavior.
apps/server/src/ws.tsStreams incremental client-preferences-updated items; adds RPC handlers for get/patch.
apps/server/src/serverRuntimeStartup.test.tsUpdates test seams for new snapshot query method.
apps/server/src/server.test.tsAdds regression test ensuring preference patch streams incrementally (no full shell reload).
apps/server/src/provider/Layers/ProviderSessionReaper.test.tsUpdates test seam to include new snapshot query method.
apps/server/src/project/ProjectSetupScriptRunner.test.tsUpdates test seam to include new snapshot query method.
apps/server/src/persistence/Services/OrchestrationCommandReceipts.tsExtends receipt schema aggregate-id union to include client-preferences singleton.
apps/server/src/persistence/Migrations/041_ProjectionSyncedClientPreferences.tsNew migration creating synced preference projection table + projector cursor seeding.
apps/server/src/persistence/Migrations/041_ProjectionSyncedClientPreferences.test.tsTests migration behavior and idempotence.
apps/server/src/persistence/Migrations.tsRegisters migration 041.
apps/server/src/persistence/Layers/OrchestrationEventStore.tsExtends persisted event schemas to include client-preferences stream/aggregate IDs.
apps/server/src/orchestration/Services/ProjectionSnapshotQuery.tsAdds getSyncedClientPreferences to snapshot query interface.
apps/server/src/orchestration/projector.tsProjects client-preferences.patched events into the in-memory read model with LWW logic.
apps/server/src/orchestration/Normalizer.tsClamps excessively future-skewed preference stamps to server receive time.
apps/server/src/orchestration/Normalizer.test.tsTests preference-stamp skew clamping behavior.
apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.tsReads synced preference singleton projection into snapshots; includes in updatedAt computation.
apps/server/src/orchestration/Layers/ProjectionPipeline.tsAdds projector to upsert synced preferences into SQLite projection with LWW guard.
apps/server/src/orchestration/Layers/ProjectionPipeline.test.tsTests deterministic rebuild and idempotence for synced preferences projection.
apps/server/src/orchestration/Layers/OrchestrationEngine.tsRoutes client-preferences.patch commands to the client-preferences aggregate ref.
apps/server/src/orchestration/Layers/OrchestrationEngine.test.tsVerifies receipts + LWW behavior for preference patches and shell projection results.
apps/server/src/orchestration/decider.tsEmits client-preferences.patched events for patch commands.
apps/server/src/checkpointing/CheckpointDiffQuery.test.tsUpdates test seams to ensure diff query doesn’t request new snapshot query method.
apps/server/src/auth/RpcAuthorization.tsRequires read/operate scopes for synced preference get/patch RPCs.
apps/mobile/src/state/use-thread-outbox-drain.tsForces default interaction mode when plan mode disabled; re-reads preference at drain-time.
apps/mobile/src/state/use-thread-composer-state.tsGates interaction mode derived from draft/thread via plan-mode helper.
apps/mobile/src/state/thread-outbox.test.tsAdds tests for drain-time gating and queued settings behavior vs preference changes.
apps/mobile/src/state/thread-outbox-model.tsAdds plan-mode-aware queued settings resolution + send decision helper.
apps/mobile/src/state/synced-client-preferences.tsAdds background worker to reconcile device cache with connected environments + update hook.
apps/mobile/src/state/synced-client-preferences.test.tsAdds tests for reconciliation, fan-out, stamping, and pending settlement behavior.
apps/mobile/src/state/synced-client-preferences-model.tsImplements LWW reconciliation + stamp generation + fan-out helpers for mobile.
apps/mobile/src/Stack.tsxMounts the synced client preferences worker alongside outbox drain worker.
apps/mobile/src/persistence/mobile-preferences.tsTreats planModeEnabled as synced/offline-cache; validates canonical updatedAt stamp.
apps/mobile/src/lib/storage.test.tsAdds coverage for loading legacy prefs and dropping non-canonical synced stamps.
apps/mobile/src/features/threads/use-plan-mode-enabled.tsAdds hook to read plan mode preference + loaded state from mobile preferences atom.
apps/mobile/src/features/threads/ThreadComposer.tsxAdds plan-mode gating of slash commands, submit-time parsing, and safer trigger replacement.
apps/mobile/src/features/threads/plan-mode.tsNew shared helper logic for gating, submit parsing, and trigger replacement.
apps/mobile/src/features/threads/plan-mode.test.tsTests plan-mode gating, submit parsing, and trigger replacement semantics.
apps/mobile/src/features/threads/NewTaskDraftScreen.tsxAdds new-task slash popover + submit-time parsing + eligibility refactor and locking.
apps/mobile/src/features/threads/new-task-submit.tsNew helpers for submission eligibility, selection resetting, and command interpretation gating.
apps/mobile/src/features/threads/new-task-submit.test.tsTests new-task submit eligibility + selection reset behavior.
apps/mobile/src/features/threads/new-task-flow-provider.tsxSwitches to synced plan mode preference state and applies plan-mode interaction gating.
apps/mobile/src/features/settings/SettingsRouteScreen.tsxAdds “Plan Mode (Legacy)” toggle to mobile Legacy section and wires to synced update hook.
apps/mobile/src/components/AppSymbol.tsxAdds Android mapping for hammer icon used by the new setting row.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment threaddocs/user/plan-mode.md Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
@macroscopeapp

macroscopeappBot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Skipped

Macroscope did not run approvability analysis for this PR. Diff is too large for automated approval analysis, so this PR cannot be approved automatically.

You can add or adjust custom eligibility rules. Learn more.

Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/use-thread-outbox-drain.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences.ts
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts
Comment threadapps/mobile/src/state/synced-client-preferences.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
Comment threadapps/web/src/hooks/synced-plan-mode.ts
Aman Thanvi added 6 commits August 15, 2026 10:40
Adds a Plan Mode (Legacy) toggle to mobile Settings (default off) that
gates the /plan and /default slash commands and forces outgoing turns to
default mode when off, mirroring web semantics across every send path
(composer, new task, queued outbox). Adds submit-time parsing and slash
support on the new-task composer. Introduces per-environment synced
client preferences (contracts schema, event-sourced server projection
with additive migration, incremental shell stream item) consumed by web
and mobile with LWW reconciliation, clock-skew clamping, and offline
device-local fallback.
Closespingdotgg#6401
- Preserve offline web plan-mode writes
- Reject impossible preference timestamps
- Retry failed web preference patches
- Order rapid web toggles monotonically
- Re-read plan mode before queued mobile delivery
- Route environment-scoped preference writes correctly
- Ignore stale mobile preference acknowledgements
- Document the mobile Legacy settings location
- Use Hermes-compatible reconciliation sorting
- Bound mobile synced-preference stamps to the canonical future-skew window.
- Gate thread-composer enqueue mode selection on preference hydration.
- Preserve newer local Plan Mode intent in read-only mobile and web sessions.
- Add Plan Mode to the user-docs index.
Comment threadapps/mobile/src/features/threads/ThreadComposer.tsx
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated

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

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 5a02ceb. Configure here.

Comment threadapps/mobile/src/state/preferences.ts
@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

Closing this PR after an automated pass over open pull requests. Mobile already supports Plan Mode. The proposal adds an unnecessary cross-client preference rewrite.

@t3dotggt3dotgg closed this Aug 23, 2026
@amanthanvi
amanthanvi deleted the t3code/feat-6401 branch August 26, 2026 23:09
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Mobile: add the Legacy features menu (Plan mode toggle) for parity with web/desktop

3 participants

@amanthanvi@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(mobile): plan mode (legacy) toggle with cross-client sync - #6614

Closed
amanthanvi wants to merge 29 commits into
pingdotgg:mainfrom
amanthanvi:t3code/feat-6401
Closed

feat(mobile): plan mode (legacy) toggle with cross-client sync#6614
amanthanvi wants to merge 29 commits into
pingdotgg:mainfrom
amanthanvi:t3code/feat-6401

Conversation

@amanthanvi

@amanthanviamanthanvi commented Aug 14, 2026

Copy link
Copy Markdown

Mobile had no way to see or control Plan Mode: /plan and /default were always-on slash commands with no toggle, no submit-time parsing, and no relationship to the web/desktop "Plan mode (legacy)" setting. This adds the toggle to mobile's Legacy settings section (default off), gates every send path the way web does (composer, new-task composer, queued outbox — including mid-drain preference changes), adds submit-time parsing and new-task slash support, and introduces per-environment synced client preferences (event-sourced server projection with an additive migration, incremental shell-stream updates, LWW with clock-skew clamping) so the toggle follows the user across web, desktop, and mobile, with offline device-local fallback.

Closes#6401

BeforeAfter
Mobile Legacy section with only Legacy Thread ListMobile Legacy section with Plan Mode toggle
Slash menu always showing /planSlash menu with /plan hidden while toggle off

Enabled state and new-task composer: slash menu enabled · new-task slash popover. Verified end-to-end on the iOS simulator (toggle gating both ways, literal /plan send while disabled, plan-mode thread creation).

Implemented by GPT-5.6 Sol (xhigh) via the Codex CLI, orchestrated and reviewed by Claude Fable 5 (Claude Code), with Claude Opus 5 run monitoring.


Note

Medium Risk
Touches interaction mode on every send/outbox path and adds multi-environment LWW reconciliation; mistakes could mis-route turns or briefly block submission until prefs hydrate.

Overview
Adds cross-client Plan Mode (legacy) on mobile: Settings exposes a toggle (default off) wired through synced client preferences with per-field LWW stamps, environment reconciliation, and patches to connected servers via syncedClientPreferences.patch.

A root SyncedClientPreferencesWorker keeps device cache and remote environments in sync; preference reconciliation readiness now gates when plan mode is considered loaded, so sends wait until hydration finishes.

Composer behavior is centralized in legacy-plan-mode helpers: /plan and /default appear only when enabled; standalone submit switches mode instead of sending; outgoing turns and queued work are forced to default when disabled. New-task and thread composers get slash popovers, safer trigger replacement, and shared submit eligibility; the outbox drain re-reads plan mode at delivery time.

Mobile preferences persist sync stamps, merge reconciled patches safely, and fan toggles to all patchable environments with retry and stale-ack handling.

Reviewed by Cursor Bugbot for commit e8f7a72. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add plan mode (legacy) toggle with cross-client preference sync

  • Introduces a client-preferences aggregate with event sourcing: a new client-preferences.patch command, client-preferences.patched event, projector (projector.ts), and DB migration 041 creating projection_synced_client_preferences with per-field LWW semantics
  • Adds WebSocket RPC syncedClientPreferences.patch requiring AuthOrchestrationOperateScope, and extends shell stream with client-preferences-updated items gated by clientPreferencesStreamItem opt-in so legacy clients are unaffected
  • Mobile composer gains /plan and /default slash commands, a command popover, submit-time mode parsing, and submission gating on preference load (legacy-plan-mode.ts, NewTaskDraftScreen.tsx, ThreadComposer.tsx)
  • Web settings coordinate plan mode hydration across environments with adopt/seed logic, pending write tracking, and serialized local persistence (useSettings.ts, synced-plan-mode.ts)
  • Risk: REQUIRED_SNAPSHOT_PROJECTORS now includes syncedClientPreferences, so snapshot readiness checks will wait for the new projector; canonicalizeClientCommandTimestamps clamps client-preferences.patchupdatedAt to server receive time if more than 5 minutes ahead

Macroscope summarized e8f7a72.

CopilotAI lite review requested due to automatic review settings August 14, 2026 14:59
@coderabbitai

coderabbitaiBot commented Aug 14, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: fd862178-6d5e-4cc2-8512-79c939d2d484

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

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Aug 14, 2026
Comment threadapps/web/src/hooks/useSettings.ts
Comment threadpackages/contracts/src/syncedClientPreferences.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/use-thread-outbox-drain.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences.ts Outdated

CopilotAI 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.

Pull request overview

Adds a cross-client “Plan Mode (Legacy)” preference that syncs per-environment via the server’s event log, and wires mobile’s UI + send paths to gate /plan / /default and interaction mode the same way web/desktop do.

Changes:

  • Introduces a new synced client preferences contract + WS RPCs (syncedClientPreferences.get/patch) and threads it through orchestration shell snapshots/stream items.
  • Implements a server-side client-preferences aggregate with LWW stamping (incl. future-skew clamping), SQLite projection, migration, and incremental shell-stream updates.
  • Adds mobile Plan Mode (Legacy) toggle + plan-mode helpers, submit-time parsing, outbox drain gating, and a background reconciler that converges preferences across connected environments with offline cache fallback.

Reviewed changes

Copilot reviewed 54 out of 54 changed files in this pull request and generated 2 comments.

Show a summary per file
FileDescription
packages/contracts/src/syncedClientPreferences.tsNew schema/types for synced client preferences + patch/request payloads.
packages/contracts/src/settings.test.tsAdds contract tests validating synced preference schema behavior.
packages/contracts/src/rpc.tsAdds WS method names + RPC definitions for get/patch synced preferences.
packages/contracts/src/orchestration.tsExtends read/shell models + shell stream union for synced preferences and adds command/event wiring.
packages/contracts/src/orchestration.test.tsEnsures generic command parsing rejects unknown-only patches; verifies legacy shell decoding tolerance.
packages/contracts/src/index.tsRe-exports synced client preferences module.
packages/client-runtime/src/state/shellReducer.tsApplies client-preferences-updated shell stream items into shell snapshots.
packages/client-runtime/src/state/shellReducer.test.tsTests reducer handling of synced preference updates.
packages/client-runtime/src/state/server.tsAdds environment RPC command for patching synced client preferences.
docs/user/plan-mode.mdNew user doc for enabling Plan Mode (Legacy) and sync behavior.
apps/web/src/hooks/useSettings.tsMerges server/client settings with synced prefs override; adds hydration/seed/write logic.
apps/web/src/hooks/useSettings.test.tsAdds extensive tests for synced plan-mode hydration controller + atom slicing behavior.
apps/server/src/ws.tsStreams incremental client-preferences-updated items; adds RPC handlers for get/patch.
apps/server/src/serverRuntimeStartup.test.tsUpdates test seams for new snapshot query method.
apps/server/src/server.test.tsAdds regression test ensuring preference patch streams incrementally (no full shell reload).
apps/server/src/provider/Layers/ProviderSessionReaper.test.tsUpdates test seam to include new snapshot query method.
apps/server/src/project/ProjectSetupScriptRunner.test.tsUpdates test seam to include new snapshot query method.
apps/server/src/persistence/Services/OrchestrationCommandReceipts.tsExtends receipt schema aggregate-id union to include client-preferences singleton.
apps/server/src/persistence/Migrations/041_ProjectionSyncedClientPreferences.tsNew migration creating synced preference projection table + projector cursor seeding.
apps/server/src/persistence/Migrations/041_ProjectionSyncedClientPreferences.test.tsTests migration behavior and idempotence.
apps/server/src/persistence/Migrations.tsRegisters migration 041.
apps/server/src/persistence/Layers/OrchestrationEventStore.tsExtends persisted event schemas to include client-preferences stream/aggregate IDs.
apps/server/src/orchestration/Services/ProjectionSnapshotQuery.tsAdds getSyncedClientPreferences to snapshot query interface.
apps/server/src/orchestration/projector.tsProjects client-preferences.patched events into the in-memory read model with LWW logic.
apps/server/src/orchestration/Normalizer.tsClamps excessively future-skewed preference stamps to server receive time.
apps/server/src/orchestration/Normalizer.test.tsTests preference-stamp skew clamping behavior.
apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.tsReads synced preference singleton projection into snapshots; includes in updatedAt computation.
apps/server/src/orchestration/Layers/ProjectionPipeline.tsAdds projector to upsert synced preferences into SQLite projection with LWW guard.
apps/server/src/orchestration/Layers/ProjectionPipeline.test.tsTests deterministic rebuild and idempotence for synced preferences projection.
apps/server/src/orchestration/Layers/OrchestrationEngine.tsRoutes client-preferences.patch commands to the client-preferences aggregate ref.
apps/server/src/orchestration/Layers/OrchestrationEngine.test.tsVerifies receipts + LWW behavior for preference patches and shell projection results.
apps/server/src/orchestration/decider.tsEmits client-preferences.patched events for patch commands.
apps/server/src/checkpointing/CheckpointDiffQuery.test.tsUpdates test seams to ensure diff query doesn’t request new snapshot query method.
apps/server/src/auth/RpcAuthorization.tsRequires read/operate scopes for synced preference get/patch RPCs.
apps/mobile/src/state/use-thread-outbox-drain.tsForces default interaction mode when plan mode disabled; re-reads preference at drain-time.
apps/mobile/src/state/use-thread-composer-state.tsGates interaction mode derived from draft/thread via plan-mode helper.
apps/mobile/src/state/thread-outbox.test.tsAdds tests for drain-time gating and queued settings behavior vs preference changes.
apps/mobile/src/state/thread-outbox-model.tsAdds plan-mode-aware queued settings resolution + send decision helper.
apps/mobile/src/state/synced-client-preferences.tsAdds background worker to reconcile device cache with connected environments + update hook.
apps/mobile/src/state/synced-client-preferences.test.tsAdds tests for reconciliation, fan-out, stamping, and pending settlement behavior.
apps/mobile/src/state/synced-client-preferences-model.tsImplements LWW reconciliation + stamp generation + fan-out helpers for mobile.
apps/mobile/src/Stack.tsxMounts the synced client preferences worker alongside outbox drain worker.
apps/mobile/src/persistence/mobile-preferences.tsTreats planModeEnabled as synced/offline-cache; validates canonical updatedAt stamp.
apps/mobile/src/lib/storage.test.tsAdds coverage for loading legacy prefs and dropping non-canonical synced stamps.
apps/mobile/src/features/threads/use-plan-mode-enabled.tsAdds hook to read plan mode preference + loaded state from mobile preferences atom.
apps/mobile/src/features/threads/ThreadComposer.tsxAdds plan-mode gating of slash commands, submit-time parsing, and safer trigger replacement.
apps/mobile/src/features/threads/plan-mode.tsNew shared helper logic for gating, submit parsing, and trigger replacement.
apps/mobile/src/features/threads/plan-mode.test.tsTests plan-mode gating, submit parsing, and trigger replacement semantics.
apps/mobile/src/features/threads/NewTaskDraftScreen.tsxAdds new-task slash popover + submit-time parsing + eligibility refactor and locking.
apps/mobile/src/features/threads/new-task-submit.tsNew helpers for submission eligibility, selection resetting, and command interpretation gating.
apps/mobile/src/features/threads/new-task-submit.test.tsTests new-task submit eligibility + selection reset behavior.
apps/mobile/src/features/threads/new-task-flow-provider.tsxSwitches to synced plan mode preference state and applies plan-mode interaction gating.
apps/mobile/src/features/settings/SettingsRouteScreen.tsxAdds “Plan Mode (Legacy)” toggle to mobile Legacy section and wires to synced update hook.
apps/mobile/src/components/AppSymbol.tsxAdds Android mapping for hammer icon used by the new setting row.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment threaddocs/user/plan-mode.md Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
@macroscopeapp

macroscopeappBot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Skipped

Macroscope did not run approvability analysis for this PR. Diff is too large for automated approval analysis, so this PR cannot be approved automatically.

You can add or adjust custom eligibility rules. Learn more.

Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/use-thread-outbox-drain.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences.ts
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts
Comment threadapps/mobile/src/state/synced-client-preferences.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
Comment threadapps/web/src/hooks/synced-plan-mode.ts
Aman Thanvi added 6 commits August 15, 2026 10:40
Adds a Plan Mode (Legacy) toggle to mobile Settings (default off) that
gates the /plan and /default slash commands and forces outgoing turns to
default mode when off, mirroring web semantics across every send path
(composer, new task, queued outbox). Adds submit-time parsing and slash
support on the new-task composer. Introduces per-environment synced
client preferences (contracts schema, event-sourced server projection
with additive migration, incremental shell stream item) consumed by web
and mobile with LWW reconciliation, clock-skew clamping, and offline
device-local fallback.
Closespingdotgg#6401
- Preserve offline web plan-mode writes
- Reject impossible preference timestamps
- Retry failed web preference patches
- Order rapid web toggles monotonically
- Re-read plan mode before queued mobile delivery
- Route environment-scoped preference writes correctly
- Ignore stale mobile preference acknowledgements
- Document the mobile Legacy settings location
- Use Hermes-compatible reconciliation sorting
- Bound mobile synced-preference stamps to the canonical future-skew window.
- Gate thread-composer enqueue mode selection on preference hydration.
- Preserve newer local Plan Mode intent in read-only mobile and web sessions.
- Add Plan Mode to the user-docs index.
Comment threadapps/mobile/src/features/threads/ThreadComposer.tsx
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated

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

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 5a02ceb. Configure here.

Comment threadapps/mobile/src/state/preferences.ts
@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

Closing this PR after an automated pass over open pull requests. Mobile already supports Plan Mode. The proposal adds an unnecessary cross-client preference rewrite.

@t3dotggt3dotgg closed this Aug 23, 2026
@amanthanvi
amanthanvi deleted the t3code/feat-6401 branch August 26, 2026 23:09
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Mobile: add the Legacy features menu (Plan mode toggle) for parity with web/desktop

3 participants

@amanthanvi@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat(mobile): plan mode (legacy) toggle with cross-client sync - #6614

Closed
amanthanvi wants to merge 29 commits into
pingdotgg:mainfrom
amanthanvi:t3code/feat-6401
Closed

feat(mobile): plan mode (legacy) toggle with cross-client sync#6614
amanthanvi wants to merge 29 commits into
pingdotgg:mainfrom
amanthanvi:t3code/feat-6401

Conversation

@amanthanvi

@amanthanviamanthanvi commented Aug 14, 2026

Copy link
Copy Markdown

Mobile had no way to see or control Plan Mode: /plan and /default were always-on slash commands with no toggle, no submit-time parsing, and no relationship to the web/desktop "Plan mode (legacy)" setting. This adds the toggle to mobile's Legacy settings section (default off), gates every send path the way web does (composer, new-task composer, queued outbox — including mid-drain preference changes), adds submit-time parsing and new-task slash support, and introduces per-environment synced client preferences (event-sourced server projection with an additive migration, incremental shell-stream updates, LWW with clock-skew clamping) so the toggle follows the user across web, desktop, and mobile, with offline device-local fallback.

Closes#6401

BeforeAfter
Mobile Legacy section with only Legacy Thread ListMobile Legacy section with Plan Mode toggle
Slash menu always showing /planSlash menu with /plan hidden while toggle off

Enabled state and new-task composer: slash menu enabled · new-task slash popover. Verified end-to-end on the iOS simulator (toggle gating both ways, literal /plan send while disabled, plan-mode thread creation).

Implemented by GPT-5.6 Sol (xhigh) via the Codex CLI, orchestrated and reviewed by Claude Fable 5 (Claude Code), with Claude Opus 5 run monitoring.


Note

Medium Risk
Touches interaction mode on every send/outbox path and adds multi-environment LWW reconciliation; mistakes could mis-route turns or briefly block submission until prefs hydrate.

Overview
Adds cross-client Plan Mode (legacy) on mobile: Settings exposes a toggle (default off) wired through synced client preferences with per-field LWW stamps, environment reconciliation, and patches to connected servers via syncedClientPreferences.patch.

A root SyncedClientPreferencesWorker keeps device cache and remote environments in sync; preference reconciliation readiness now gates when plan mode is considered loaded, so sends wait until hydration finishes.

Composer behavior is centralized in legacy-plan-mode helpers: /plan and /default appear only when enabled; standalone submit switches mode instead of sending; outgoing turns and queued work are forced to default when disabled. New-task and thread composers get slash popovers, safer trigger replacement, and shared submit eligibility; the outbox drain re-reads plan mode at delivery time.

Mobile preferences persist sync stamps, merge reconciled patches safely, and fan toggles to all patchable environments with retry and stale-ack handling.

Reviewed by Cursor Bugbot for commit e8f7a72. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add plan mode (legacy) toggle with cross-client preference sync

  • Introduces a client-preferences aggregate with event sourcing: a new client-preferences.patch command, client-preferences.patched event, projector (projector.ts), and DB migration 041 creating projection_synced_client_preferences with per-field LWW semantics
  • Adds WebSocket RPC syncedClientPreferences.patch requiring AuthOrchestrationOperateScope, and extends shell stream with client-preferences-updated items gated by clientPreferencesStreamItem opt-in so legacy clients are unaffected
  • Mobile composer gains /plan and /default slash commands, a command popover, submit-time mode parsing, and submission gating on preference load (legacy-plan-mode.ts, NewTaskDraftScreen.tsx, ThreadComposer.tsx)
  • Web settings coordinate plan mode hydration across environments with adopt/seed logic, pending write tracking, and serialized local persistence (useSettings.ts, synced-plan-mode.ts)
  • Risk: REQUIRED_SNAPSHOT_PROJECTORS now includes syncedClientPreferences, so snapshot readiness checks will wait for the new projector; canonicalizeClientCommandTimestamps clamps client-preferences.patchupdatedAt to server receive time if more than 5 minutes ahead

Macroscope summarized e8f7a72.

CopilotAI lite review requested due to automatic review settings August 14, 2026 14:59
@coderabbitai

coderabbitaiBot commented Aug 14, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: fd862178-6d5e-4cc2-8512-79c939d2d484

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

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Aug 14, 2026
Comment threadapps/web/src/hooks/useSettings.ts
Comment threadpackages/contracts/src/syncedClientPreferences.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/use-thread-outbox-drain.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences.ts Outdated

CopilotAI 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.

Pull request overview

Adds a cross-client “Plan Mode (Legacy)” preference that syncs per-environment via the server’s event log, and wires mobile’s UI + send paths to gate /plan / /default and interaction mode the same way web/desktop do.

Changes:

  • Introduces a new synced client preferences contract + WS RPCs (syncedClientPreferences.get/patch) and threads it through orchestration shell snapshots/stream items.
  • Implements a server-side client-preferences aggregate with LWW stamping (incl. future-skew clamping), SQLite projection, migration, and incremental shell-stream updates.
  • Adds mobile Plan Mode (Legacy) toggle + plan-mode helpers, submit-time parsing, outbox drain gating, and a background reconciler that converges preferences across connected environments with offline cache fallback.

Reviewed changes

Copilot reviewed 54 out of 54 changed files in this pull request and generated 2 comments.

Show a summary per file
FileDescription
packages/contracts/src/syncedClientPreferences.tsNew schema/types for synced client preferences + patch/request payloads.
packages/contracts/src/settings.test.tsAdds contract tests validating synced preference schema behavior.
packages/contracts/src/rpc.tsAdds WS method names + RPC definitions for get/patch synced preferences.
packages/contracts/src/orchestration.tsExtends read/shell models + shell stream union for synced preferences and adds command/event wiring.
packages/contracts/src/orchestration.test.tsEnsures generic command parsing rejects unknown-only patches; verifies legacy shell decoding tolerance.
packages/contracts/src/index.tsRe-exports synced client preferences module.
packages/client-runtime/src/state/shellReducer.tsApplies client-preferences-updated shell stream items into shell snapshots.
packages/client-runtime/src/state/shellReducer.test.tsTests reducer handling of synced preference updates.
packages/client-runtime/src/state/server.tsAdds environment RPC command for patching synced client preferences.
docs/user/plan-mode.mdNew user doc for enabling Plan Mode (Legacy) and sync behavior.
apps/web/src/hooks/useSettings.tsMerges server/client settings with synced prefs override; adds hydration/seed/write logic.
apps/web/src/hooks/useSettings.test.tsAdds extensive tests for synced plan-mode hydration controller + atom slicing behavior.
apps/server/src/ws.tsStreams incremental client-preferences-updated items; adds RPC handlers for get/patch.
apps/server/src/serverRuntimeStartup.test.tsUpdates test seams for new snapshot query method.
apps/server/src/server.test.tsAdds regression test ensuring preference patch streams incrementally (no full shell reload).
apps/server/src/provider/Layers/ProviderSessionReaper.test.tsUpdates test seam to include new snapshot query method.
apps/server/src/project/ProjectSetupScriptRunner.test.tsUpdates test seam to include new snapshot query method.
apps/server/src/persistence/Services/OrchestrationCommandReceipts.tsExtends receipt schema aggregate-id union to include client-preferences singleton.
apps/server/src/persistence/Migrations/041_ProjectionSyncedClientPreferences.tsNew migration creating synced preference projection table + projector cursor seeding.
apps/server/src/persistence/Migrations/041_ProjectionSyncedClientPreferences.test.tsTests migration behavior and idempotence.
apps/server/src/persistence/Migrations.tsRegisters migration 041.
apps/server/src/persistence/Layers/OrchestrationEventStore.tsExtends persisted event schemas to include client-preferences stream/aggregate IDs.
apps/server/src/orchestration/Services/ProjectionSnapshotQuery.tsAdds getSyncedClientPreferences to snapshot query interface.
apps/server/src/orchestration/projector.tsProjects client-preferences.patched events into the in-memory read model with LWW logic.
apps/server/src/orchestration/Normalizer.tsClamps excessively future-skewed preference stamps to server receive time.
apps/server/src/orchestration/Normalizer.test.tsTests preference-stamp skew clamping behavior.
apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.tsReads synced preference singleton projection into snapshots; includes in updatedAt computation.
apps/server/src/orchestration/Layers/ProjectionPipeline.tsAdds projector to upsert synced preferences into SQLite projection with LWW guard.
apps/server/src/orchestration/Layers/ProjectionPipeline.test.tsTests deterministic rebuild and idempotence for synced preferences projection.
apps/server/src/orchestration/Layers/OrchestrationEngine.tsRoutes client-preferences.patch commands to the client-preferences aggregate ref.
apps/server/src/orchestration/Layers/OrchestrationEngine.test.tsVerifies receipts + LWW behavior for preference patches and shell projection results.
apps/server/src/orchestration/decider.tsEmits client-preferences.patched events for patch commands.
apps/server/src/checkpointing/CheckpointDiffQuery.test.tsUpdates test seams to ensure diff query doesn’t request new snapshot query method.
apps/server/src/auth/RpcAuthorization.tsRequires read/operate scopes for synced preference get/patch RPCs.
apps/mobile/src/state/use-thread-outbox-drain.tsForces default interaction mode when plan mode disabled; re-reads preference at drain-time.
apps/mobile/src/state/use-thread-composer-state.tsGates interaction mode derived from draft/thread via plan-mode helper.
apps/mobile/src/state/thread-outbox.test.tsAdds tests for drain-time gating and queued settings behavior vs preference changes.
apps/mobile/src/state/thread-outbox-model.tsAdds plan-mode-aware queued settings resolution + send decision helper.
apps/mobile/src/state/synced-client-preferences.tsAdds background worker to reconcile device cache with connected environments + update hook.
apps/mobile/src/state/synced-client-preferences.test.tsAdds tests for reconciliation, fan-out, stamping, and pending settlement behavior.
apps/mobile/src/state/synced-client-preferences-model.tsImplements LWW reconciliation + stamp generation + fan-out helpers for mobile.
apps/mobile/src/Stack.tsxMounts the synced client preferences worker alongside outbox drain worker.
apps/mobile/src/persistence/mobile-preferences.tsTreats planModeEnabled as synced/offline-cache; validates canonical updatedAt stamp.
apps/mobile/src/lib/storage.test.tsAdds coverage for loading legacy prefs and dropping non-canonical synced stamps.
apps/mobile/src/features/threads/use-plan-mode-enabled.tsAdds hook to read plan mode preference + loaded state from mobile preferences atom.
apps/mobile/src/features/threads/ThreadComposer.tsxAdds plan-mode gating of slash commands, submit-time parsing, and safer trigger replacement.
apps/mobile/src/features/threads/plan-mode.tsNew shared helper logic for gating, submit parsing, and trigger replacement.
apps/mobile/src/features/threads/plan-mode.test.tsTests plan-mode gating, submit parsing, and trigger replacement semantics.
apps/mobile/src/features/threads/NewTaskDraftScreen.tsxAdds new-task slash popover + submit-time parsing + eligibility refactor and locking.
apps/mobile/src/features/threads/new-task-submit.tsNew helpers for submission eligibility, selection resetting, and command interpretation gating.
apps/mobile/src/features/threads/new-task-submit.test.tsTests new-task submit eligibility + selection reset behavior.
apps/mobile/src/features/threads/new-task-flow-provider.tsxSwitches to synced plan mode preference state and applies plan-mode interaction gating.
apps/mobile/src/features/settings/SettingsRouteScreen.tsxAdds “Plan Mode (Legacy)” toggle to mobile Legacy section and wires to synced update hook.
apps/mobile/src/components/AppSymbol.tsxAdds Android mapping for hammer icon used by the new setting row.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment threaddocs/user/plan-mode.md Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
@macroscopeapp

macroscopeappBot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Skipped

Macroscope did not run approvability analysis for this PR. Diff is too large for automated approval analysis, so this PR cannot be approved automatically.

You can add or adjust custom eligibility rules. Learn more.

Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/use-thread-outbox-drain.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences.ts
Comment threadapps/web/src/hooks/useSettings.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
Comment threadapps/web/src/hooks/useSettings.ts
Comment threadapps/mobile/src/state/synced-client-preferences.ts Outdated
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated
Comment threadapps/web/src/hooks/synced-plan-mode.ts
Aman Thanvi added 6 commits August 15, 2026 10:40
Adds a Plan Mode (Legacy) toggle to mobile Settings (default off) that
gates the /plan and /default slash commands and forces outgoing turns to
default mode when off, mirroring web semantics across every send path
(composer, new task, queued outbox). Adds submit-time parsing and slash
support on the new-task composer. Introduces per-environment synced
client preferences (contracts schema, event-sourced server projection
with additive migration, incremental shell stream item) consumed by web
and mobile with LWW reconciliation, clock-skew clamping, and offline
device-local fallback.
Closespingdotgg#6401
- Preserve offline web plan-mode writes
- Reject impossible preference timestamps
- Retry failed web preference patches
- Order rapid web toggles monotonically
- Re-read plan mode before queued mobile delivery
- Route environment-scoped preference writes correctly
- Ignore stale mobile preference acknowledgements
- Document the mobile Legacy settings location
- Use Hermes-compatible reconciliation sorting
- Bound mobile synced-preference stamps to the canonical future-skew window.
- Gate thread-composer enqueue mode selection on preference hydration.
- Preserve newer local Plan Mode intent in read-only mobile and web sessions.
- Add Plan Mode to the user-docs index.
Comment threadapps/mobile/src/features/threads/ThreadComposer.tsx
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts
Comment threadapps/mobile/src/state/synced-client-preferences-model.ts Outdated

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

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 5a02ceb. Configure here.

Comment threadapps/mobile/src/state/preferences.ts
@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

Closing this PR after an automated pass over open pull requests. Mobile already supports Plan Mode. The proposal adds an unnecessary cross-client preference rewrite.

@t3dotggt3dotgg closed this Aug 23, 2026
@amanthanvi
amanthanvi deleted the t3code/feat-6401 branch August 26, 2026 23:09
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Mobile: add the Legacy features menu (Plan mode toggle) for parity with web/desktop

3 participants

@amanthanvi@t3dotgg