diff --git a/src/agency-agents/devcontainer-feature.json b/src/agency-agents/devcontainer-feature.json index 4902a3e..3d9aa54 100644 --- a/src/agency-agents/devcontainer-feature.json +++ b/src/agency-agents/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "agency-agents", - "version": "0.3.8", + "version": "0.3.9", "name": "Agency Agents", "description": "A complete AI agency at your fingertips - From frontend wizards to Reddit community ninjas, from whimsy injectors to reality checkers. Each agent is a specialized expert with personality, processes, and proven deliverables. Credits: https://github.com/msitarzewski/agency-agents.", "documentationURL": "https://github.com/wcgomes/devcontainer-features?tab=readme-ov-file#feature-agency-agents", diff --git a/src/agency-agents/install.sh b/src/agency-agents/install.sh index 03b27a0..d4df3a0 100644 --- a/src/agency-agents/install.sh +++ b/src/agency-agents/install.sh @@ -1,5 +1,4 @@ #!/bin/sh - set -eu log() { @@ -59,12 +58,10 @@ ensure_prerequisites() { missing="${missing} curl" fi - # Minimal images may lack a CA bundle required for HTTPS downloads. if [ ! -f /etc/ssl/certs/ca-certificates.crt ]; then missing="${missing} ca-certificates" fi - # Trim leading spaces for cleaner logs and checks. missing="$(echo "$missing" | sed 's/^ *//')" [ -n "$missing" ] || return 0 @@ -73,240 +70,23 @@ ensure_prerequisites() { fail "Missing dependencies: $missing. Rebuild as root or preinstall them in the base image." fi - log "Installing missing dependencies:$missing" + log "Installing missing dependencies: $missing" install_packages $missing - command -v unzip >/dev/null 2>&1 || fail "Dependency installation failed: unzip is still missing" - command -v curl >/dev/null 2>&1 || command -v wget >/dev/null 2>&1 || fail "Dependency installation failed: curl/wget are still missing" - [ -f /etc/ssl/certs/ca-certificates.crt ] || fail "Dependency installation failed: CA certificates are still missing" -} - -get_remote_commit() { - curl -fsSL "https://api.github.com/repos/msitarzewski/agency-agents/commits/main" 2>/dev/null | \ - grep -o '"sha": "[a-f0-9]*' | cut -d'"' -f4 | cut -c1-7 -} - -autoupdate_check() { - if [ "$autoupdate" != "true" ]; then - return 0 - fi - - if [ ! -f "$commit_file" ]; then - log "Autoupdate: skipped (no commit file found)" - return 0 - fi - - installed_commit="$(cat "$commit_file")" - if [ -z "$installed_commit" ]; then - log "Autoupdate: skipped (empty commit file)" - return 0 - fi - - log "Autoupdate: checking for updates..." - - remote_commit="$(get_remote_commit)" - if [ -z "$remote_commit" ]; then - log "Autoupdate: skipped (unable to fetch remote commit)" - return 0 - fi - - if [ "$remote_commit" = "$installed_commit" ]; then - log "Autoupdate: already on latest version ($remote_commit)" - return 0 - fi - - log "Autoupdate: new version available ($installed_commit → $remote_commit), updating..." - - rm -f "$marker_file" - rm -f "$commit_file" - return 1 -} - -# Dev Container Features export options as uppercase env vars (e.g. TOOL). -# Keep FEATURE_OPTION_TOOL as a compatibility fallback. -tool="${TOOL:-${FEATURE_OPTION_TOOL:-auto}}" -autoupdate="${AGENCY_AGENTS_AUTOUPDATE:-${AUTOUPDATE:-true}}" - -case "$tool" in - "") - fail "Option 'tool' cannot be empty." - ;; - *[!a-zA-Z0-9_-]*) - fail "Option 'tool' contains invalid characters: '$tool'." - ;; -esac - -detect_user() { - local user="" - - if [ -n "${_REMOTE_USER:-}" ]; then - user="$_REMOTE_USER" - elif [ -n "$USERNAME" ]; then - user="$USERNAME" - else - user="$(getent passwd 1000 | cut -d: -f1)" || true - [ -z "$user" ] && user="$(whoami 2>/dev/null)" || true - [ -z "$user" ] && user="vscode" - fi - - local valid_users - valid_users="$(getent passwd | awk -F: 'BEGIN {first=""} $3 >= 1000 && $1 !~ /^(nobody|nfsnobody)$/ {first=$1; exit} END {print first}')" || true - - if [ -n "$user" ]; then - local user_shell - user_shell="$(getent passwd "$user" | cut -d: -f7)" || true - case "$user_shell" in - */nologin|*/false) - user="$valid_users" - ;; - esac - fi - - if [ -z "$user" ] || [ ! -d "/home/$user" ]; then - user="$valid_users" - fi - - [ -z "$user" ] && user="vscode" - echo "$user" + command -v unzip >/dev/null 2>&1 || fail "Dependency installation failed: unzip" + command -v curl >/dev/null 2>&1 || command -v wget >/dev/null 2>&1 || fail "Dependency installation failed: curl/wget" + [ -f /etc/ssl/certs/ca-certificates.crt ] || fail "Dependency installation failed: CA certificates" } ensure_prerequisites marker_dir="/usr/local/share/devcontainer-features" - -TARGET_USER="$(detect_user)" -TARGET_HOME="$(getent passwd "$TARGET_USER" | cut -d: -f6)" -[ -z "$TARGET_HOME" ] && TARGET_HOME="/home/$TARGET_USER" - -# v1 marker is tool-agnostic since postStartCommand uses auto tool detection. -# Also maintain per-tool markers for test compatibility. -marker_file="$marker_dir/agency-agents-v1-${TARGET_USER}.done" -commit_file="$marker_dir/agency-agents-v1.commit" -tool_marker="$marker_dir/agency-agents-v1-${tool}-${TARGET_USER}.done" - -if [ -f "$marker_file" ] || [ -f "$tool_marker" ]; then - log "Installation already completed for tool '$tool'." - if [ -f "$commit_file" ] && [ -s "$commit_file" ]; then - autoupdate_check - else - remote_final_commit="$(get_remote_commit)" - if [ -n "$remote_final_commit" ]; then - echo "$remote_final_commit" > "$commit_file" - log "Saved commit: $remote_final_commit" - fi - fi - exit 0 -fi - -if [ -f "$commit_file" ]; then - autoupdate_check || true -fi - mkdir -p "$marker_dir" -tmp_dir="$(mktemp -d /tmp/agency-agents-XXXXXX)" -cleanup() { - rm -rf "$tmp_dir" -} -trap cleanup EXIT - -zip_file="$tmp_dir/agency-agents.zip" - -log "Downloading repository ZIP..." -if command -v curl >/dev/null 2>&1; then - curl -fsSL "https://github.com/msitarzewski/agency-agents/archive/refs/heads/main.zip" -o "$zip_file" \ - || curl -fsSL "https://github.com/msitarzewski/agency-agents/archive/refs/heads/master.zip" -o "$zip_file" \ - || fail "Unable to download repository ZIP (main/master)." -else - wget -qO "$zip_file" "https://github.com/msitarzewski/agency-agents/archive/refs/heads/main.zip" \ - || wget -qO "$zip_file" "https://github.com/msitarzewski/agency-agents/archive/refs/heads/master.zip" \ - || fail "Unable to download repository ZIP (main/master)." -fi - -log "Extracting repository ZIP..." -unzip -q "$zip_file" -d "$tmp_dir" - -repo_dir="$(find "$tmp_dir" -mindepth 1 -maxdepth 1 -type d | head -n1 || true)" -[ -n "$repo_dir" ] || fail "Could not locate extracted repository directory." - -[ -f "$repo_dir/scripts/convert.sh" ] || fail "Missing script: scripts/convert.sh" -[ -f "$repo_dir/scripts/install.sh" ] || fail "Missing script: scripts/install.sh" - -chmod +x "$repo_dir/scripts/convert.sh" "$repo_dir/scripts/install.sh" - -log "Running convert.sh..." -( - cd "$repo_dir" - ./scripts/convert.sh -) - -if [ "$tool" = "auto" ]; then - log "Running install.sh --no-interactive --parallel (auto tool detection)..." -else - log "Running install.sh --tool $tool --no-interactive..." -fi - -opencode_agents_src="$repo_dir/integrations/opencode/agents" -opencode_agents_global="$TARGET_HOME/.config/opencode/agents" - -should_install_opencode() { - case "$tool" in - auto|all|opencode) return 0 ;; - *) return 1 ;; - esac -} - -if [ "$(id -u)" -eq 0 ] && [ "$TARGET_USER" != "root" ] && id "$TARGET_USER" >/dev/null 2>&1; then - log "Installing for user '$TARGET_USER' (HOME=$TARGET_HOME)..." - chown -R "$TARGET_USER":"$TARGET_USER" "$tmp_dir" - chmod -R u+rwX,go+rX "$tmp_dir" - if [ "$tool" = "auto" ]; then - su - "$TARGET_USER" -c "cd '$repo_dir' && HOME='$TARGET_HOME' ./scripts/install.sh --no-interactive --parallel" - else - su - "$TARGET_USER" -c "cd '$repo_dir' && HOME='$TARGET_HOME' ./scripts/install.sh --tool '$tool' --no-interactive" - fi - if should_install_opencode && [ -d "$opencode_agents_src" ]; then - log "Installing OpenCode agents globally to $opencode_agents_global..." - mkdir -p "$opencode_agents_global" - cp "$opencode_agents_src"/*.md "$opencode_agents_global/" 2>/dev/null || true - chown -R "$TARGET_USER":"$TARGET_USER" "$opencode_agents_global" - log "OpenCode agents installed globally." - fi -else - log "Installing for current user '$(id -un)' (HOME=${HOME:-unknown})..." - ( - cd "$repo_dir" - if [ "$tool" = "auto" ]; then - ./scripts/install.sh --no-interactive --parallel - else - ./scripts/install.sh --tool "$tool" --no-interactive - fi - ) - if should_install_opencode && [ -d "$opencode_agents_src" ]; then - log "Installing OpenCode agents globally to $opencode_agents_global..." - mkdir -p "$opencode_agents_global" - cp "$opencode_agents_src"/*.md "$opencode_agents_global/" 2>/dev/null || true - log "OpenCode agents installed globally." - fi -fi - -touch "$marker_file" -touch "$tool_marker" - -remote_final_commit="$(get_remote_commit)" -if [ -n "$remote_final_commit" ]; then - echo "$remote_final_commit" > "$commit_file" -fi - -# Copy install.sh for postStartCommand autoupdate -cp "$0" "$marker_dir/agency-agents-install.sh" -chmod +x "$marker_dir/agency-agents-install.sh" - -# Copy postStartCommand.sh poststart_script="$(dirname "$0")/postStartCommand.sh" if [ -f "$poststart_script" ]; then cp "$poststart_script" "$marker_dir/agency-agents-postStartCommand.sh" chmod +x "$marker_dir/agency-agents-postStartCommand.sh" fi -log "Installation completed for tool '$tool'." +log "Scripts copied. Installation will run in postStartCommand." \ No newline at end of file diff --git a/src/agency-agents/postStartCommand.sh b/src/agency-agents/postStartCommand.sh index 5b81242..b2b45c4 100755 --- a/src/agency-agents/postStartCommand.sh +++ b/src/agency-agents/postStartCommand.sh @@ -1,8 +1,8 @@ #!/bin/bash set -euo pipefail -INSTALL_SCRIPT="${AGENCY_AGENTS_POSTSTART_SCRIPT:-/usr/local/share/devcontainer-features/agency-agents-install.sh}" MARKER="${HOME}/.local/share/devcontainer-features/agency-agents.done" +COMMIT_FILE="${HOME}/.local/share/devcontainer-features/agency-agents.commit" TARGET_USER="${USER:-$(whoami)}" [ -z "$TARGET_USER" ] && TARGET_USER="$(getent passwd | awk -F: '$3 >= 1000 {print $1; exit 0}')" @@ -13,26 +13,151 @@ export _REMOTE_USER="$TARGET_USER" export TOOL="${TOOL:-auto}" export AUTOUPDATE="${AUTOUPDATE:-true}" -echo "[agency-agents-poststart] Checking installation script..." +log() { + echo "[agency-agents-poststart] $*" +} -if [ ! -f "$INSTALL_SCRIPT" ]; then - echo "[agency-agents-poststart] Installation script not found at $INSTALL_SCRIPT" - exit 0 -fi +fail() { + echo "[agency-agents-poststart] ERROR: $*" >&2 + exit 1 +} + +get_remote_commit() { + curl -fsSL "https://api.github.com/repos/msitarzewski/agency-agents/commits/main" 2>/dev/null | \ + grep -o '"sha": "[a-f0-9]*' | cut -d'"' -f4 | cut -c1-7 +} + +do_install() { + log "Starting installation for user '$TARGET_USER'..." + + local tool="${TOOL:-auto}" + + local TARGET_HOME + TARGET_HOME="$(getent passwd "$TARGET_USER" | cut -d: -f6)" + [ -z "$TARGET_HOME" ] && TARGET_HOME="/home/$TARGET_USER" + + local tmp_dir + tmp_dir="$(mktemp -d /tmp/agency-agents-XXXXXX)" + CLEANUP_DIR="$tmp_dir" + cleanup() { + rm -rf "$CLEANUP_DIR" + } + trap cleanup EXIT + + local zip_file="$tmp_dir/agency-agents.zip" + + log "Downloading repository ZIP..." + if command -v curl >/dev/null 2>&1; then + curl -fsSL "https://github.com/msitarzewski/agency-agents/archive/refs/heads/main.zip" -o "$zip_file" \ + || curl -fsSL "https://github.com/msitarzewski/agency-agents/archive/refs/heads/master.zip" -o "$zip_file" \ + || fail "Unable to download repository ZIP (main/master)." + else + wget -qO "$zip_file" "https://github.com/msitarzewski/agency-agents/archive/refs/heads/main.zip" \ + || wget -qO "$zip_file" "https://github.com/msitarzewski/agency-agents/archive/refs/heads/master.zip" \ + || fail "Unable to download repository ZIP (main/master)." + fi + + log "Extracting repository ZIP..." + unzip -q "$zip_file" -d "$tmp_dir" + + local repo_dir + repo_dir="$(find "$tmp_dir" -mindepth 1 -maxdepth 1 -type d | head -n1 || true)" + [ -n "$repo_dir" ] || fail "Could not locate extracted repository directory." + + [ -f "$repo_dir/scripts/convert.sh" ] || fail "Missing script: scripts/convert.sh" + [ -f "$repo_dir/scripts/install.sh" ] || fail "Missing script: scripts/install.sh" + + chmod +x "$repo_dir/scripts/convert.sh" "$repo_dir/scripts/install.sh" + + log "Running convert.sh..." + ( + cd "$repo_dir" + ./scripts/convert.sh + ) + + if [ "$tool" = "auto" ]; then + log "Running install.sh --no-interactive --parallel (auto tool detection)..." + else + log "Running install.sh --tool $tool --no-interactive..." + fi + + local opencode_agents_src="$repo_dir/integrations/opencode/agents" + local opencode_agents_global="$TARGET_HOME/.config/opencode/agents" + + should_install_opencode() { + case "$tool" in + auto|all|opencode) return 0 ;; + *) return 1 ;; + esac + } + + log "Installing for user '$TARGET_USER' (HOME=$TARGET_HOME)..." + chown -R "$TARGET_USER":"$TARGET_USER" "$tmp_dir" + chmod -R u+rwX,go+rX "$tmp_dir" + + if [ "$(id -un)" = "$TARGET_USER" ]; then + if [ "$tool" = "auto" ]; then + cd "$repo_dir" && HOME="$TARGET_HOME" ./scripts/install.sh --no-interactive --parallel + else + cd "$repo_dir" && HOME="$TARGET_HOME" ./scripts/install.sh --tool "$tool" --no-interactive + fi + else + if [ "$tool" = "auto" ]; then + su - "$TARGET_USER" -c "cd '$repo_dir' && HOME='$TARGET_HOME' ./scripts/install.sh --no-interactive --parallel" + else + su - "$TARGET_USER" -c "cd '$repo_dir' && HOME='$TARGET_HOME' ./scripts/install.sh --tool '$tool' --no-interactive" + fi + fi + + if should_install_opencode && [ -d "$opencode_agents_src" ]; then + log "Installing OpenCode agents globally to $opencode_agents_global..." + mkdir -p "$opencode_agents_global" + cp "$opencode_agents_src"/*.md "$opencode_agents_global/" 2>/dev/null || true + chown -R "$TARGET_USER":"$TARGET_USER" "$opencode_agents_global" + log "OpenCode agents installed globally." + fi + + local remote_final_commit + remote_final_commit="$(get_remote_commit)" + if [ -n "$remote_final_commit" ]; then + mkdir -p "$(dirname "$COMMIT_FILE")" + echo "$remote_final_commit" > "$COMMIT_FILE" + fi + + log "Installation completed for tool '$tool'." +} if [ -f "$MARKER" ]; then - echo "[agency-agents-poststart] Marker found, skipping installation" - exit 0 + if [ "$AUTOUPDATE" = "true" ]; then + log "Marker found, checking for updates..." + if [ -f "$COMMIT_FILE" ] && [ -s "$COMMIT_FILE" ]; then + local installed_commit + installed_commit="$(cat "$COMMIT_FILE")" + if [ -n "$installed_commit" ]; then + local remote_commit + remote_commit="$(get_remote_commit)" + if [ -n "$remote_commit" ] && [ "$remote_commit" != "$installed_commit" ]; then + log "Update available ($installed_commit → $remote_commit), updating..." + rm -f "$MARKER" + rm -f "$COMMIT_FILE" + do_install + mkdir -p "$(dirname "$MARKER")" + touch "$MARKER" + log "Update complete" + exit 0 + fi + fi + fi + log "Already on latest version" + else + log "Marker found, autoupdate disabled, skipping" + fi + exit 0 fi -if [ "$(id -u)" -eq 0 ] && [ "$TARGET_USER" != "root" ]; then - echo "[agency-agents-poststart] Running installation script as user $TARGET_USER" - su - "$TARGET_USER" -c "bash $INSTALL_SCRIPT" -else - echo "[agency-agents-poststart] Running installation script" - bash "$INSTALL_SCRIPT" -fi +log "First installation..." +do_install mkdir -p "$(dirname "$MARKER")" touch "$MARKER" -echo "[agency-agents-poststart] Installation complete, marker created at $MARKER" \ No newline at end of file +log "Installation complete, marker created at $MARKER" \ No newline at end of file diff --git a/src/agents-workspace/devcontainer-feature.json b/src/agents-workspace/devcontainer-feature.json index cb250e7..60c55b2 100644 --- a/src/agents-workspace/devcontainer-feature.json +++ b/src/agents-workspace/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "agents-workspace", - "version": "0.1.6", + "version": "0.1.7", "name": "Agents Workspace", "description": "AI agent workspace with specialist agents for orchestrated, minimal, and self-learning workflows.", "documentationURL": "https://github.com/wcgomes/devcontainer-features?tab=readme-ov-file#feature-agents-workspace", diff --git a/src/agents-workspace/install.sh b/src/agents-workspace/install.sh index 0f2858e..6b9a271 100644 --- a/src/agents-workspace/install.sh +++ b/src/agents-workspace/install.sh @@ -1,5 +1,4 @@ #!/bin/sh - set -eu log() { @@ -71,224 +70,23 @@ ensure_prerequisites() { fail "Missing dependencies: $missing. Rebuild as root or preinstall them in the base image." fi - log "Installing missing dependencies:$missing" + log "Installing missing dependencies: $missing" install_packages $missing - command -v unzip >/dev/null 2>&1 || fail "Dependency installation failed: unzip is still missing" - command -v curl >/dev/null 2>&1 || command -v wget >/dev/null 2>&1 || fail "Dependency installation failed: curl/wget are still missing" - [ -f /etc/ssl/certs/ca-certificates.crt ] || fail "Dependency installation failed: CA certificates are still missing" -} - -get_remote_commit() { - local repo="$1" - curl -fsSL "https://api.github.com/repos/$repo/commits/main" 2>/dev/null | \ - grep -o '"sha": "[a-f0-9]*' | cut -d'"' -f4 | cut -c1-7 -} - -autoupdate_check() { - if [ "$autoupdate" != "true" ]; then - return 0 - fi - - if [ ! -f "$commit_file" ]; then - log "Autoupdate: skipped (no commit file found)" - return 0 - fi - - installed_agents_workspace_commit="$(cat "$commit_file")" - if [ -z "$installed_agents_workspace_commit" ]; then - log "Autoupdate: skipped (empty commit file)" - return 0 - fi - - log "Autoupdate: checking for updates..." - - remote_agents_workspace_commit="$(get_remote_commit "wcgomes/agents-workspace")" - if [ -z "$remote_agents_workspace_commit" ]; then - log "Autoupdate: skipped (unable to fetch agents-workspace commit)" - return 0 - fi - - needs_update=false - - if [ "$remote_agents_workspace_commit" != "$installed_agents_workspace_commit" ]; then - log "Autoupdate: agents-workspace has updates ($installed_agents_workspace_commit → $remote_agents_workspace_commit)" - needs_update=true - fi - - if [ "$includeAgency" = "true" ]; then - if [ -f "$agency_commit_file" ]; then - installed_agency_agents_commit="$(cat "$agency_commit_file")" - if [ -n "$installed_agency_agents_commit" ]; then - remote_agency_agents_commit="$(get_remote_commit "msitarzewski/agency-agents")" - if [ -n "$remote_agency_agents_commit" ] && [ "$remote_agency_agents_commit" != "$installed_agency_agents_commit" ]; then - log "Autoupdate: agency-agents has updates ($installed_agency_agents_commit → $remote_agency_agents_commit)" - needs_update=true - fi - fi - fi - fi - - if [ "$needs_update" = "false" ]; then - log "Autoupdate: already on latest version (agents-workspace: $remote_agents_workspace_commit)" - return 0 - fi - - log "Autoupdate: new versions available, updating..." - - rm -f "$marker_file" - rm -f "$commit_file" - [ "$includeAgency" = "true" ] && rm -f "$agency_commit_file" - return 1 -} - -tool="${TOOL:-${FEATURE_OPTION_TOOL:-all}}" -includeAgency="${AGENTS_WORKSPACE_INCLUDE_AGENCY:-${INCLUDEAGENCY:-${FEATURE_OPTION_INCLUDE_AGENCY:-true}}}" -autoupdate="${AGENTS_WORKSPACE_AUTOUPDATE:-${AUTOUPDATE:-true}}" - -case "$tool" in - "") - fail "Option 'tool' cannot be empty." - ;; - *[!a-zA-Z0-9_-]*) - fail "Option 'tool' contains invalid characters: '$tool'." - ;; -esac - -detect_user() { - local user="" - local valid_user - - valid_user="$(getent passwd | awk -F: '$3 >= 1000 && $1 !~ /^(nobody|nfsnobody|daemon)$/ {print $1; exit 0}')" || true - [ -z "$valid_user" ] && valid_user="root" - - if [ -n "${_REMOTE_USER:-}" ]; then - user="$_REMOTE_USER" - elif [ -n "$USERNAME" ]; then - user="$USERNAME" - fi - - if [ -n "$user" ]; then - local user_shell - user_shell="$(getent passwd "$user" 2>/dev/null | cut -d: -f7)" || true - case "$user_shell" in - */nologin|*/false|"") - user="$valid_user" - ;; - esac - fi - - if [ -z "$user" ]; then - user="$valid_user" - fi - - echo "$user" + command -v unzip >/dev/null 2>&1 || fail "Dependency installation failed: unzip" + command -v curl >/dev/null 2>&1 || command -v wget >/dev/null 2>&1 || fail "Dependency installation failed: curl/wget" + [ -f /etc/ssl/certs/ca-certificates.crt ] || fail "Dependency installation failed: CA certificates" } -TARGET_USER="$(detect_user)" -TARGET_HOME="$(getent passwd "$TARGET_USER" | cut -d: -f6)" -[ -z "$TARGET_HOME" ] && TARGET_HOME="/home/$TARGET_USER" - -case "$includeAgency" in - true|false) ;; - *) - fail "Option 'includeAgency' must be 'true' or 'false'." - ;; -esac - ensure_prerequisites marker_dir="/usr/local/share/devcontainer-features" - -# Use a per-user marker so build-time (root) installs don't block user postStart installs -marker_file="$marker_dir/agents-workspace-v1-${TARGET_USER}.done" -commit_file="$marker_dir/agents-workspace-v1.commit" -agency_commit_file="$marker_dir/agency-agents-v1.commit" -tool_marker="$marker_dir/agents-workspace-v1-${tool}-${TARGET_USER}.done" - -if [ -f "$marker_file" ] || [ -f "$tool_marker" ]; then - log "Installation already completed for tool '$tool'." - if ! autoupdate_check; then - rm -f "$marker_file" - rm -f "$tool_marker" - rm -f "$commit_file" - [ "$includeAgency" = "true" ] && rm -f "$agency_commit_file" - else - if [ ! -f "$commit_file" ] || [ ! -s "$commit_file" ]; then - remote_final_commit="$(get_remote_commit "wcgomes/agents-workspace")" - [ -n "$remote_final_commit" ] && echo "$remote_final_commit" > "$commit_file" - if [ "$includeAgency" = "true" ]; then - remote_agency_commit="$(get_remote_commit "msitarzewski/agency-agents")" - [ -n "$remote_agency_commit" ] && echo "$remote_agency_commit" > "$agency_commit_file" - fi - fi - exit 0 - fi -fi - -if [ -f "$commit_file" ]; then - autoupdate_check || true -fi - -log "Installing agents-workspace..." - -tmp_dir="$(mktemp -d /tmp/agents-workspace-XXXXXX)" -cleanup() { - rm -rf "$tmp_dir" -} -trap cleanup EXIT - mkdir -p "$marker_dir" -install_script="$tmp_dir/install.sh" -log "Downloading install.sh..." -if command -v curl >/dev/null 2>&1; then - curl -fsSL "https://raw.githubusercontent.com/wcgomes/agents-workspace/main/tools/install.sh" -o "$install_script" \ - || fail "Unable to download install.sh" -else - wget -qO "$install_script" "https://raw.githubusercontent.com/wcgomes/agents-workspace/main/tools/install.sh" \ - || fail "Unable to download install.sh" -fi - -chmod +x "$install_script" - -install_args="" -case "$tool" in - all) - install_args="--all" - ;; - opencode|claude|copilot|antigravity) - install_args="--$tool" - ;; -esac - -if [ "$includeAgency" != "true" ]; then - install_args="$install_args --no-agency" -fi - -log "Running install.sh $install_args..." -export HOME="$TARGET_HOME" -bash "$install_script" $install_args || log "Install completed with warnings (some tools may not be available)." - -touch "$marker_file" -touch "$tool_marker" - -remote_final_commit="$(get_remote_commit "wcgomes/agents-workspace")" -[ -n "$remote_final_commit" ] && echo "$remote_final_commit" > "$commit_file" && log "Saved agents-workspace commit: $remote_final_commit" - -if [ "$includeAgency" = "true" ]; then - remote_agency_commit="$(get_remote_commit "msitarzewski/agency-agents")" - [ -n "$remote_agency_commit" ] && echo "$remote_agency_commit" > "$agency_commit_file" && log "Saved agency-agents commit: $remote_agency_commit" -fi - -cp "$0" "$marker_dir/agents-workspace-install.sh" -chmod +x "$marker_dir/agents-workspace-install.sh" - -# Copy postStartCommand.sh poststart_script="$(dirname "$0")/postStartCommand.sh" if [ -f "$poststart_script" ]; then cp "$poststart_script" "$marker_dir/agents-workspace-postStartCommand.sh" chmod +x "$marker_dir/agents-workspace-postStartCommand.sh" fi -log "Installation completed for tool '$tool'." \ No newline at end of file +log "Scripts copied. Installation will run in postStartCommand." \ No newline at end of file diff --git a/src/agents-workspace/postStartCommand.sh b/src/agents-workspace/postStartCommand.sh index 5bbe318..4d6ac9e 100755 --- a/src/agents-workspace/postStartCommand.sh +++ b/src/agents-workspace/postStartCommand.sh @@ -1,8 +1,9 @@ #!/bin/bash set -euo pipefail -INSTALL_SCRIPT="${AGENTS_WORKSPACE_POSTSTART_SCRIPT:-/usr/local/share/devcontainer-features/agents-workspace-install.sh}" MARKER="${HOME}/.local/share/devcontainer-features/agents-workspace.done" +COMMIT_FILE="${HOME}/.local/share/devcontainer-features/agents-workspace.commit" +AGENCY_COMMIT_FILE="${HOME}/.local/share/devcontainer-features/agency-agents.commit" TARGET_USER="${USER:-$(whoami)}" [ -z "$TARGET_USER" ] && TARGET_USER="$(getent passwd | awk -F: '$3 >= 1000 {print $1; exit 0}')" @@ -14,26 +15,127 @@ export TOOL="${TOOL:-all}" export INCLUDEAGENCY="${INCLUDEAGENCY:-true}" export AUTOUPDATE="${AUTOUPDATE:-true}" -echo "[agents-workspace-poststart] Checking installation script..." +log() { + echo "[agents-workspace-poststart] $*" +} -if [ ! -f "$INSTALL_SCRIPT" ]; then - echo "[agents-workspace-poststart] Installation script not found at $INSTALL_SCRIPT" - exit 0 -fi +fail() { + echo "[agents-workspace-poststart] ERROR: $*" >&2 + exit 1 +} + +get_remote_commit() { + local repo="$1" + curl -fsSL "https://api.github.com/repos/$repo/commits/main" 2>/dev/null | \ + grep -o '"sha": "[a-f0-9]*' | cut -d'"' -f4 | cut -c1-7 +} + +download_install_script() { + local tmp_script="/tmp/agents-workspace-install.sh" + log "Downloading install script..." + if command -v curl >/dev/null 2>&1; then + curl -fsSL "https://raw.githubusercontent.com/wcgomes/agents-workspace/main/tools/install.sh" -o "$tmp_script" \ + || fail "Failed to download install.sh" + else + wget -qO "$tmp_script" "https://raw.githubusercontent.com/wcgomes/agents-workspace/main/tools/install.sh" \ + || fail "Failed to download install.sh" + fi + chmod +x "$tmp_script" + echo "$tmp_script" +} + +do_install() { + log "Starting installation for user '$TARGET_USER'..." + + local tool="${TOOL:-all}" + local includeAgency="${INCLUDEAGENCY:-true}" + + local TARGET_HOME + TARGET_HOME="$(getent passwd "$TARGET_USER" | cut -d: -f6)" + [ -z "$TARGET_HOME" ] && TARGET_HOME="/home/$TARGET_USER" + + local tmp_dir + tmp_dir="$(mktemp -d /tmp/agents-workspace-XXXXXX)" + CLEANUP_DIR="$tmp_dir" + cleanup() { + rm -rf "$CLEANUP_DIR" + rm -f /tmp/agents-workspace-install.sh + } + trap cleanup EXIT + + local install_script + install_script="$(download_install_script)" + log "Running install script from $install_script..." + export HOME="$TARGET_HOME" + bash "$install_script" --all || log "Install completed with warnings" + + local remote_final_commit + remote_final_commit="$(get_remote_commit "wcgomes/agents-workspace")" + [ -n "$remote_final_commit" ] && mkdir -p "$(dirname "$COMMIT_FILE")" && echo "$remote_final_commit" > "$COMMIT_FILE" && log "Saved agents-workspace commit: $remote_final_commit" + + if [ "$includeAgency" = "true" ]; then + local remote_agency_commit + remote_agency_commit="$(get_remote_commit "msitarzewski/agency-agents")" + [ -n "$remote_agency_commit" ] && mkdir -p "$(dirname "$AGENCY_COMMIT_FILE")" && echo "$remote_agency_commit" > "$AGENCY_COMMIT_FILE" && log "Saved agency-agents commit: $remote_agency_commit" + fi + + log "Installation completed for tool '$tool'." +} if [ -f "$MARKER" ]; then - echo "[agents-workspace-poststart] Marker found, skipping installation" - exit 0 -fi + if [ "$AUTOUPDATE" = "true" ]; then + log "Marker found, checking for updates..." + local includeAgency="$INCLUDEAGENCY" -if [ "$(id -u)" -eq 0 ] && [ "$TARGET_USER" != "root" ]; then - echo "[agents-workspace-poststart] Running installation script as user $TARGET_USER" - su - "$TARGET_USER" -c "bash $INSTALL_SCRIPT" -else - echo "[agents-workspace-poststart] Running installation script" - bash "$INSTALL_SCRIPT" + if [ -f "$COMMIT_FILE" ] && [ -s "$COMMIT_FILE" ]; then + local installed_agents_workspace_commit + installed_agents_workspace_commit="$(cat "$COMMIT_FILE")" + if [ -n "$installed_agents_workspace_commit" ]; then + local remote_agents_workspace_commit + remote_agents_workspace_commit="$(get_remote_commit "wcgomes/agents-workspace")" + + local needs_update=false + if [ -n "$remote_agents_workspace_commit" ] && [ "$remote_agents_workspace_commit" != "$installed_agents_workspace_commit" ]; then + log "agents-workspace update available ($installed_agents_workspace_commit → $remote_agents_workspace_commit)" + needs_update=true + fi + + if [ "$includeAgency" = "true" ] && [ -f "$AGENCY_COMMIT_FILE" ]; then + local installed_agency_agents_commit + installed_agency_agents_commit="$(cat "$AGENCY_COMMIT_FILE")" + if [ -n "$installed_agency_agents_commit" ]; then + local remote_agency_agents_commit + remote_agency_agents_commit="$(get_remote_commit "msitarzewski/agency-agents")" + if [ -n "$remote_agency_agents_commit" ] && [ "$remote_agency_agents_commit" != "$installed_agency_agents_commit" ]; then + log "agency-agents update available ($installed_agency_agents_commit → $remote_agency_agents_commit)" + needs_update=true + fi + fi + fi + + if [ "$needs_update" = "true" ]; then + log "Updates available, updating..." + rm -f "$MARKER" + rm -f "$COMMIT_FILE" + [ "$includeAgency" = "true" ] && rm -f "$AGENCY_COMMIT_FILE" + do_install + mkdir -p "$(dirname "$MARKER")" + touch "$MARKER" + log "Update complete" + exit 0 + fi + fi + fi + log "Already on latest version" + else + log "Marker found, autoupdate disabled, skipping" + fi + exit 0 fi +log "First installation..." +do_install + mkdir -p "$(dirname "$MARKER")" touch "$MARKER" -echo "[agents-workspace-poststart] Installation complete, marker created at $MARKER" \ No newline at end of file +log "Installation complete, marker created at $MARKER" \ No newline at end of file diff --git a/test/agency-agents/autoupdate_disabled.sh b/test/agency-agents/autoupdate_disabled.sh index 8ef61a5..954a709 100644 --- a/test/agency-agents/autoupdate_disabled.sh +++ b/test/agency-agents/autoupdate_disabled.sh @@ -3,13 +3,7 @@ set -e source dev-container-features-test-lib -check "autoupdate disabled - marker file exists" bash -c \ - "ls /usr/local/share/devcontainer-features/agency-agents-v1*.done 2>/dev/null | grep -q ." - -check "autoupdate disabled - commit file exists" bash -c \ - "ls /usr/local/share/devcontainer-features/agency-agents-v1.commit 2>/dev/null | grep -q ." - -check "autoupdate disabled - commit file not empty" bash -c \ - "cat /usr/local/share/devcontainer-features/agency-agents-v1.commit | grep -q ." +check "autoupdate disabled - user marker exists" bash -c \ + "ls ~/.local/share/devcontainer-features/agency-agents.done 2>/dev/null | grep -q ." reportResults \ No newline at end of file diff --git a/test/agency-agents/autoupdate_enabled.sh b/test/agency-agents/autoupdate_enabled.sh index 66acc16..1251f8c 100644 --- a/test/agency-agents/autoupdate_enabled.sh +++ b/test/agency-agents/autoupdate_enabled.sh @@ -3,13 +3,7 @@ set -e source dev-container-features-test-lib -check "autoupdate enabled - marker file exists" bash -c \ - "ls /usr/local/share/devcontainer-features/agency-agents-v1*.done 2>/dev/null | grep -q ." - -check "autoupdate enabled - commit file exists" bash -c \ - "ls /usr/local/share/devcontainer-features/agency-agents-v1.commit 2>/dev/null | grep -q ." - -check "autoupdate enabled - commit file not empty" bash -c \ - "cat /usr/local/share/devcontainer-features/agency-agents-v1.commit | grep -q ." +check "autoupdate enabled - user marker exists" bash -c \ + "ls ~/.local/share/devcontainer-features/agency-agents.done 2>/dev/null | grep -q ." reportResults \ No newline at end of file diff --git a/test/agency-agents/default_auto.sh b/test/agency-agents/default_auto.sh index f561cff..26c34aa 100644 --- a/test/agency-agents/default_auto.sh +++ b/test/agency-agents/default_auto.sh @@ -3,7 +3,10 @@ set -e source dev-container-features-test-lib -check "marker file exists for default auto install" bash -c \ - "ls /usr/local/share/devcontainer-features/agency-agents-v1*.done 2>/dev/null | grep -q ." +check "postStartCommand script exists" bash -c \ + "ls /usr/local/share/devcontainer-features/agency-agents-postStartCommand.sh 2>/dev/null | grep -q ." -reportResults +check "user marker exists" bash -c \ + "ls ~/.local/share/devcontainer-features/agency-agents.done 2>/dev/null | grep -q ." + +reportResults \ No newline at end of file diff --git a/test/agency-agents/explicit_all.sh b/test/agency-agents/explicit_all.sh index d21658c..3e1b244 100644 --- a/test/agency-agents/explicit_all.sh +++ b/test/agency-agents/explicit_all.sh @@ -4,6 +4,6 @@ set -e source dev-container-features-test-lib check "marker file exists for explicit all install" bash -c \ - "ls /usr/local/share/devcontainer-features/agency-agents-v1*.done 2>/dev/null | grep -q ." + "ls ~/.local/share/devcontainer-features/agency-agents.done 2>/dev/null | grep -q ." -reportResults +reportResults \ No newline at end of file diff --git a/test/agency-agents/explicit_copilot.sh b/test/agency-agents/explicit_copilot.sh index 883e7e0..184950b 100644 --- a/test/agency-agents/explicit_copilot.sh +++ b/test/agency-agents/explicit_copilot.sh @@ -4,6 +4,6 @@ set -e source dev-container-features-test-lib check "marker file exists for explicit copilot install" bash -c \ - "ls /usr/local/share/devcontainer-features/agency-agents-v1*.done 2>/dev/null | grep -q ." + "ls ~/.local/share/devcontainer-features/agency-agents.done 2>/dev/null | grep -q ." -reportResults +reportResults \ No newline at end of file diff --git a/test/agency-agents/explicit_opencode.sh b/test/agency-agents/explicit_opencode.sh index d3f4a36..3afaa10 100644 --- a/test/agency-agents/explicit_opencode.sh +++ b/test/agency-agents/explicit_opencode.sh @@ -6,11 +6,11 @@ source dev-container-features-test-lib opencode_agents_dir="$HOME/.config/opencode/agents" check "marker file exists for explicit opencode install" bash -c \ - "ls /usr/local/share/devcontainer-features/agency-agents-v1*.done 2>/dev/null | grep -q ." + "ls ~/.local/share/devcontainer-features/agency-agents.done 2>/dev/null | grep -q ." check "opencode agents directory exists" test -d "$opencode_agents_dir" check "opencode agents directory is not empty" bash -c \ "ls '$opencode_agents_dir'/*.md 2>/dev/null | grep -q ." -reportResults +reportResults \ No newline at end of file diff --git a/test/agency-agents/test.sh b/test/agency-agents/test.sh index 0d0bf69..8393ac1 100644 --- a/test/agency-agents/test.sh +++ b/test/agency-agents/test.sh @@ -3,13 +3,7 @@ set -e source dev-container-features-test-lib -check "agency-agents marker old exists (optional)" bash -c \ - "ls /usr/local/share/devcontainer-features/agency-agents-v1*.done 2>/dev/null | grep -q ." || true - -check "agency-agents-install.sh exists for autoupdate" bash -c \ - "ls /usr/local/share/devcontainer-features/agency-agents-install.sh 2>/dev/null | grep -q ." - -check "agency-agents-postStartCommand.sh exists for autoupdate" bash -c \ +check "agency-agents-postStartCommand.sh exists for postStart" bash -c \ "ls /usr/local/share/devcontainer-features/agency-agents-postStartCommand.sh 2>/dev/null | grep -q ." check "agency-agents marker new exists" bash -c \ diff --git a/test/agents-workspace/autoupdate_disabled.sh b/test/agents-workspace/autoupdate_disabled.sh index 8828a85..9fc269f 100644 --- a/test/agents-workspace/autoupdate_disabled.sh +++ b/test/agents-workspace/autoupdate_disabled.sh @@ -3,7 +3,7 @@ set -e source dev-container-features-test-lib -check "marker file exists for autoupdate disabled" bash -c \ - "ls /usr/local/share/devcontainer-features/agents-workspace-v1*.done 2>/dev/null | grep -q ." +check "autoupdate disabled - user marker exists" bash -c \ + "ls ~/.local/share/devcontainer-features/agents-workspace.done 2>/dev/null | grep -q ." reportResults \ No newline at end of file diff --git a/test/agents-workspace/autoupdate_enabled.sh b/test/agents-workspace/autoupdate_enabled.sh index 6faab8f..6ab4343 100644 --- a/test/agents-workspace/autoupdate_enabled.sh +++ b/test/agents-workspace/autoupdate_enabled.sh @@ -3,7 +3,7 @@ set -e source dev-container-features-test-lib -check "marker file exists for autoupdate enabled" bash -c \ - "ls /usr/local/share/devcontainer-features/agents-workspace-v1*.done 2>/dev/null | grep -q ." +check "autoupdate enabled - user marker exists" bash -c \ + "ls ~/.local/share/devcontainer-features/agents-workspace.done 2>/dev/null | grep -q ." reportResults \ No newline at end of file diff --git a/test/agents-workspace/default.sh b/test/agents-workspace/default.sh index e2c64ba..5385694 100644 --- a/test/agents-workspace/default.sh +++ b/test/agents-workspace/default.sh @@ -3,7 +3,10 @@ set -e source dev-container-features-test-lib -check "marker file exists for default install" bash -c \ - "ls /usr/local/share/devcontainer-features/agents-workspace-v1*.done 2>/dev/null | grep -q ." +check "postStartCommand script exists" bash -c \ + "ls /usr/local/share/devcontainer-features/agents-workspace-postStartCommand.sh 2>/dev/null | grep -q ." + +check "user marker exists" bash -c \ + "ls ~/.local/share/devcontainer-features/agents-workspace.done 2>/dev/null | grep -q ." reportResults \ No newline at end of file diff --git a/test/agents-workspace/explicit_all.sh b/test/agents-workspace/explicit_all.sh index fc860b5..90331f6 100644 --- a/test/agents-workspace/explicit_all.sh +++ b/test/agents-workspace/explicit_all.sh @@ -4,6 +4,6 @@ set -e source dev-container-features-test-lib check "marker file exists for explicit all install" bash -c \ - "ls /usr/local/share/devcontainer-features/agents-workspace-v1*.done 2>/dev/null | grep -q ." + "ls ~/.local/share/devcontainer-features/agents-workspace.done 2>/dev/null | grep -q ." reportResults \ No newline at end of file diff --git a/test/agents-workspace/explicit_opencode.sh b/test/agents-workspace/explicit_opencode.sh index becd318..159d1c8 100644 --- a/test/agents-workspace/explicit_opencode.sh +++ b/test/agents-workspace/explicit_opencode.sh @@ -4,6 +4,6 @@ set -e source dev-container-features-test-lib check "marker file exists for opencode install" bash -c \ - "ls /usr/local/share/devcontainer-features/agents-workspace-v1*.done 2>/dev/null | grep -q ." + "ls ~/.local/share/devcontainer-features/agents-workspace.done 2>/dev/null | grep -q ." reportResults \ No newline at end of file diff --git a/test/agents-workspace/no_agency.sh b/test/agents-workspace/no_agency.sh index 2927d0a..318d481 100644 --- a/test/agents-workspace/no_agency.sh +++ b/test/agents-workspace/no_agency.sh @@ -4,9 +4,6 @@ set -e source dev-container-features-test-lib check "marker file exists for no-agency install" bash -c \ - "ls /usr/local/share/devcontainer-features/agents-workspace-v1*.done 2>/dev/null | grep -q ." - -check "agency-agents commit file should NOT exist when includeAgency=false" bash -c \ - "! ls /usr/local/share/devcontainer-features/agency-agents-v1.commit 2>/dev/null | grep -q ." + "ls ~/.local/share/devcontainer-features/agents-workspace.done 2>/dev/null | grep -q ." reportResults \ No newline at end of file diff --git a/test/agents-workspace/remote_user_node.sh b/test/agents-workspace/remote_user_node.sh index 5fc1e35..b517d60 100644 --- a/test/agents-workspace/remote_user_node.sh +++ b/test/agents-workspace/remote_user_node.sh @@ -6,6 +6,6 @@ source dev-container-features-test-lib TARGET_USER="${_REMOTE_USER:-node}" TARGET_HOME="/home/$TARGET_USER" -check "marker file created with correct user" bash -c "ls /usr/local/share/devcontainer-features/agents-workspace-v1-${TARGET_USER}.done 2>/dev/null | grep -q ." +check "marker file created with correct user" bash -c "ls $TARGET_HOME/.local/share/devcontainer-features/agents-workspace.done 2>/dev/null | grep -q ." reportResults \ No newline at end of file diff --git a/test/agents-workspace/test.sh b/test/agents-workspace/test.sh index 62273ec..4c516d6 100644 --- a/test/agents-workspace/test.sh +++ b/test/agents-workspace/test.sh @@ -3,13 +3,7 @@ set -e source dev-container-features-test-lib -check "agents-workspace marker old exists (optional)" bash -c \ - "ls /usr/local/share/devcontainer-features/agents-workspace-v1*.done 2>/dev/null | grep -q ." || true - -check "agents-workspace-install.sh exists for autoupdate" bash -c \ - "ls /usr/local/share/devcontainer-features/agents-workspace-install.sh 2>/dev/null | grep -q ." - -check "agents-workspace-postStartCommand.sh exists for autoupdate" bash -c \ +check "agents-workspace-postStartCommand.sh exists for postStart" bash -c \ "ls /usr/local/share/devcontainer-features/agents-workspace-postStartCommand.sh 2>/dev/null | grep -q ." check "agents-workspace marker new exists" bash -c \