diff --git a/.github/workflows/update-version-and-create-tag.yml b/.github/workflows/update-version-and-create-tag.yml index 13b7328e..93f43a31 100644 --- a/.github/workflows/update-version-and-create-tag.yml +++ b/.github/workflows/update-version-and-create-tag.yml @@ -11,6 +11,7 @@ on: - "cmd/generate_changelog/incoming/*.txt" - "scripts/pattern_descriptions/*.json" - "web/static/data/pattern_descriptions.json" + - "**/*.md" permissions: contents: write # Ensure the workflow has write permissions diff --git a/.vscode/settings.json b/.vscode/settings.json index aeab1bf9..0df7dae0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -162,6 +162,8 @@ "unconfigured", "unmarshalling", "updatepatterns", + "useb", + "USERPROFILE", "videoid", "webp", "WEBVTT", @@ -176,7 +178,12 @@ "youtu", "YTDLP" ], - "cSpell.ignorePaths": ["go.mod", ".gitignore", "CHANGELOG.md"], + "cSpell.ignorePaths": [ + "go.mod", + ".gitignore", + "CHANGELOG.md", + "./scripts/installer/install.*" + ], "markdownlint.config": { "MD004": false, "MD011": false, diff --git a/README.md b/README.md index 783d69e5..12673655 100644 --- a/README.md +++ b/README.md @@ -118,16 +118,12 @@ Keep in mind that many of these were recorded when Fabric was Python-based, so r - [Breaking problems into components](#breaking-problems-into-components) - [Too many prompts](#too-many-prompts) - [Installation](#installation) - - [Get Latest Release Binaries](#get-latest-release-binaries) - - [Windows](#windows) - - [macOS (arm64)](#macos-arm64) - - [macOS (amd64)](#macos-amd64) - - [Linux (amd64)](#linux-amd64) - - [Linux (arm64)](#linux-arm64) + - [One-Line Install (Recommended)](#one-line-install-recommended) + - [Manual Binary Downloads](#manual-binary-downloads) - [Using package managers](#using-package-managers) - [macOS (Homebrew)](#macos-homebrew) - [Arch Linux (AUR)](#arch-linux-aur) - - [Windows](#windows-1) + - [Windows](#windows) - [From Source](#from-source) - [Docker](#docker) - [Environment Variables](#environment-variables) @@ -206,38 +202,25 @@ Fabric has Patterns for all sorts of life and work activities, including: ## Installation -To install Fabric, you can use the latest release binaries or install it from the source. +### One-Line Install (Recommended) -### Get Latest Release Binaries +**Unix/Linux/macOS:** -#### Windows - -Via PowerShell, just copy and paste and run the following snippet to install the binary into `{HOME}\.local\bin`. Please make sure that directory is included in your `PATH`. - -```powershell -$ErrorActionPreference = "Stop" -$LATEST="https://github.com/danielmiessler/fabric/releases/latest/download/fabric-windows-amd64.exe" -$DIR="${HOME}\.local\bin" -New-Item -Path $DIR -ItemType Directory -Force -Invoke-WebRequest -URI "${LATEST}" -outfile "${DIR}\fabric.exe" -& "${DIR}\fabric.exe" /version +```bash +curl -fsSL https://raw.githubusercontent.com/danielmiessler/fabric/main/scripts/installer/install.sh | bash ``` -#### macOS (arm64) +**Windows PowerShell:** -`curl -L https://github.com/danielmiessler/fabric/releases/latest/download/fabric-darwin-arm64 > fabric && chmod +x fabric && ./fabric --version` +```powershell +iwr -useb https://raw.githubusercontent.com/danielmiessler/fabric/main/scripts/installer/install.ps1 | iex +``` -#### macOS (amd64) +> See [scripts/installer/README.md](./scripts/installer/README.md) for custom installation options and troubleshooting. -`curl -L https://github.com/danielmiessler/fabric/releases/latest/download/fabric-darwin-amd64 > fabric && chmod +x fabric && ./fabric --version` +### Manual Binary Downloads -#### Linux (amd64) - -`curl -L https://github.com/danielmiessler/fabric/releases/latest/download/fabric-linux-amd64 > fabric && chmod +x fabric && ./fabric --version` - -#### Linux (arm64) - -`curl -L https://github.com/danielmiessler/fabric/releases/latest/download/fabric-linux-arm64 > fabric && chmod +x fabric && ./fabric --version` +The latest release binary archives and their expected SHA256 hashes can be found at ### Using package managers diff --git a/cmd/generate_changelog/incoming/1745.txt b/cmd/generate_changelog/incoming/1745.txt new file mode 100644 index 00000000..952759c2 --- /dev/null +++ b/cmd/generate_changelog/incoming/1745.txt @@ -0,0 +1,7 @@ +### PR [#1745](https://github.com/danielmiessler/Fabric/pull/1745) by [ksylvan](https://github.com/ksylvan): Fabric Installation Improvements and Automated Release Updates + +- Streamlined install process with one-line installer scripts and updated documentation +- Added bash installer script for Unix systems +- Added PowerShell installer script for Windows +- Created installer documentation with usage examples +- Simplified README installation with one-line installers diff --git a/data/patterns/pattern_explanations.md b/data/patterns/pattern_explanations.md index c99ba94f..e1cf5a8d 100644 --- a/data/patterns/pattern_explanations.md +++ b/data/patterns/pattern_explanations.md @@ -178,48 +178,47 @@ 174. **refine_design_document**: Refines a design document based on a design review by analyzing, mapping concepts, and implementing changes using valid Markdown. 175. **review_design**: Reviews and analyzes architecture design, focusing on clarity, component design, system integrations, security, performance, scalability, and data management. 176. **sanitize_broken_html_to_markdown**: Converts messy HTML into clean, properly formatted Markdown, applying custom styling and ensuring compatibility with Vite. -177. **show_fabric_options_markmap**: Visualizes the functionality of the Fabric framework by representing its components, commands, and features based on the provided input. -178. **solve_with_cot**: Provides detailed, step-by-step responses with chain of thought reasoning, using structured thinking, reflection, and output sections. -179. **suggest_pattern**: Suggests appropriate fabric patterns or commands based on user input, providing clear explanations and options for users. -180. **summarize**: Summarizes content into a 20-word sentence, main points, and takeaways, formatted with numbered lists in Markdown. -181. **summarize_board_meeting**: Creates formal meeting notes from board meeting transcripts for corporate governance documentation. -182. **summarize_debate**: Summarizes debates, identifies primary disagreement, extracts arguments, and provides analysis of evidence and argument strength to predict outcomes. -183. **summarize_git_changes**: Summarizes recent project updates from the last 7 days, focusing on key changes with enthusiasm. -184. **summarize_git_diff**: Summarizes and organizes Git diff changes with clear, succinct commit messages and bullet points. -185. **summarize_lecture**: Extracts relevant topics, definitions, and tools from lecture transcripts, providing structured summaries with timestamps and key takeaways. -186. **summarize_legislation**: Summarizes complex political proposals and legislation by analyzing key points, proposed changes, and providing balanced, positive, and cynical characterizations. -187. **summarize_meeting**: Analyzes meeting transcripts to extract a structured summary, including an overview, key points, tasks, decisions, challenges, timeline, references, and next steps. -188. **summarize_micro**: Summarizes content into a 20-word sentence, 3 main points, and 3 takeaways, formatted in clear, concise Markdown. -189. **summarize_newsletter**: Extracts the most meaningful, interesting, and useful content from a newsletter, summarizing key sections such as content, opinions, tools, companies, and follow-up items in clear, structured Markdown. -190. **summarize_paper**: Summarizes an academic paper by detailing its title, authors, technical approach, distinctive features, experimental setup, results, advantages, limitations, and conclusion in a clear, structured format using human-readable Markdown. -191. **summarize_prompt**: Summarizes AI chat prompts by describing the primary function, unique approach, and expected output in a concise paragraph. The summary is focused on the prompt's purpose without unnecessary details or formatting. -192. **summarize_pull-requests**: Summarizes pull requests for a coding project by providing a summary and listing the top PRs with human-readable descriptions. -193. **summarize_rpg_session**: Summarizes a role-playing game session by extracting key events, combat stats, character changes, quotes, and more. -194. **t_analyze_challenge_handling**: Provides 8-16 word bullet points evaluating how well challenges are being addressed, calling out any lack of effort. -195. **t_check_metrics**: Analyzes deep context from the TELOS file and input instruction, then provides a wisdom-based output while considering metrics and KPIs to assess recent improvements. -196. **t_create_h3_career**: Summarizes context and produces wisdom-based output by deeply analyzing both the TELOS File and the input instruction, considering the relationship between the two. -197. **t_create_opening_sentences**: Describes from TELOS file the person's identity, goals, and actions in 4 concise, 32-word bullet points, humbly. -198. **t_describe_life_outlook**: Describes from TELOS file a person's life outlook in 5 concise, 16-word bullet points. -199. **t_extract_intro_sentences**: Summarizes from TELOS file a person's identity, work, and current projects in 5 concise and grounded bullet points. -200. **t_extract_panel_topics**: Creates 5 panel ideas with titles and descriptions based on deep context from a TELOS file and input. -201. **t_find_blindspots**: Identify potential blindspots in thinking, frames, or models that may expose the individual to error or risk. -202. **t_find_negative_thinking**: Analyze a TELOS file and input to identify negative thinking in documents or journals, followed by tough love encouragement. -203. **t_find_neglected_goals**: Analyze a TELOS file and input instructions to identify goals or projects that have not been worked on recently. -204. **t_give_encouragement**: Analyze a TELOS file and input instructions to evaluate progress, provide encouragement, and offer recommendations for continued effort. -205. **t_red_team_thinking**: Analyze a TELOS file and input instructions to red-team thinking, models, and frames, then provide recommendations for improvement. -206. **t_threat_model_plans**: Analyze a TELOS file and input instructions to create threat models for a life plan and recommend improvements. -207. **t_visualize_mission_goals_projects**: Analyze a TELOS file and input instructions to create an ASCII art diagram illustrating the relationship of missions, goals, and projects. -208. **t_year_in_review**: Analyze a TELOS file to create insights about a person or entity, then summarize accomplishments and visualizations in bullet points. -209. **to_flashcards**: Create Anki flashcards from a given text, focusing on concise, optimized questions and answers without external context. -210. **transcribe_minutes**: Extracts (from meeting transcription) meeting minutes, identifying actionables, insightful ideas, decisions, challenges, and next steps in a structured format. -211. **translate**: Translates sentences or documentation into the specified language code while maintaining the original formatting and tone. -212. **tweet**: Provides a step-by-step guide on crafting engaging tweets with emojis, covering Twitter basics, account creation, features, and audience targeting. -213. **write_essay**: Writes essays in the style of a specified author, embodying their unique voice, vocabulary, and approach. Uses `author_name` variable. -214. **write_essay_pg**: Writes concise, clear essays in the style of Paul Graham, focusing on simplicity, clarity, and illumination of the provided topic. -215. **write_hackerone_report**: Generates concise, clear, and reproducible bug bounty reports, detailing vulnerability impact, steps to reproduce, and exploit details for triagers. -216. **write_latex**: Generates syntactically correct LaTeX code for a new.tex document, ensuring proper formatting and compatibility with pdflatex. -217. **write_micro_essay**: Writes concise, clear, and illuminating essays on the given topic in the style of Paul Graham. -218. **write_nuclei_template_rule**: Generates Nuclei YAML templates for detecting vulnerabilities using HTTP requests, matchers, extractors, and dynamic data extraction. -219. **write_pull-request**: Drafts detailed pull request descriptions, explaining changes, providing reasoning, and identifying potential bugs from the git diff command output. -220. **write_semgrep_rule**: Creates accurate and working Semgrep rules based on input, following syntax guidelines and specific language considerations. -221. **youtube_summary**: Create concise, timestamped Youtube video summaries that highlight key points. +177. **solve_with_cot**: Provides detailed, step-by-step responses with chain of thought reasoning, using structured thinking, reflection, and output sections. +178. **suggest_pattern**: Suggests appropriate fabric patterns or commands based on user input, providing clear explanations and options for users. +179. **summarize**: Summarizes content into a 20-word sentence, main points, and takeaways, formatted with numbered lists in Markdown. +180. **summarize_board_meeting**: Creates formal meeting notes from board meeting transcripts for corporate governance documentation. +181. **summarize_debate**: Summarizes debates, identifies primary disagreement, extracts arguments, and provides analysis of evidence and argument strength to predict outcomes. +182. **summarize_git_changes**: Summarizes recent project updates from the last 7 days, focusing on key changes with enthusiasm. +183. **summarize_git_diff**: Summarizes and organizes Git diff changes with clear, succinct commit messages and bullet points. +184. **summarize_lecture**: Extracts relevant topics, definitions, and tools from lecture transcripts, providing structured summaries with timestamps and key takeaways. +185. **summarize_legislation**: Summarizes complex political proposals and legislation by analyzing key points, proposed changes, and providing balanced, positive, and cynical characterizations. +186. **summarize_meeting**: Analyzes meeting transcripts to extract a structured summary, including an overview, key points, tasks, decisions, challenges, timeline, references, and next steps. +187. **summarize_micro**: Summarizes content into a 20-word sentence, 3 main points, and 3 takeaways, formatted in clear, concise Markdown. +188. **summarize_newsletter**: Extracts the most meaningful, interesting, and useful content from a newsletter, summarizing key sections such as content, opinions, tools, companies, and follow-up items in clear, structured Markdown. +189. **summarize_paper**: Summarizes an academic paper by detailing its title, authors, technical approach, distinctive features, experimental setup, results, advantages, limitations, and conclusion in a clear, structured format using human-readable Markdown. +190. **summarize_prompt**: Summarizes AI chat prompts by describing the primary function, unique approach, and expected output in a concise paragraph. The summary is focused on the prompt's purpose without unnecessary details or formatting. +191. **summarize_pull-requests**: Summarizes pull requests for a coding project by providing a summary and listing the top PRs with human-readable descriptions. +192. **summarize_rpg_session**: Summarizes a role-playing game session by extracting key events, combat stats, character changes, quotes, and more. +193. **t_analyze_challenge_handling**: Provides 8-16 word bullet points evaluating how well challenges are being addressed, calling out any lack of effort. +194. **t_check_metrics**: Analyzes deep context from the TELOS file and input instruction, then provides a wisdom-based output while considering metrics and KPIs to assess recent improvements. +195. **t_create_h3_career**: Summarizes context and produces wisdom-based output by deeply analyzing both the TELOS File and the input instruction, considering the relationship between the two. +196. **t_create_opening_sentences**: Describes from TELOS file the person's identity, goals, and actions in 4 concise, 32-word bullet points, humbly. +197. **t_describe_life_outlook**: Describes from TELOS file a person's life outlook in 5 concise, 16-word bullet points. +198. **t_extract_intro_sentences**: Summarizes from TELOS file a person's identity, work, and current projects in 5 concise and grounded bullet points. +199. **t_extract_panel_topics**: Creates 5 panel ideas with titles and descriptions based on deep context from a TELOS file and input. +200. **t_find_blindspots**: Identify potential blindspots in thinking, frames, or models that may expose the individual to error or risk. +201. **t_find_negative_thinking**: Analyze a TELOS file and input to identify negative thinking in documents or journals, followed by tough love encouragement. +202. **t_find_neglected_goals**: Analyze a TELOS file and input instructions to identify goals or projects that have not been worked on recently. +203. **t_give_encouragement**: Analyze a TELOS file and input instructions to evaluate progress, provide encouragement, and offer recommendations for continued effort. +204. **t_red_team_thinking**: Analyze a TELOS file and input instructions to red-team thinking, models, and frames, then provide recommendations for improvement. +205. **t_threat_model_plans**: Analyze a TELOS file and input instructions to create threat models for a life plan and recommend improvements. +206. **t_visualize_mission_goals_projects**: Analyze a TELOS file and input instructions to create an ASCII art diagram illustrating the relationship of missions, goals, and projects. +207. **t_year_in_review**: Analyze a TELOS file to create insights about a person or entity, then summarize accomplishments and visualizations in bullet points. +208. **to_flashcards**: Create Anki flashcards from a given text, focusing on concise, optimized questions and answers without external context. +209. **transcribe_minutes**: Extracts (from meeting transcription) meeting minutes, identifying actionables, insightful ideas, decisions, challenges, and next steps in a structured format. +210. **translate**: Translates sentences or documentation into the specified language code while maintaining the original formatting and tone. +211. **tweet**: Provides a step-by-step guide on crafting engaging tweets with emojis, covering Twitter basics, account creation, features, and audience targeting. +212. **write_essay**: Writes essays in the style of a specified author, embodying their unique voice, vocabulary, and approach. Uses `author_name` variable. +213. **write_essay_pg**: Writes concise, clear essays in the style of Paul Graham, focusing on simplicity, clarity, and illumination of the provided topic. +214. **write_hackerone_report**: Generates concise, clear, and reproducible bug bounty reports, detailing vulnerability impact, steps to reproduce, and exploit details for triagers. +215. **write_latex**: Generates syntactically correct LaTeX code for a new.tex document, ensuring proper formatting and compatibility with pdflatex. +216. **write_micro_essay**: Writes concise, clear, and illuminating essays on the given topic in the style of Paul Graham. +217. **write_nuclei_template_rule**: Generates Nuclei YAML templates for detecting vulnerabilities using HTTP requests, matchers, extractors, and dynamic data extraction. +218. **write_pull-request**: Drafts detailed pull request descriptions, explaining changes, providing reasoning, and identifying potential bugs from the git diff command output. +219. **write_semgrep_rule**: Creates accurate and working Semgrep rules based on input, following syntax guidelines and specific language considerations. +220. **youtube_summary**: Create concise, timestamped Youtube video summaries that highlight key points. diff --git a/scripts/installer/README.md b/scripts/installer/README.md new file mode 100644 index 00000000..51e24a47 --- /dev/null +++ b/scripts/installer/README.md @@ -0,0 +1,114 @@ +# Fabric One-Line Installer + +This directory contains the official one-line installer scripts for Fabric. + +## Quick Start + +### Unix/Linux/macOS + +Install Fabric with a single command: + +```bash +curl -fsSL https://raw.githubusercontent.com/danielmiessler/fabric/main/scripts/installer/install.sh | bash +``` + +### Windows (PowerShell) + +Install Fabric with a single PowerShell command: + +```powershell +iwr -useb https://raw.githubusercontent.com/danielmiessler/fabric/main/scripts/installer/install.ps1 | iex +``` + +## Custom Installation Directory + +### Unix/Linux/macOS + +By default, Fabric is installed to `~/.local/bin`. To install elsewhere: + +```bash +curl -fsSL https://raw.githubusercontent.com/danielmiessler/fabric/main/scripts/installer/install.sh | INSTALL_DIR=/usr/local/bin bash +``` + +For system-wide installation (requires sudo): + +```bash +curl -fsSL https://raw.githubusercontent.com/danielmiessler/fabric/main/scripts/installer/install.sh | sudo INSTALL_DIR=/usr/local/bin bash +``` + +### Windows (PowerShell) + +By default, Fabric is installed to `%USERPROFILE%\.local\bin`. To install elsewhere: + +```powershell +$env:INSTALL_DIR="C:\tools"; iwr -useb https://raw.githubusercontent.com/danielmiessler/fabric/main/scripts/installer/install.ps1 | iex +``` + +## Supported Systems + +- **Operating Systems**: Darwin (macOS), Linux, Windows +- **Architectures**: x86_64, arm64, i386 (Windows only) + +## What It Does + +1. **Detects** your OS and architecture automatically +2. **Downloads** the latest Fabric release from GitHub +3. **Extracts** only the `fabric` binary (not the full archive) +4. **Installs** to your chosen directory (default: `~/.local/bin`) +5. **Verifies** the installation works correctly +6. **Provides** PATH setup instructions if needed + +## Features + +- ✅ **Cross-platform** - Unix/Linux/macOS (bash) and Windows (PowerShell) +- ✅ **Zero dependencies** - No additional tools required +- ✅ **Automatic detection** - OS and architecture +- ✅ **Smart extraction** - Only the binary, not extra files +- ✅ **Error handling** - Clear messages and graceful failures +- ✅ **PATH guidance** - Helps you set up your environment +- ✅ **Verification** - Tests the installation before completing + +## Requirements + +### Unix/Linux/macOS + +- `curl` or `wget` for downloading +- `tar` for extraction (standard on all Unix systems) +- Write permissions to the installation directory + +### Windows + +- PowerShell (built into Windows) +- Write permissions to the installation directory + +## After Installation + +1. **Configure Fabric**: Run `fabric --setup` +2. **Add API keys**: Follow the setup prompts +3. **Start using**: Try `fabric --help` or `fabric --listpatterns` + +## Troubleshooting + +**Permission denied?** + +- Try with `sudo` for system directories +- Or choose a directory you can write to: `INSTALL_DIR=~/bin` + +**Binary not found after install?** + +- Add the install directory to your PATH +- The installer provides specific instructions for your shell + +**Download fails?** + +- Check your internet connection +- Verify GitHub is accessible from your network + +## Alternative Installation Methods + +If the one-liner doesn't work for you, see the main [Installation Guide](../../README.md#installation) for: + +- Binary downloads +- Package managers (Homebrew, winget, AUR) +- Docker images +- Building from source diff --git a/scripts/installer/install.ps1 b/scripts/installer/install.ps1 new file mode 100644 index 00000000..805c4259 --- /dev/null +++ b/scripts/installer/install.ps1 @@ -0,0 +1,253 @@ +# Fabric Windows Installer Script +# Usage: iwr -useb https://raw.githubusercontent.com/danielmiessler/fabric/main/scripts/installer/install.ps1 | iex +# Usage with custom directory: $env:INSTALL_DIR="C:\tools"; iwr -useb https://raw.githubusercontent.com/danielmiessler/fabric/main/scripts/installer/install.ps1 | iex + +param( + [string]$InstallDir = $env:INSTALL_DIR +) + +$ErrorActionPreference = "Stop" + +# Colors for output (Windows Console colors) +$Colors = @{ + Red = "Red" + Green = "Green" + Yellow = "Yellow" + Blue = "Cyan" + White = "White" +} + +# Print functions +function Write-Info { + param([string]$Message) + Write-Host "[INFO] $Message" -ForegroundColor $Colors.Blue +} + +function Write-Success { + param([string]$Message) + Write-Host "[SUCCESS] $Message" -ForegroundColor $Colors.Green +} + +function Write-Warning { + param([string]$Message) + Write-Host "[WARNING] $Message" -ForegroundColor $Colors.Yellow +} + +function Write-Error { + param([string]$Message) + Write-Host "[ERROR] $Message" -ForegroundColor $Colors.Red +} + +# Detect Windows architecture +function Get-Architecture { + $arch = $env:PROCESSOR_ARCHITECTURE + $archAMD64 = $env:PROCESSOR_ARCHITEW6432 + + # Check for ARM64 + if ($arch -eq "ARM64") { + return "arm64" + } + + # Check for x86_64/AMD64 + if ($arch -eq "AMD64" -or $archAMD64 -eq "AMD64") { + return "x86_64" + } + + # Check for x86 (32-bit) + if ($arch -eq "X86") { + return "i386" + } + + Write-Error "Unsupported architecture: $arch" + Write-Error "This installer supports x86_64, i386, and arm64" + exit 1 +} + +# Test if running with appropriate permissions for directory +function Test-WritePermission { + param([string]$Path) + + try { + if (!(Test-Path $Path)) { + New-Item -Path $Path -ItemType Directory -Force | Out-Null + } + + $testFile = Join-Path $Path "fabric_write_test.tmp" + "test" | Out-File -FilePath $testFile -Force + Remove-Item $testFile -Force + return $true + } + catch { + return $false + } +} + +# Download and install Fabric +function Install-Fabric { + param( + [string]$Architecture, + [string]$InstallDirectory + ) + + # Construct download URL + $filename = "fabric_Windows_$Architecture.zip" + $downloadUrl = "https://github.com/danielmiessler/fabric/releases/latest/download/$filename" + + Write-Info "Downloading Fabric for Windows $Architecture..." + Write-Info "URL: $downloadUrl" + + # Create temporary directory + $tempDir = Join-Path $env:TEMP "fabric_install_$(Get-Random)" + New-Item -Path $tempDir -ItemType Directory -Force | Out-Null + $tempFile = Join-Path $tempDir "fabric.zip" + + try { + # Download the archive + Write-Info "Downloading archive..." + Invoke-WebRequest -Uri $downloadUrl -OutFile $tempFile -UseBasicParsing + + Write-Info "Extracting Fabric binary..." + + # Extract the zip file + Add-Type -AssemblyName System.IO.Compression.FileSystem + $zip = [System.IO.Compression.ZipFile]::OpenRead($tempFile) + + # Find and extract only fabric.exe + $fabricEntry = $zip.Entries | Where-Object { $_.Name -eq "fabric.exe" } + if (!$fabricEntry) { + Write-Error "fabric.exe not found in the downloaded archive" + exit 1 + } + + # Create install directory if it doesn't exist + if (!(Test-Path $InstallDirectory)) { + Write-Info "Creating install directory: $InstallDirectory" + New-Item -Path $InstallDirectory -ItemType Directory -Force | Out-Null + } + + # Extract fabric.exe to install directory + $fabricPath = Join-Path $InstallDirectory "fabric.exe" + Write-Info "Installing Fabric to $fabricPath..." + + [System.IO.Compression.ZipFileExtensions]::ExtractToFile($fabricEntry, $fabricPath, $true) + $zip.Dispose() + + Write-Success "Fabric installed successfully to $fabricPath" + return $fabricPath + } + catch { + Write-Error "Failed to download or extract Fabric: $($_.Exception.Message)" + exit 1 + } + finally { + # Clean up + if (Test-Path $tempDir) { + Remove-Item $tempDir -Recurse -Force -ErrorAction SilentlyContinue + } + } +} + +# Check if directory is in PATH +function Test-InPath { + param([string]$Directory) + + $pathDirs = $env:PATH -split ';' + return $pathDirs -contains $Directory +} + +# Provide PATH setup instructions +function Show-PathInstructions { + param([string]$InstallDir) + + if (Test-InPath $InstallDir) { + Write-Success "✅ $InstallDir is already in your PATH" + } + else { + Write-Warning "⚠️ $InstallDir is not in your PATH" + Write-Info "To use fabric from anywhere, you have a few options:" + Write-Info "" + Write-Info "Option 1 - Add to PATH for current user (recommended):" + Write-Info " `$currentPath = [Environment]::GetEnvironmentVariable('PATH', 'User')" + Write-Info " [Environment]::SetEnvironmentVariable('PATH', `"`$currentPath;$InstallDir`", 'User')" + Write-Info "" + Write-Info "Option 2 - Add to PATH for all users (requires admin):" + Write-Info " `$currentPath = [Environment]::GetEnvironmentVariable('PATH', 'Machine')" + Write-Info " [Environment]::SetEnvironmentVariable('PATH', `"`$currentPath;$InstallDir`", 'Machine')" + Write-Info "" + Write-Info "Option 3 - Add to current session only:" + Write-Info " `$env:PATH += `";$InstallDir`"" + Write-Info "" + Write-Info "After updating PATH, restart your terminal or run: refreshenv" + } +} + +# Verify installation +function Test-Installation { + param([string]$FabricPath) + + if (Test-Path $FabricPath) { + Write-Info "Verifying installation..." + try { + $version = & $FabricPath --version 2>$null + if ($LASTEXITCODE -eq 0) { + Write-Success "Fabric $version is working correctly!" + } + else { + Write-Warning "Fabric binary exists but --version failed" + } + } + catch { + Write-Warning "Fabric binary exists but could not run --version" + } + } + else { + Write-Error "Fabric binary not found at $FabricPath" + exit 1 + } +} + +# Main installation function +function Main { + Write-Info "🚀 Starting Fabric installation..." + + # Detect architecture + $arch = Get-Architecture + Write-Info "Detected architecture: $arch" + + # Determine install directory + if (!$InstallDir) { + $InstallDir = Join-Path $env:USERPROFILE ".local\bin" + } + + Write-Info "Install directory: $InstallDir" + + # Check permissions + if (!(Test-WritePermission $InstallDir)) { + Write-Error "Cannot write to $InstallDir" + Write-Error "Try running as Administrator or choose a different directory" + Write-Info "Example with custom directory: `$env:INSTALL_DIR=`"C:\tools`"; iwr -useb ... | iex" + exit 1 + } + + # Install Fabric + $fabricPath = Install-Fabric -Architecture $arch -InstallDirectory $InstallDir + + # Verify installation + Test-Installation -FabricPath $fabricPath + + # Check PATH and provide instructions + Show-PathInstructions -InstallDir $InstallDir + + Write-Info "" + Write-Success "🎉 Installation complete!" + Write-Info "" + Write-Info "Next steps:" + Write-Info " 1. Run 'fabric --setup' to configure Fabric" + Write-Info " 2. Add your API keys and preferences" + Write-Info " 3. Start using Fabric with 'fabric --help'" + Write-Info "" + Write-Info "Documentation: https://github.com/danielmiessler/fabric" +} + +# Run main function +Main \ No newline at end of file diff --git a/scripts/installer/install.sh b/scripts/installer/install.sh new file mode 100755 index 00000000..d0c7f65e --- /dev/null +++ b/scripts/installer/install.sh @@ -0,0 +1,219 @@ +#!/bin/bash +# Fabric Installer Script +# Usage: curl -fsSL https://raw.githubusercontent.com/danielmiessler/fabric/main/scripts/installer/install.sh | bash +# Usage with custom directory: curl -fsSL https://raw.githubusercontent.com/danielmiessler/fabric/main/scripts/installer/install.sh | INSTALL_DIR=/usr/local/bin bash + +set -e + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Print functions +print_info() { + printf "${BLUE}[INFO]${NC} %s\n" "$1" +} + +print_success() { + printf "${GREEN}[SUCCESS]${NC} %s\n" "$1" +} + +print_warning() { + printf "${YELLOW}[WARNING]${NC} %s\n" "$1" +} + +print_error() { + printf "${RED}[ERROR]${NC} %s\n" "$1" >&2 +} + +# Detect OS +detect_os() { + case "$(uname -s)" in + Darwin*) + echo "Darwin" + ;; + Linux*) + echo "Linux" + ;; + *) + print_error "Unsupported operating system: $(uname -s)" + print_error "This installer only supports Darwin (macOS) and Linux" + exit 1 + ;; + esac +} + +# Detect architecture +detect_arch() { + case "$(uname -m)" in + x86_64|amd64) + echo "x86_64" + ;; + arm64|aarch64) + echo "arm64" + ;; + *) + print_error "Unsupported architecture: $(uname -m)" + print_error "This installer only supports x86_64 and arm64" + exit 1 + ;; + esac +} + +# Check if command exists +command_exists() { + command -v "$1" >/dev/null 2>&1 +} + +# Download and extract fabric +install_fabric() { + local os="$1" + local arch="$2" + local install_dir="$3" + + # Construct download URL + local filename="fabric_${os}_${arch}.tar.gz" + local download_url="https://github.com/danielmiessler/fabric/releases/latest/download/${filename}" + + print_info "Downloading Fabric for ${os} ${arch}..." + print_info "URL: ${download_url}" + + # Create temporary directory + local temp_dir + temp_dir=$(mktemp -d) + local temp_file="${temp_dir}/fabric.tar.gz" + + # Download the archive + if command_exists curl; then + if ! curl -fsSL "${download_url}" -o "${temp_file}"; then + print_error "Failed to download Fabric" + rm -rf "${temp_dir}" + exit 1 + fi + elif command_exists wget; then + if ! wget -q "${download_url}" -O "${temp_file}"; then + print_error "Failed to download Fabric" + rm -rf "${temp_dir}" + exit 1 + fi + else + print_error "Neither curl nor wget found. Please install one of them and try again." + exit 1 + fi + + print_info "Extracting Fabric binary..." + + # Extract only the fabric binary from the archive + if ! tar -xzf "${temp_file}" -C "${temp_dir}" fabric; then + print_error "Failed to extract Fabric binary" + rm -rf "${temp_dir}" + exit 1 + fi + + # Create install directory if it doesn't exist + if [ ! -d "${install_dir}" ]; then + print_info "Creating install directory: ${install_dir}" + if ! mkdir -p "${install_dir}"; then + print_error "Failed to create install directory: ${install_dir}" + print_error "You may need to run with sudo or choose a different directory" + rm -rf "${temp_dir}" + exit 1 + fi + fi + + # Move binary to install directory + print_info "Installing Fabric to ${install_dir}/fabric..." + if ! mv "${temp_dir}/fabric" "${install_dir}/fabric"; then + print_error "Failed to install Fabric to ${install_dir}" + print_error "You may need to run with sudo or choose a different directory" + rm -rf "${temp_dir}" + exit 1 + fi + + # Make sure it's executable + chmod +x "${install_dir}/fabric" + + # Clean up + rm -rf "${temp_dir}" + + print_success "Fabric installed successfully to ${install_dir}/fabric" +} + +# Check PATH and provide instructions +check_path() { + local install_dir="$1" + + if echo "$PATH" | grep -q "${install_dir}"; then + print_success "✅ ${install_dir} is already in your PATH" + else + print_warning "⚠️ ${install_dir} is not in your PATH" + print_info "To use fabric from anywhere, add the following to your shell profile:" + print_info " export PATH=\"\$PATH:${install_dir}\"" + print_info "" + print_info "For bash, add it to ~/.bashrc or ~/.bash_profile" + print_info "For zsh, add it to ~/.zshrc" + print_info "For fish, run: fish_add_path ${install_dir}" + fi +} + +# Verify installation +verify_installation() { + local install_dir="$1" + local fabric_path="${install_dir}/fabric" + + if [ -x "${fabric_path}" ]; then + print_info "Verifying installation..." + local version + if version=$("${fabric_path}" --version 2>/dev/null); then + print_success "Fabric ${version} is working correctly!" + else + print_warning "Fabric binary exists but --version failed" + fi + else + print_error "Fabric binary not found at ${fabric_path}" + exit 1 + fi +} + +# Main installation function +main() { + print_info "🚀 Starting Fabric installation..." + + # Detect system + local os + local arch + os=$(detect_os) + arch=$(detect_arch) + + print_info "Detected system: ${os} ${arch}" + + # Determine install directory + local install_dir="${INSTALL_DIR:-${HOME}/.local/bin}" + + print_info "Install directory: ${install_dir}" + + # Install fabric + install_fabric "${os}" "${arch}" "${install_dir}" + + # Verify installation + verify_installation "${install_dir}" + + # Check PATH + check_path "${install_dir}" + + print_info "" + print_success "🎉 Installation complete!" + print_info "" + print_info "Next steps:" + print_info " 1. Run 'fabric --setup' to configure Fabric" + print_info " 2. Add your API keys and preferences" + print_info " 3. Start using Fabric with 'fabric --help'" + print_info "" + print_info "Documentation: https://github.com/danielmiessler/fabric" +} + +# Run main function +main "$@" \ No newline at end of file