From c6c0f97a4cb4a7d7fad7f3754cca4702461c12dc Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 24 May 2026 08:43:11 +0000 Subject: [PATCH 1/2] feat: add Pi Coding Agent to AI assistant options Adds Pi (https://pi.dev) as a sixth selectable AI coding assistant in the setup wizard. Installs via npm using the upstream-recommended --ignore-scripts flag, reusing the existing ensure_node_for_npm helper so Node.js is auto-installed if missing. --- README.md | 4 +++- scripts/squarebox-setup.sh | 2 +- setup.sh | 21 ++++++++++++++++----- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 2c814f7..8ba177e 100644 --- a/README.md +++ b/README.md @@ -149,6 +149,7 @@ container rebuilds. | [Google Gemini CLI](https://github.com/google-gemini/gemini-cli) | TypeScript | Google Gemini in the terminal * | | [OpenAI Codex CLI](https://github.com/openai/codex) | TypeScript | OpenAI Codex in the terminal * | | [opencode](https://github.com/anomalyco/opencode) | Go | AI coding TUI | +| [Pi Coding Agent](https://github.com/earendil-works/pi) | TypeScript | Minimal terminal coding harness (Earendil) * | \* Requires Node.js (auto-installed if needed). @@ -325,6 +326,7 @@ First-run selections add to that: | Google Gemini CLI | ~50 MB | | OpenAI Codex CLI | ~50 MB | | OpenCode | ~30 MB | +| Pi Coding Agent | ~50 MB | | lazygit / gh-dash / yazi | ~10 / ~10 / ~10 MB | | micro / edit | ~12 / ~7 MB | | fresh / nvim | ~10 / ~45 MB | @@ -350,7 +352,7 @@ get new features without waiting for a squarebox release, at the cost of build-time pinning for that tier. Third-party install scripts (Claude Code, uv, .NET) delegate to the vendor -installer. npm-based AI tools (Copilot CLI, Gemini CLI, Codex CLI) use npm's +installer. npm-based AI tools (Copilot CLI, Gemini CLI, Codex CLI, Pi) use npm's built-in integrity verification. For the full trust model (what `install.sh` does on your machine, how each diff --git a/scripts/squarebox-setup.sh b/scripts/squarebox-setup.sh index cf0f604..3cb8566 100644 --- a/scripts/squarebox-setup.sh +++ b/scripts/squarebox-setup.sh @@ -31,7 +31,7 @@ usage() { ${BOLD}Sections:${RESET} git Git identity (name, email) github GitHub CLI authentication - ai AI coding assistants (claude, copilot, gemini, codex, opencode) + ai AI coding assistants (claude, copilot, gemini, codex, opencode, pi) editors Text editors (micro, edit, fresh, nvim) tuis TUI tools (lazygit, gh-dash, yazi) multiplexers Terminal multiplexers (tmux, zellij) diff --git a/setup.sh b/setup.sh index fa80b9b..331f734 100755 --- a/setup.sh +++ b/setup.sh @@ -348,13 +348,14 @@ if $INTERACTIVE; then gemini) gum_selected="${gum_selected:+$gum_selected,}Google Gemini CLI" ;; codex) gum_selected="${gum_selected:+$gum_selected,}OpenAI Codex CLI" ;; opencode) gum_selected="${gum_selected:+$gum_selected,}OpenCode" ;; + pi) gum_selected="${gum_selected:+$gum_selected,}Pi Coding Agent" ;; esac done gum_args=(--no-limit --header "Select AI coding assistants (space=toggle, enter=confirm):") [ -n "$gum_selected" ] && gum_args+=(--selected "$gum_selected") selected=$(gum choose "${gum_args[@]}" \ "Claude Code" "GitHub Copilot CLI" "Google Gemini CLI" \ - "OpenAI Codex CLI" "OpenCode") || true + "OpenAI Codex CLI" "OpenCode" "Pi Coding Agent") || true ai_choice="" while IFS= read -r line; do case "$line" in @@ -363,11 +364,12 @@ if $INTERACTIVE; then "Google Gemini CLI") ai_choice="${ai_choice:+$ai_choice,}gemini" ;; "OpenAI Codex CLI") ai_choice="${ai_choice:+$ai_choice,}codex" ;; "OpenCode") ai_choice="${ai_choice:+$ai_choice,}opencode" ;; + "Pi Coding Agent") ai_choice="${ai_choice:+$ai_choice,}pi" ;; esac done <<< "$selected" else echo "Select AI coding assistants (comma-separated, 'all', or press Enter to skip):" - for ai_item in "1:claude:Claude Code" "2:copilot:GitHub Copilot CLI" "3:gemini:Google Gemini CLI" "4:codex:OpenAI Codex CLI" "5:opencode:OpenCode"; do + for ai_item in "1:claude:Claude Code" "2:copilot:GitHub Copilot CLI" "3:gemini:Google Gemini CLI" "4:codex:OpenAI Codex CLI" "5:opencode:OpenCode" "6:pi:Pi Coding Agent"; do num="${ai_item%%:*}"; rest="${ai_item#*:}"; key="${rest%%:*}"; label="${rest#*:}" if [[ ",$ai_prev," == *",${key},"* ]]; then echo " ${num}) ${label} [installed]" @@ -375,13 +377,13 @@ if $INTERACTIVE; then echo " ${num}) ${label}" fi done - read -rp "Selection [1,2,3,4,5/all/skip]: " ai_selection + read -rp "Selection [1,2,3,4,5,6/all/skip]: " ai_selection if [ -z "$ai_selection" ] && [ -n "$ai_prev" ]; then ai_choice="$ai_prev" else ai_choice="" if [ "$ai_selection" = "all" ]; then - ai_choice="claude,copilot,gemini,codex,opencode" + ai_choice="claude,copilot,gemini,codex,opencode,pi" elif [ -n "$ai_selection" ]; then for item in $(echo "$ai_selection" | tr ',' ' '); do case "$item" in @@ -390,6 +392,7 @@ if $INTERACTIVE; then 3) ai_choice="${ai_choice:+$ai_choice,}gemini" ;; 4) ai_choice="${ai_choice:+$ai_choice,}codex" ;; 5) ai_choice="${ai_choice:+$ai_choice,}opencode" ;; + 6) ai_choice="${ai_choice:+$ai_choice,}pi" ;; esac done fi @@ -423,6 +426,13 @@ install_codex() { run_with_spinner "Installing OpenAI Codex CLI..." npm install -g --silent @openai/codex } +install_pi() { + if command -v pi &>/dev/null; then echo "Pi Coding Agent already installed, skipping."; return 0; fi + ensure_node_for_npm + # --ignore-scripts is the upstream-recommended install flag (see pi.dev). + run_with_spinner "Installing Pi Coding Agent..." npm install -g --silent --ignore-scripts @earendil-works/pi-coding-agent +} + for ai_tool in $(echo "$ai_choice" | tr ',' ' '); do case "$ai_tool" in claude) @@ -443,13 +453,14 @@ for ai_tool in $(echo "$ai_choice" | tr ',' ' '); do copilot) install_copilot || echo "Warning: GitHub Copilot CLI installation failed." ;; gemini) install_gemini || echo "Warning: Google Gemini CLI installation failed." ;; codex) install_codex || echo "Warning: OpenAI Codex CLI installation failed." ;; + pi) install_pi || echo "Warning: Pi Coding Agent installation failed." ;; esac done # Set aliases based on selection — c maps to first selected tool in priority order { c_target="" - for ai_tool in claude copilot gemini codex opencode; do + for ai_tool in claude copilot gemini codex opencode pi; do if [[ ",$ai_choice," == *",$ai_tool,"* ]]; then [ -z "$c_target" ] && c_target="$ai_tool" case "$ai_tool" in From 74a1485e996a3621bab44e1015c26e85223c786f Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 24 May 2026 10:50:22 +0000 Subject: [PATCH 2/2] test: cover pi install path in setup-editors E2E suite Append `pi` to the pre-seeded ai-tool list and assert the binary is on PATH after setup. The c-alias assertion stays pinned to opencode since opencode precedes pi in the AI priority order. --- scripts/e2e-test.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/e2e-test.sh b/scripts/e2e-test.sh index 69cb820..a76eecb 100755 --- a/scripts/e2e-test.sh +++ b/scripts/e2e-test.sh @@ -167,7 +167,7 @@ suite_setup() { suite_setup_editors() { # Pre-seed selections in /workspace/.squarebox/ mkdir -p /workspace/.squarebox - echo "opencode" > /workspace/.squarebox/ai-tool + echo "opencode,pi" > /workspace/.squarebox/ai-tool echo "micro,edit,fresh,nvim" > /workspace/.squarebox/editors echo "lazygit,gh-dash,yazi" > /workspace/.squarebox/tuis echo "tmux,zellij" > /workspace/.squarebox/multiplexer @@ -194,6 +194,7 @@ suite_setup_editors() { # 3.7 editors installed run_test "3.7a opencode installed" command -v opencode + run_test "3.7a2 pi installed" command -v pi run_test "3.7b micro installed" command -v micro run_test "3.7c edit installed" command -v edit run_test "3.7d fresh installed" command -v fresh