utils

package
v1.9.0 Latest Latest
Warning

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

Go to latest
Published: Jul 15, 2026 License: MIT Imports: 24 Imported by: 1

Documentation

Index

Constants

View Source
const (
	AuthMFARequired  = "auth_mfa_required"
	UsernameRequired = "user_username_required"

	// WorkSession gate codes (returned by alpacon-server work_sessions/services.py)
	WorkSessionRequired         = "work_session_required"
	WorkSessionNotUsable        = "work_session_not_usable"
	WorkSessionNotActive        = "work_session_not_active"
	WorkSessionExpired          = "work_session_expired"
	WorkSessionScopeNotAllowed  = "work_session_scope_not_allowed"
	WorkSessionServerNotAllowed = "work_session_server_not_allowed"
	WorkSessionAssigneeMismatch = "work_session_assignee_mismatch"

	// ExitCodeWorkSessionDenied is the process exit code for WorkSession gate refusals.
	ExitCodeWorkSessionDenied = 3

	// ExitCodePendingApproval is the process exit code for an action that landed
	// pending human approval (a sudo HITL SUDO_APPROVAL_REQUIRED denial, or a work
	// session created in the pending state) and was not waited on with --wait.
	// It is distinct from ExitCodeWorkSessionDenied (3): the action was not
	// refused, it is awaiting an out-of-band approve/reject in the Alpacon console
	// (web/Slack). Scripts and AI agents branch on it to "wait or check later"
	// rather than treat it as a hard failure.
	ExitCodePendingApproval = 4

	// PendingApprovalStatus is the stable machine-readable status string emitted
	// under --output json when an action is pending human approval.
	PendingApprovalStatus = "pending_approval"
)
View Source
const (
	OutputFormatTable = "table"
	OutputFormatJSON  = "json"
)

Valid values for the --output persistent flag.

View Source
const UsageErrorCode = "usage_error"

UsageErrorCode is the synthetic error_code for local validation failures that never reached the server.

Variables

View Source
var OutputFormat string

OutputFormat holds the value of the --output persistent flag. Bound by cmd/root.go; read by PrintTable and PrintJson.

View Source
var Version string = "dev"

Functions

func Blue

func Blue(value string) string

Blue returns a bold blue string for terminal output.

func Bold added in v1.2.0

func Bold(value string) string

Bold returns a bold string for terminal output.

func BoolPointerToString

func BoolPointerToString(value *bool) string

func BuildURL

func BuildURL(basePath, relativePath string, params map[string]string) string

func CleanupTempFile added in v1.5.0

func CleanupTempFile(f *os.File)

CleanupTempFile closes f and removes the backing file. Safe to call with a nil pointer. Intended as the cleanup half of SpoolToTempFile.

func CliError

func CliError(msg string, args ...any)

CliError handles all error messages in the CLI.

func CliErrorEnvelopeWithExit added in v1.7.2

func CliErrorEnvelopeWithExit(operation string, err error, format string, args ...any)

CliErrorEnvelopeWithExit reports a command failure and exits(1): json mode prints the envelope to stderr with the server code from err; table mode matches CliErrorWithExit.

func CliErrorWithExit added in v1.0.0

func CliErrorWithExit(msg string, args ...any)

CliErrorWithExit handles all error messages in the CLI.

func CliInfo

func CliInfo(msg string, args ...any)

CliInfo handles all informational messages in the CLI.

func CliInfoWithExit

func CliInfoWithExit(msg string, args ...any)

CliInfoWithExit prints an informational message to stderr and exits the program with a status code of 0

func CliSuccess added in v1.2.0

func CliSuccess(msg string, args ...any)

CliSuccess handles all success messages in the CLI.

func CliUsageErrorEnvelopeWithExit added in v1.7.2

func CliUsageErrorEnvelopeWithExit(operation string, format string, args ...any)

CliUsageErrorEnvelopeWithExit is the local-validation variant; error_code is fixed to UsageErrorCode. Exits(1).

func CliWarning

func CliWarning(msg string, args ...any)

CliWarning handles all warning messages in the CLI.

