Something went wrong. Try again.
small gleam coding and persistent agent daemon with a detachable cli and a canvas ui forked from okami.mom/albedo
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113package daemon
import ( "context" "fmt" "net/http" "net/url" "unicode/utf8"
"albedo/cli/internal/daemon/protocol")
const maxShellOutputBytes = 16 << 20
// ShellCommand and ShellOutputPage use the generated OpenAPI contract types.type ShellCommand = protocol.ShellCommandtype ShellOutputPage = protocol.ShellCommandOutput
func ShellCommandErrorText(c ShellCommand) string { if c.Error == nil { return "" } return *c.Error}
func NewShellCommandID() (string, error) { return operationID() }
func validShellCommand(c ShellCommand) error { if c.ID == "" || c.Command == "" || !utf8.ValidString(c.Output) || c.OutputBytes < int64(len(c.Output)) || c.OutputBytes > maxShellOutputBytes { return fieldError("shell command") } switch c.Status { case "running": if c.ExitCode != nil || c.HistorySeq != nil { return fieldError("shell command status") } case "completed", "cancelled", "interrupted", "failed": default: return fieldError("shell command status") } if c.HistorySeq != nil && *c.HistorySeq < 1 { return fieldError("shell command history sequence") } return nil}
func decodeShellCommand(data []byte) (ShellCommand, error) { var envelope protocol.ShellCommandResponse if err := decodeRequired(data, &envelope, "shell_command"); err != nil { return ShellCommand{}, err } return envelope.ShellCommand, validShellCommand(envelope.ShellCommand)}
// PutShellCommand uses the stable client UUIDv7 supplied by the caller. The same// ID and command may safely be replayed after an uncertain transport failure.func PutShellCommand(ctx context.Context, conn *Connection, session, id, command string) (ShellCommand, error) { var result ShellCommand err := executeMutation(ctx, conn, operation{Name: "run shell command", Method: http.MethodPut, Path: fmt.Sprintf("/sessions/%s/shell-commands/%s", url.PathEscape(session), url.PathEscape(id)), Body: protocol.PutShellCommandJSONRequestBody{Command: command}, Policy: noRecovery}, []int{200, 201}, func(data []byte, _ int) error { var err error result, err = decodeShellCommand(data) if err == nil && (result.ID != id || result.Command != command) { return fieldError("shell command identity") } return err }) return result, err}
func GetShellCommand(ctx context.Context, conn *Connection, session, id string) (ShellCommand, error) { var result ShellCommand err := executeRead(ctx, conn, operation{Name: "read shell command", Method: http.MethodGet, Path: fmt.Sprintf("/sessions/%s/shell-commands/%s", url.PathEscape(session), url.PathEscape(id)), Policy: readRecovery}, func(data []byte) error { var err error result, err = decodeShellCommand(data) if err == nil && result.ID != id { return fieldError("shell command identity") } return err }) return result, err}
func StopShellCommand(ctx context.Context, conn *Connection, session, id string) (ShellCommand, error) { var result ShellCommand err := executeMutation(ctx, conn, operation{Name: "stop shell command", Method: http.MethodPost, Path: fmt.Sprintf("/sessions/%s/shell-commands/%s/stop", url.PathEscape(session), url.PathEscape(id)), Body: struct{}{}, Policy: noRecovery}, []int{200}, func(data []byte, _ int) error { var err error result, err = decodeShellCommand(data) if err == nil && result.ID != id { return fieldError("shell command identity") } return err }) return result, err}
func GetShellCommandOutput(ctx context.Context, conn *Connection, session, id string, offset int64, limit int) (ShellOutputPage, error) { var result ShellOutputPage if offset < 0 || offset > maxShellOutputBytes || limit < 4 || limit > 65536 { return result, fieldError("shell output page") } path := fmt.Sprintf("/sessions/%s/shell-commands/%s/output?offset=%d&limit=%d", url.PathEscape(session), url.PathEscape(id), offset, limit) err := executeRead(ctx, conn, operation{Name: "read shell output", Method: http.MethodGet, Path: path, Policy: readRecovery}, func(data []byte) error { if err := decodeRequired(data, &result, "text", "next_offset"); err != nil { return err } if !utf8.ValidString(result.Text) || len(result.Text) > limit || result.NextOffset != nil && *result.NextOffset != offset+int64(len(result.Text)) { return fieldError("shell output page") } return nil }) return result, err}