Squash of 63 commits spanning waves 46-93 (plus interspersed docs commits) of the gradual Postbox->TelegramEngine consumer-side migration. Scope: 139 files changed, 2123 insertions(+), 452 deletions(-). ## Themes by wave-block **Waves 46-58 — Peer field migrations + facade additions** Foundational EnginePeer convenience init additions (PeerReference, RenderedPeer, SelectivePrivacyPeer). Multiple `peer: Peer` field migrations across PeerInfo, ChatList, and SettingsUI components. **Waves 59-73 — peer field cascade + EnginePeer wrap drops** Series of single- to two-file peer-field migrations; consumer-side wrap removal (`EnginePeer(peer)` -> direct EnginePeer use); `as? TelegramUser` cast conversion to `case let .user(...)` enum match. Wave 64: RenderedPeer convenience init. Wave 68: SelectivePrivacyPeer convenience init. **Waves 74-83 — controller-Node bridge cleanup + small migrations** Wave-71 shadow-pattern cleanup at controller->Node bridges. Migrations of ChatRecentActionsController.peer (74), PeerInfoMember (75), MentionChatInputPanelItem (76), PassportUI SecureIdAuthController (77), AccountWithInfo + ShareController (78), peerInputActivitiesPromise (79), InactiveChannel (80), BlockedPeers (81), openHashtag resolveSignal (82), NotificationExceptionsList (83). **Waves 84-90 — TelegramEngine.Resources facade migrations** Per-method Shape-A/B sweeps converting `<ctx>.account.postbox.mediaBox.X(...)` to `<ctx>.engine.resources.X(...)`. Wave 90 was a single-commit big sweep: 40 fetchedMediaResource sites in 25 files migrated to engine.resources.fetch facade in one atomic pass with first-pass-clean build. Methods covered: storeResourceData, completedResourcePath, cancelInteractiveResourceFetch, resourceRangesStatus, resourceStatus, fetch (fetchedMediaResource). **Waves 91-92 — additional type migrations** Wave 91: ItemListWebsiteItem.peer + RecentSessionsController enum-case payload + openWebSession callback Peer? -> EnginePeer?. Wave 92: ChatListController StateHolder.EntryContext status type MediaResourceStatus -> EngineMediaResource.FetchStatus. **Wave 93 — speculative `import Postbox` drop sweep** Drop import from 7 wave-touched files where it became unused; restore in 5 files where bare PeerId/Message/MediaId/StoryId references escaped the pre-flight regex. Includes one MediaId(...) -> EngineMedia.Id(...) swap in InAppPurchaseManager to unlock its import drop. ## Build state Final state at squash: clean Telegram/Telegram build at debug_sim_arm64. ## Persistent-state notes - Pre-existing WIP unchanged across the squashed range: - build-system/bazel-rules/sourcekit-bazel-bsp submodule marker - Untracked: build-system/tulsi/, submodules/TgVoip/, third-party/libx264/ Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6.1 KiB
Wave 54: ClearPeerHistory.init + openClearHistory chatPeer: Peer → EnginePeer
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task.
Goal: Migrate the chatPeer: parameter type on both ClearPeerHistory.init and openClearHistory from Peer to EnginePeer. Closes wave-53's deferred sibling.
Wave shape: Bundled method-signature migration (familiar from waves 41/44/47/50/53). Mechanical as?/is cluster on a single field, with EnginePeer.init boundary lifts at each call site.
Tech Stack: Swift, Bazel, Make.py.
Pre-Flight Inventory (validated 2026-04-25)
2 files modified, 16 edits.
File 1: submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift (PIS)
| Line | Current | After | Note |
|---|---|---|---|
| 3213 | func openClearHistory(... peer: Peer, chatPeer: Peer) { |
... chatPeer: EnginePeer) |
type-site |
| 3230 | EnginePeer(chatPeer).compactDisplayTitle |
chatPeer.compactDisplayTitle |
drop wrap |
| 3232 | EnginePeer(chatPeer).compactDisplayTitle |
chatPeer.compactDisplayTitle |
drop wrap |
| 3251 | EnginePeer(chatPeer).compactDisplayTitle |
chatPeer.compactDisplayTitle |
drop wrap |
| 3269 | EnginePeer(chatPeer).compactDisplayTitle |
chatPeer.compactDisplayTitle |
drop wrap |
| 7416 | init(... peer: Peer, chatPeer: Peer, cachedData: ...) |
... chatPeer: EnginePeer, cachedData: ... |
type-site |
| 7421 | } else if chatPeer is TelegramSecretChat { |
} else if case .secretChat = chatPeer { |
conversion |
| 7425 | } else if let group = chatPeer as? TelegramGroup { |
} else if case let .legacyGroup(group) = chatPeer { |
conversion |
| 7436 | } else if let channel = chatPeer as? TelegramChannel { |
} else if case let .channel(channel) = chatPeer { |
conversion |
| 7464 | if let user = chatPeer as? TelegramUser, user.botInfo != nil { |
if case let .user(user) = chatPeer, user.botInfo != nil { |
conversion |
peer: parameter stays Peer-typed in both functions: openClearHistory doesn't reference peer in its body; ClearPeerHistory.init uses only peer.id == context.account.peerId (line 7417), which works on Peer (and would also work on EnginePeer, but migrating it would require 6 boundary lifts at PISPBA call sites for no internal benefit).
File 2: submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreenPerformButtonAction.swift (PISPBA)
| Line | Current | After | Note |
|---|---|---|---|
| 851 | chatPeer: chatPeer._asPeer() |
chatPeer: chatPeer |
drop wave-53 ADD |
| 857 | chatPeer: user |
chatPeer: EnginePeer(user) |
boundary lift (TelegramUser) |
| 1067 | chatPeer: channel |
chatPeer: EnginePeer(channel) |
boundary lift (TelegramChannel) |
| 1073 | chatPeer: channel |
chatPeer: EnginePeer(channel) |
boundary lift (TelegramChannel) |
| 1234 | chatPeer: group |
chatPeer: EnginePeer(group) |
boundary lift (TelegramGroup) |
| 1240 | chatPeer: group |
chatPeer: EnginePeer(group) |
boundary lift (TelegramGroup) |
Net accounting
- Drops: 5 (4
EnginePeer(chatPeer).compactDisplayTitle+ 1_asPeer()bridge from wave 53). - Adds: 5 boundary lifts (5
EnginePeer(...)wraps at PISPBA call sites). - Conversions: 4 (
is/as?→case let). - Type-site: 2 (signature changes on PIS:3213 and PIS:7416).
Net internal-bridge progress: 5 drops − 5 adds = 0 raw count. But ratchet kills 4 internal display-call wraps (EnginePeer(chatPeer).compactDisplayTitle patterns) which is the hot path; only call-site boundary lifts remain. Closes wave-53's deferred ADD at PISPBA:851.
Tasks
Task 1: PIS signature edits + body wrap drops
- Step 1: Edit
openClearHistorysignature at PIS:3213
Replace peer: Peer, chatPeer: Peer) with peer: Peer, chatPeer: EnginePeer).
- Step 2: Drop 4
EnginePeer(chatPeer).compactDisplayTitlewraps
replace_all=true of EnginePeer(chatPeer).compactDisplayTitle → chatPeer.compactDisplayTitle. (Only 4 occurrences in the file, all in openClearHistory body; verified by grep.)
- Step 3: Edit
ClearPeerHistory.initsignature at PIS:7416
Replace peer: Peer, chatPeer: Peer, cachedData: with peer: Peer, chatPeer: EnginePeer, cachedData:.
- Step 4: Convert PIS:7421
is TelegramSecretChat
Replace } else if chatPeer is TelegramSecretChat { with } else if case .secretChat = chatPeer {.
- Step 5: Convert PIS:7425
as? TelegramGroup
Replace } else if let group = chatPeer as? TelegramGroup { with } else if case let .legacyGroup(group) = chatPeer {.
- Step 6: Convert PIS:7436
as? TelegramChannel
Replace } else if let channel = chatPeer as? TelegramChannel { with } else if case let .channel(channel) = chatPeer {.
- Step 7: Convert PIS:7464
as? TelegramUser
Replace if let user = chatPeer as? TelegramUser, user.botInfo != nil { with if case let .user(user) = chatPeer, user.botInfo != nil {.
Task 2: PISPBA call-site lifts + bridge drop
- Step 1: Drop wave-53
_asPeer()bridge at PISPBA:851
Replace chatPeer: chatPeer._asPeer() with chatPeer: chatPeer.
- Step 2: Lift PISPBA:857
chatPeer: user
Replace peer: user, chatPeer: user) with peer: user, chatPeer: EnginePeer(user)).
- Step 3: Lift channel call sites (PISPBA:1067 + 1073)
replace_all=true of chatPeer: channel → chatPeer: EnginePeer(channel). Verify exactly 2 hits flipped.
- Step 4: Lift group call sites (PISPBA:1234 + 1240)
replace_all=true of chatPeer: group → chatPeer: EnginePeer(group). Verify exactly 2 hits flipped.
Task 3: Build verification
- Step 1: Run full build with
--continueOnError.
Forecast 1 iteration. Risk: hidden chatPeer access on Peer-typed shape elsewhere (none expected — body audit complete).
Task 4: Commit + log
- Step 1: Commit wave with the two file paths explicitly.
- Step 2: Update
docs/superpowers/postbox-refactor-log.mdand the memory file. - Step 3: Commit log.