func CompactStrings added in v1.5.0

func CompactStrings(ss []string) []string

CompactStrings trims whitespace from each element and drops empty entries.

func ConfirmAction added in v1.2.0

func ConfirmAction(msg string, args ...any)

ConfirmAction prompts the user for confirmation before a destructive action. In non-interactive mode (piped stdin, CI, etc.), it exits and asks for --yes flag. Returns on confirm; exits the program on decline.

func CreateAndEditTempFile

func CreateAndEditTempFile(data []byte) (string, error)

func DecodeJWTPayload added in v1.1.0

func DecodeJWTPayload(token string) (map[string]any, error)

DecodeJWTPayload decodes the payload (second segment) of a JWT token without verifying the signature. Returns the claims as a map.

func DeleteFile

func DeleteFile(path string) error

func ExtractBaseDomain added in v1.1.0

func ExtractBaseDomain(workspaceURL string) string

ExtractBaseDomain extracts the top-level base domain from a workspace URL. For example, "https://myws.us1.alpacon.io" returns "alpacon.io". Returns "" if the hostname has fewer than 3 parts (e.g. self-hosted with no subdomain).

func ExtractWorkspaceName added in v0.4.0

func ExtractWorkspaceName(workspaceURL string) string

ExtractWorkspaceName extracts workspace name from workspace URL

func FormatJSON added in v1.6.0

func FormatJSON(value any) (string, error)

func GetCLIVersion

func GetCLIVersion() string

func GetUserAgent

func GetUserAgent() string

func Green

func Green(value string) string

Green returns a bold green string for terminal output.

func HTTPStatusCode added in v1.8.1

func HTTPStatusCode(err error) int

HTTPStatusCode returns the HTTP status carried by err, or 0 if none—lets callers tell 404 from 401.

func HandleCommonErrors added in v1.0.0

func HandleCommonErrors(err error, serverName string, callbacks ErrorHandlerCallbacks) error

HandleCommonErrors handles common errors (MFA, UsernameRequired) with retry logic Returns nil if error was handled successfully, otherwise returns the original or new error

func HandleWorkSessionError added in v1.4.8

func HandleWorkSessionError(err error, operation, serverName, authMethod, activeWS string)

HandleWorkSessionError prints a WorkSession gate diagnostic and exits(3); no-op for other errors.

func IsControlRune added in v1.9.0

func IsControlRune(r rune) bool

IsControlRune reports whether r is a C0, DEL, or C1 control character (the last can introduce CSI/OSC on 8-bit terminals).

func IsInteractiveShell added in v0.4.4

func IsInteractiveShell() bool

IsInteractiveShell checks if the current program is running in an interactive terminal.

func IsLocalTarget added in v0.4.0

func IsLocalTarget(target string) bool

IsLocalTarget checks if a target string represents a local location

func IsRemoteTarget added in v0.4.0

func IsRemoteTarget(target string) bool

IsRemoteTarget checks if a target string represents a remote location A target is considered remote if it contains a colon (:)

func IsUUID

func IsUUID(str string) bool

func OpenBrowser added in v1.3.3

func OpenBrowser(url string)

OpenBrowser attempts to open the given URL in the user's default browser. It silently falls back to doing nothing if the browser cannot be opened (e.g., headless server, SSH session, container) or if another process recently opened a browser (debounce).

Set ALPACON_NO_BROWSER=1 to disable browser auto-open globally.

func ParseErrorResponse added in v0.4.0

func ParseErrorResponse(err error) (string, string)

func PrettyJSON

func PrettyJSON(data []byte) (*bytes.Buffer, error)

func PrintHeader

func PrintHeader(header string)

func PrintJSONError added in v1.6.0

func PrintJSONError[T any](w io.Writer, envelope JSONErrorEnvelope[T])

func PrintJSONValue added in v1.6.0

func PrintJSONValue(w io.Writer, value any) error

func PrintJson

func PrintJson(body []byte)

func PrintPendingApproval added in v1.7.2

func PrintPendingApproval(message, requestID string, retry NextAction)

