Sessions Integration Feature

Nucleic-Session: FC94353F-9F0D-4BCC-AD7C-0FB14E38C2E5
Co-authored-by: Nucleic <[email protected]>
This commit is contained in:
2026-07-05 01:55:25 -07:00
co-authored by Nucleic
parent e156ea2e59
commit 4e8f5db2bb
@@ -867,12 +867,54 @@ final class RemoteStore: ObservableObject {
// MARK: - Plumbing
/// Route an intent to the active host's connection (mesh P3). Every current intent — subscribe,
/// send-input, approvals, favorite/archive/delete, start-chat — targets a session or project on
/// the Mac whose list is on screen, i.e. the active one.
/// Route an intent to the Mac that owns its target (mesh P3). Sessions/projects/to-dos are shown
/// merged across every connected Mac, so an intent goes to the connection that owns the session,
/// project, or to-do it names — not to a single "active" host. Host-agnostic pulls (list
/// sessions/dashboard) broadcast to every live Mac; a project-less to-do capture (no owner) goes
/// to the first live Mac. Demo has no connections and mutates the seeded aggregate directly.
private func send(_ msg: ClientMsg) {
if demoMode { demoHandle(msg); return }
activeConnection?.send(msg)
switch msg {
// Session-owning intents → the Mac that has this session.
case .subscribe(let s):
connection(owningSession: s.sessionID)?.send(msg)
case .unsubscribe(let id), .interrupt(let id), .deleteSession(let id), .discard(let id),
.integrate(let id, _), .renameSession(let id, _), .setFavorite(let id, _),
.setArchived(let id, _), .setSessionModel(let id, _), .setSessionEffort(let id, _),
.setSessionAuto(let id, _), .setSessionAutoShip(let id, _), .setSessionShipBranch(let id, _),
.sendInput(let id, _), .cancelQueuedMessage(let id, _), .fetchDiff(let id):
connection(owningSession: id)?.send(msg)
// Project-owning intents → the Mac that has this project.
case .startChat(let req):
connection(owningProject: req.projectID)?.send(msg)
case .dispatchTodo(_, let projectID):
connection(owningProject: projectID)?.send(msg)
// To-do-owning intents → the Mac that has this to-do.
case .setTodoStatus(let id, _), .deleteTodo(let id):
connection(owningTodo: id)?.send(msg)
// A capture with a project goes to that Mac; a project-less one has no owner → first live.
case .captureTodo(let req):
if let pid = req.projectID, let conn = connection(owningProject: pid) { conn.send(msg) }
else { firstLiveConnection?.send(msg) }
// Approvals carry no sessionID — `respond(_:_:)` routes by the approval's session directly;
// a stray one here (or a notification-driven decision) broadcasts and the owner resolves it.
case .approvalRespond:
broadcastLive(msg)
// Host-agnostic pulls → every live Mac.
case .listSessions, .listDashboard:
broadcastLive(msg)
// Never originated from here (connection-internal, or handled by dedicated loops).
case .hello, .ping, .listPeers, .addressUpdate, .meshRoster,
.registerLiveActivity, .endLiveActivity,
.transferOffer, .transferChunk, .transferCommit, .transferCancel, .fetchTranscript:
break
}
}
// MARK: - Live Activity push registration (UX_IOS §5.3)