diff --git a/install.ps1 b/install.ps1 index a82b11a..a3949fb 100644 --- a/install.ps1 +++ b/install.ps1 @@ -9,10 +9,16 @@ $ErrorActionPreference = "Stop" $SourceDir = $PSScriptRoot $TargetDir = if ($env:MOSAIC_HOME) { $env:MOSAIC_HOME } else { Join-Path $env:USERPROFILE ".config\mosaic" } +function Write-Ok { param([string]$Msg) Write-Host " ✓ " -ForegroundColor Green -NoNewline; Write-Host $Msg } +function Write-Warn { param([string]$Msg) Write-Host " ⚠ " -ForegroundColor Yellow -NoNewline; Write-Host $Msg } +function Write-Fail { param([string]$Msg) Write-Host " ✗ " -ForegroundColor Red -NoNewline; Write-Host $Msg } +function Write-Step { param([string]$Msg) Write-Host ""; Write-Host $Msg -ForegroundColor White -BackgroundColor DarkGray } + +# ── Install framework ──────────────────────────────────────── +Write-Step " Installing Mosaic framework " + if (-not (Test-Path $TargetDir)) { New-Item -ItemType Directory -Path $TargetDir -Force | Out-Null } -# Sync files: remove old content, copy new -Write-Host "[mosaic-install] Copying framework to $TargetDir..." Get-ChildItem $TargetDir -Exclude ".git" | Remove-Item -Recurse -Force Get-ChildItem $SourceDir -Exclude ".git" | ForEach-Object { $dest = Join-Path $TargetDir $_.Name @@ -24,67 +30,89 @@ Get-ChildItem $SourceDir -Exclude ".git" | ForEach-Object { } } -Write-Host "[mosaic-install] Installed framework to $TargetDir" +Write-Ok "Framework installed to $TargetDir" + +# ── Post-install tasks ─────────────────────────────────────── +Write-Step " Post-install tasks " -# Run post-install scripts (PowerShell versions) $binDir = Join-Path $TargetDir "bin" -Write-Host "[mosaic-install] Linking runtime compatibility assets" try { - & "$binDir\mosaic-link-runtime-assets.ps1" + & "$binDir\mosaic-link-runtime-assets.ps1" *>$null + Write-Ok "Runtime assets linked" } catch { - Write-Host "[mosaic-install] WARNING: runtime asset linking failed (framework install still complete)" -ForegroundColor Yellow + Write-Warn "Runtime asset linking failed (non-fatal)" } -Write-Host "[mosaic-install] Syncing universal skills" if ($env:MOSAIC_SKIP_SKILLS_SYNC -eq "1") { - Write-Host "[mosaic-install] Skipping skills sync (MOSAIC_SKIP_SKILLS_SYNC=1)" + Write-Ok "Skills sync skipped (MOSAIC_SKIP_SKILLS_SYNC=1)" } else { try { - & "$binDir\mosaic-sync-skills.ps1" + & "$binDir\mosaic-sync-skills.ps1" *>$null + Write-Ok "Skills synced" } catch { - Write-Host "[mosaic-install] WARNING: skills sync failed (framework install still complete)" -ForegroundColor Yellow + Write-Warn "Skills sync failed (non-fatal)" } } -Write-Host "[mosaic-install] Migrating runtime-local skills to Mosaic junctions" try { - & "$binDir\mosaic-migrate-local-skills.ps1" -Apply + & "$binDir\mosaic-migrate-local-skills.ps1" -Apply *>$null + Write-Ok "Local skills migrated" } catch { - Write-Host "[mosaic-install] WARNING: local skill migration failed (framework install still complete)" -ForegroundColor Yellow + Write-Warn "Local skill migration failed (non-fatal)" } -Write-Host "[mosaic-install] Running health audit" try { - & "$binDir\mosaic-doctor.ps1" + & "$binDir\mosaic-doctor.ps1" *>$null + Write-Ok "Health audit passed" } catch { - Write-Host "[mosaic-install] WARNING: doctor reported issues (run mosaic-doctor.ps1 -FailOnWarn)" -ForegroundColor Yellow + Write-Warn "Health audit reported issues — run 'mosaic doctor' for details" } -# Ensure mosaic bin is in User PATH persistently +# ── PATH configuration ─────────────────────────────────────── +Write-Step " PATH configuration " + $mosaicBin = Join-Path $TargetDir "bin" $userPath = [Environment]::GetEnvironmentVariable("Path", "User") +$pathChanged = $false + if ($userPath -and $userPath.Split(";") -contains $mosaicBin) { - Write-Host "[mosaic-install] PATH: $mosaicBin already in User PATH ✓" + Write-Ok "Already in User PATH" } else { $newPath = if ($userPath) { "$mosaicBin;$userPath" } else { $mosaicBin } [Environment]::SetEnvironmentVariable("Path", $newPath, "User") $env:Path = "$mosaicBin;$env:Path" - Write-Host "[mosaic-install] PATH: Added $mosaicBin to User PATH ✓" - Write-Host "[mosaic-install] Open a new terminal for PATH changes to take effect." + Write-Ok "Added to User PATH" + $pathChanged = $true } -Write-Host "[mosaic-install] Done." +# ── Summary ────────────────────────────────────────────────── +Write-Host "" +Write-Host " Mosaic installed successfully." -ForegroundColor Green +Write-Host "" + +$nextSteps = @() + +if ($pathChanged) { + $nextSteps += "Open a new terminal (or log out and back in) to activate PATH." +} $soulPath = Join-Path $TargetDir "SOUL.md" if (-not (Test-Path $soulPath)) { - Write-Host "" - Write-Host "[mosaic-install] Set up your agent identity by running: mosaic init" - Write-Host "[mosaic-install] This generates SOUL.md - the universal behavioral contract for all agent sessions." + $nextSteps += "Run 'mosaic init' to set up your agent identity (SOUL.md)." +} + +if ($nextSteps.Count -gt 0) { + Write-Host " Next steps:" -ForegroundColor White + for ($i = 0; $i -lt $nextSteps.Count; $i++) { + Write-Host " $($i + 1). " -NoNewline + Write-Host $nextSteps[$i] -ForegroundColor Cyan + } + Write-Host "" } diff --git a/install.sh b/install.sh index 3a236c4..b05f188 100755 --- a/install.sh +++ b/install.sh @@ -4,6 +4,21 @@ set -euo pipefail SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" TARGET_DIR="${MOSAIC_HOME:-$HOME/.config/mosaic}" +# Colors (disabled if not a terminal) +if [[ -t 1 ]]; then + GREEN='\033[0;32m' YELLOW='\033[0;33m' RED='\033[0;31m' + CYAN='\033[0;36m' BOLD='\033[1m' RESET='\033[0m' +else + GREEN='' YELLOW='' RED='' CYAN='' BOLD='' RESET='' +fi + +ok() { echo -e " ${GREEN}✓${RESET} $1"; } +warn() { echo -e " ${YELLOW}⚠${RESET} $1" >&2; } +fail() { echo -e " ${RED}✗${RESET} $1" >&2; } +step() { echo -e "\n${BOLD}$1${RESET}"; } + +step "Installing Mosaic framework" + mkdir -p "$TARGET_DIR" if command -v rsync >/dev/null 2>&1; then @@ -16,33 +31,40 @@ fi chmod +x "$TARGET_DIR"/bin/* chmod +x "$TARGET_DIR"/install.sh -echo "[mosaic-install] Installed framework to $TARGET_DIR" +ok "Framework installed to $TARGET_DIR" -echo "[mosaic-install] Linking runtime compatibility assets" -if ! "$TARGET_DIR/bin/mosaic-link-runtime-assets"; then - echo "[mosaic-install] WARNING: runtime asset linking failed (framework install still complete)" >&2 +step "Post-install tasks" + +if "$TARGET_DIR/bin/mosaic-link-runtime-assets" >/dev/null 2>&1; then + ok "Runtime assets linked" +else + warn "Runtime asset linking failed (non-fatal)" fi -echo "[mosaic-install] Syncing universal skills" if [[ "${MOSAIC_SKIP_SKILLS_SYNC:-0}" == "1" ]]; then - echo "[mosaic-install] Skipping skills sync (MOSAIC_SKIP_SKILLS_SYNC=1)" + ok "Skills sync skipped (MOSAIC_SKIP_SKILLS_SYNC=1)" else - if ! "$TARGET_DIR/bin/mosaic-sync-skills"; then - echo "[mosaic-install] WARNING: skills sync failed (framework install still complete)" >&2 + if "$TARGET_DIR/bin/mosaic-sync-skills" >/dev/null 2>&1; then + ok "Skills synced" + else + warn "Skills sync failed (non-fatal)" fi fi -echo "[mosaic-install] Migrating runtime-local skills to Mosaic links" -if ! "$TARGET_DIR/bin/mosaic-migrate-local-skills" --apply; then - echo "[mosaic-install] WARNING: local skill migration failed (framework install still complete)" >&2 +if "$TARGET_DIR/bin/mosaic-migrate-local-skills" --apply >/dev/null 2>&1; then + ok "Local skills migrated" +else + warn "Local skill migration failed (non-fatal)" fi -echo "[mosaic-install] Running health audit" -if ! "$TARGET_DIR/bin/mosaic-doctor"; then - echo "[mosaic-install] WARNING: doctor reported issues (run ~/.config/mosaic/bin/mosaic-doctor --fail-on-warn)" >&2 +if "$TARGET_DIR/bin/mosaic-doctor" >/dev/null 2>&1; then + ok "Health audit passed" +else + warn "Health audit reported issues — run 'mosaic doctor' for details" fi -# Ensure ~/.config/mosaic/bin is in PATH persistently +step "PATH configuration" + PATH_LINE="export PATH=\"$TARGET_DIR/bin:\$PATH\"" # Find the right shell profile @@ -56,20 +78,39 @@ else SHELL_PROFILE="$HOME/.profile" fi +PATH_CHANGED=false if grep -qF "$TARGET_DIR/bin" "$SHELL_PROFILE" 2>/dev/null; then - echo "[mosaic-install] PATH: $TARGET_DIR/bin already in $SHELL_PROFILE ✓" + ok "Already in PATH via $SHELL_PROFILE" else { echo "" echo "# Mosaic agent framework" echo "$PATH_LINE" } >> "$SHELL_PROFILE" - echo "[mosaic-install] PATH: Added $TARGET_DIR/bin to $SHELL_PROFILE ✓" - echo "[mosaic-install] Run 'source $SHELL_PROFILE' or open a new terminal to activate." + ok "Added to PATH in $SHELL_PROFILE" + PATH_CHANGED=true +fi + +# ── Summary ────────────────────────────────────────────────── +echo "" +echo -e "${GREEN}${BOLD} Mosaic installed successfully.${RESET}" +echo "" + +# Collect next steps +NEXT_STEPS=() + +if [[ "$PATH_CHANGED" == "true" ]]; then + NEXT_STEPS+=("Run ${CYAN}source $SHELL_PROFILE${RESET} or log out and back in to activate PATH.") fi if [[ ! -f "$TARGET_DIR/SOUL.md" ]]; then - echo "" - echo "[mosaic-install] Set up your agent identity by running: mosaic init" - echo "[mosaic-install] This generates SOUL.md — the universal behavioral contract for all agent sessions." + NEXT_STEPS+=("Run ${CYAN}mosaic init${RESET} to set up your agent identity (SOUL.md).") +fi + +if [[ ${#NEXT_STEPS[@]} -gt 0 ]]; then + echo -e " ${BOLD}Next steps:${RESET}" + for i in "${!NEXT_STEPS[@]}"; do + echo -e " $((i+1)). ${NEXT_STEPS[$i]}" + done + echo "" fi