wire protocol is generated now instead of being hard coded with versioning for commands.
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
# Wire protocol contract
|
||||
|
||||
`wire-contract.json` is the canonical catalog for the MessagePack protocol
|
||||
shared by the server and agent. Generated TypeScript and Go artifacts must not
|
||||
be edited directly.
|
||||
|
||||
Generate artifacts from the repository root:
|
||||
|
||||
```text
|
||||
bun scripts/generate-wire-protocol.ts
|
||||
```
|
||||
|
||||
Verify that checked-in artifacts match the contract:
|
||||
|
||||
```text
|
||||
bun scripts/generate-wire-protocol.ts --check
|
||||
```
|
||||
|
||||
Protocol version 1 follows additive compatibility:
|
||||
|
||||
- Existing message and field meanings may not change.
|
||||
- New optional fields, message types, and commands may be added.
|
||||
- Fields may not become required for peers that advertise an older or absent
|
||||
protocol version.
|
||||
- Removing or redefining a wire value requires a new protocol version.
|
||||
|
||||
Agents that predate protocol negotiation omit `protocolVersion`; the server
|
||||
treats them as protocol version 1.
|
||||
|
||||
## Command versions
|
||||
|
||||
Every command supports version 1 by default. A breaking change must be added
|
||||
under `commandVersioning.overrides`; an existing command version must never be
|
||||
edited to introduce a breaking payload or semantic change.
|
||||
|
||||
An override declares the latest contiguous version and documents every
|
||||
breaking transition:
|
||||
|
||||
```json
|
||||
{
|
||||
"desktop_start": {
|
||||
"latestVersion": 2,
|
||||
"changes": {
|
||||
"2": {
|
||||
"breaking": true,
|
||||
"summary": "Replace numeric quality with a named profile",
|
||||
"migration": "Map quality 1-40 to low, 41-80 to balanced, and 81-100 to high"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- Adding an optional field with an unchanged meaning does not require a bump.
|
||||
- Removing or renaming a field requires a new command version.
|
||||
- Changing a field type, units, default, valid range, or meaning requires a
|
||||
new command version.
|
||||
- Changing result semantics requires a new command version.
|
||||
- Versions are contiguous and old handlers remain available while supported.
|
||||
- A new version requires migration text and compatibility fixtures.
|
||||
- A command with more than one version may not be encoded implicitly; the
|
||||
server must select a mutually supported version for the connected agent.
|
||||
|
||||
At target-aware server boundaries, construct envelopes with
|
||||
`versionCommandForClient`. It selects the highest shared version and throws
|
||||
before transmission when the agent omitted the command or has no overlapping
|
||||
range. Generic legacy send sites remain safe while all declared commands have
|
||||
exactly one version; the encoder refuses implicit encoding as soon as a command
|
||||
becomes multi-version.
|
||||
@@ -0,0 +1,217 @@
|
||||
{
|
||||
"$schema": "./wire-contract.schema.json",
|
||||
"schemaVersion": 1,
|
||||
"protocolVersion": 1,
|
||||
"encoding": "messagepack",
|
||||
"compatibility": "additive",
|
||||
"commandVersioning": {
|
||||
"defaultVersion": 1,
|
||||
"overrides": {}
|
||||
},
|
||||
"serverToAgentMessageTypes": [
|
||||
"enrollment_challenge",
|
||||
"enrollment_status",
|
||||
"hello_ack",
|
||||
"ping",
|
||||
"pong",
|
||||
"command",
|
||||
"command_abort",
|
||||
"frame_ack",
|
||||
"plugin_event",
|
||||
"notification_config"
|
||||
],
|
||||
"agentToServerMessageTypes": [
|
||||
"hello",
|
||||
"ping",
|
||||
"pong",
|
||||
"frame",
|
||||
"status",
|
||||
"console_output",
|
||||
"file_list_result",
|
||||
"file_download",
|
||||
"file_upload_result",
|
||||
"file_read_result",
|
||||
"file_search_result",
|
||||
"file_icon_result",
|
||||
"file_thumb_result",
|
||||
"file_dirsize_result",
|
||||
"file_peek_result",
|
||||
"file_hash_result",
|
||||
"command_result",
|
||||
"desktop_encoder_capabilities",
|
||||
"desktop_stream_stats",
|
||||
"desktop_cursor",
|
||||
"client_logs_result",
|
||||
"screenshot_result",
|
||||
"command_progress",
|
||||
"process_list_result",
|
||||
"process_icon_result",
|
||||
"script_result",
|
||||
"plugin_event",
|
||||
"notification",
|
||||
"keylog_file_list",
|
||||
"keylog_file_content",
|
||||
"keylog_clear_result",
|
||||
"keylog_delete_result",
|
||||
"keylog_permission_result",
|
||||
"voice_uplink",
|
||||
"desktop_audio_uplink",
|
||||
"webcam_devices",
|
||||
"backstage_clone_progress",
|
||||
"backstage_lookup_result",
|
||||
"backstage_browser_check_result",
|
||||
"backstage_installed_apps_result",
|
||||
"backstage_dxgi_status",
|
||||
"backstage_browser_launch_status",
|
||||
"backstage_window_list_result",
|
||||
"clipboard_content",
|
||||
"proxy_data",
|
||||
"proxy_close",
|
||||
"disconnect_info",
|
||||
"webrtc_p2p_answer",
|
||||
"webrtc_p2p_ice"
|
||||
],
|
||||
"commands": [
|
||||
"agent_update",
|
||||
"backstage_browser_check",
|
||||
"backstage_enable_cursor",
|
||||
"backstage_enable_dxgi",
|
||||
"backstage_enable_keyboard",
|
||||
"backstage_enable_mouse",
|
||||
"backstage_enable_uia",
|
||||
"backstage_installed_apps",
|
||||
"backstage_key_down",
|
||||
"backstage_key_up",
|
||||
"backstage_kill_all",
|
||||
"backstage_lookup",
|
||||
"backstage_mouse_down",
|
||||
"backstage_mouse_move",
|
||||
"backstage_mouse_up",
|
||||
"backstage_mouse_wheel",
|
||||
"backstage_request_keyframe",
|
||||
"backstage_select_display",
|
||||
"backstage_set_fps",
|
||||
"backstage_set_quality",
|
||||
"backstage_set_resolution",
|
||||
"backstage_start",
|
||||
"backstage_start_browser_injected",
|
||||
"backstage_start_chrome_injected",
|
||||
"backstage_start_process",
|
||||
"backstage_start_process_injected",
|
||||
"backstage_stop",
|
||||
"backstage_window_list",
|
||||
"client_logs_request",
|
||||
"clipboard_set",
|
||||
"clipboard_sync_start",
|
||||
"clipboard_sync_stop",
|
||||
"console_input",
|
||||
"console_resize",
|
||||
"console_start",
|
||||
"console_stop",
|
||||
"darwin_request_permissions",
|
||||
"desktop_audio_start",
|
||||
"desktop_audio_stop",
|
||||
"desktop_enable_cursor",
|
||||
"desktop_enable_keyboard",
|
||||
"desktop_enable_mouse",
|
||||
"desktop_encoder_capabilities",
|
||||
"desktop_key_down",
|
||||
"desktop_key_up",
|
||||
"desktop_mouse_down",
|
||||
"desktop_mouse_move",
|
||||
"desktop_mouse_up",
|
||||
"desktop_mouse_wheel",
|
||||
"desktop_request_keyframe",
|
||||
"desktop_select_display",
|
||||
"desktop_set_bitrate",
|
||||
"desktop_set_duplication",
|
||||
"desktop_set_fps",
|
||||
"desktop_set_profile",
|
||||
"desktop_set_quality",
|
||||
"desktop_set_resolution",
|
||||
"desktop_start",
|
||||
"desktop_stop",
|
||||
"desktop_text",
|
||||
"disconnect",
|
||||
"elevate",
|
||||
"file_chmod",
|
||||
"file_copy",
|
||||
"file_delete",
|
||||
"file_dirsize",
|
||||
"file_download",
|
||||
"file_execute",
|
||||
"file_hash",
|
||||
"file_icon",
|
||||
"file_list",
|
||||
"file_mkdir",
|
||||
"file_move",
|
||||
"file_peek",
|
||||
"file_read",
|
||||
"file_request_access",
|
||||
"file_search",
|
||||
"file_thumb",
|
||||
"file_upload",
|
||||
"file_upload_http",
|
||||
"file_write",
|
||||
"file_zip",
|
||||
"keylog_clear_all",
|
||||
"keylog_delete",
|
||||
"keylog_list",
|
||||
"keylog_request_permission",
|
||||
"keylog_retrieve",
|
||||
"plugin_load",
|
||||
"plugin_load_http",
|
||||
"plugin_unload",
|
||||
"privacy_start",
|
||||
"privacy_status",
|
||||
"privacy_stop",
|
||||
"process_icon",
|
||||
"process_kill",
|
||||
"process_list",
|
||||
"process_resume",
|
||||
"process_suspend",
|
||||
"proxy_close",
|
||||
"proxy_connect",
|
||||
"proxy_data",
|
||||
"reconnect",
|
||||
"screenshot",
|
||||
"script_exec",
|
||||
"silent_exec",
|
||||
"uninstall",
|
||||
"virtual_enable_cursor",
|
||||
"virtual_enable_keyboard",
|
||||
"virtual_enable_mouse",
|
||||
"virtual_key_down",
|
||||
"virtual_key_up",
|
||||
"virtual_kill_all",
|
||||
"virtual_mouse_down",
|
||||
"virtual_mouse_move",
|
||||
"virtual_mouse_up",
|
||||
"virtual_mouse_wheel",
|
||||
"virtual_request_keyframe",
|
||||
"virtual_set_fps",
|
||||
"virtual_set_quality",
|
||||
"virtual_start",
|
||||
"virtual_start_process",
|
||||
"virtual_stop",
|
||||
"virtual_window_list",
|
||||
"voice_capabilities",
|
||||
"voice_downlink",
|
||||
"voice_session_start",
|
||||
"voice_session_stop",
|
||||
"webcam_list",
|
||||
"webcam_select",
|
||||
"webcam_set_fps",
|
||||
"webcam_set_quality",
|
||||
"webcam_start",
|
||||
"webcam_stop",
|
||||
"webrtc_p2p_ice",
|
||||
"webrtc_p2p_offer",
|
||||
"webrtc_p2p_stop",
|
||||
"webrtc_publish",
|
||||
"webrtc_stop",
|
||||
"winre_install",
|
||||
"winre_probe",
|
||||
"winre_uninstall"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://overlord.local/schemas/wire-contract.schema.json",
|
||||
"title": "Overlord wire contract",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"schemaVersion",
|
||||
"protocolVersion",
|
||||
"encoding",
|
||||
"compatibility",
|
||||
"commandVersioning",
|
||||
"serverToAgentMessageTypes",
|
||||
"agentToServerMessageTypes",
|
||||
"commands"
|
||||
],
|
||||
"properties": {
|
||||
"$schema": { "type": "string" },
|
||||
"schemaVersion": { "type": "integer", "minimum": 1 },
|
||||
"protocolVersion": { "type": "integer", "minimum": 1 },
|
||||
"encoding": { "const": "messagepack" },
|
||||
"compatibility": { "enum": ["additive"] },
|
||||
"commandVersioning": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["defaultVersion", "overrides"],
|
||||
"properties": {
|
||||
"defaultVersion": { "const": 1 },
|
||||
"overrides": {
|
||||
"type": "object",
|
||||
"propertyNames": { "$ref": "#/$defs/wireName" },
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["latestVersion", "changes"],
|
||||
"properties": {
|
||||
"latestVersion": { "type": "integer", "minimum": 2 },
|
||||
"changes": {
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^[2-9][0-9]*$": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["breaking", "summary", "migration"],
|
||||
"properties": {
|
||||
"breaking": { "const": true },
|
||||
"summary": { "type": "string", "minLength": 1 },
|
||||
"migration": { "type": "string", "minLength": 1 }
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"serverToAgentMessageTypes": {
|
||||
"type": "array",
|
||||
"uniqueItems": true,
|
||||
"items": { "$ref": "#/$defs/wireName" }
|
||||
},
|
||||
"agentToServerMessageTypes": {
|
||||
"type": "array",
|
||||
"uniqueItems": true,
|
||||
"items": { "$ref": "#/$defs/wireName" }
|
||||
},
|
||||
"commands": {
|
||||
"type": "array",
|
||||
"uniqueItems": true,
|
||||
"items": { "$ref": "#/$defs/wireName" }
|
||||
}
|
||||
},
|
||||
"$defs": {
|
||||
"wireName": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user