Add Remote Braille IPC to the host and both SDKs

remote.braille requests and events carry a typed op under a
braille-stream lease: the controller's width and gestures for a
controlled reader, rendered cells back to its child, and cells, local
geometry and display gestures for a controller. Direction is validated
per role; a full mailbox revokes the lease. No display owner is
attached yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Chase CichorzandClaude Opus 5.5 committed 2026-11-06 16:06:38 -05:00
1 parent 477d860fb8
commit 2651b5e9bd
10 files changed
+476 -3

No files matched your search

+7 -1
View File
@@ -77,6 +77,7 @@ type SessionEvent struct {
Speech *RemoteSpeech `json:"speech,omitempty"`
Input *RemoteCapturedKey `json:"input,omitempty"`
Focus string `json:"focus,omitempty"`
Braille *RemoteBraille `json:"braille,omitempty"`
}
func ValidRole(role string) bool { return role == "controller" || role == "controlled" }
@@ -97,7 +98,7 @@ func ValidSessionEvent(event SessionEvent) bool {
if event.Sequence == 0 || event.Epoch == 0 {
return false
}
if event.Kind != "remote.input" && event.Input != nil || event.Kind != "remote.focus" && event.Focus != "" {
if event.Kind != "remote.input" && event.Input != nil || event.Kind != "remote.focus" && event.Focus != "" || event.Kind != "remote.braille" && event.Braille != nil {
return false
}
switch event.Kind {
@@ -107,6 +108,11 @@ func ValidSessionEvent(event SessionEvent) bool {
return event.Speech == nil && ((event.Action == "" && len(event.Lease) == 32) || (len(event.Action) == 32 && event.Lease == "")) && event.Role == "" && len(event.Grants) == 0 && slices.Contains([]string{"closed", "expired", "local", "replaced"}, event.Reason)
case "remote.input":
return event.Action == "" && len(event.Lease) == 32 && event.Role == "" && len(event.Grants) == 0 && event.Reason == "" && event.Speech == nil && event.Input != nil && ValidRemoteCapturedKey(*event.Input)
case "remote.braille":
// Role is not carried on events; either direction-valid form is accepted
// and the receiving child applies its own role.
return event.Action == "" && len(event.Lease) == 32 && event.Role == "" && len(event.Grants) == 0 && event.Reason == "" && event.Speech == nil && event.Braille != nil &&
(ValidRemoteBrailleFor("controlled", false, *event.Braille) || ValidRemoteBrailleFor("controller", false, *event.Braille))
case "remote.focus":
return event.Action == "" && len(event.Lease) == 32 && event.Role == "" && len(event.Grants) == 0 && event.Speech == nil && ValidRemoteFocusEvent(event.Focus, event.Reason)
case "remote.output":