PrintPendingApproval emits the structured "pending approval" feedback for an action that requires out-of-band human approval and was not waited on. Under --output json it writes a {"status":"pending_approval", ...} envelope to stdout; otherwise it writes an actionable message to stderr. requestID may be empty when the surface cannot supply one. retry is a surface-specific retry action (e.g. the exact command to re-run); its Command stays a pure, executable string so a machine consumer can run it directly, with any hint in Description. It never exits — the caller owns process exit so the exit-code contract stays in one place.

func PrintTable

func PrintTable(slice any)

func ProcessEditedData

func ProcessEditedData(originalData []byte) (any, error)

ProcessEditedData facilitates user modifications to original data, formats it, supports editing via a temp file, compares the edited data against the original, and parses it into JSON. If no changes are made, the update is aborted and an error is returned.

func PromptForBool

func PromptForBool(prompt string) bool

func PromptForInput

func PromptForInput(promptText string) string

func PromptForInputWithDefault added in v1.3.4

func PromptForInputWithDefault(promptText, defaultValue string) string

PromptForInputWithDefault prompts for input and returns the default if empty.

func PromptForIntInput

func PromptForIntInput(promptText string, defaultValue int) int

func PromptForListInput

func PromptForListInput(promptText string) []string

func PromptForPassword

func PromptForPassword(promptText string) string

func PromptForRequiredInput

func PromptForRequiredInput(promptText string) string

func PromptForRequiredIntInput

func PromptForRequiredIntInput(promptText string) int

func Red

func Red(value string) string

Red returns a bold red string for terminal output.

func RemoteFileName added in v1.6.0

func RemoteFileName(remotePath string) (string, error)

RemoteFileName returns the final path component for a remote file path.

func RemovePrefixBeforeAPI

func RemovePrefixBeforeAPI(url string) string

func SaveFile

func SaveFile(fileName string, data []byte) error

func SaveStreamAtomic added in v1.5.0

func SaveStreamAtomic(fileName string, r io.Reader) (int64, error)
func ShowLogo(rightLines []string)

ShowLogo renders the Pacabot mascot with up to 3 lines of text. When the terminal is wide enough the text sits to the right of the art (lines 1-3 align with art rows 1-3); otherwise it falls back to rendering text below the art so wrapped lines don't break the half-block pixel art rendering.

Pixel art ported from strategy/brand-assets/pacabot/pacabot.sh. In color mode, body cells render as spaces with BG=cyan so the cell background fills any inter-line gap. In plain mode (no TTY / NO_COLOR), body cells substitute █ glyphs so the silhouette stays visible without ANSI codes. Edge half-blocks (▄ ▀) are kept in both modes — they define the shape: ▄ corners and ! bar bottom (FG cyan, glyph extends below the em-box in most fonts), and ▀ for the eye (grey on cyan) and the mouth (grey FG). Brand colors: primary #27AAE1, secondary #58595B.

func SplitAndParseInt

func SplitAndParseInt(input string) []int

func SplitAndTrim added in v1.4.4

func SplitAndTrim(s, sep string) []string

SplitAndTrim splits s by sep, trims whitespace from each element, and drops empty entries. Returns nil when the input is empty or yields no non-empty elements.

func SplitPath

func SplitPath(path string) (string, string)

func SpoolToTempFile added in v1.5.0

func SpoolToTempFile(pattern string, fn func(io.Writer) error) (*os.File, int64, error)

SpoolToTempFile creates a temp file, invokes fn to write into it, closes it to surface flush errors, then reopens it for reading with its size. On any error the temp file is closed and removed. The caller owns cleanup on success.

func StripANSIEscapes added in v1.9.0

func StripANSIEscapes(s string) string

func StripControlChars added in v1.9.0

func StripControlChars(s string) string

func TimeFormat

func TimeFormat(value int) *string

func TimeUtils

func TimeUtils(t time.Time) string

func TruncateString

func TruncateString(str string, num int) string

func Unzip

func Unzip(src string, dest string) error

func WriteToPager added in v1.0.0

func WriteToPager() (io.Writer, func())

