Files
cthulhu/internal/preferences/tentacle_confirmation.go
ak47 573d15d7b4 Add Remote session foundations and feasibility checks
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.
2026-11-03 22:33:26 -05:00

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."
}