Skip to content
Closed
Original file line number Diff line number Diff line change
Expand Up @@ -35,43 +35,6 @@ public struct MobileSyncCollectionID: RawRepresentable, Codable, Hashable, Senda
/// `mobile.workspace.list` payload (same snake_case wire names) plus an
/// explicit `sort_index` so list order syncs without positional inference.
public struct WorkspaceSyncRecord: MobileSyncRecord {
/// One surface row within a workspace.
public struct Surface: Codable, Equatable, Sendable {
/// Stable surface identifier.
public let surfaceID: String
/// Open surface-kind wire string.
public let kind: String
/// User-facing surface title.
public let title: String
/// Backing file path for file-based surfaces, when reported.
public let filePath: String?
/// Bounded checklist/status payload for todo surfaces.
public let todo: MobileTodoSnapshot?

/// Creates a surface row from its wire fields.
public init(
surfaceID: String,
kind: String,
title: String,
filePath: String?,
todo: MobileTodoSnapshot? = nil
) {
self.surfaceID = surfaceID
self.kind = kind
self.title = title
self.filePath = filePath
self.todo = todo
}

private enum CodingKeys: String, CodingKey {
case surfaceID = "surface_id"
case kind
case title
case filePath = "file_path"
case todo
}
}

/// One terminal row within a workspace.
public struct Terminal: Codable, Equatable, Sendable {
/// Stable terminal identifier.
Expand Down Expand Up @@ -141,9 +104,6 @@ public struct WorkspaceSyncRecord: MobileSyncRecord {
public let sortIndex: Int
/// Terminal rows belonging to this workspace, in spatial order.
public let terminals: [Terminal]
/// All surface rows belonging to this workspace, in spatial order.
/// `nil` when decoded from a Mac that predates surface inventory support.
public let surfaces: [Surface]?
/// Simulator panes belonging to this workspace, in spatial order.
public let simulators: [MobileSimulatorPanelDescriptor]

Expand All @@ -170,7 +130,6 @@ public struct WorkspaceSyncRecord: MobileSyncRecord {
hasUnread: Bool,
sortIndex: Int,
terminals: [Terminal],
surfaces: [Surface]? = nil,
simulators: [MobileSimulatorPanelDescriptor] = []
) {
self.id = id
Expand All @@ -189,7 +148,6 @@ public struct WorkspaceSyncRecord: MobileSyncRecord {
self.hasUnread = hasUnread
self.sortIndex = sortIndex
self.terminals = terminals
self.surfaces = surfaces
self.simulators = simulators
}

Expand All @@ -214,7 +172,6 @@ public struct WorkspaceSyncRecord: MobileSyncRecord {
hasUnread = try container.decode(Bool.self, forKey: .hasUnread)
sortIndex = try container.decode(Int.self, forKey: .sortIndex)
terminals = try container.decode([Terminal].self, forKey: .terminals)
surfaces = try container.decodeIfPresent([Surface].self, forKey: .surfaces)
simulators = try container.decodeIfPresent(
[MobileSimulatorPanelDescriptor].self,
forKey: .simulators
Expand All @@ -238,7 +195,6 @@ public struct WorkspaceSyncRecord: MobileSyncRecord {
case hasUnread = "has_unread"
case sortIndex = "sort_index"
case terminals
case surfaces
case simulators
}
}
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -29,32 +29,6 @@ struct MobileStateSyncFrameCodingTests {
isReady: true,
isFocused: false
)
],
surfaces: [
WorkspaceSyncRecord.Surface(
surfaceID: "surface-future",
kind: "simulator",
title: "iPhone 17 Pro",
filePath: nil
),
WorkspaceSyncRecord.Surface(
surfaceID: "surface-todo",
kind: MobileSurfaceKind.todo.rawValue,
title: "Todo",
filePath: nil,
todo: MobileTodoSnapshot(
status: .needsAttention,
statusHidden: false,
items: [
MobileTodoItem(
id: "item-1",
text: "Review the renderer",
state: .inProgress,
origin: .agent
),
]
)
)
]
)
}
Expand All @@ -77,46 +51,6 @@ struct MobileStateSyncFrameCodingTests {
let terminals = object["terminals"] as? [[String: Any]]
#expect(terminals?.first?["is_ready"] as? Bool == true)
#expect(terminals?.first?["is_focused"] as? Bool == false)
let surfaces = object["surfaces"] as? [[String: Any]]
#expect(surfaces?.first?["surface_id"] as? String == "surface-future")
#expect(surfaces?.first?["kind"] as? String == "simulator")
#expect(surfaces?.first?["file_path"] == nil)
let todo = surfaces?[1]["todo"] as? [String: Any]
#expect(todo?["status"] as? String == "needs-attention")
#expect(todo?["status_hidden"] as? Bool == false)
let items = todo?["items"] as? [[String: Any]]
#expect(items?.first?["id"] as? String == "item-1")
#expect(items?.first?["state"] as? String == "in_progress")
#expect(items?.first?["origin"] as? String == "agent")
}

@Test func mobileSurfaceKindPreservesUnknownRawValues() throws {
let kind = MobileSurfaceKind(rawValue: "simulator")
let data = try JSONEncoder().encode(kind)
#expect(String(decoding: data, as: UTF8.self) == #""simulator""#)
#expect(try JSONDecoder().decode(MobileSurfaceKind.self, from: data) == kind)
}

@Test func workspaceRecordWithoutSurfacesDecodesAndReencodesWithoutTheField() throws {
let json = #"{"id":"ws-old","title":"old","is_selected":false,"is_pinned":false,"last_activity_at":1,"has_unread":false,"sort_index":0,"terminals":[]}"#
let decoded = try MobileSyncFrameCoder().decode(
WorkspaceSyncRecord.self,
fromJSONString: json
)
#expect(decoded.surfaces == nil)
let object = try MobileSyncFrameCoder().jsonObject(from: decoded)
#expect(object["surfaces"] == nil)
}

@Test func workspaceRecordRoundTripsSurfaceInventory() throws {
let decoded = try JSONDecoder().decode(
WorkspaceSyncRecord.self,
from: JSONEncoder().encode(workspace)
)
#expect(decoded == workspace)
#expect(decoded.surfaces?.first?.kind == "simulator")
#expect(decoded.surfaces?[1].todo?.status == .needsAttention)
#expect(decoded.surfaces?[1].todo?.items.first?.state == .inProgress)
}

@Test func workspaceRecordDefaultsMissingDescriptionTruncatedFlagToFalse() throws {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,4 @@ public enum ChatArtifactError: Error, Sendable, Equatable {
case macUnreachable
/// The file exceeds the inline preview size limit.
case tooLarge(limitBytes: Int64)
/// The Mac answered with an error this client does not recognize.
///
/// Distinct from ``macUnreachable``: the connection worked and the Mac
/// replied, so messaging must not blame connectivity.
case unknown(code: String?)
}
Loading