fix(relay): use current APNs registration routing for queued jobs - #10859
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (2)
Included review availability: Your plan provides up to 10 included reviews per hour; 0 remain after this review. 📝 WalkthroughWalkthroughAPNs signed delivery jobs now use the device’s current bundle ID and APS environment when the delivery token still matches. Tests cover Live Activity, push-notification, and legacy jobs without signed routing metadata. ChangesAPNs routing validation
Priority: ⬇️ Low Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to Token-matching APNs jobs now route using the device’s current bundle and environment metadata, with coverage for Live Activity, notification, and legacy jobs. No current merge-blocking risk remains. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — The change is narrowly scoped to correcting APNs bundle and environment routing for queued deliveries while preserving existing token and freshness checks. Targeted tests cover both delivery types and legacy or changed registration metadata. You can add or adjust custom eligibility rules. Learn more. |
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: Scenario and decoded snapshot size10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
Merges `pingdotgg/t3code` into the fork: upstream `2a3035353` from base `a37c66406`, 53 commits. Landed as a merge commit, not a cherry-pick. Tracker entry: `docs/fork/upstream-merge-log.md`. Gaps this merge opened or extended: `docs/fork/gaps.md`. ## Usable as-is Fork can expose these with no Moatless backend or deployment work. - **Project icons everywhere they belong** — favicon in the new-thread project picker (pingdotgg#10790), the project record passed to `ProjectFavicon` so icons cannot drift (pingdotgg#10714), and the same icon in the command palette (pingdotgg#10712). `apps/web/src/components/ProjectFavicon.tsx`, `DraftHeroHeadline.tsx`. - **Composer and sidebar layout settling** — footer held still while thread data loads (pingdotgg#10768), the bar under the composer no longer pops in (pingdotgg#10727), chat text no longer shows through a 1px gap under composer banners (pingdotgg#10635), scroll-to-end button kept close to the composer (pingdotgg#10543), sidebar rows no longer flash and shift on click (pingdotgg#10713), settings sidebar no longer shifts when switching pages (pingdotgg#10705). - **Minimap turn navigation** (pingdotgg#8531) — previous/next turn controls, `apps/web/src/components/chat/` minimap surface. Pure client state. - **Terminal** — copy selection with Ctrl+Insert (pingdotgg#8541), honor terminal link browser overrides (pingdotgg#10060). - **Usage panel** — account columns aligned across limit rows (pingdotgg#10690), email-bearing account labels hidden (pingdotgg#10668). - **Setup wizards consolidated into shared components** (pingdotgg#10832). - **File drops onto sidebar threads** (pingdotgg#7892) — rides the attachment upload path the fork already has; `useSidebarPendingFileDropStore` threaded through `ChatView.tsx` and `_chat.$environmentId.$threadId.tsx`. - **Mobile** — drag handles to arrange threads (pingdotgg#10496), Android wallpaper colors (pingdotgg#10691), optional Material You layout (pingdotgg#10692), tolerate native `Headers` without `getSetCookie` (pingdotgg#10851), respect notification permission when tokens rotate (pingdotgg#10850). - **Desktop** — macOS installer artwork (pingdotgg#10632, pingdotgg#10819, pingdotgg#10820), layout control hit targets (pingdotgg#10673), context menus in the browser (pingdotgg#10670), no declarations during bundling (pingdotgg#10679), keyring loading deferred until macOS cookie import (pingdotgg#10667). `electron-desktop` is kept in tree and is not a compliance target. - **Dependency and hygiene** — Effect `rc.112` and Alchemy `beta.76` (pingdotgg#10652) with reference syncs (pingdotgg#10653, pingdotgg#10654), and the knip export classification sweep across server modules (pingdotgg#10274–pingdotgg#10282). ## Unsupported in Moatless / needs implementation - **Attach files to question answers** (#7220dfe2c, pingdotgg#9871). Upstream added the wire capability `questionAttachments` in `packages/contracts/src/environment.ts` and threads `supportsQuestionAttachments` through `ChatView.tsx` → `ChatComposer.tsx`. The fork takes upstream's plumbing verbatim; the capability is simply absent from what Moatless reports, so the composer correctly offers nothing. **To implement:** accept attachments on the answer-submission path and report `capabilities.questionAttachments: true`. The sibling `ServerProvider.reportsContextWindow` flag lands in the same shape. Recorded in `gaps.md`. - **Pull request merge defaults** (#7d9aaf6a7, pingdotgg#8088). Adds `pullRequestMergeMethodOverrides` to `packages/contracts/src/settings.ts` — a per-project merge method plus a last-used default, surfaced in `ProjectSettingsPanel.tsx` and `PullRequestDetailPanel.tsx`. **To implement:** Moatless must persist these settings fields, and the panel that consumes them needs `pullRequests.detail`, which Moatless does not dispatch (it serves only `pullRequests.summary`). Recorded in `gaps.md` under Pull requests. - **Relay push-notification routing** (pingdotgg#10859, pingdotgg#10849, pingdotgg#10848) — current APNs registration routing for queued jobs, requeue checks for queued iOS alerts, shared notification policy prioritizing waiting agents. These land in `infra/relay/`, which belongs to the `cloud-relay-connect` concern the fork has decided out. No fork app code imports them; taken as upstream and left inert. ## Backend behavior to consider reproducing in Moatless Upstream server behavior the fork cannot use directly — `apps/server` is not what Moatless runs — but that would improve Moatless. - **Give completed turns a full session idle window** (#430fbd1ff, pingdotgg#10689). Upstream's `ProviderSessionReaper` was measuring idle time from a point that cut a completed turn's window short, so provider sessions were reaped earlier than intended and the next turn paid a cold start. Worth checking whatever Moatless uses to retire provider sessions against the same case. - **Release consumed event replay pages** (#08463e2c4, pingdotgg#10777). `OrchestrationEventStore` held every page it had produced while replaying, so a long thread's replay grew without bound. Upstream moved it to `Stream.paginate`. If Moatless replays orchestration events to reconnecting clients, it has the same shape of exposure. - **Stop Windows terminal processes when closing** (#47eed9fac, pingdotgg#10771) — terminal child processes outlived their session on Windows. Relevant to Moatless only if it hosts terminals on Windows runners. - **Generate thread titles with the selected model across connections** (#bc4b00666, pingdotgg#10526) — title generation was falling back to a default model rather than the connection's selected one. - **Keep preview snapshots usable by the agent and let it save them** (#061543e9e, pingdotgg#10501) — adds a `save` argument to the MCP `preview_snapshot` tool so the agent can persist a snapshot rather than only view it. Recorded in `gaps.md` under Preview automation. ## Conflicts 7 files. Full reasoning is in the tracker entry; the two worth reading here: - **`SettingsSidebarNav.tsx`** — upstream deleted the settings sub-section nav wholesale (`settingsSectionVisibility.ts` no longer exists upstream), which collided with the fork's admin/personal split. Kept upstream's removal and rebuilt the split on top of it, extracting `renderNavItem` so both nav groups render identical rows. - **`ChatComposer.tsx`** — both hunks resolved to upstream. The fork comment there documented `maxFileAttachmentBytes`, which upstream now owns itself. `pnpm-lock.yaml` was `theirs` then re-derived with `vp i`. `apps/server/src/cli/pair.ts` is the one file in the upstream range that did not land — the fork deletes that surface deliberately, and the tripwire confirms it is still deleted. ## A rename that no conflict marked Upstream's Effect bump renamed `Schema.TaggedErrorClass` to `Schema.TaggedError`. Upstream renamed its own two occurrences, so those merged clean — but the fork's three (`UnsupportedMethodError` in `packages/contracts/src/auth.ts`, `SandboxNotRunningError` in `packages/contracts/src/sandbox.ts`, and one in `apps/web/src/environments/primary/auth.ts`) have no upstream counterpart, so git carried them through untouched. Typecheck failed with one `TS2551` and about forty cascading `TS2740`s in `rpc.ts` behind it. All three renamed. ## Verification `verify.mjs` is green on seven checks: duplicate-adds, tripwires, resolution-check, unsupported-methods, `fmt:check`, lint, typecheck. `test` is red on **`@t3tools/desktop` only**, and it is the machine rather than this merge: `scripts/browser-secret-native.test.mjs` shells out to `pkg-config --cflags --libs libsecret-1`, which the sandbox image does not carry. The file is byte-identical to upstream and fails the same way on a clean tree; the standing entry is in `gaps.md`. 1289 tests pass, 1 suite fails to compile. Four packages did not finish under parallel load and all four pass alone — `@t3tools/web` 383 files, `t3` 293, `@t3tools/mobile` 155, `t3code-relay` 28. Unsupported methods: 1 ADD, 0 DROP, 2 KEEP, 4 known exceptions. The ADD is `sandbox.detail` and it is **pre-existing drift, not merge-introduced** — confirmed by re-running the derivation against `HEAD^1`. Applied anyway, with the union entry documenting that Moatless dispatches `sandbox.subscribeDetail` and not its one-shot sibling. `duplicate-adds.mjs` reported `target="_blank"` in `MessagesTimeline.tsx`. Both parents have it once, on two unrelated anchors — the fork's `MessageOriginIcon` and upstream's new question-attachment link. The script now skips a bare JSX attribute on its own line, for the same reason it already skips punctuation. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- Moatless task: https://moatless.soaplabstest.com/tasks/ff7d0df5-d989-4ec6-95c6-4e730cf3fd6f
## What's Changed * fix(relay): use current APNs registration routing for queued jobs by @juliusmarminge in pingdotgg/t3code#10859 * fix(server): release consumed event replay pages by @Gigioxx in pingdotgg/t3code#10777 * feat(mobile): arrange threads with drag handles by @juliusmarminge in pingdotgg/t3code#10496 * feat(mobile): add Android agent notifications and ongoing activity by @ryanrhughes in pingdotgg/t3code#10416 **Full Changelog**: pingdotgg/t3code@v0.0.41-nightly.20260909.1426...v0.0.41-nightly.20260909.1439 Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.41-nightly.20260909.1439
A queued APNs job can retain a valid token after registration changes its bundle ID or APNs environment. Sending old routing metadata can produce a permanent APNs rejection and invalidate the current token.
Use the current registration's routing after validating the queued token. This handles both stale routing snapshots and older jobs that omit routing metadata. It follows up the review of merged #10849.
Validation: all 49 APNs delivery tests pass, including both delivery kinds with changed bundles, changed APNs environments, and omitted legacy fields. Tests assert the actual HTTP host and topic. Relay typecheck and targeted lint pass. Queue routing changes have no visual layout changes.
Implemented with GPT-6 in Codex.