diff --git a/.gitignore b/.gitignore index bf6a25d52..902ea6439 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ evals/swe-bench/repos/ evals/swe-bench/results/ evals/swe-bench/dockerfiles/ __pycache__ +.vercel diff --git a/apps/marketing/.gitignore b/apps/marketing/.gitignore index 1f9030c6d..0c3049d1e 100644 --- a/apps/marketing/.gitignore +++ b/apps/marketing/.gitignore @@ -1,3 +1,4 @@ dist/ .astro/ node_modules/ +.vercel diff --git a/apps/marketing/public/install.md b/apps/marketing/public/install.md deleted file mode 120000 index deb797142..000000000 --- a/apps/marketing/public/install.md +++ /dev/null @@ -1 +0,0 @@ -../../../install.md \ No newline at end of file diff --git a/apps/marketing/public/install.md b/apps/marketing/public/install.md new file mode 100644 index 000000000..3cc4b4d90 --- /dev/null +++ b/apps/marketing/public/install.md @@ -0,0 +1,101 @@ +# fabro + +> AI-powered workflow orchestration platform. Workflows are defined as DOT graphs and executed by the Fabro engine. + +I want you to install Fabro for me. Execute all the steps below autonomously. + +OBJECTIVE: Install the Fabro CLI binary and verify it works. + +DONE WHEN: `fabro --version` prints a version string. + +## TODO + +- [ ] Ensure the `gh` CLI is installed and authenticated +- [ ] Detect the platform and download the correct release asset +- [ ] Extract the binary and install it to `~/.fabro/bin` +- [ ] Add `~/.fabro/bin` to PATH in the user's shell config +- [ ] Verify `fabro --version` works + +## Ensure `gh` CLI is available + +You need the GitHub CLI (`gh`) installed and authenticated. Check with: + +```bash +gh auth status +``` + +If `gh` is not installed, install it: + +- **macOS:** `brew install gh` +- **Linux:** See https://github.com/cli/cli/blob/trunk/docs/install_linux.md + +Then authenticate with `gh auth login` if needed. + +## Detect platform and download + +Determine the correct release asset based on the platform: + +| OS | Architecture | Asset name | +|---|---|---| +| macOS | arm64 (Apple Silicon) | `fabro-aarch64-apple-darwin.tar.gz` | +| Linux | x86_64 | `fabro-x86_64-unknown-linux-gnu.tar.gz` | + +On macOS, if `uname -m` reports `x86_64`, check for Rosetta translation with `sysctl -n sysctl.proc_translated`. If it returns `1`, the actual architecture is arm64. + +Download the asset using `gh`: + +```bash +gh release download --repo fabro-sh/fabro --pattern "fabro-.tar.gz" --dir /tmp/fabro-install --clobber +``` + +Replace `` with the correct target triple from the table above. + +## Extract and install + +```bash +tar xzf /tmp/fabro-install/fabro-.tar.gz -C /tmp/fabro-install +mkdir -p ~/.fabro/bin +mv /tmp/fabro-install/fabro-/fabro ~/.fabro/bin/fabro +chmod +x ~/.fabro/bin/fabro +rm -rf /tmp/fabro-install +``` + +## Add to PATH + +If `~/.fabro/bin` is not already on PATH, you must add it to the user's shell configuration file so it persists across sessions. + +**zsh** — append to `~/.zshrc` (or `$ZDOTDIR/.zshrc` if `ZDOTDIR` is set): + +```bash +printf '\n# fabro\nexport PATH="$HOME/.fabro/bin:$PATH"\n' >> ~/.zshrc +``` + +**bash** — append to `~/.bash_profile` if it exists, otherwise `~/.bashrc`: + +```bash +printf '\n# fabro\nexport PATH="$HOME/.fabro/bin:$PATH"\n' >> ~/.bash_profile +``` + +**fish** — append to `~/.config/fish/config.fish`: + +```bash +printf '\n# fabro\nfish_add_path $HOME/.fabro/bin\n' >> ~/.config/fish/config.fish +``` + +After updating the config file, export PATH for the current session too: + +```bash +export PATH="$HOME/.fabro/bin:$PATH" +``` + +## Verify + +```bash +fabro --version +``` + +This must print a version string like `fabro 0.x.y`. If it does, installation is complete. + +Tell the user to run `fabro install` in their terminal to complete setup. + +EXECUTE NOW: Complete the above TODO list to achieve: `fabro --version` prints a version string. diff --git a/apps/marketing/public/install.sh b/apps/marketing/public/install.sh deleted file mode 120000 index 1d7ea8003..000000000 --- a/apps/marketing/public/install.sh +++ /dev/null @@ -1 +0,0 @@ -../../../install.sh \ No newline at end of file diff --git a/apps/marketing/public/install.sh b/apps/marketing/public/install.sh new file mode 100755 index 000000000..9315e0ca7 --- /dev/null +++ b/apps/marketing/public/install.sh @@ -0,0 +1,162 @@ +#!/bin/sh +set -eu + +REPO="fabro-sh/fabro" + +# Colors (only when stderr is a terminal) +if [ -t 2 ]; then + RED='\033[0;31m' + GREEN='\033[0;32m' + DIM='\033[2m' + BOLD='\033[1m' + BOLD_CYAN='\033[1;36m' + RESET='\033[0m' +else + RED='' + GREEN='' + DIM='' + BOLD='' + BOLD_CYAN='' + RESET='' +fi + +info() { printf " %b\n" "$1" >&2; } +step() { printf " ${BOLD}%b${RESET}\n" "$1" >&2; } +dim() { printf " ${DIM}%b${RESET}\n" "$1" >&2; } +success() { printf " ${GREEN}✔${RESET} %b\n" "$1" >&2; } +error() { printf " ${RED}✗ %b${RESET}\n" "$1" >&2; exit 1; } + +# --- Header --- +printf "\n ⚒️ ${BOLD}Fabro Install${RESET}\n\n" >&2 + +# --- Require gh CLI --- +if ! command -v gh >/dev/null 2>&1; then + error "gh CLI is required but not installed. Install it from ${BOLD_CYAN}https://cli.github.com${RESET}" +fi + +# --- Detect platform --- +OS="$(uname -s)" +ARCH="$(uname -m)" + +case "$OS" in + Darwin) + # Detect Rosetta translation + if [ "$ARCH" = "x86_64" ]; then + if sysctl -n sysctl.proc_translated 2>/dev/null | grep -q 1; then + ARCH="arm64" + fi + fi + case "$ARCH" in + arm64) TARGET="aarch64-apple-darwin" ;; + *) error "Unsupported macOS architecture: $ARCH. Supported: Apple Silicon (arm64)" ;; + esac + ;; + Linux) + case "$ARCH" in + x86_64) TARGET="x86_64-unknown-linux-gnu" ;; + *) error "Unsupported Linux architecture: $ARCH. Supported: x86_64" ;; + esac + ;; + *) + error "Unsupported OS: $OS. Supported platforms: macOS (Apple Silicon), Linux (x86_64)" + ;; +esac + +ASSET="fabro-${TARGET}.tar.gz" +TMPDIR="$(mktemp -d)" +trap 'rm -rf "$TMPDIR"' EXIT + +dim "Downloading fabro for ${TARGET}..." +gh release download --repo "$REPO" --pattern "$ASSET" --dir "$TMPDIR" --clobber + +dim "Extracting..." +tar xzf "${TMPDIR}/${ASSET}" -C "$TMPDIR" + +# --- Install binary --- +INSTALL_DIR="${FABRO_INSTALL_DIR:-$HOME/.fabro/bin}" +mkdir -p "$INSTALL_DIR" +mv "${TMPDIR}/fabro-${TARGET}/fabro" "${INSTALL_DIR}/fabro" + +chmod +x "${INSTALL_DIR}/fabro" + +# --- Verify --- +VERSION="$("${INSTALL_DIR}/fabro" --version 2>/dev/null || true)" +if [ -z "$VERSION" ]; then + error "Installation failed: could not run fabro --version" +fi + +tildify() { + if [ "${1#"$HOME"/}" != "$1" ]; then + echo "~/${1#"$HOME"/}" + else + echo "$1" + fi +} + +success "Installed ${VERSION} to ${BOLD_CYAN}$(tildify "${INSTALL_DIR}/fabro")${RESET}" + +# --- Ensure install dir is on PATH --- +if command -v fabro >/dev/null 2>&1; then + dim "fabro is already on \$PATH, skipping shell config" +else + tilde_bin_dir=$(tildify "$INSTALL_DIR") + echo "" >&2 + + if [ -t 2 ] && [ -e /dev/tty ]; then + case $(basename "${SHELL:-sh}") in + zsh) + : "${ZDOTDIR:="$HOME"}" + shell_config="${ZDOTDIR%/}/.zshrc" + { + printf '\n# fabro\n' + echo "export PATH=\"$INSTALL_DIR:\$PATH\"" + } >>"$shell_config" + info "Added ${BOLD_CYAN}${tilde_bin_dir}${RESET} to \$PATH in ${BOLD_CYAN}$(tildify "$shell_config")${RESET}" + ;; + bash) + shell_config="$HOME/.bashrc" + if [ -f "$HOME/.bash_profile" ]; then + shell_config="$HOME/.bash_profile" + fi + { + printf '\n# fabro\n' + echo "export PATH=\"$INSTALL_DIR:\$PATH\"" + } >>"$shell_config" + info "Added ${BOLD_CYAN}${tilde_bin_dir}${RESET} to \$PATH in ${BOLD_CYAN}$(tildify "$shell_config")${RESET}" + ;; + fish) + fish_config="$HOME/.config/fish/config.fish" + mkdir -p "$(dirname "$fish_config")" + { + printf '\n# fabro\n' + echo "fish_add_path $INSTALL_DIR" + } >>"$fish_config" + info "Added ${BOLD_CYAN}${tilde_bin_dir}${RESET} to \$PATH in ${BOLD_CYAN}$(tildify "$fish_config")${RESET}" + ;; + *) + info "Add ${BOLD_CYAN}${tilde_bin_dir}${RESET} to your PATH:" + echo "" >&2 + info " ${BOLD}export PATH=\"${INSTALL_DIR}:\$PATH\"${RESET}" + ;; + esac + else + info "Add ${BOLD_CYAN}${tilde_bin_dir}${RESET} to your PATH:" + echo "" >&2 + info " ${BOLD}export PATH=\"${INSTALL_DIR}:\$PATH\"${RESET}" + fi + + export PATH="${INSTALL_DIR}:$PATH" +fi +echo "" >&2 + +# --- Prompt to run setup wizard --- +if [ -t 2 ] && [ -e /dev/tty ]; then + printf " ${BOLD}Run ${BOLD_CYAN}fabro install${RESET}${BOLD} now to complete setup? [Y/n]${RESET} " >&2 + read -r answer &2; exec "${INSTALL_DIR}/fabro" install ;; + esac +else + info "Run ${BOLD_CYAN}fabro install${RESET} to complete setup." +fi diff --git a/install.md b/install.md deleted file mode 100644 index 3cc4b4d90..000000000 --- a/install.md +++ /dev/null @@ -1,101 +0,0 @@ -# fabro - -> AI-powered workflow orchestration platform. Workflows are defined as DOT graphs and executed by the Fabro engine. - -I want you to install Fabro for me. Execute all the steps below autonomously. - -OBJECTIVE: Install the Fabro CLI binary and verify it works. - -DONE WHEN: `fabro --version` prints a version string. - -## TODO - -- [ ] Ensure the `gh` CLI is installed and authenticated -- [ ] Detect the platform and download the correct release asset -- [ ] Extract the binary and install it to `~/.fabro/bin` -- [ ] Add `~/.fabro/bin` to PATH in the user's shell config -- [ ] Verify `fabro --version` works - -## Ensure `gh` CLI is available - -You need the GitHub CLI (`gh`) installed and authenticated. Check with: - -```bash -gh auth status -``` - -If `gh` is not installed, install it: - -- **macOS:** `brew install gh` -- **Linux:** See https://github.com/cli/cli/blob/trunk/docs/install_linux.md - -Then authenticate with `gh auth login` if needed. - -## Detect platform and download - -Determine the correct release asset based on the platform: - -| OS | Architecture | Asset name | -|---|---|---| -| macOS | arm64 (Apple Silicon) | `fabro-aarch64-apple-darwin.tar.gz` | -| Linux | x86_64 | `fabro-x86_64-unknown-linux-gnu.tar.gz` | - -On macOS, if `uname -m` reports `x86_64`, check for Rosetta translation with `sysctl -n sysctl.proc_translated`. If it returns `1`, the actual architecture is arm64. - -Download the asset using `gh`: - -```bash -gh release download --repo fabro-sh/fabro --pattern "fabro-.tar.gz" --dir /tmp/fabro-install --clobber -``` - -Replace `` with the correct target triple from the table above. - -## Extract and install - -```bash -tar xzf /tmp/fabro-install/fabro-.tar.gz -C /tmp/fabro-install -mkdir -p ~/.fabro/bin -mv /tmp/fabro-install/fabro-/fabro ~/.fabro/bin/fabro -chmod +x ~/.fabro/bin/fabro -rm -rf /tmp/fabro-install -``` - -## Add to PATH - -If `~/.fabro/bin` is not already on PATH, you must add it to the user's shell configuration file so it persists across sessions. - -**zsh** — append to `~/.zshrc` (or `$ZDOTDIR/.zshrc` if `ZDOTDIR` is set): - -```bash -printf '\n# fabro\nexport PATH="$HOME/.fabro/bin:$PATH"\n' >> ~/.zshrc -``` - -**bash** — append to `~/.bash_profile` if it exists, otherwise `~/.bashrc`: - -```bash -printf '\n# fabro\nexport PATH="$HOME/.fabro/bin:$PATH"\n' >> ~/.bash_profile -``` - -**fish** — append to `~/.config/fish/config.fish`: - -```bash -printf '\n# fabro\nfish_add_path $HOME/.fabro/bin\n' >> ~/.config/fish/config.fish -``` - -After updating the config file, export PATH for the current session too: - -```bash -export PATH="$HOME/.fabro/bin:$PATH" -``` - -## Verify - -```bash -fabro --version -``` - -This must print a version string like `fabro 0.x.y`. If it does, installation is complete. - -Tell the user to run `fabro install` in their terminal to complete setup. - -EXECUTE NOW: Complete the above TODO list to achieve: `fabro --version` prints a version string. diff --git a/install.md b/install.md new file mode 120000 index 000000000..396c24616 --- /dev/null +++ b/install.md @@ -0,0 +1 @@ +apps/marketing/public/install.md \ No newline at end of file diff --git a/install.sh b/install.sh deleted file mode 100755 index 9315e0ca7..000000000 --- a/install.sh +++ /dev/null @@ -1,162 +0,0 @@ -#!/bin/sh -set -eu - -REPO="fabro-sh/fabro" - -# Colors (only when stderr is a terminal) -if [ -t 2 ]; then - RED='\033[0;31m' - GREEN='\033[0;32m' - DIM='\033[2m' - BOLD='\033[1m' - BOLD_CYAN='\033[1;36m' - RESET='\033[0m' -else - RED='' - GREEN='' - DIM='' - BOLD='' - BOLD_CYAN='' - RESET='' -fi - -info() { printf " %b\n" "$1" >&2; } -step() { printf " ${BOLD}%b${RESET}\n" "$1" >&2; } -dim() { printf " ${DIM}%b${RESET}\n" "$1" >&2; } -success() { printf " ${GREEN}✔${RESET} %b\n" "$1" >&2; } -error() { printf " ${RED}✗ %b${RESET}\n" "$1" >&2; exit 1; } - -# --- Header --- -printf "\n ⚒️ ${BOLD}Fabro Install${RESET}\n\n" >&2 - -# --- Require gh CLI --- -if ! command -v gh >/dev/null 2>&1; then - error "gh CLI is required but not installed. Install it from ${BOLD_CYAN}https://cli.github.com${RESET}" -fi - -# --- Detect platform --- -OS="$(uname -s)" -ARCH="$(uname -m)" - -case "$OS" in - Darwin) - # Detect Rosetta translation - if [ "$ARCH" = "x86_64" ]; then - if sysctl -n sysctl.proc_translated 2>/dev/null | grep -q 1; then - ARCH="arm64" - fi - fi - case "$ARCH" in - arm64) TARGET="aarch64-apple-darwin" ;; - *) error "Unsupported macOS architecture: $ARCH. Supported: Apple Silicon (arm64)" ;; - esac - ;; - Linux) - case "$ARCH" in - x86_64) TARGET="x86_64-unknown-linux-gnu" ;; - *) error "Unsupported Linux architecture: $ARCH. Supported: x86_64" ;; - esac - ;; - *) - error "Unsupported OS: $OS. Supported platforms: macOS (Apple Silicon), Linux (x86_64)" - ;; -esac - -ASSET="fabro-${TARGET}.tar.gz" -TMPDIR="$(mktemp -d)" -trap 'rm -rf "$TMPDIR"' EXIT - -dim "Downloading fabro for ${TARGET}..." -gh release download --repo "$REPO" --pattern "$ASSET" --dir "$TMPDIR" --clobber - -dim "Extracting..." -tar xzf "${TMPDIR}/${ASSET}" -C "$TMPDIR" - -# --- Install binary --- -INSTALL_DIR="${FABRO_INSTALL_DIR:-$HOME/.fabro/bin}" -mkdir -p "$INSTALL_DIR" -mv "${TMPDIR}/fabro-${TARGET}/fabro" "${INSTALL_DIR}/fabro" - -chmod +x "${INSTALL_DIR}/fabro" - -# --- Verify --- -VERSION="$("${INSTALL_DIR}/fabro" --version 2>/dev/null || true)" -if [ -z "$VERSION" ]; then - error "Installation failed: could not run fabro --version" -fi - -tildify() { - if [ "${1#"$HOME"/}" != "$1" ]; then - echo "~/${1#"$HOME"/}" - else - echo "$1" - fi -} - -success "Installed ${VERSION} to ${BOLD_CYAN}$(tildify "${INSTALL_DIR}/fabro")${RESET}" - -# --- Ensure install dir is on PATH --- -if command -v fabro >/dev/null 2>&1; then - dim "fabro is already on \$PATH, skipping shell config" -else - tilde_bin_dir=$(tildify "$INSTALL_DIR") - echo "" >&2 - - if [ -t 2 ] && [ -e /dev/tty ]; then - case $(basename "${SHELL:-sh}") in - zsh) - : "${ZDOTDIR:="$HOME"}" - shell_config="${ZDOTDIR%/}/.zshrc" - { - printf '\n# fabro\n' - echo "export PATH=\"$INSTALL_DIR:\$PATH\"" - } >>"$shell_config" - info "Added ${BOLD_CYAN}${tilde_bin_dir}${RESET} to \$PATH in ${BOLD_CYAN}$(tildify "$shell_config")${RESET}" - ;; - bash) - shell_config="$HOME/.bashrc" - if [ -f "$HOME/.bash_profile" ]; then - shell_config="$HOME/.bash_profile" - fi - { - printf '\n# fabro\n' - echo "export PATH=\"$INSTALL_DIR:\$PATH\"" - } >>"$shell_config" - info "Added ${BOLD_CYAN}${tilde_bin_dir}${RESET} to \$PATH in ${BOLD_CYAN}$(tildify "$shell_config")${RESET}" - ;; - fish) - fish_config="$HOME/.config/fish/config.fish" - mkdir -p "$(dirname "$fish_config")" - { - printf '\n# fabro\n' - echo "fish_add_path $INSTALL_DIR" - } >>"$fish_config" - info "Added ${BOLD_CYAN}${tilde_bin_dir}${RESET} to \$PATH in ${BOLD_CYAN}$(tildify "$fish_config")${RESET}" - ;; - *) - info "Add ${BOLD_CYAN}${tilde_bin_dir}${RESET} to your PATH:" - echo "" >&2 - info " ${BOLD}export PATH=\"${INSTALL_DIR}:\$PATH\"${RESET}" - ;; - esac - else - info "Add ${BOLD_CYAN}${tilde_bin_dir}${RESET} to your PATH:" - echo "" >&2 - info " ${BOLD}export PATH=\"${INSTALL_DIR}:\$PATH\"${RESET}" - fi - - export PATH="${INSTALL_DIR}:$PATH" -fi -echo "" >&2 - -# --- Prompt to run setup wizard --- -if [ -t 2 ] && [ -e /dev/tty ]; then - printf " ${BOLD}Run ${BOLD_CYAN}fabro install${RESET}${BOLD} now to complete setup? [Y/n]${RESET} " >&2 - read -r answer &2; exec "${INSTALL_DIR}/fabro" install ;; - esac -else - info "Run ${BOLD_CYAN}fabro install${RESET} to complete setup." -fi diff --git a/install.sh b/install.sh new file mode 120000 index 000000000..3b33bd0bd --- /dev/null +++ b/install.sh @@ -0,0 +1 @@ +apps/marketing/public/install.sh \ No newline at end of file