From 54f0edcac44680beb66fdbcaf352abdbb84e7e76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?d=20=F0=9F=94=B9?= <258577966+voidborne-d@users.noreply.github.com> Date: Wed, 25 Feb 2026 06:09:15 +0000 Subject: [PATCH] feat(pilotctl): add --encoding flag to send-message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add client-side --encoding flag that wraps the payload in a JSON envelope before sending. No wire protocol changes — the data is sent as a standard TypeJSON frame. Usage: pilotctl send-message target --data '?Uk/co' --encoding lambda # Sends TypeJSON: {"encoding":"lambda","data":"?Uk/co"} This enables agents to exchange messages in custom encodings (e.g. Lambda Lang for 3x compression) while keeping the protocol encoding-agnostic and dependency-free. Ref: https://github.com/TeoSlayer/pilotprotocol/issues/5 --- cmd/pilotctl/main.go | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/cmd/pilotctl/main.go b/cmd/pilotctl/main.go index d98d9fd..addca93 100644 --- a/cmd/pilotctl/main.go +++ b/cmd/pilotctl/main.go @@ -364,7 +364,7 @@ Communication commands: pilotctl send --data [--timeout ] pilotctl recv [--count ] [--timeout ] pilotctl send-file - pilotctl send-message --data [--type text|json|binary] + pilotctl send-message --data [--type text|json|binary] [--encoding ] pilotctl subscribe [--count ] [--timeout ] pilotctl publish --data @@ -815,9 +815,9 @@ func cmdContext() { "returns": "filename, bytes, destination, ack", }, "send-message": map[string]interface{}{ - "args": []string{"", "--data ", "[--type text|json|binary]"}, - "description": "Send a typed message via data exchange (port 1001). Default type: text", - "returns": "target, type, bytes, ack", + "args": []string{"", "--data ", "[--type text|json|binary]", "[--encoding ]"}, + "description": "Send a typed message via data exchange (port 1001). Default type: text. --encoding wraps data in a JSON envelope {\"encoding\":\"\",\"data\":\"...\"}", + "returns": "target, type, bytes, encoding, ack", }, "subscribe": map[string]interface{}{ "args": []string{"", "", "[--count ]", "[--timeout ]"}, @@ -2318,7 +2318,7 @@ func cmdSendFile(args []string) { func cmdSendMessage(args []string) { flags, pos := parseFlags(args) if len(pos) < 1 { - fatalCode("invalid_argument", "usage: pilotctl send-message --data [--type text|json|binary]") + fatalCode("invalid_argument", "usage: pilotctl send-message --data [--type text|json|binary] [--encoding ]") } d := connectDriver() @@ -2334,6 +2334,27 @@ func cmdSendMessage(args []string) { fatalCode("invalid_argument", "--data is required") } msgType := flagString(flags, "type", "text") + encoding := flagString(flags, "encoding", "") + + // If --encoding is set, wrap the payload in a JSON envelope and force type to json. + // This is a client-side convenience: the wire still carries a standard JSON frame. + // The receiver can inspect the "encoding" field to decode the payload. + // + // Example: + // pilotctl send-message target --data "?Uk/co" --encoding lambda + // → sends TypeJSON: {"encoding":"lambda","data":"?Uk/co"} + if encoding != "" { + envelope := map[string]string{ + "encoding": encoding, + "data": data, + } + b, marshalErr := json.Marshal(envelope) + if marshalErr != nil { + fatalCode("internal", "marshal encoding envelope: %v", marshalErr) + } + data = string(b) + msgType = "json" + } client, err := dataexchange.Dial(d, target) if err != nil { @@ -2368,6 +2389,9 @@ func cmdSendMessage(args []string) { "type": msgType, "bytes": len(data), } + if encoding != "" { + result["encoding"] = encoding + } if ack != nil { result["ack"] = string(ack.Payload) }