Documentation
¶
Overview ¶
Package ui implements the bubbletea TUI, SSH helpers, and CUE recipe execution for honey.
Index ¶
- Constants
- func BuildCueRecipeTranscript(history [][]HostExecResult) string
- func CueHookNotifyRemote(ctx context.Context, recipe cuetry.Recipe, stepNo int, kind cuetry.StepKind, ...)
- func CueStepNotifyAppendSuffix(ctx context.Context, recipe cuetry.Recipe, stepNo int, kind cuetry.StepKind, ...) string
- func CueStepNotifyRemote(ctx context.Context, recipe cuetry.Recipe, stepNo int, kind cuetry.StepKind, ...)
- func DefaultLocalFilesRoot() string
- func DetectTransferTargetRuntime(cache *ClientCache, sshUser string, rec hosts.Record) (string, string, string, error)
- func DialSSHLeafForRecord(user string, r hosts.Record) (*ssh.Client, func(), error)
- func FormatCueStepHostResultsForNotify(stepNo int, group []HostExecResult) string
- func FormatTargetForDryRun(r hosts.Record) string
- func GetExecutor(r hosts.Record) hostexec.Executor
- func HostConnectableForTransfer(r hosts.Record) bool
- func IsAgentTransferValidationError(err error) bool
- func IsSSHConnTransientError(err error) bool
- func LoadAISystemPromptFromConfigPath(configPath string) string
- func LoadTransferConfigFromConfigPath(configPath string) config.TransferConfigEffective
- func PrintStaticTable(records []hosts.Record) error
- func RemoteCopyLocalToRemote(user string, record hosts.Record, localPath, remotePath string, ...) error
- func RemoteCopyRemoteToLocal(user string, record hosts.Record, remotePath, localPath string, ...) error
- func ResizeFromColsRows(cols, rows int) *remotecommand.TerminalSize
- func ResolveAgentTransferSigningHints(configPath string, cloud AgentCloudBackend, ref *CloudBackendRef) (cloudtransfer.SigningHints, error)
- func ResolveLocalPathUnderRoot(root, requested string) (string, error)
- func RunCueRecipeSteps(ctx context.Context, out io.Writer, recipe cuetry.Recipe, recipeDir string, ...) error
- func RunK8sPodWebTTY(ctx context.Context, r hosts.Record, stdin io.Reader, stdout, stderr io.Writer, ...) error
- func RunRecordingReplay(recordDir, baseName string) error
- func RunTable(records []hosts.Record, sshUser string, opts RunTableOptions) error
- func RunTerminalInteractive(user string, r hosts.Record) error
- func SSHClientCacheKey(user string, r hosts.Record) string
- func StreamCueRecipeSteps(ctx context.Context, recipe cuetry.Recipe, recipeDir string, ...) error
- func StreamSFTPDownloadParallel(user string, jobs []SFTPDownloadJob, maxConc int, out chan<- HostExecResult, ...) error
- func StreamSFTPUploadParallel(user string, recs []hosts.Record, localAbs, remotePath string, maxConc int, ...) error
- func StreamSSHParallel(ctx context.Context, user string, jobs []hosts.Record, kvTunnel bool, ...) error
- func StreamScriptUploadRunParallel(ctx context.Context, user string, recs []hosts.Record, ...) error
- func TransferStagingObjectKey(cloud AgentCloudBackend, src, dst hosts.Record) string
- func TruncateCueTranscript(s string, maxChars int) string
- func WrapRecordingReader(inner io.Reader, recorder *SessionRecorder, direction string) io.Reader
- func WrapRecordingWriter(inner io.Writer, recorder *SessionRecorder, direction string) io.Writer
- func WriteCueKVTunnelDryLine(out io.Writer, recipe cuetry.Recipe, stepIdx int, step cuetry.RecipeStep, ...)
- func WriteCueSSHPrivateKeyDryLine(out io.Writer, stepIdx int, step cuetry.RecipeStep, def *cuetry.RecipeDefaults)
- func WriteCueStepHooksDryLines(out io.Writer, stepIdx int, step cuetry.RecipeStep)
- func WriteCueStepNotifyDryLine(out io.Writer, step cuetry.RecipeStep)
- type AgentCloudBackend
- type AgentTransferEndpoint
- type AgentTransferEvent
- func ExecuteAgentCloudTransfer(job AgentTransferJob, cache *ClientCache) ([]AgentTransferEvent, error)
- func ExecuteAgentCloudTransferWithEmit(job AgentTransferJob, cache *ClientCache, emit func(AgentTransferEvent)) ([]AgentTransferEvent, error)
- func RunAgentTransferWithFallback(ctx context.Context, cache *ClientCache, ...) ([]AgentTransferEvent, error)
- type AgentTransferJob
- type AgentTransferValidationError
- type ClientCache
- type CloudBackendRef
- type Executor
- type HostClient
- type HostExecResult
- func ExecuteSFTPDownloadParallel(user string, jobs []SFTPDownloadJob, maxConc int) ([]HostExecResult, error)
- func ExecuteSFTPUploadParallel(user string, recs []hosts.Record, localAbs, remotePath string, maxConc int) ([]HostExecResult, error)
- func ExecuteSSHParallel(user string, recs []hosts.Record, remoteCmdFunc func(hosts.Record) string, ...) ([]HostExecResult, error)
- func ExecuteScriptUploadRunParallel(user string, recs []hosts.Record, localAbs, remotePath, remoteCmd string, ...) ([]HostExecResult, error)
- func RunOneSFTPUploadWithProgress(user string, r hosts.Record, localAbs, remotePath string, cache *ClientCache, ...) HostExecResult
- func SortHostExecForUI(s []HostExecResult) []HostExecResult
- type LocalFileEntry
- type RecipeKVCoordinator
- func (c *RecipeKVCoordinator) Close()
- func (c *RecipeKVCoordinator) EnsureK8sExecBridgeEnv(user string, r hosts.Record, k8c *k8sNativeClient) (map[string]string, error)
- func (c *RecipeKVCoordinator) EnsureKVTunnelEnv(user string, r hosts.Record, hc *sshclient.HoneyClient) (map[string]string, error)
- func (c *RecipeKVCoordinator) EnsureSession() (*stepkv.Session, error)
- func (c *RecipeKVCoordinator) InvalidateHost(user string, r hosts.Record)
- type RecipeMeta
- type RemoteFileEntry
- type RunTableOptions
- type SFTPDownloadJob
- type SSHPostHostResultFunc
- type SSHRemoteCmdFunc
- type SessionRecorder
- func (r *SessionRecorder) Close() error
- func (r *SessionRecorder) Path() string
- func (r *SessionRecorder) RecordData(direction string, payload []byte)
- func (r *SessionRecorder) RecordError(err error)
- func (r *SessionRecorder) RecordHostExecResult(res HostExecResult)
- func (r *SessionRecorder) RecordRecipeMeta(meta RecipeMeta)
- func (r *SessionRecorder) RecordResize(cols, rows int)
- type SessionRecorderOptions
Constants ¶
const ( StageFallbackDetect = "fallback_detect" StageFallbackDetectFailed = "fallback_detect_failed" StagePresignPutStart = "presign_put_start" StagePresignPut = "presign_put" StagePresignPutFailed = "presign_put_failed" StagePresignGetStart = "presign_get_start" StagePresignGet = "presign_get" StagePresignGetFailed = "presign_get_failed" StagePresignMultipartStart = "presign_multipart_start" StagePresignMultipart = "presign_multipart" StagePresignMultipartAbort = "presign_multipart_aborted" StagePresignComplete = "presign_complete" StagePresignCompleteFailed = "presign_complete_failed" StagePresignCleanup = "presign_cleanup" StagePresignCleanupFailed = "presign_cleanup_failed" StagePresignFallback = "presign_falling_back_to_agent" )
Fallback-path stage names. Emitted as the Stage field on AgentTransferEvent
Variables ¶
This section is empty.
Functions ¶
func BuildCueRecipeTranscript ¶ added in v0.2.8
func BuildCueRecipeTranscript(history [][]HostExecResult) string
BuildCueRecipeTranscript formats prior CUE step HostExecResult groups for an AI summarizer.
func CueHookNotifyRemote ¶ added in v0.2.8
func CueHookNotifyRemote(ctx context.Context, recipe cuetry.Recipe, stepNo int, kind cuetry.StepKind, phase, hostName string, notify *cuetry.RecipeNotify, body string)
CueHookNotifyRemote sends notify after a per-host hook; failures are logged only.
func CueStepNotifyAppendSuffix ¶ added in v0.2.8
func CueStepNotifyAppendSuffix(ctx context.Context, recipe cuetry.Recipe, stepNo int, kind cuetry.StepKind, notify *cuetry.RecipeNotify, body string) string
CueStepNotifyAppendSuffix sends notify after a successful AI step; returns text to append on missing receivers or send errors.
func CueStepNotifyRemote ¶ added in v0.2.8
func CueStepNotifyRemote(ctx context.Context, recipe cuetry.Recipe, stepNo int, kind cuetry.StepKind, notify *cuetry.RecipeNotify, body string)
CueStepNotifyRemote sends notify after a non-AI step; failures are logged only (no change to streamed host rows).
func DefaultLocalFilesRoot ¶ added in v0.2.8
func DefaultLocalFilesRoot() string
DefaultLocalFilesRoot returns the configured or home-directory root for local file browser paths.
func DetectTransferTargetRuntime ¶ added in v0.2.8
func DetectTransferTargetRuntime(cache *ClientCache, sshUser string, rec hosts.Record) (string, string, string, error)
DetectTransferTargetRuntime runs uname on the host to determine GOOS/GOARCH for agent binaries.
func DialSSHLeafForRecord ¶ added in v0.2.7
DialSSHLeafForRecord returns a leaf *ssh.Client for SSH to hosts.Record.PrimaryIP (same transport as the TUI). Kubernetes pod records are not supported for raw SSH in this helper.
func FormatCueStepHostResultsForNotify ¶ added in v0.2.8
func FormatCueStepHostResultsForNotify(stepNo int, group []HostExecResult) string
FormatCueStepHostResultsForNotify formats one step’s host results for notify bodies (non-AI steps).
func FormatTargetForDryRun ¶
FormatTargetForDryRun returns a string describing how the target will be connected to.
func GetExecutor ¶
GetExecutor returns the appropriate Executor for a host record.
func HostConnectableForTransfer ¶ added in v0.2.8
HostConnectableForTransfer reports whether a record can be dialed for SSH or Kubernetes pod exec.
func IsAgentTransferValidationError ¶ added in v0.2.8
IsAgentTransferValidationError reports whether err is an AgentTransferValidationError (HTTP 400 class input).
func IsSSHConnTransientError ¶ added in v0.2.8
IsSSHConnTransientError reports whether err is a transport-level failure that often clears after closing the TCP/SSH session and dialing again (stale cache entry, local routing/socket glitch, reset by peer).
func LoadAISystemPromptFromConfigPath ¶ added in v0.2.8
LoadAISystemPromptFromConfigPath returns defaults.ai_system_prompt from the honey YAML at path, if loadable.
func LoadTransferConfigFromConfigPath ¶ added in v0.2.8
func LoadTransferConfigFromConfigPath(configPath string) config.TransferConfigEffective
LoadTransferConfigFromConfigPath returns the effective transfer config from the honey YAML at path. If path is empty or the file fails to load, returns defaults.
func PrintStaticTable ¶ added in v0.2.6
PrintStaticTable prints the records as an ASCII table to stdout and exits.
func RemoteCopyLocalToRemote ¶ added in v0.2.8
func RemoteCopyLocalToRemote(user string, record hosts.Record, localPath, remotePath string, cache *ClientCache) error
RemoteCopyLocalToRemote uploads a local file to the remote path.
func RemoteCopyRemoteToLocal ¶ added in v0.2.8
func RemoteCopyRemoteToLocal(user string, record hosts.Record, remotePath, localPath string, cache *ClientCache) error
RemoteCopyRemoteToLocal downloads a remote file to a local path.
func ResizeFromColsRows ¶ added in v0.2.7
func ResizeFromColsRows(cols, rows int) *remotecommand.TerminalSize
ResizeFromColsRows returns a terminal size for k8s remotecommand, or nil if cols or rows are non-positive.
func ResolveAgentTransferSigningHints ¶ added in v0.2.8
func ResolveAgentTransferSigningHints(configPath string, cloud AgentCloudBackend, ref *CloudBackendRef) (cloudtransfer.SigningHints, error)
ResolveAgentTransferSigningHints loads honey config when ref is set and fills AWS/GCP signing hints (same semantics as the web files API). configPath is the explicit or resolved honey YAML path.
func ResolveLocalPathUnderRoot ¶ added in v0.2.8
ResolveLocalPathUnderRoot resolves requested against root and ensures the result stays under root.
func RunCueRecipeSteps ¶
func RunCueRecipeSteps(ctx context.Context, out io.Writer, recipe cuetry.Recipe, recipeDir string, records []hosts.Record, sshUser string, execute bool, cliEnv map[string]string, configPath string, aiSystemPromptFromCfg string, secretResolver cuetry.SecretResolver, pluginMgr *plugins.Manager, rec *SessionRecorder) error
RunCueRecipeSteps executes a CUE recipe over a slice of target records without streaming. cliEnv is merged into each command/script step's remote env (overrides recipe env on duplicate keys); nil is treated as empty. configPath is the resolved honey YAML path (may be empty); agent_transfer with cloud_backend_ref requires it. rec, when non-nil, records a batch .hrec.jsonl (plan on dry-run, result rows on execute). Caller must Close(rec).
func RunK8sPodWebTTY ¶ added in v0.2.7
func RunK8sPodWebTTY( ctx context.Context, r hosts.Record, stdin io.Reader, stdout, stderr io.Writer, cols, rows int, resizeCh <-chan *remotecommand.TerminalSize, ) error
RunK8sPodWebTTY runs an interactive shell in a Kubernetes pod with TTY over stdin/stdout/stderr, using the same dial path as the CLI (ephemeral debug container). Resize events are consumed from resizeCh.
func RunRecordingReplay ¶ added in v0.2.8
RunRecordingReplay plays one .hrec.jsonl in a nested full-screen Bubble Tea view.
func RunTable ¶
func RunTable(records []hosts.Record, sshUser string, opts RunTableOptions) error
RunTable shows an interactive table and optionally execs ssh. After SSH/Tunnel disconnects, it returns to the UI.
func RunTerminalInteractive ¶ added in v0.2.9
RunTerminalInteractive opens an interactive session (SSH, K8s, or Proxmox) on os.Stdin/Stdout.
func SSHClientCacheKey ¶ added in v0.2.8
SSHClientCacheKey is the stable cache key for a pooled SSH client for (user, record).
func StreamCueRecipeSteps ¶
func StreamCueRecipeSteps(ctx context.Context, recipe cuetry.Recipe, recipeDir string, records []hosts.Record, sshUser string, cliEnv map[string]string, configPath string, aiSystemPromptFromCfg string, secretResolver cuetry.SecretResolver, pluginMgr *plugins.Manager, execute bool, out chan<- HostExecResult) error
StreamCueRecipeSteps executes a CUE recipe step-by-step, streaming results. configPath is the resolved honey YAML path (may be empty); agent_transfer steps with cloud_backend_ref require it. aiSystemPromptFromCfg is defaults.ai_system_prompt (already loaded), used only for the terminal ai step.
func StreamSFTPDownloadParallel ¶
func StreamSFTPDownloadParallel(user string, jobs []SFTPDownloadJob, maxConc int, out chan<- HostExecResult, cache *ClientCache) error
StreamSFTPDownloadParallel downloads files from multiple hosts in parallel.
func StreamSFTPUploadParallel ¶
func StreamSFTPUploadParallel(user string, recs []hosts.Record, localAbs, remotePath string, maxConc int, out chan<- HostExecResult, cache *ClientCache) error
StreamSFTPUploadParallel uploads the same local file to remotePath on each record (SFTP over DialHoneyClient). Failures on one host do not cancel others.
func StreamSSHParallel ¶
func StreamSSHParallel(ctx context.Context, user string, jobs []hosts.Record, kvTunnel bool, remoteCmd SSHRemoteCmdFunc, maxConc int, out chan<- HostExecResult, cache *ClientCache, recipeKV *RecipeKVCoordinator, recipeScopedKV bool, post SSHPostHostResultFunc) error
StreamSSHParallel runs the command on records and streams results to out channel. It does not close the channel itself.
func StreamScriptUploadRunParallel ¶
func StreamScriptUploadRunParallel(ctx context.Context, user string, recs []hosts.Record, localAbs, remotePath string, kvTunnel bool, remoteCmd SSHRemoteCmdFunc, maxConc int, out chan<- HostExecResult, cache *ClientCache, recipeKV *RecipeKVCoordinator, recipeScopedKV bool, post SSHPostHostResultFunc) error
StreamScriptUploadRunParallel uploads a script and executes it on multiple hosts in parallel.
func TransferStagingObjectKey ¶ added in v0.2.8
func TransferStagingObjectKey(cloud AgentCloudBackend, src, dst hosts.Record) string
TransferStagingObjectKey builds a unique object key when the caller leaves cloud.Object empty.
func TruncateCueTranscript ¶ added in v0.2.8
TruncateCueTranscript limits transcript size for LLM input; keeps head and tail with a banner if truncated.
func WrapRecordingReader ¶ added in v0.2.8
WrapRecordingReader returns a Reader that tees reads into recorder when non-nil.
func WrapRecordingWriter ¶ added in v0.2.8
WrapRecordingWriter returns a Writer that tees writes into recorder when non-nil.
func WriteCueKVTunnelDryLine ¶ added in v0.2.8
func WriteCueKVTunnelDryLine(out io.Writer, recipe cuetry.Recipe, stepIdx int, step cuetry.RecipeStep, def *cuetry.RecipeDefaults)
WriteCueKVTunnelDryLine prints one plan line when kv_tunnel is enabled for the step or defaults.
func WriteCueSSHPrivateKeyDryLine ¶ added in v0.2.9
func WriteCueSSHPrivateKeyDryLine(out io.Writer, stepIdx int, step cuetry.RecipeStep, def *cuetry.RecipeDefaults)
WriteCueSSHPrivateKeyDryLine prints one plan line when ssh_private_key is set for the step or defaults.
func WriteCueStepHooksDryLines ¶ added in v0.2.8
func WriteCueStepHooksDryLines(out io.Writer, stepIdx int, step cuetry.RecipeStep)
WriteCueStepHooksDryLines prints one plan line per configured hook (no secrets).
func WriteCueStepNotifyDryLine ¶ added in v0.2.8
func WriteCueStepNotifyDryLine(out io.Writer, step cuetry.RecipeStep)
WriteCueStepNotifyDryLine prints one plan line when notify is enabled (boolean only; no secrets).
Types ¶
type AgentCloudBackend ¶ added in v0.2.8
type AgentCloudBackend struct {
Provider string `json:"provider"`
Bucket string `json:"bucket"`
Prefix string `json:"prefix,omitempty"`
Object string `json:"object,omitempty"`
Region string `json:"region,omitempty"`
Endpoint string `json:"endpoint,omitempty"`
}
AgentCloudBackend describes the cloud object target path for staging.
type AgentTransferEndpoint ¶ added in v0.2.8
AgentTransferEndpoint identifies one source/destination endpoint for transfer.
type AgentTransferEvent ¶ added in v0.2.8
type AgentTransferEvent struct {
Stage string `json:"stage"`
Host string `json:"host,omitempty"`
Success bool `json:"success"`
Message string `json:"message,omitempty"`
Error string `json:"error,omitempty"`
Attempt int `json:"attempt,omitempty"`
Timestamp time.Time `json:"timestamp"`
}
AgentTransferEvent is emitted for each orchestration stage.
func ExecuteAgentCloudTransfer ¶ added in v0.2.8
func ExecuteAgentCloudTransfer(job AgentTransferJob, cache *ClientCache) ([]AgentTransferEvent, error)
ExecuteAgentCloudTransfer orchestrates source upload and destination download using ephemeral transfer agents over existing HostClient connections (SSH / k8s pod exec abstraction).
func ExecuteAgentCloudTransferWithEmit ¶ added in v0.2.8
func ExecuteAgentCloudTransferWithEmit(job AgentTransferJob, cache *ClientCache, emit func(AgentTransferEvent)) ([]AgentTransferEvent, error)
ExecuteAgentCloudTransferWithEmit runs the transfer and calls emit for each event.
func RunAgentTransferWithFallback ¶ added in v0.2.8
func RunAgentTransferWithFallback( ctx context.Context, cache *ClientCache, sshUser, agentOverride, preferredAgentPath, agentBuildCacheDir, agentRemoteDir string, src, dst hosts.Record, srcPath, dstPath string, cloud AgentCloudBackend, keepObject bool, maxRetries int, hints cloudtransfer.SigningHints, transferCfg config.TransferConfigEffective, emit func(AgentTransferEvent), ) ([]AgentTransferEvent, error)
RunAgentTransferWithFallback runs Build + Execute, transparently retrying via the agent path on fallback-path failure when transferCfg.PresignedRetryWithAgent is true. Returns the combined event timeline across both attempts so the caller always sees the full record.
emit may be nil; when non-nil it receives events as they happen for both attempts (the original fallback-path attempt and the agent-path retry).
type AgentTransferJob ¶ added in v0.2.8
type AgentTransferJob struct {
SSHUser string `json:"ssh_user"`
ResolvedSourceUser string `json:"resolved_source_user"`
ResolvedDestUser string `json:"resolved_dest_user"`
AgentLocalPath string `json:"agent_local_path"`
SourceAgentLocalPath string `json:"source_agent_local_path,omitempty"`
DestAgentLocalPath string `json:"dest_agent_local_path,omitempty"`
AgentRemoteDir string `json:"agent_remote_dir,omitempty"`
Source AgentTransferEndpoint `json:"source"`
Destination AgentTransferEndpoint `json:"destination"`
Cloud AgentCloudBackend `json:"cloud"`
CredentialProvider string `json:"credential_provider,omitempty"`
CredentialEnv map[string]string `json:"credential_env,omitempty"`
CredentialExpiresAtUnix int64 `json:"credential_expires_at_unix,omitempty"`
KeepObject bool `json:"keep_object,omitempty"`
MaxRetries int `json:"max_retries,omitempty"`
// FallbackPlan is non-nil when the curl-based presigned-URL transport should be
// used instead of the staged-agent path. See docs/superpowers/specs/2026-05-12-presigned-url-transfer-path-design.md.
FallbackPlan *presign.Plan `json:"-"`
FallbackCapabilitySrc string `json:"-"`
FallbackCapabilityDst string `json:"-"`
// RetryWithAgentOnCurlFailure controls whether a fallback-path failure transparently
// retries via the agent path.
RetryWithAgentOnCurlFailure bool `json:"retry_with_agent_on_curl_failure,omitempty"`
}
AgentTransferJob describes one A->cloud->B transfer orchestration request.
func BuildAgentTransferJob ¶ added in v0.2.8
func BuildAgentTransferJob( ctx context.Context, cache *ClientCache, sshUser, agentOverride, preferredAgentPath, agentBuildCacheDir, agentRemoteDir string, src, dst hosts.Record, srcPath, dstPath string, cloud AgentCloudBackend, keepObject bool, maxRetries int, hints cloudtransfer.SigningHints, transferCfg config.TransferConfigEffective, ) (AgentTransferJob, error)
BuildAgentTransferJob wires cloud credentials, per-target agent binaries, and staging object key. preferredAgentPath is used when agentOverride is empty (e.g. web server default binary); agentBuildCacheDir overrides the directory for cross-compiled agents (empty uses HONEY_TRANSFER_AGENT_CACHE or os temp).
transferCfg controls whether the fallback-path (presigned-URL) transport is attempted before falling back to staging the transfer-agent binary. When transferCfg.ForceAgentPath is true, the curl branch is bypassed.
type AgentTransferValidationError ¶ added in v0.2.8
type AgentTransferValidationError struct {
// contains filtered or unexported fields
}
AgentTransferValidationError indicates user/input issues (HTTP 400).
func (*AgentTransferValidationError) Error ¶ added in v0.2.8
func (e *AgentTransferValidationError) Error() string
type ClientCache ¶
type ClientCache struct {
// contains filtered or unexported fields
}
ClientCache maintains a pool of open HostClient connections for reuse across steps.
func NewClientCache ¶
func NewClientCache() *ClientCache
NewClientCache creates a new initialized ClientCache.
func (*ClientCache) CloseAll ¶
func (c *ClientCache) CloseAll()
CloseAll closes all cached connections and clears the cache.
func (*ClientCache) Evict ¶ added in v0.2.8
func (c *ClientCache) Evict(user string, r hosts.Record)
Evict removes the cached client for this host (if any) and closes it so the next GetOrDial establishes a fresh connection.
func (*ClientCache) GetOrDial ¶
func (c *ClientCache) GetOrDial(user string, r hosts.Record) (HostClient, error)
GetOrDial returns an existing connection or dials a new one and stores it.
type CloudBackendRef ¶ added in v0.2.8
type CloudBackendRef struct {
Kind string `json:"kind"`
Name string `json:"name,omitempty"`
Index *int `json:"index,omitempty"`
}
CloudBackendRef selects a backend entry from honey YAML for agent-transfer signing hints.
type HostClient ¶
type HostClient = hostexec.HostClient
HostClient aliases the shared execution interface (see internal/hostexec).
type HostExecResult ¶
type HostExecResult struct {
Name string
IP string
Provider string
Success bool
Skipped bool // when CEL was false; no SSH/SFTP ran
ExitCode int
Output string
ErrMsg string // transport / spawn failure (not remote stderr)
// HookPhase / HookOutput are set when a CUE step hook ran after the main result (command/script only).
HookPhase string // "on_success" or "on_failure"
HookOutput string // captured stdout+stderr from the hook (local or remote)
}
HostExecResult is the outcome of one non-interactive ssh run.
func ExecuteSFTPDownloadParallel ¶
func ExecuteSFTPDownloadParallel(user string, jobs []SFTPDownloadJob, maxConc int) ([]HostExecResult, error)
ExecuteSFTPDownloadParallel runs each download job (possibly different local paths per host) in parallel.
func ExecuteSFTPUploadParallel ¶
func ExecuteSFTPUploadParallel(user string, recs []hosts.Record, localAbs, remotePath string, maxConc int) ([]HostExecResult, error)
ExecuteSFTPUploadParallel executes an SFTP upload in parallel across multiple hosts and returns results synchronously.
func ExecuteSSHParallel ¶
func ExecuteSSHParallel(user string, recs []hosts.Record, remoteCmdFunc func(hosts.Record) string, maxConc int) ([]HostExecResult, error)
ExecuteSSHParallel runs the same remote shell command on every record that has PrimaryIP set. Failures on individual hosts do not cancel others. It uses DialHoneyClient (golang.org/x/crypto/ssh + ~/.ssh/config) with known_hosts verification.
func ExecuteScriptUploadRunParallel ¶
func ExecuteScriptUploadRunParallel(user string, recs []hosts.Record, localAbs, remotePath, remoteCmd string, maxConc int) ([]HostExecResult, error)
ExecuteScriptUploadRunParallel uploads localAbs to remotePath on each host over SFTP, then runs remoteCmd on the same SSH connection (one session per host per step).
func RunOneSFTPUploadWithProgress ¶ added in v0.2.8
func RunOneSFTPUploadWithProgress(user string, r hosts.Record, localAbs, remotePath string, cache *ClientCache, onProgress func(written, total int64)) HostExecResult
RunOneSFTPUploadWithProgress uploads one local file to remotePath on r, like runOneSFTPUpload. onProgress is optional; it receives cumulative bytes written toward the remote and the local file size. Live updates are emitted for *sshclient.HoneyClient (SFTP); other executors only report start/end.
func SortHostExecForUI ¶
func SortHostExecForUI(s []HostExecResult) []HostExecResult
SortHostExecForUI orders failures first, then host name (case-insensitive).
type LocalFileEntry ¶ added in v0.2.8
type LocalFileEntry struct {
Name string `json:"name"`
Path string `json:"path"`
IsDir bool `json:"is_dir"`
Size int64 `json:"size"`
Mode string `json:"mode"`
ModifiedAt time.Time `json:"modified_at"`
}
LocalFileEntry mirrors RemoteFileEntry for local directories.
func ListLocalDirUnderRoot ¶ added in v0.2.8
func ListLocalDirUnderRoot(root, requested string) (string, []LocalFileEntry, error)
ListLocalDirUnderRoot lists a directory under the resolved root path.
type RecipeKVCoordinator ¶ added in v0.2.8
type RecipeKVCoordinator struct {
// contains filtered or unexported fields
}
RecipeKVCoordinator owns one operator-side stepkv session for a cue-exec run and one forward (SSH remote-forward or k8s exec bridge) per cached client key. The mutex is only held while the per-key placeholder is reserved; the slow handshake runs outside the lock so parallel hosts don't serialize.
func NewRecipeKVCoordinator ¶ added in v0.2.8
func NewRecipeKVCoordinator(ttl time.Duration) *RecipeKVCoordinator
NewRecipeKVCoordinator constructs a coordinator; ttl defaults to stepKVTunnelTTL when <= 0.
func (*RecipeKVCoordinator) Close ¶ added in v0.2.8
func (c *RecipeKVCoordinator) Close()
Close stops all remote listeners / k8s bridges and closes the stepkv session.
func (*RecipeKVCoordinator) EnsureK8sExecBridgeEnv ¶ added in v0.2.8
func (c *RecipeKVCoordinator) EnsureK8sExecBridgeEnv(user string, r hosts.Record, k8c *k8sNativeClient) (map[string]string, error)
EnsureK8sExecBridgeEnv returns HONEY_KV_* for this pod by multiplexing pod loopback HTTP to the shared stepkv session over a long-lived kubectl exec.
func (*RecipeKVCoordinator) EnsureKVTunnelEnv ¶ added in v0.2.8
func (c *RecipeKVCoordinator) EnsureKVTunnelEnv(user string, r hosts.Record, hc *sshclient.HoneyClient) (map[string]string, error)
EnsureKVTunnelEnv returns HONEY_KV_* for this host's remote-forward into the shared session.
func (*RecipeKVCoordinator) EnsureSession ¶ added in v0.2.9
func (c *RecipeKVCoordinator) EnsureSession() (*stepkv.Session, error)
EnsureSession returns the shared stepkv session, creating it if needed (no SSH forward).
func (*RecipeKVCoordinator) InvalidateHost ¶ added in v0.2.8
func (c *RecipeKVCoordinator) InvalidateHost(user string, r hosts.Record)
InvalidateHost tears down this host's remote-forward or k8s exec bridge only (e.g. after cache evict). The shared stepkv session stays open for other hosts.
type RecipeMeta ¶ added in v0.2.8
type RecipeMeta struct {
RecipePath string `json:"recipe_path"`
HostCount int `json:"host_count"`
RecipeContentHash string `json:"recipe_content_hash"`
StartedAt time.Time `json:"started_at"`
}
RecipeMeta describes the recipe that a cue-exec batch is about to run. Recorded into the session file so a later "recent runs" enumeration can attribute the recording to a recipe and detect in-browser edits.
type RemoteFileEntry ¶ added in v0.2.8
type RemoteFileEntry = hostexec.RemoteFileEntry
RemoteFileEntry aliases remote file metadata for JSON APIs.
func RemoteListDir ¶ added in v0.2.8
func RemoteListDir(user string, record hosts.Record, remotePath string, cache *ClientCache) ([]RemoteFileEntry, error)
RemoteListDir lists a directory on the remote host using a cached SSH/k8s client.
type RunTableOptions ¶ added in v0.2.8
type RunTableOptions struct {
RecordDir string
RecordEnabled bool
// Config is the honey YAML already loaded for this session (optional; nil if none / load failed).
Config *config.File
// ConfigPath is the resolved honey YAML path (may be empty); CUE agent_transfer steps with cloud_backend_ref need it.
ConfigPath string
}
RunTableOptions configures optional session recording for the TUI table.
type SFTPDownloadJob ¶
SFTPDownloadJob is one remote→local file copy for a specific host.
type SSHPostHostResultFunc ¶ added in v0.2.8
type SSHPostHostResultFunc func(ctx context.Context, r hosts.Record, res *HostExecResult)
SSHPostHostResultFunc runs after each host's main SSH run and before the result is emitted (e.g. CUE step hooks). It may set res.HookPhase and res.HookOutput. Hook failures must not change the original step success fields.
type SSHRemoteCmdFunc ¶ added in v0.2.8
SSHRemoteCmdFunc builds the remote shell string. kv is nil when kv_tunnel is disabled; otherwise it contains HONEY_KV_URL (reachable from the remote via SSH remote forward) and HONEY_KV_TOKEN for Authorization.
type SessionRecorder ¶ added in v0.2.8
type SessionRecorder struct {
// contains filtered or unexported fields
}
SessionRecorder appends JSONL events to a single .hrec.jsonl file (TTY data, resize, errors, close).
func NewBatchSessionRecorder ¶ added in v0.2.8
func NewBatchSessionRecorder(dir, trigger, user string, jobCount int) (*SessionRecorder, error)
NewBatchSessionRecorder creates a recorder for one parallel exec or CUE batch run (one file per invocation).
func NewSessionRecorder ¶ added in v0.2.8
func NewSessionRecorder(opts SessionRecorderOptions) (*SessionRecorder, error)
NewSessionRecorder creates a recorder writing to opts.Dir with a timestamped filename.
func (*SessionRecorder) Close ¶ added in v0.2.8
func (r *SessionRecorder) Close() error
Close writes a "close" event and closes the underlying file.
func (*SessionRecorder) Path ¶ added in v0.2.8
func (r *SessionRecorder) Path() string
Path returns the absolute path of the recording file, or empty if r is nil.
func (*SessionRecorder) RecordData ¶ added in v0.2.8
func (r *SessionRecorder) RecordData(direction string, payload []byte)
RecordData writes a base64-encoded payload for the given direction (e.g. in/out).
func (*SessionRecorder) RecordError ¶ added in v0.2.8
func (r *SessionRecorder) RecordError(err error)
RecordError records a non-fatal error message on the session.
func (*SessionRecorder) RecordHostExecResult ¶ added in v0.2.8
func (r *SessionRecorder) RecordHostExecResult(res HostExecResult)
RecordHostExecResult writes one structured "result" event (parallel exec / batch output).
func (*SessionRecorder) RecordRecipeMeta ¶ added in v0.2.8
func (r *SessionRecorder) RecordRecipeMeta(meta RecipeMeta)
RecordRecipeMeta writes one "recipe-meta" structured event into the recording. Safe to call on a nil recorder.
func (*SessionRecorder) RecordResize ¶ added in v0.2.8
func (r *SessionRecorder) RecordResize(cols, rows int)
RecordResize records a terminal resize event.
type SessionRecorderOptions ¶ added in v0.2.8
type SessionRecorderOptions struct {
Dir string
Trigger string
Mode string
Provider string
HostName string
HostIP string
User string
// HostSegment, when set, is used for the filename segment instead of HostName/IP (e.g. batch-12).
HostSegment string
}
SessionRecorderOptions configures filename segments and metadata for a new session recording.
Source Files
¶
- agent_transfer.go
- agent_transfer_fallback.go
- agent_transfer_job.go
- agent_transfer_session.go
- agent_transfer_signing.go
- client_cache.go
- cue_ai_transcript.go
- cue_recipe_ai_exec.go
- cue_recipe_graph.go
- cue_recipe_hooks.go
- cue_recipe_plugin.go
- cue_recipe_run.go
- cue_recipe_when.go
- cue_step_notify.go
- doc.go
- executor.go
- file_browser.go
- k8s_executor.go
- k8s_kv_exec_bridge.go
- k8s_kv_pod.go
- k8s_tunnel.go
- k8s_web_tty.go
- klog.go
- recipe_kv.go
- recording_replay.go
- session_recorder.go
- ssh_batch.go
- ssh_batch_kv_tunnel.go
- ssh_dial.go
- ssh_kv_forward.go
- ssh_term.go
- ssh_transport_errors.go
- ssh_web_dial.go
- static_table.go
- table.go
- table_agent_transfer.go
- table_columns.go
- table_exec_view.go
- table_tunnel.go
- table_update.go
- transfer_detect.go