cli

package
v0.17.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 1, 2026 License: AGPL-3.0 Imports: 40 Imported by: 0

Documentation

Overview

Package cli is the command-line client (design 04 §4).

A client of the API and nothing more (R-261). The CLI must not have a capability the API lacks, and the way to keep that true is to give it no access to anything else: this package talks HTTP and does not import internal/core at all. If a command here needs something the API cannot do, the answer is an endpoint, not a shortcut.

Index

Constants

View Source
const (
	EnvServer = "PANDO_SERVER"
	EnvToken  = "PANDO_TOKEN"
)

The environment a machine authenticates with.

`pando login` is for a person at a terminal: it stores a token in a file under their home directory, which is the right place for it and the wrong place for CI, a container, or an MCP client's configuration block. Those have an environment and no home directory worth writing to, and without this the only way to use a minted token was to write the credentials file by hand.

Named constants because the reference quotes them: `docs/cli.md` and the console's API screen are generated, and a documented variable name that nothing reads is the drift this whole mechanism exists to prevent.

View Source
const (
	EnvJoinToken  = "PANDO_JOIN_TOKEN"
	EnvSetupToken = "PANDO_SETUP_TOKEN"
)

Where `pando join` reads its two secrets when they are not on the command line, which other users of the machine can read and shell history keeps (R-194).

Variables

View Source
var ErrNotLoggedIn = errors.New("not logged in — run `pando login` first, or set PANDO_SERVER and PANDO_TOKEN")

ErrNotLoggedIn is returned when there is no stored credential.

View Source
var Version = "dev"

Version is this CLI's version, set by main from the release build's stamp.

Functions

func Commands

func Commands() []*cobra.Command

Commands returns the client half of the CLI (design 04 §4).

Every one of these is a wrapper over an endpoint. That is the constraint R-261 puts on this package and the reason it reads repetitively: a command that did something the API cannot do would be a capability the console and MCP could never have.

func ExitCodeOf

func ExitCodeOf(err error) int

ExitCodeOf returns the code err asks the process to exit with: its own, if it carries one, and otherwise 1.

func MCPCommand

func MCPCommand() *cobra.Command

MCPCommand runs the MCP server over stdio (R-262, design 04 §3).

Pando also serves the same server itself at /api/v1/mcp (R-413), which a client adds by address and signs in to with OAuth. This is for a client that runs a program instead: it uses the token `pando login` stored, on the agent's own machine.

func PackDirectory

func PackDirectory(dir string) ([]byte, int, error)

PackDirectory writes dir as a gzipped tar, returning the archive and how many files it holds.

func SaveCredentials

func SaveCredentials(c Credentials) error

SaveCredentials writes the token, readable only by its owner.

func SelfUpdateCmd

func SelfUpdateCmd() *cobra.Command

SelfUpdateCmd is `pando self-update`. Beside `version` rather than among the API's commands: it acts on this binary, not on an installation (R-261).

Types

type APIError

type APIError struct {
	Status  int
	Code    string `json:"code"`
	Message string `json:"message"`
	Remedy  string `json:"remedy,omitempty"`
	ReqID   string `json:"request_id,omitempty"`

	// Details is the envelope's structured part, for a command that turns a
	// refusal into the flag that answers it.
	Details map[string]any `json:"details,omitempty"`
}

APIError is the server's error envelope (design 00 §3.2).

Rendered as written. The messages are held to the R-105 standard — self contained, actionable, pasteable into an assistant — and paraphrasing them here would undo that at the last step.

func (*APIError) Error

func (e *APIError) Error() string

type Client

type Client struct {
	BaseURL string
	Token   string
	HTTP    *http.Client
	// Warn receives the version-skew warning (R-353). Nil says nothing.
	Warn io.Writer
}

Client talks to a Pando server.

func New

func New(urlOverride string) (*Client, error)

New builds a client from stored credentials, with the server URL overridable so a script can point at a different install without logging in again.

func (*Client) Do

func (c *Client) Do(method, path string, body, out any) error

Do makes a request and decodes the response into out.

func (*Client) Exec

func (c *Client) Exec(ctx context.Context, opts ExecOptions) error

Exec opens a terminal inside a running workload (R-086).

Returns the command's exit status so `pando exec app -- false` can be used in a script the way ssh is. A transport failure is a Go error; a non-zero exit inside the container is an exitError and not a failure of this command.

func (*Client) Stream

func (c *Client) Stream(method, path string, body any) (io.ReadCloser, error)

Stream opens a response body for streaming, for logs and other long reads.

func (*Client) UploadIcon

func (c *Client) UploadIcon(appID string, image []byte) error

UploadIcon sets an app's tile image (R-340). The server decides what the bytes are; the content type sent is only a courtesy.

func (*Client) UploadSource

func (c *Client) UploadSource(appID string, archive []byte) error

UploadSource sends a packed directory as an app's source.

type Credentials

type Credentials struct {
	URL   string `json:"url"`
	Token string `json:"token"`
	User  string `json:"user,omitempty"`
}

Credentials are what `pando login` stores.

A token rather than a session cookie: a session is bound to a browser's lifetime and revoked on a password change, which is right for a browser and wrong for a script that runs at 3am. The token is delegated, so it acts as its owner and holds nothing they do not (R-058).

func LoadCredentials

func LoadCredentials() (Credentials, error)

LoadCredentials reads the stored token.

type ExecOptions

type ExecOptions struct {
	AppID    string
	Workload string
	Command  []string

	// In, Out and Err are the local ends of the terminal. Fields rather than
	// os.Stdin directly so the failure path can be tested without a tty.
	In  *os.File
	Out io.Writer
	Err io.Writer
}

ExecOptions is one terminal session.

type ExitCode

type ExitCode struct {
	Code int
	Err  error
}

ExitCode is an error that asks the process to exit with a particular code.

For the outcomes a script needs to tell apart without reading the output: `pando app detection --wait` exits 2 when a person has to answer questions before the app can be accepted, and 1 when detection failed or was blocked.

func (*ExitCode) Error

func (e *ExitCode) Error() string

func (*ExitCode) Unwrap

func (e *ExitCode) Unwrap() error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL