#!/usr/bin/env bash # Build and optionally configure a Docker sandbox interactively. set -o errexit set -o nounset set -o pipefail readonly KIT_PATH="$HOME/.sbx/kits/hypoport.ai" readonly TEMPLATE='127.0.0.1:62735/finmas.de/mux033/opencode-ops:latest' require_command() { local command_name="$1" local message="$2" if ! command -v "$command_name" >/dev/null 2>&1; then printf '%s\n' "$message" >&2 exit 1 fi } ask_yes_no() { local prompt="$1" local answer while true; do read -r -p "$prompt [y/n] " answer || exit 0 case "$answer" in [Yy]) return 0 ;; [Nn]) return 1 ;; *) printf 'Please answer yes or no.\n' ;; esac done } prompt_component() { local result_var="$1" local label="$2" shift 2 local options=("$@" custom) local choice custom_value while true; do printf '%s:\n' "$label" select choice in "${options[@]}"; do case "$choice" in custom) read -r -p "Custom $label: " custom_value || exit 0 if [[ -n "$custom_value" ]]; then printf -v "$result_var" '%s' "$custom_value" return 0 fi printf 'The custom value cannot be empty.\n' ;; '') printf 'Please select one of the listed options.\n' ;; *) printf -v "$result_var" '%s' "$choice" return 0 ;; esac done done } main() { require_command sbx 'We cannot build a Docker sbx image because sbx does not seem to be installed.' require_command jq 'We cannot list existing Docker sbx sandboxes because jq does not seem to be installed.' local build_from_scratch if ask_yes_no 'Build from scratch?'; then build_from_scratch=true else build_from_scratch=false fi local sandbox_json if ! sandbox_json=$(sbx ls --json); then printf 'Unable to retrieve the existing Docker sbx sandboxes.\n' >&2 exit 1 fi if ! jq -s -e 'length == 1 and (.[0].sandboxes | type == "array")' \ <<< "$sandbox_json" >/dev/null; then printf 'The output from sbx ls --json was not the expected JSON format.\n' >&2 exit 1 fi local -a sandbox_names mapfile -t sandbox_names < <(jq -r '.sandboxes[].name' <<< "$sandbox_json") local base_sandbox_name next_version selected_sandbox local -a current_workspace_paths=() local -a workspace_paths=() if [[ "$build_from_scratch" == true ]]; then prompt_component sandbox_prefix 'Sandbox prefix' 'finmas-gmbh' 'private' prompt_component sandbox_purpose 'Sandbox purpose' 'git-work' 'generic-research' prompt_component sandbox_suffix 'Sandbox suffix' 'finmas-api' 'private-api' base_sandbox_name="${sandbox_prefix}-${sandbox_purpose}-${sandbox_suffix}" next_version=1 else require_command fzf 'We cannot select an existing Docker sbx image because fzf does not seem to be installed.' if ((${#sandbox_names[@]} == 0)); then printf 'No existing Docker sbx sandboxes were found.\n' >&2 exit 1 fi if ! selected_sandbox=$(printf '%s\n' "${sandbox_names[@]}" | fzf \ --prompt='Select Docker sbx image: ' --height=40% --reverse); then printf 'No Docker sbx image was selected.\n' exit 0 fi mapfile -t current_workspace_paths < <( jq -r --arg name "$selected_sandbox" \ '.sandboxes[] | select(.name == $name) | .workspaces[]?' \ <<< "$sandbox_json" ) if [[ "$selected_sandbox" =~ ^(.*)-v([0-9]+)$ ]]; then base_sandbox_name="${BASH_REMATCH[1]}" next_version=$((10#${BASH_REMATCH[2]} + 1)) else base_sandbox_name="$selected_sandbox" next_version=1 fi fi local new_sandbox_name="${base_sandbox_name}-v${next_version}" if [[ "$build_from_scratch" == true && ( "$sandbox_prefix" != 'finmas-gmbh' || "$sandbox_suffix" == 'private-api' ) ]]; then workspace_paths=("$HOME/docker-sbx/empty") else workspace_paths=("$HOME/Documents/git") fi if [[ "$build_from_scratch" == true ]]; then current_workspace_paths=("${workspace_paths[@]}") fi printf 'Workspace directories in the current sandbox:\n' if ((${#current_workspace_paths[@]} == 0)); then printf 'No workspace directories were reported.\n' else printf '%s\n' "${current_workspace_paths[@]}" fi if ask_yes_no 'Do you want to add additional workspace directories?'; then local workspace_path while true; do read -r -p 'Additional workspace path (press Enter when finished): ' workspace_path || exit 0 [[ -z "$workspace_path" ]] && break workspace_paths+=("$workspace_path") done fi printf 'Creating Docker sbx image: %s\n' "$new_sandbox_name" if ! sbx create opencode \ --name "$new_sandbox_name" \ --kit "$KIT_PATH" \ --template "$TEMPLATE" \ "${workspace_paths[@]}"; then printf 'Unable to create Docker sbx image: %s\n' "$new_sandbox_name" >&2 exit 1 fi } main "$@"