mirror of
https://github.com/OpenRouterTeam/spawn.git
synced 2026-05-09 19:49:58 +00:00
Wire up connection tracking across all 10 clouds so users can reconnect to and delete previously spawned servers via `spawn list` and `spawn delete`. Phase 1 - Connection tracking: - Extend save_vm_connection() with cloud and metadata params - Add save_vm_connection to create_server() in all cloud libs - Extend VMConnection with cloud, deleted, deleted_at, metadata fields Phase 2 - Delete via interactive picker: - Add "Delete this server" option to spawn list picker - Build delete scripts that reuse each cloud's destroy_server() - Confirmation UX with spinner feedback - Soft-delete marking in history (deleted records show [deleted]) Phase 3 - Standalone delete command: - spawn delete (aliases: rm, destroy) with interactive picker - Filter support: spawn delete -a <agent> -c <cloud> Also improves reconnect hints for Fly (fly ssh console) and Daytona (daytona ssh) connections. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
99 lines
2.7 KiB
Bash
99 lines
2.7 KiB
Bash
#!/bin/bash
|
|
set -eo pipefail
|
|
# Common bash functions for local machine spawn scripts
|
|
# No cloud provisioning — runs agents directly on the user's machine
|
|
|
|
# ============================================================
|
|
# Provider-agnostic functions
|
|
# ============================================================
|
|
|
|
# Source shared provider-agnostic functions (local or remote fallback)
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)"
|
|
if [[ -n "${SCRIPT_DIR}" && -f "${SCRIPT_DIR}/../../shared/common.sh" ]]; then
|
|
source "${SCRIPT_DIR}/../../shared/common.sh"
|
|
else
|
|
eval "$(curl -fsSL https://raw.githubusercontent.com/OpenRouterTeam/spawn/main/shared/common.sh)"
|
|
fi
|
|
|
|
# ============================================================
|
|
# Local machine functions
|
|
# ============================================================
|
|
|
|
# No authentication needed for local machine
|
|
ensure_local_ready() {
|
|
log_info "Running on local machine"
|
|
|
|
# Ensure basic tools are available
|
|
if ! command -v curl &>/dev/null; then
|
|
log_error "curl is required but not installed"
|
|
return 1
|
|
fi
|
|
|
|
check_python_available || return 1
|
|
}
|
|
|
|
# No server name needed — use hostname
|
|
get_server_name() {
|
|
local name
|
|
name=$(hostname 2>/dev/null || echo "local")
|
|
echo "${name}"
|
|
}
|
|
|
|
# No server creation — it's the local machine
|
|
create_server() {
|
|
local name="${1}"
|
|
log_info "Using local machine: ${name}"
|
|
|
|
save_vm_connection "localhost" "${USER:-$(whoami)}" "" "$name" "local"
|
|
}
|
|
|
|
# No cloud-init needed
|
|
wait_for_cloud_init() {
|
|
:
|
|
}
|
|
|
|
# Run a command locally
|
|
# The command string is passed directly to bash -c for shell parsing.
|
|
# All callers pass trusted, hardcoded command strings (not user input).
|
|
run_server() {
|
|
local cmd="${1}"
|
|
bash -c "${cmd}"
|
|
}
|
|
|
|
# Copy a file locally
|
|
upload_file() {
|
|
local local_path="${1}"
|
|
local remote_path="${2}"
|
|
# Expand ~ in remote_path
|
|
local expanded_path="${remote_path/#\~/$HOME}"
|
|
mkdir -p "$(dirname "${expanded_path}")"
|
|
cp "${local_path}" "${expanded_path}"
|
|
}
|
|
|
|
# Start an interactive session locally
|
|
interactive_session() {
|
|
local cmd="${1}"
|
|
bash -c "${cmd}"
|
|
}
|
|
|
|
# No server to destroy
|
|
destroy_server() {
|
|
log_info "Nothing to destroy (local machine)"
|
|
}
|
|
|
|
# No servers to list
|
|
list_servers() {
|
|
printf '%s\n' "$(hostname 2>/dev/null || echo "local")"
|
|
}
|
|
|
|
# ============================================================
|
|
# Cloud adapter interface
|
|
# ============================================================
|
|
|
|
cloud_authenticate() { ensure_local_ready; }
|
|
cloud_provision() { create_server "$1"; }
|
|
cloud_wait_ready() { :; }
|
|
cloud_run() { run_server "$1"; }
|
|
cloud_upload() { upload_file "$1" "$2"; }
|
|
cloud_interactive() { bash -c "$1"; }
|
|
cloud_label() { echo "local machine"; }
|