WriteToPager returns a writer that buffers output and pipes it through a pager only when the output exceeds the terminal height. The caller must call the returned cleanup function when done writing.

Behavior:

  • If stdout is not a terminal (e.g. piped), prints directly to stdout.
  • If the output fits within the terminal height, prints directly to stdout.
  • Otherwise, pipes through the PAGER environment variable or "less -RSX".
  • Falls back to direct stdout if the pager command is not available.

func Yellow

func Yellow(value string) string

Yellow returns a bold yellow string for terminal output.

func ZipToWriter added in v1.5.0

func ZipToWriter(folderPath string, w io.Writer) error

Types

type ErrorHandlerCallbacks added in v1.0.0

type ErrorHandlerCallbacks struct {
	// OnMFARequired is called when MFA authentication is required
	// serverName: the name of the server requiring MFA
	OnMFARequired func(serverName string) error

	// OnUsernameRequired is called when username is required
	OnUsernameRequired func() error

	// CheckMFACompleted is called to poll for MFA completion via a lightweight endpoint.
	// If nil, falls back to the legacy RefreshToken+RetryOperation loop.
	CheckMFACompleted func() (bool, error)

	// RefreshToken is called before each MFA retry to refresh the access token
	// so the server can see the latest MFA completion state
	RefreshToken func() error

	// RetryOperation is called to retry the original operation after error handling
	// Should return nil on success, error on failure
	RetryOperation func() error
}

ErrorHandlerCallbacks defines callback functions for handling different error types

type ErrorResponse added in v0.4.0

type ErrorResponse struct {
	Code   string `json:"code"`
	Source string `json:"source"`
}

type JSONErrorEnvelope added in v1.6.0

type JSONErrorEnvelope[T any] struct {
	OK          bool         `json:"ok"`
	ExitCode    int          `json:"exit_code,omitempty"`
	ErrorCode   string       `json:"error_code,omitempty"`
	Message     string       `json:"message"`
	Reason      string       `json:"reason,omitempty"`
	Context     T            `json:"context"`
	NextActions []NextAction `json:"next_actions,omitempty"`
}

type NextAction added in v1.9.0

type NextAction struct {
	Command     string `json:"command,omitempty"`
	Description string `json:"description,omitempty"`
}

NextAction is one actionable follow-up. Command is a pure, runnable command (no inline comments) for machine consumers; Description carries the human hint. Either may be empty—a pure command needs no hint, and a guidance-only pointer (e.g. "approve it in the console") carries no runnable command—so both fields are omitempty.

func (NextAction) PlainText added in v1.9.0

func (a NextAction) PlainText() string

PlainText renders the action as a human-facing line: "command # description", or just the command or description when the other is empty.

type SSHTarget added in v0.4.0

type SSHTarget struct {
	User string // Username (empty if not specified)
	Host string // Hostname/server name
	Path string // Path (empty if not specified)
}

SSHTarget represents a parsed SSH-like target with user, host, and path components

func ParseSSHTarget added in v0.4.0

func ParseSSHTarget(target string) SSHTarget

ParseSSHTarget parses SSH-like target strings and returns the components Supports formats: - host - user@host - host:path - user@host:path An '@' is only treated as the user separator when it precedes the first ':', so a remote path may itself contain '@' (e.g. host:/tmp/alice@example.com).

type Spinner added in v1.0.0

type Spinner struct {
	// contains filtered or unexported fields
}

Spinner displays an animated spinner with a message. When stderr is not a terminal (e.g., piped or redirected), the spinner animation is replaced with a single static progress line so logs stay clean without ANSI artifacts.

func NewSpinner added in v1.0.0

func NewSpinner(message string) *Spinner

NewSpinner creates a new spinner with the given message If the message ends with "...", the dots will animate (. -> .. -> ...)

func (*Spinner) Start added in v1.0.0

func (s *Spinner) Start()

Start begins the spinner animation

func (*Spinner) Stop added in v1.0.0

func (s *Spinner) Stop()

Stop stops the spinner animation

Jump to

Keyboard shortcuts

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