Add opt-in Tentacle protocol 1.1, explicit remote grants, lifecycle IPC and expiring core leases in both SDKs. Revoke access before update preparation, including failed updates. Add transient secret entries, shared Braille cell export and isolated Xorg recovery experiments with focused tests and documented limitations. Production consent, desktop services and live interoperability remain pending.
79 lines
3.6 KiB
Go
79 lines
3.6 KiB
Go
// Copyright (c) 2026 Storm Dragon
|
|
// Authors: Storm Dragon, Angus Kola
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
package preferences
|
|
|
|
import (
|
|
"fmt"
|
|
"slices"
|
|
"strings"
|
|
|
|
"git.stormux.org/storm/cthulhu/internal/tentacle"
|
|
)
|
|
|
|
func tentacleUpdateCapabilities(entry tentacle.Entry, manifest tentacle.Manifest) string {
|
|
var previous []string
|
|
if entry.Presentation {
|
|
previous = append(previous, "presentation")
|
|
}
|
|
if entry.Interaction {
|
|
previous = append(previous, "interaction")
|
|
}
|
|
if entry.ReaderSettings {
|
|
previous = append(previous, "reader-settings")
|
|
}
|
|
previous = append(previous, entry.RemoteGrants...)
|
|
if len(previous) == 0 {
|
|
previous = append(previous, "none")
|
|
}
|
|
declared := manifest.Capabilities
|
|
if len(declared) == 0 {
|
|
declared = []string{"none"}
|
|
}
|
|
return "Current capabilities: " + strings.Join(previous, ", ") +
|
|
". Repository declares: " + strings.Join(declared, ", ") + "."
|
|
}
|
|
|
|
func tentacleInstallConfirmation(entry tentacle.Entry, manifest tentacle.Manifest, label string) string {
|
|
permissions := "This tentacle can register reader commands."
|
|
if slices.Contains(manifest.Capabilities, "presentation") {
|
|
permissions = "This tentacle can register reader commands and send speech and braille messages."
|
|
}
|
|
if slices.Contains(manifest.Capabilities, "interaction") {
|
|
permissions = "This tentacle can register reader commands, send speech and braille messages, open internal forms, read the focused item and clipboard when invoked, and write clipboard text."
|
|
}
|
|
if slices.Contains(manifest.Capabilities, "reader-settings") {
|
|
permissions += " It can also add preferences pages and quick settings, inspect speech voices, and temporarily change the reader voice configuration."
|
|
}
|
|
permissions += remotePermissions(manifest.Capabilities)
|
|
return fmt.Sprintf("%s %s version %s from %s?\n\n%s\n\nOnly install packages from publishers you trust. Tentacles run with your account's access; resource limits do not protect your files or network.\n\nTentacle management changes take effect immediately.", label, entry.Name, entry.Version, entry.Repository, permissions)
|
|
}
|
|
|
|
func tentacleUpdateConfirmation(entry tentacle.Entry, update tentacle.AvailableUpdate, manifest tentacle.Manifest) string {
|
|
permissions := tentacleUpdateCapabilities(entry, manifest) + remotePermissions(manifest.Capabilities)
|
|
return fmt.Sprintf("Update %s from version %s to version %s?\n\n%s\n\nOnly update packages from publishers you trust. Tentacles run with your account's access.\n\nChanges take effect immediately.", update.Name, update.InstalledVersion, update.AvailableVersion, permissions)
|
|
}
|
|
|
|
// Install grants describe direction explicitly and never imply active consent.
|
|
func remotePermissions(grants []string) string {
|
|
descriptions := []struct{ grant, text string }{
|
|
{"output-observe", "share local reader output with the remote controller"},
|
|
{"remote-present", "present output received from the controlled computer"},
|
|
{"keyboard-capture", "capture local keyboard input for the controlled computer"},
|
|
{"keyboard-inject", "accept keyboard input from the remote controller"},
|
|
{"braille-stream", "exchange remote braille cells and supported display gestures"},
|
|
{"clipboard-exchange", "send clipboard text explicitly and receive text with session permission"},
|
|
}
|
|
var requested []string
|
|
for _, item := range descriptions {
|
|
if slices.Contains(grants, item.grant) {
|
|
requested = append(requested, item.text)
|
|
}
|
|
}
|
|
if len(requested) == 0 {
|
|
return ""
|
|
}
|
|
return " Requested remote access: " + strings.Join(requested, "; ") + ". Installation does not start a connection or authorize control. Each session requires local approval, and unavailable reader operations remain disabled."
|
|
}
|