@wangyaoshen/remux 0.3.8-dev.29e114b
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/ISSUE_TEMPLATE/bug_report.md +47 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +38 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +28 -0
- package/.github/dependabot.yml +33 -0
- package/.github/workflows/ci.yml +65 -0
- package/.github/workflows/deploy.yml +65 -0
- package/.github/workflows/publish.yml +312 -0
- package/.github/workflows/release-please.yml +21 -0
- package/.gitmodules +3 -0
- package/.nvmrc +1 -0
- package/.release-please-manifest.json +3 -0
- package/CLAUDE.md +104 -0
- package/Dockerfile +23 -0
- package/LICENSE +21 -0
- package/README.md +120 -0
- package/apps/ios/Config/signing.xcconfig +4 -0
- package/apps/ios/Package.swift +26 -0
- package/apps/ios/Remux.xcodeproj/project.pbxproj +477 -0
- package/apps/ios/Remux.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/Contents.json +23 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_1024x1024.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_120x120.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_152x152.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_167x167.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_180x180.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_20x20.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_29x29.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_40x40.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_58x58.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_60x60.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_76x76.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_80x80.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_87x87.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/Contents.json +6 -0
- package/apps/ios/Sources/Remux/Extensions/FaceIDManager.swift +29 -0
- package/apps/ios/Sources/Remux/Extensions/InspectCache.swift +66 -0
- package/apps/ios/Sources/Remux/MainTabView.swift +32 -0
- package/apps/ios/Sources/Remux/Remux.entitlements +8 -0
- package/apps/ios/Sources/Remux/RemuxiOSApp.swift +14 -0
- package/apps/ios/Sources/Remux/RootView.swift +130 -0
- package/apps/ios/Sources/Remux/Views/Control/ControlView.swift +102 -0
- package/apps/ios/Sources/Remux/Views/Inspect/InspectView.swift +98 -0
- package/apps/ios/Sources/Remux/Views/Live/LiveTerminalView.swift +132 -0
- package/apps/ios/Sources/Remux/Views/Now/NowView.swift +173 -0
- package/apps/ios/Sources/Remux/Views/Onboarding/ManualConnectView.swift +55 -0
- package/apps/ios/Sources/Remux/Views/Onboarding/OnboardingView.swift +70 -0
- package/apps/ios/Sources/Remux/Views/Onboarding/QRScannerView.swift +92 -0
- package/apps/ios/Sources/Remux/Views/Settings/MeView.swift +136 -0
- package/apps/macos/Package.swift +37 -0
- package/apps/macos/Resources/shell-integration/bash/bash-preexec.sh +382 -0
- package/apps/macos/Resources/shell-integration/bash/ghostty.bash +315 -0
- package/apps/macos/Resources/shell-integration/elvish/lib/ghostty-integration.elv +191 -0
- package/apps/macos/Resources/shell-integration/fish/vendor_conf.d/ghostty-shell-integration.fish +246 -0
- package/apps/macos/Resources/shell-integration/nushell/vendor/autoload/ghostty.nu +110 -0
- package/apps/macos/Resources/shell-integration/zsh/.zshenv +61 -0
- package/apps/macos/Resources/shell-integration/zsh/ghostty-integration +458 -0
- package/apps/macos/Resources/terminfo/67/ghostty +0 -0
- package/apps/macos/Resources/terminfo/78/xterm-ghostty +0 -0
- package/apps/macos/Sources/Remux/AppDelegate.swift +257 -0
- package/apps/macos/Sources/Remux/CrashReporter.swift +210 -0
- package/apps/macos/Sources/Remux/FinderIntegration.swift +117 -0
- package/apps/macos/Sources/Remux/GhosttyConfig.swift +311 -0
- package/apps/macos/Sources/Remux/KeyboardShortcuts/ShortcutAction.swift +115 -0
- package/apps/macos/Sources/Remux/KeyboardShortcuts/ShortcutSettingsView.swift +271 -0
- package/apps/macos/Sources/Remux/KeyboardShortcuts/StoredShortcut.swift +149 -0
- package/apps/macos/Sources/Remux/MainContentView.swift +308 -0
- package/apps/macos/Sources/Remux/MenuBarManager.swift +275 -0
- package/apps/macos/Sources/Remux/NotificationManager.swift +145 -0
- package/apps/macos/Sources/Remux/PortScanner.swift +152 -0
- package/apps/macos/Sources/Remux/RemuxApp.swift +13 -0
- package/apps/macos/Sources/Remux/SSHDetector.swift +151 -0
- package/apps/macos/Sources/Remux/SessionPersistence.swift +226 -0
- package/apps/macos/Sources/Remux/SocketController.swift +258 -0
- package/apps/macos/Sources/Remux/UpdateChecker.swift +152 -0
- package/apps/macos/Sources/Remux/Views/CommandPalette.swift +198 -0
- package/apps/macos/Sources/Remux/Views/ConnectionView.swift +84 -0
- package/apps/macos/Sources/Remux/Views/InspectView.swift +127 -0
- package/apps/macos/Sources/Remux/Views/SettingsView.swift +77 -0
- package/apps/macos/Sources/Remux/Views/Sidebar/SidebarView.swift +410 -0
- package/apps/macos/Sources/Remux/Views/SplitTree/BrowserPanel.swift +193 -0
- package/apps/macos/Sources/Remux/Views/SplitTree/MarkdownPanel.swift +277 -0
- package/apps/macos/Sources/Remux/Views/SplitTree/PanelProtocol.swift +14 -0
- package/apps/macos/Sources/Remux/Views/SplitTree/SplitNode.swift +149 -0
- package/apps/macos/Sources/Remux/Views/SplitTree/SplitView.swift +234 -0
- package/apps/macos/Sources/Remux/Views/SplitTree/TerminalPanel.swift +26 -0
- package/apps/macos/Sources/Remux/Views/TabBarView.swift +94 -0
- package/apps/macos/Sources/Remux/Views/Terminal/ClipboardHelper.swift +101 -0
- package/apps/macos/Sources/Remux/Views/Terminal/CopyModeOverlay.swift +325 -0
- package/apps/macos/Sources/Remux/Views/Terminal/GhosttyNativeTerminalView.swift +39 -0
- package/apps/macos/Sources/Remux/Views/Terminal/GhosttyNativeView.swift +559 -0
- package/apps/macos/Sources/Remux/Views/Terminal/SurfaceSearchOverlay.swift +109 -0
- package/apps/macos/Sources/Remux/Views/Terminal/TerminalContainerView.swift +95 -0
- package/apps/macos/Sources/Remux/Views/Terminal/TerminalRelay.swift +117 -0
- package/build.mjs +33 -0
- package/native/android/DecodeGoldenPayloads.kt +487 -0
- package/native/android/ProtocolModels.kt +188 -0
- package/native/ios/DecodeGoldenPayloads.swift +711 -0
- package/native/ios/ProtocolModels.swift +200 -0
- package/package.json +45 -0
- package/packages/RemuxKit/Package.swift +27 -0
- package/packages/RemuxKit/Sources/RemuxKit/Device/DeviceManager.swift +27 -0
- package/packages/RemuxKit/Sources/RemuxKit/Models/ProtocolModels.swift +206 -0
- package/packages/RemuxKit/Sources/RemuxKit/Networking/MessageRouter.swift +108 -0
- package/packages/RemuxKit/Sources/RemuxKit/Networking/RemuxConnection.swift +395 -0
- package/packages/RemuxKit/Sources/RemuxKit/State/RemuxState.swift +188 -0
- package/packages/RemuxKit/Sources/RemuxKit/Storage/KeychainStore.swift +142 -0
- package/packages/RemuxKit/Sources/RemuxKit/Terminal/GhosttyBridge.swift +145 -0
- package/packages/RemuxKit/Sources/RemuxKit/Terminal/GhosttyTerminalView.swift +35 -0
- package/packages/RemuxKit/Sources/RemuxKit/Terminal/Resources/ghostty-terminal.html +91 -0
- package/packages/RemuxKit/Tests/RemuxKitTests/ConnectionIntegrationTest.swift +74 -0
- package/packages/RemuxKit/Tests/RemuxKitTests/KeychainStoreTests.swift +81 -0
- package/packages/RemuxKit/Tests/RemuxKitTests/ProtocolModelsTests.swift +179 -0
- package/packages/RemuxKit/Tests/RemuxKitTests/RemuxStateTests.swift +62 -0
- package/playwright.config.ts +17 -0
- package/pnpm-lock.yaml +1588 -0
- package/pty-daemon.js +303 -0
- package/release-please-config.json +14 -0
- package/scripts/auto-deploy.sh +46 -0
- package/scripts/build-dmg.sh +121 -0
- package/scripts/build-ghostty-kit.sh +43 -0
- package/scripts/check-active-terminology.mjs +132 -0
- package/scripts/setup-ci-secrets.sh +80 -0
- package/scripts/sync-ghostty-web.sh +28 -0
- package/scripts/upload-testflight.sh +100 -0
- package/server.js +7074 -0
- package/src/adapters/agent-events.ts +246 -0
- package/src/adapters/claude-code.ts +158 -0
- package/src/adapters/codex.ts +210 -0
- package/src/adapters/generic-shell.ts +58 -0
- package/src/adapters/index.ts +15 -0
- package/src/adapters/registry.ts +99 -0
- package/src/adapters/types.ts +41 -0
- package/src/auth.ts +174 -0
- package/src/e2ee.ts +236 -0
- package/src/git-service.ts +168 -0
- package/src/message-buffer.ts +137 -0
- package/src/pty-daemon.ts +357 -0
- package/src/push.ts +127 -0
- package/src/renderers.ts +455 -0
- package/src/server.ts +2407 -0
- package/src/service.ts +226 -0
- package/src/session.ts +978 -0
- package/src/store.ts +1422 -0
- package/src/team.ts +123 -0
- package/src/tunnel.ts +126 -0
- package/src/types.d.ts +50 -0
- package/src/vt-tracker.ts +188 -0
- package/src/workspace-head.ts +144 -0
- package/src/workspace.ts +153 -0
- package/src/ws-handler.ts +1526 -0
- package/start.ps1 +83 -0
- package/tests/adapters.test.js +171 -0
- package/tests/auth.test.js +243 -0
- package/tests/codex-adapter.test.js +535 -0
- package/tests/durable-stream.test.js +153 -0
- package/tests/e2e/app.spec.js +530 -0
- package/tests/e2ee.test.js +325 -0
- package/tests/message-buffer.test.js +245 -0
- package/tests/message-routing.test.js +305 -0
- package/tests/pty-daemon.test.js +346 -0
- package/tests/push.test.js +281 -0
- package/tests/renderers.test.js +391 -0
- package/tests/search-shell.test.js +499 -0
- package/tests/server.test.js +882 -0
- package/tests/service.test.js +267 -0
- package/tests/store.test.js +369 -0
- package/tests/tunnel.test.js +67 -0
- package/tests/workspace-head.test.js +116 -0
- package/tests/workspace.test.js +417 -0
- package/tsconfig.backend.json +11 -0
- package/tsconfig.json +15 -0
- package/tui/client/client_test.go +125 -0
- package/tui/client/connection.go +342 -0
- package/tui/client/host_manager.go +141 -0
- package/tui/config/cache.go +81 -0
- package/tui/config/config.go +53 -0
- package/tui/config/config_test.go +89 -0
- package/tui/go.mod +32 -0
- package/tui/go.sum +50 -0
- package/tui/main.go +261 -0
- package/tui/tests/integration_test.go +283 -0
- package/tui/ui/model.go +310 -0
- package/vitest.config.js +10 -0
|
@@ -0,0 +1,487 @@
|
|
|
1
|
+
package remux.protocol
|
|
2
|
+
|
|
3
|
+
import java.io.File
|
|
4
|
+
|
|
5
|
+
fun main(args: Array<String>) {
|
|
6
|
+
require(args.isNotEmpty()) { "expected fixture file paths" }
|
|
7
|
+
val decoded = mutableListOf<String>()
|
|
8
|
+
|
|
9
|
+
for (fixturePath in args) {
|
|
10
|
+
val fileName = File(fixturePath).name
|
|
11
|
+
val root = SimpleJsonParser(File(fixturePath).readText()).parseValue().asObject()
|
|
12
|
+
|
|
13
|
+
when (fileName) {
|
|
14
|
+
"auth.legacy.json" -> decodeLegacyAuth(root)
|
|
15
|
+
"auth.envelope.json" -> decodeAuthEnvelope(root)
|
|
16
|
+
"auth_ok.legacy.json" -> decodeLegacyAuthOk(root)
|
|
17
|
+
"auth_ok.envelope.json" -> decodeAuthOkEnvelope(root)
|
|
18
|
+
"auth_error.legacy.json" -> decodeLegacyAuthError(root)
|
|
19
|
+
"auth_error.envelope.json" -> decodeAuthErrorEnvelope(root)
|
|
20
|
+
"inspect_content.legacy.json" -> decodeLegacyInspectContent(root)
|
|
21
|
+
"inspect_content.envelope.json" -> decodeInspectContentEnvelope(root)
|
|
22
|
+
"error.legacy.json" -> decodeLegacyError(root)
|
|
23
|
+
"pong.legacy.json" -> decodeLegacyPong(root)
|
|
24
|
+
"workspace_state.legacy.json" -> decodeLegacyWorkspaceState(root)
|
|
25
|
+
"workspace_state.envelope.json" -> decodeWorkspaceStateEnvelope(root)
|
|
26
|
+
"request_inspect.legacy.json" -> decodeLegacyInspectRequest(root)
|
|
27
|
+
"request_inspect.envelope.json" -> decodeInspectRequestEnvelope(root)
|
|
28
|
+
"inspect_snapshot.legacy.json" -> decodeLegacyInspectSnapshot(root)
|
|
29
|
+
"inspect_snapshot.envelope.json" -> decodeInspectSnapshotEnvelope(root)
|
|
30
|
+
"bandwidth_stats.legacy.json" -> decodeLegacyBandwidthStats(root)
|
|
31
|
+
"bandwidth_stats.envelope.json" -> decodeBandwidthStatsEnvelope(root)
|
|
32
|
+
else -> error("unknown fixture $fileName")
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
decoded += fileName
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
println(decoded.joinToString(","))
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
private fun decodeLegacyAuth(obj: Map<String, JsonValue>): LegacyAuth = LegacyAuth(
|
|
42
|
+
type = obj.requireString("type"),
|
|
43
|
+
token = obj.requireString("token"),
|
|
44
|
+
password = obj.optionalString("password"),
|
|
45
|
+
cols = obj.optionalInt("cols"),
|
|
46
|
+
rows = obj.optionalInt("rows"),
|
|
47
|
+
capabilities = obj.optionalObject("capabilities")?.let(::decodeProtocolCapabilities),
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
private fun decodeAuthEnvelope(obj: Map<String, JsonValue>): RemuxEnvelope<AuthPayload> = RemuxEnvelope(
|
|
51
|
+
domain = obj.requireString("domain"),
|
|
52
|
+
type = obj.requireString("type"),
|
|
53
|
+
version = obj.requireInt("version"),
|
|
54
|
+
requestId = obj.optionalString("requestId"),
|
|
55
|
+
emittedAt = obj.requireString("emittedAt"),
|
|
56
|
+
source = obj.requireString("source"),
|
|
57
|
+
payload = decodeAuthPayload(obj.requireObject("payload")),
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
private fun decodeLegacyAuthOk(obj: Map<String, JsonValue>): LegacyAuthOk = LegacyAuthOk(
|
|
61
|
+
type = obj.requireString("type"),
|
|
62
|
+
capabilities = obj.requireObject("capabilities").let(::decodeProtocolCapabilities),
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
private fun decodeAuthOkEnvelope(obj: Map<String, JsonValue>): RemuxEnvelope<AuthOkPayload> = RemuxEnvelope(
|
|
66
|
+
domain = obj.requireString("domain"),
|
|
67
|
+
type = obj.requireString("type"),
|
|
68
|
+
version = obj.requireInt("version"),
|
|
69
|
+
requestId = obj.optionalString("requestId"),
|
|
70
|
+
emittedAt = obj.requireString("emittedAt"),
|
|
71
|
+
source = obj.requireString("source"),
|
|
72
|
+
payload = AuthOkPayload(
|
|
73
|
+
capabilities = obj.requireObject("payload").requireObject("capabilities").let(::decodeProtocolCapabilities),
|
|
74
|
+
),
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
private fun decodeLegacyAuthError(obj: Map<String, JsonValue>): LegacyAuthError = LegacyAuthError(
|
|
78
|
+
type = obj.requireString("type"),
|
|
79
|
+
reason = obj.requireString("reason"),
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
private fun decodeAuthErrorEnvelope(obj: Map<String, JsonValue>): RemuxEnvelope<AuthErrorPayload> = RemuxEnvelope(
|
|
83
|
+
domain = obj.requireString("domain"),
|
|
84
|
+
type = obj.requireString("type"),
|
|
85
|
+
version = obj.requireInt("version"),
|
|
86
|
+
requestId = obj.optionalString("requestId"),
|
|
87
|
+
emittedAt = obj.requireString("emittedAt"),
|
|
88
|
+
source = obj.requireString("source"),
|
|
89
|
+
payload = AuthErrorPayload(
|
|
90
|
+
reason = obj.requireObject("payload").requireString("reason"),
|
|
91
|
+
),
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
private fun decodeLegacyInspectContent(obj: Map<String, JsonValue>): LegacyInspectContent = LegacyInspectContent(
|
|
95
|
+
type = obj.requireString("type"),
|
|
96
|
+
content = obj.requireString("content"),
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
private fun decodeInspectContentEnvelope(obj: Map<String, JsonValue>): RemuxEnvelope<InspectContentPayload> = RemuxEnvelope(
|
|
100
|
+
domain = obj.requireString("domain"),
|
|
101
|
+
type = obj.requireString("type"),
|
|
102
|
+
version = obj.requireInt("version"),
|
|
103
|
+
requestId = obj.optionalString("requestId"),
|
|
104
|
+
emittedAt = obj.requireString("emittedAt"),
|
|
105
|
+
source = obj.requireString("source"),
|
|
106
|
+
payload = InspectContentPayload(
|
|
107
|
+
content = obj.requireObject("payload").requireString("content"),
|
|
108
|
+
),
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
private fun decodeLegacyError(obj: Map<String, JsonValue>): LegacyErrorMessage = LegacyErrorMessage(
|
|
112
|
+
type = obj.requireString("type"),
|
|
113
|
+
code = obj.optionalInt("code"),
|
|
114
|
+
message = obj.requireString("message"),
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
private fun decodeLegacyPong(obj: Map<String, JsonValue>): LegacyPong = LegacyPong(
|
|
118
|
+
type = obj.requireString("type"),
|
|
119
|
+
timestamp = obj.requireNumber("timestamp"),
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
private fun decodeLegacyWorkspaceState(obj: Map<String, JsonValue>): LegacyWorkspaceState = LegacyWorkspaceState(
|
|
123
|
+
type = obj.requireString("type"),
|
|
124
|
+
session = obj.requireString("session"),
|
|
125
|
+
tabs = obj.requireList("tabs").map { decodeWorkspaceTab(it.asObject()) },
|
|
126
|
+
activeTabIndex = obj.requireInt("activeTabIndex"),
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
private fun decodeWorkspaceStateEnvelope(obj: Map<String, JsonValue>): RemuxEnvelope<WorkspaceState> = RemuxEnvelope(
|
|
130
|
+
domain = obj.requireString("domain"),
|
|
131
|
+
type = obj.requireString("type"),
|
|
132
|
+
version = obj.requireInt("version"),
|
|
133
|
+
requestId = obj.optionalString("requestId"),
|
|
134
|
+
emittedAt = obj.requireString("emittedAt"),
|
|
135
|
+
source = obj.requireString("source"),
|
|
136
|
+
payload = decodeWorkspaceState(obj.requireObject("payload")),
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
private fun decodeLegacyInspectRequest(obj: Map<String, JsonValue>): LegacyInspectRequest = LegacyInspectRequest(
|
|
140
|
+
type = obj.requireString("type"),
|
|
141
|
+
scope = obj.requireString("scope"),
|
|
142
|
+
paneId = obj.optionalString("paneId"),
|
|
143
|
+
tabIndex = obj.optionalInt("tabIndex"),
|
|
144
|
+
cursor = obj.optionalString("cursor"),
|
|
145
|
+
query = obj.optionalString("query"),
|
|
146
|
+
limit = obj.optionalInt("limit"),
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
private fun decodeInspectRequestEnvelope(obj: Map<String, JsonValue>): RemuxEnvelope<InspectRequest> = RemuxEnvelope(
|
|
150
|
+
domain = obj.requireString("domain"),
|
|
151
|
+
type = obj.requireString("type"),
|
|
152
|
+
version = obj.requireInt("version"),
|
|
153
|
+
requestId = obj.optionalString("requestId"),
|
|
154
|
+
emittedAt = obj.requireString("emittedAt"),
|
|
155
|
+
source = obj.requireString("source"),
|
|
156
|
+
payload = decodeInspectRequest(obj.requireObject("payload")),
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
private fun decodeLegacyInspectSnapshot(obj: Map<String, JsonValue>): LegacyInspectSnapshot = LegacyInspectSnapshot(
|
|
160
|
+
type = obj.requireString("type"),
|
|
161
|
+
descriptor = decodeInspectDescriptor(obj.requireObject("descriptor")),
|
|
162
|
+
items = obj.requireList("items").map { decodeInspectItem(it.asObject()) },
|
|
163
|
+
cursor = obj.optionalString("cursor"),
|
|
164
|
+
truncated = obj.requireBoolean("truncated"),
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
private fun decodeInspectSnapshotEnvelope(obj: Map<String, JsonValue>): RemuxEnvelope<InspectSnapshot> = RemuxEnvelope(
|
|
168
|
+
domain = obj.requireString("domain"),
|
|
169
|
+
type = obj.requireString("type"),
|
|
170
|
+
version = obj.requireInt("version"),
|
|
171
|
+
requestId = obj.optionalString("requestId"),
|
|
172
|
+
emittedAt = obj.requireString("emittedAt"),
|
|
173
|
+
source = obj.requireString("source"),
|
|
174
|
+
payload = decodeInspectSnapshot(obj.requireObject("payload")),
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
private fun decodeLegacyBandwidthStats(obj: Map<String, JsonValue>): LegacyBandwidthStats = LegacyBandwidthStats(
|
|
178
|
+
type = obj.requireString("type"),
|
|
179
|
+
stats = decodeBandwidthStats(obj.requireObject("stats")),
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
private fun decodeBandwidthStatsEnvelope(obj: Map<String, JsonValue>): RemuxEnvelope<BandwidthStatsPayload> = RemuxEnvelope(
|
|
183
|
+
domain = obj.requireString("domain"),
|
|
184
|
+
type = obj.requireString("type"),
|
|
185
|
+
version = obj.requireInt("version"),
|
|
186
|
+
requestId = obj.optionalString("requestId"),
|
|
187
|
+
emittedAt = obj.requireString("emittedAt"),
|
|
188
|
+
source = obj.requireString("source"),
|
|
189
|
+
payload = BandwidthStatsPayload(
|
|
190
|
+
stats = decodeBandwidthStats(obj.requireObject("payload").requireObject("stats")),
|
|
191
|
+
),
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
private fun decodeProtocolCapabilities(obj: Map<String, JsonValue>): ProtocolCapabilities = ProtocolCapabilities(
|
|
195
|
+
envelope = obj.requireBoolean("envelope"),
|
|
196
|
+
inspectV2 = obj.requireBoolean("inspectV2"),
|
|
197
|
+
deviceTrust = obj.requireBoolean("deviceTrust"),
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
private fun decodeAuthPayload(obj: Map<String, JsonValue>): AuthPayload = AuthPayload(
|
|
201
|
+
token = obj.requireString("token"),
|
|
202
|
+
password = obj.optionalString("password"),
|
|
203
|
+
cols = obj.optionalInt("cols"),
|
|
204
|
+
rows = obj.optionalInt("rows"),
|
|
205
|
+
capabilities = obj.optionalObject("capabilities")?.let(::decodeProtocolCapabilities),
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
private fun decodeWorkspaceState(obj: Map<String, JsonValue>): WorkspaceState = WorkspaceState(
|
|
209
|
+
session = obj.requireString("session"),
|
|
210
|
+
tabs = obj.requireList("tabs").map { decodeWorkspaceTab(it.asObject()) },
|
|
211
|
+
activeTabIndex = obj.requireInt("activeTabIndex"),
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
private fun decodeWorkspaceTab(obj: Map<String, JsonValue>): WorkspaceTab = WorkspaceTab(
|
|
215
|
+
index = obj.requireInt("index"),
|
|
216
|
+
name = obj.requireString("name"),
|
|
217
|
+
active = obj.requireBoolean("active"),
|
|
218
|
+
isFullscreen = obj.requireBoolean("isFullscreen"),
|
|
219
|
+
hasBell = obj.requireBoolean("hasBell"),
|
|
220
|
+
panes = obj.requireList("panes").map { decodeWorkspacePane(it.asObject()) },
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
private fun decodeWorkspacePane(obj: Map<String, JsonValue>): WorkspacePane = WorkspacePane(
|
|
224
|
+
id = obj.requireString("id"),
|
|
225
|
+
focused = obj.requireBoolean("focused"),
|
|
226
|
+
title = obj.requireString("title"),
|
|
227
|
+
command = obj.optionalString("command"),
|
|
228
|
+
cwd = obj.optionalString("cwd"),
|
|
229
|
+
rows = obj.requireInt("rows"),
|
|
230
|
+
cols = obj.requireInt("cols"),
|
|
231
|
+
x = obj.requireInt("x"),
|
|
232
|
+
y = obj.requireInt("y"),
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
private fun decodeInspectRequest(obj: Map<String, JsonValue>): InspectRequest = InspectRequest(
|
|
236
|
+
scope = obj.requireString("scope"),
|
|
237
|
+
paneId = obj.optionalString("paneId"),
|
|
238
|
+
tabIndex = obj.optionalInt("tabIndex"),
|
|
239
|
+
cursor = obj.optionalString("cursor"),
|
|
240
|
+
query = obj.optionalString("query"),
|
|
241
|
+
limit = obj.optionalInt("limit"),
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
private fun decodeInspectSnapshot(obj: Map<String, JsonValue>): InspectSnapshot = InspectSnapshot(
|
|
245
|
+
descriptor = decodeInspectDescriptor(obj.requireObject("descriptor")),
|
|
246
|
+
items = obj.requireList("items").map { decodeInspectItem(it.asObject()) },
|
|
247
|
+
cursor = obj.optionalString("cursor"),
|
|
248
|
+
truncated = obj.requireBoolean("truncated"),
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
private fun decodeInspectDescriptor(obj: Map<String, JsonValue>): InspectDescriptor = InspectDescriptor(
|
|
252
|
+
scope = obj.requireString("scope"),
|
|
253
|
+
source = obj.requireString("source"),
|
|
254
|
+
precision = obj.requireString("precision"),
|
|
255
|
+
staleness = obj.requireString("staleness"),
|
|
256
|
+
capturedAt = obj.requireString("capturedAt"),
|
|
257
|
+
paneId = obj.optionalString("paneId"),
|
|
258
|
+
tabIndex = obj.optionalInt("tabIndex"),
|
|
259
|
+
totalItems = obj.optionalInt("totalItems"),
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
private fun decodeInspectItem(obj: Map<String, JsonValue>): InspectItem = InspectItem(
|
|
263
|
+
type = obj.requireString("type"),
|
|
264
|
+
content = obj.requireString("content"),
|
|
265
|
+
lineNumber = obj.optionalInt("lineNumber"),
|
|
266
|
+
timestamp = obj.requireString("timestamp"),
|
|
267
|
+
paneId = obj.optionalString("paneId"),
|
|
268
|
+
highlights = obj.optionalList("highlights")?.map { decodeInspectHighlight(it.asObject()) },
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
private fun decodeInspectHighlight(obj: Map<String, JsonValue>): InspectHighlight = InspectHighlight(
|
|
272
|
+
start = obj.requireInt("start"),
|
|
273
|
+
end = obj.requireInt("end"),
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
private fun decodeBandwidthStats(obj: Map<String, JsonValue>): BandwidthStats = BandwidthStats(
|
|
277
|
+
rawBytesPerSec = obj.requireNumber("rawBytesPerSec"),
|
|
278
|
+
compressedBytesPerSec = obj.requireNumber("compressedBytesPerSec"),
|
|
279
|
+
savedPercent = obj.requireNumber("savedPercent"),
|
|
280
|
+
fullSnapshotsSent = obj.requireInt("fullSnapshotsSent"),
|
|
281
|
+
diffUpdatesSent = obj.requireInt("diffUpdatesSent"),
|
|
282
|
+
avgChangedRowsPerDiff = obj.requireNumber("avgChangedRowsPerDiff"),
|
|
283
|
+
totalRawBytes = obj.requireInt("totalRawBytes"),
|
|
284
|
+
totalCompressedBytes = obj.requireInt("totalCompressedBytes"),
|
|
285
|
+
totalSavedBytes = obj.requireInt("totalSavedBytes"),
|
|
286
|
+
rttMs = obj.optionalInt("rttMs"),
|
|
287
|
+
protocolName = obj.requireString("protocol"),
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
sealed class JsonValue {
|
|
291
|
+
data class JsonString(val value: String) : JsonValue()
|
|
292
|
+
data class JsonNumber(val value: Double) : JsonValue()
|
|
293
|
+
data class JsonBoolean(val value: Boolean) : JsonValue()
|
|
294
|
+
data class JsonObject(val value: Map<String, JsonValue>) : JsonValue()
|
|
295
|
+
data class JsonArray(val value: List<JsonValue>) : JsonValue()
|
|
296
|
+
object JsonNull : JsonValue()
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
private fun JsonValue.asObject(): Map<String, JsonValue> = when (this) {
|
|
300
|
+
is JsonValue.JsonObject -> value
|
|
301
|
+
else -> error("expected object")
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
private fun Map<String, JsonValue>.requireValue(key: String): JsonValue = this[key] ?: error("missing $key")
|
|
305
|
+
private fun Map<String, JsonValue>.requireObject(key: String): Map<String, JsonValue> = requireValue(key).asObject()
|
|
306
|
+
private fun Map<String, JsonValue>.optionalObject(key: String): Map<String, JsonValue>? = when (val value = this[key]) {
|
|
307
|
+
null, JsonValue.JsonNull -> null
|
|
308
|
+
is JsonValue.JsonObject -> value.value
|
|
309
|
+
else -> error("expected object for $key")
|
|
310
|
+
}
|
|
311
|
+
private fun Map<String, JsonValue>.requireString(key: String): String = when (val value = requireValue(key)) {
|
|
312
|
+
is JsonValue.JsonString -> value.value
|
|
313
|
+
else -> error("expected string for $key")
|
|
314
|
+
}
|
|
315
|
+
private fun Map<String, JsonValue>.optionalString(key: String): String? = when (val value = this[key]) {
|
|
316
|
+
null, JsonValue.JsonNull -> null
|
|
317
|
+
is JsonValue.JsonString -> value.value
|
|
318
|
+
else -> error("expected string for $key")
|
|
319
|
+
}
|
|
320
|
+
private fun Map<String, JsonValue>.requireBoolean(key: String): Boolean = when (val value = requireValue(key)) {
|
|
321
|
+
is JsonValue.JsonBoolean -> value.value
|
|
322
|
+
else -> error("expected boolean for $key")
|
|
323
|
+
}
|
|
324
|
+
private fun Map<String, JsonValue>.requireNumber(key: String): Double = when (val value = requireValue(key)) {
|
|
325
|
+
is JsonValue.JsonNumber -> value.value
|
|
326
|
+
else -> error("expected number for $key")
|
|
327
|
+
}
|
|
328
|
+
private fun Map<String, JsonValue>.requireInt(key: String): Int = requireNumber(key).toInt()
|
|
329
|
+
private fun Map<String, JsonValue>.optionalInt(key: String): Int? = when (val value = this[key]) {
|
|
330
|
+
null, JsonValue.JsonNull -> null
|
|
331
|
+
is JsonValue.JsonNumber -> value.value.toInt()
|
|
332
|
+
else -> error("expected number for $key")
|
|
333
|
+
}
|
|
334
|
+
private fun Map<String, JsonValue>.requireList(key: String): List<JsonValue> = when (val value = requireValue(key)) {
|
|
335
|
+
is JsonValue.JsonArray -> value.value
|
|
336
|
+
else -> error("expected array for $key")
|
|
337
|
+
}
|
|
338
|
+
private fun Map<String, JsonValue>.optionalList(key: String): List<JsonValue>? = when (val value = this[key]) {
|
|
339
|
+
null, JsonValue.JsonNull -> null
|
|
340
|
+
is JsonValue.JsonArray -> value.value
|
|
341
|
+
else -> error("expected array for $key")
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
private class SimpleJsonParser(private val input: String) {
|
|
345
|
+
private var index = 0
|
|
346
|
+
|
|
347
|
+
fun parseValue(): JsonValue {
|
|
348
|
+
skipWhitespace()
|
|
349
|
+
return when (peek()) {
|
|
350
|
+
'"' -> JsonValue.JsonString(parseString())
|
|
351
|
+
'{' -> parseObject()
|
|
352
|
+
'[' -> parseArray()
|
|
353
|
+
't' -> {
|
|
354
|
+
expectLiteral("true")
|
|
355
|
+
JsonValue.JsonBoolean(true)
|
|
356
|
+
}
|
|
357
|
+
'f' -> {
|
|
358
|
+
expectLiteral("false")
|
|
359
|
+
JsonValue.JsonBoolean(false)
|
|
360
|
+
}
|
|
361
|
+
'n' -> {
|
|
362
|
+
expectLiteral("null")
|
|
363
|
+
JsonValue.JsonNull
|
|
364
|
+
}
|
|
365
|
+
else -> JsonValue.JsonNumber(parseNumber())
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
private fun parseObject(): JsonValue.JsonObject {
|
|
370
|
+
expect('{')
|
|
371
|
+
skipWhitespace()
|
|
372
|
+
if (peek() == '}') {
|
|
373
|
+
index++
|
|
374
|
+
return JsonValue.JsonObject(emptyMap())
|
|
375
|
+
}
|
|
376
|
+
val map = linkedMapOf<String, JsonValue>()
|
|
377
|
+
while (true) {
|
|
378
|
+
val key = parseString()
|
|
379
|
+
skipWhitespace()
|
|
380
|
+
expect(':')
|
|
381
|
+
val value = parseValue()
|
|
382
|
+
map[key] = value
|
|
383
|
+
skipWhitespace()
|
|
384
|
+
when (peek()) {
|
|
385
|
+
',' -> {
|
|
386
|
+
index++
|
|
387
|
+
skipWhitespace()
|
|
388
|
+
}
|
|
389
|
+
'}' -> {
|
|
390
|
+
index++
|
|
391
|
+
return JsonValue.JsonObject(map)
|
|
392
|
+
}
|
|
393
|
+
else -> error("expected ',' or '}' at index $index")
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
private fun parseArray(): JsonValue.JsonArray {
|
|
399
|
+
expect('[')
|
|
400
|
+
skipWhitespace()
|
|
401
|
+
if (peek() == ']') {
|
|
402
|
+
index++
|
|
403
|
+
return JsonValue.JsonArray(emptyList())
|
|
404
|
+
}
|
|
405
|
+
val items = mutableListOf<JsonValue>()
|
|
406
|
+
while (true) {
|
|
407
|
+
items += parseValue()
|
|
408
|
+
skipWhitespace()
|
|
409
|
+
when (peek()) {
|
|
410
|
+
',' -> {
|
|
411
|
+
index++
|
|
412
|
+
skipWhitespace()
|
|
413
|
+
}
|
|
414
|
+
']' -> {
|
|
415
|
+
index++
|
|
416
|
+
return JsonValue.JsonArray(items)
|
|
417
|
+
}
|
|
418
|
+
else -> error("expected ',' or ']' at index $index")
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
private fun parseString(): String {
|
|
424
|
+
expect('"')
|
|
425
|
+
val builder = StringBuilder()
|
|
426
|
+
while (true) {
|
|
427
|
+
require(index < input.length) { "unterminated string" }
|
|
428
|
+
val current = input[index++]
|
|
429
|
+
when (current) {
|
|
430
|
+
'"' -> return builder.toString()
|
|
431
|
+
'\\' -> {
|
|
432
|
+
require(index < input.length) { "unterminated escape" }
|
|
433
|
+
val escaped = input[index++]
|
|
434
|
+
builder.append(
|
|
435
|
+
when (escaped) {
|
|
436
|
+
'"', '\\', '/' -> escaped
|
|
437
|
+
'b' -> '\b'
|
|
438
|
+
'f' -> '\u000C'
|
|
439
|
+
'n' -> '\n'
|
|
440
|
+
'r' -> '\r'
|
|
441
|
+
't' -> '\t'
|
|
442
|
+
'u' -> parseUnicodeEscape()
|
|
443
|
+
else -> error("unsupported escape \\$escaped")
|
|
444
|
+
},
|
|
445
|
+
)
|
|
446
|
+
}
|
|
447
|
+
else -> builder.append(current)
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
private fun parseUnicodeEscape(): Char {
|
|
453
|
+
require(index + 4 <= input.length) { "invalid unicode escape" }
|
|
454
|
+
val hex = input.substring(index, index + 4)
|
|
455
|
+
index += 4
|
|
456
|
+
return hex.toInt(16).toChar()
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
private fun parseNumber(): Double {
|
|
460
|
+
val start = index
|
|
461
|
+
while (index < input.length && input[index] in "-+0123456789.eE") {
|
|
462
|
+
index++
|
|
463
|
+
}
|
|
464
|
+
return input.substring(start, index).toDouble()
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
private fun expect(expected: Char) {
|
|
468
|
+
require(peek() == expected) { "expected '$expected' at index $index" }
|
|
469
|
+
index++
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
private fun expectLiteral(expected: String) {
|
|
473
|
+
require(input.startsWith(expected, index)) { "expected $expected at index $index" }
|
|
474
|
+
index += expected.length
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
private fun skipWhitespace() {
|
|
478
|
+
while (index < input.length && input[index].isWhitespace()) {
|
|
479
|
+
index++
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
private fun peek(): Char {
|
|
484
|
+
require(index < input.length) { "unexpected end of input" }
|
|
485
|
+
return input[index]
|
|
486
|
+
}
|
|
487
|
+
}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
package remux.protocol
|
|
2
|
+
|
|
3
|
+
data class ProtocolCapabilities(
|
|
4
|
+
val envelope: Boolean,
|
|
5
|
+
val inspectV2: Boolean,
|
|
6
|
+
val deviceTrust: Boolean,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
data class AuthPayload(
|
|
10
|
+
val token: String,
|
|
11
|
+
val password: String?,
|
|
12
|
+
val cols: Int?,
|
|
13
|
+
val rows: Int?,
|
|
14
|
+
val capabilities: ProtocolCapabilities?,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
data class AuthOkPayload(
|
|
18
|
+
val capabilities: ProtocolCapabilities,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
data class AuthErrorPayload(
|
|
22
|
+
val reason: String,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
data class InspectContentPayload(
|
|
26
|
+
val content: String,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
data class RemuxEnvelope<T>(
|
|
30
|
+
val domain: String,
|
|
31
|
+
val type: String,
|
|
32
|
+
val version: Int,
|
|
33
|
+
val requestId: String?,
|
|
34
|
+
val emittedAt: String,
|
|
35
|
+
val source: String,
|
|
36
|
+
val payload: T,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
data class WorkspacePane(
|
|
40
|
+
val id: String,
|
|
41
|
+
val focused: Boolean,
|
|
42
|
+
val title: String,
|
|
43
|
+
val command: String?,
|
|
44
|
+
val cwd: String?,
|
|
45
|
+
val rows: Int,
|
|
46
|
+
val cols: Int,
|
|
47
|
+
val x: Int,
|
|
48
|
+
val y: Int,
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
data class WorkspaceTab(
|
|
52
|
+
val index: Int,
|
|
53
|
+
val name: String,
|
|
54
|
+
val active: Boolean,
|
|
55
|
+
val isFullscreen: Boolean,
|
|
56
|
+
val hasBell: Boolean,
|
|
57
|
+
val panes: List<WorkspacePane>,
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
data class WorkspaceState(
|
|
61
|
+
val session: String,
|
|
62
|
+
val tabs: List<WorkspaceTab>,
|
|
63
|
+
val activeTabIndex: Int,
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
data class InspectHighlight(
|
|
67
|
+
val start: Int,
|
|
68
|
+
val end: Int,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
data class InspectDescriptor(
|
|
72
|
+
val scope: String,
|
|
73
|
+
val source: String,
|
|
74
|
+
val precision: String,
|
|
75
|
+
val staleness: String,
|
|
76
|
+
val capturedAt: String,
|
|
77
|
+
val paneId: String?,
|
|
78
|
+
val tabIndex: Int?,
|
|
79
|
+
val totalItems: Int?,
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
data class InspectItem(
|
|
83
|
+
val type: String,
|
|
84
|
+
val content: String,
|
|
85
|
+
val lineNumber: Int?,
|
|
86
|
+
val timestamp: String,
|
|
87
|
+
val paneId: String?,
|
|
88
|
+
val highlights: List<InspectHighlight>?,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
data class InspectSnapshot(
|
|
92
|
+
val descriptor: InspectDescriptor,
|
|
93
|
+
val items: List<InspectItem>,
|
|
94
|
+
val cursor: String?,
|
|
95
|
+
val truncated: Boolean,
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
data class InspectRequest(
|
|
99
|
+
val scope: String,
|
|
100
|
+
val paneId: String?,
|
|
101
|
+
val tabIndex: Int?,
|
|
102
|
+
val cursor: String?,
|
|
103
|
+
val query: String?,
|
|
104
|
+
val limit: Int?,
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
data class BandwidthStats(
|
|
108
|
+
val rawBytesPerSec: Double,
|
|
109
|
+
val compressedBytesPerSec: Double,
|
|
110
|
+
val savedPercent: Double,
|
|
111
|
+
val fullSnapshotsSent: Int,
|
|
112
|
+
val diffUpdatesSent: Int,
|
|
113
|
+
val avgChangedRowsPerDiff: Double,
|
|
114
|
+
val totalRawBytes: Int,
|
|
115
|
+
val totalCompressedBytes: Int,
|
|
116
|
+
val totalSavedBytes: Int,
|
|
117
|
+
val rttMs: Int?,
|
|
118
|
+
val protocolName: String,
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
data class BandwidthStatsPayload(
|
|
122
|
+
val stats: BandwidthStats,
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
data class LegacyAuthOk(
|
|
126
|
+
val type: String,
|
|
127
|
+
val capabilities: ProtocolCapabilities,
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
data class LegacyAuth(
|
|
131
|
+
val type: String,
|
|
132
|
+
val token: String,
|
|
133
|
+
val password: String?,
|
|
134
|
+
val cols: Int?,
|
|
135
|
+
val rows: Int?,
|
|
136
|
+
val capabilities: ProtocolCapabilities?,
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
data class LegacyAuthError(
|
|
140
|
+
val type: String,
|
|
141
|
+
val reason: String,
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
data class LegacyErrorMessage(
|
|
145
|
+
val type: String,
|
|
146
|
+
val code: Int?,
|
|
147
|
+
val message: String,
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
data class LegacyPong(
|
|
151
|
+
val type: String,
|
|
152
|
+
val timestamp: Double,
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
data class LegacyWorkspaceState(
|
|
156
|
+
val type: String,
|
|
157
|
+
val session: String,
|
|
158
|
+
val tabs: List<WorkspaceTab>,
|
|
159
|
+
val activeTabIndex: Int,
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
data class LegacyInspectRequest(
|
|
163
|
+
val type: String,
|
|
164
|
+
val scope: String,
|
|
165
|
+
val paneId: String?,
|
|
166
|
+
val tabIndex: Int?,
|
|
167
|
+
val cursor: String?,
|
|
168
|
+
val query: String?,
|
|
169
|
+
val limit: Int?,
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
data class LegacyInspectSnapshot(
|
|
173
|
+
val type: String,
|
|
174
|
+
val descriptor: InspectDescriptor,
|
|
175
|
+
val items: List<InspectItem>,
|
|
176
|
+
val cursor: String?,
|
|
177
|
+
val truncated: Boolean,
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
data class LegacyBandwidthStats(
|
|
181
|
+
val type: String,
|
|
182
|
+
val stats: BandwidthStats,
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
data class LegacyInspectContent(
|
|
186
|
+
val type: String,
|
|
187
|
+
val content: String,
|
|
188
|
+
)
|