commit 66836c7ceb659c6ac24f3c2580a88b0a58417aec Author: luulam Date: Tue Jul 21 11:30:47 2026 +0700 test diff --git a/setup-pi.sh b/setup-pi.sh new file mode 100755 index 0000000..46d3cb6 --- /dev/null +++ b/setup-pi.sh @@ -0,0 +1,365 @@ +#!/usr/bin/env bash +# setup-pi.sh — Install pi and configure models/settings like the reference machine. +# +# Usage: +# curl -fsSL | bash # or +# bash setup-pi.sh +# bash setup-pi.sh --force # overwrite existing config files +# PI_INSTALL_METHOD=npm bash setup-pi.sh +# +# After install, edit API keys in: +# ~/.pi/agent/models.json + +set -euo pipefail + +PI_HOME="${PI_HOME:-$HOME/.pi}" +AGENT_DIR="$PI_HOME/agent" +FORCE=0 +INSTALL_METHOD="${PI_INSTALL_METHOD:-auto}" # auto | bun | npm +PI_PACKAGE="@earendil-works/pi-coding-agent" + +# ── args ────────────────────────────────────────────────────────────────────── +for arg in "$@"; do + case "$arg" in + --force|-f) FORCE=1 ;; + --bun) INSTALL_METHOD=bun ;; + --npm) INSTALL_METHOD=npm ;; + --help|-h) + sed -n '2,14p' "$0" + exit 0 + ;; + *) + echo "Unknown option: $arg" >&2 + exit 1 + ;; + esac +done + +# ── helpers ──────────────────────────────────────────────────────────────────── +info() { printf '\033[1;34m==>\033[0m %s\n' "$*"; } +ok() { printf '\033[1;32m✓\033[0m %s\n' "$*"; } +warn() { printf '\033[1;33m!\033[0m %s\n' "$*"; } +die() { printf '\033[1;31m✗\033[0m %s\n' "$*" >&2; exit 1; } + +write_file() { + # write_file + local path="$1" + if [[ -f "$path" && $FORCE -eq 0 ]]; then + warn "skip existing: $path (use --force to overwrite)" + return 0 + fi + mkdir -p "$(dirname "$path")" + cat > "$path" + ok "wrote $path" +} + +have() { command -v "$1" >/dev/null 2>&1; } + +# ── 1. prerequisites ────────────────────────────────────────────────────────── +info "Checking prerequisites" + +if ! have curl && ! have wget; then + die "Need curl or wget" +fi + +# Node is required for pi runtime even when installed via bun +if ! have node; then + die "Node.js is required. Install Node 20+ then re-run." +fi + +NODE_MAJOR="$(node -p 'process.versions.node.split(".")[0]')" +if (( NODE_MAJOR < 20 )); then + warn "Node $NODE_MAJOR detected; pi recommends Node 20+" +fi +ok "node $(node -v)" + +# ── 2. install pi ───────────────────────────────────────────────────────────── +info "Installing $PI_PACKAGE" + +resolve_method() { + case "$INSTALL_METHOD" in + bun|npm) echo "$INSTALL_METHOD" ;; + auto) + if have bun; then echo bun + elif have npm; then echo npm + else die "Need bun or npm to install pi" + fi + ;; + *) die "Invalid PI_INSTALL_METHOD=$INSTALL_METHOD (use auto|bun|npm)" ;; + esac +} + +METHOD="$(resolve_method)" +case "$METHOD" in + bun) + ok "using bun $(bun -v 2>/dev/null || true)" + bun install -g "$PI_PACKAGE" + # Ensure bun bin is on PATH for this session + export BUN_INSTALL="${BUN_INSTALL:-$HOME/.bun}" + export PATH="$BUN_INSTALL/bin:$PATH" + ;; + npm) + ok "using npm $(npm -v 2>/dev/null || true)" + npm install -g --ignore-scripts "$PI_PACKAGE" + ;; +esac + +if ! have pi; then + die "pi binary not found on PATH after install. Add bun/npm global bin to PATH and re-run." +fi +ok "pi $(pi --version 2>/dev/null || echo installed) via $METHOD" + +# ── 3. directory layout ─────────────────────────────────────────────────────── +info "Creating $AGENT_DIR" +mkdir -p "$AGENT_DIR"/{sessions,extensions,skills,bin,npm,ayu/checkpoints} +ok "dirs ready" + +# ── 4. settings.json ────────────────────────────────────────────────────────── +info "Writing settings.json" +write_file "$AGENT_DIR/settings.json" <<'EOF' +{ + "defaultProvider": "llm-gw", + "defaultModel": "code", + "packages": [], + "images": { + "blockImages": true + }, + "terminal": { + "showTerminalProgress": true + }, + "steeringMode": "one-at-a-time", + "theme": "dark", + "hideThinkingBlock": true, + "collapseChangelog": true, + "defaultProjectTrust": "always", + "warnings": { + "anthropicExtraUsage": true + }, + "defaultThinkingLevel": "high", + "enableInstallTelemetry": false, + "compaction": { + "enabled": true, + "reserveTokens": 25600, + "keepRecentTokens": 20000 + }, + "retry": { + "enabled": true, + "maxRetries": 3, + "baseDelayMs": 2000, + "provider": { + "timeoutMs": 300000, + "maxRetries": 2, + "maxRetryDelayMs": 60000 + } + }, + "lsp": { + "hookMode": "disabled" + }, + "httpIdleTimeoutMs": 120000, + "treeFilterMode": "default" +} +EOF + +# ── 5. models.json (template keys) ──────────────────────────────────────────── +info "Writing models.json (API key placeholders)" +write_file "$AGENT_DIR/models.json" <<'EOF' +{ + "providers": { + "llm-gw": { + "baseUrl": "https://llm-gw.luulam.dev/v1", + "apiKey": "YOUR_LLM_GW_API_KEY", + "api": "openai-completions", + "models": [ + { + "id": "code", + "name": "code", + "reasoning": false, + "input": ["text"], + "contextWindow": 256000, + "maxTokens": 128000, + "cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 } + } + ] + }, + "mbbank": { + "baseUrl": "https://api-sandbox.mbbank.com.vn/llm-gateway-dev/v1", + "apiKey": "YOUR_MBBANK_API_KEY", + "api": "openai-completions", + "models": [ + { + "id": "glm-text", + "name": "glm-text", + "reasoning": false, + "input": ["text"], + "contextWindow": 256000, + "maxTokens": 128000, + "cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 } + } + ] + } + } +} +EOF + +# ── 6. APPEND_SYSTEM.md ─────────────────────────────────────────────────────── +info "Writing APPEND_SYSTEM.md" +write_file "$AGENT_DIR/APPEND_SYSTEM.md" <<'EOF' +# Default Coding Guidelines + +Apply these guidelines by default for all coding, reviewing, debugging, and refactoring tasks. + +## Karpathy Guidelines + +Behavioral guidelines to reduce common LLM coding mistakes. These guidelines bias toward caution over speed. For trivial tasks, use judgment. + +### 1. Think Before Coding + +Don't assume. Don't hide confusion. Surface tradeoffs. + +Before implementing: +- State your assumptions explicitly. If uncertain, ask. +- If multiple interpretations exist, present them; don't pick silently. +- If a simpler approach exists, say so. Push back when warranted. +- If something is unclear, stop. Name what's confusing. Ask. + +### 2. Simplicity First + +Minimum code that solves the problem. Nothing speculative. + +- No features beyond what was asked. +- No abstractions for single-use code. +- No "flexibility" or "configurability" that wasn't requested. +- No error handling for impossible scenarios. +- If you write 200 lines and it could be 50, rewrite it. + +Ask yourself: "Would a senior engineer say this is overcomplicated?" If yes, simplify. + +### 3. Surgical Changes + +Touch only what you must. Clean up only your own mess. + +When editing existing code: +- Don't "improve" adjacent code, comments, or formatting. +- Don't refactor things that aren't broken. +- Match existing style, even if you'd do it differently. +- If you notice unrelated dead code, mention it; don't delete it. + +When your changes create orphans: +- Remove imports, variables, or functions that your changes made unused. +- Don't remove pre-existing dead code unless asked. + +The test: every changed line should trace directly to the user's request. + +### 4. Goal-Driven Execution + +Define success criteria. Loop until verified. + +Transform tasks into verifiable goals: +- "Add validation" → "Write tests for invalid inputs, then make them pass." +- "Fix the bug" → "Write a test that reproduces it, then make it pass." +- "Refactor X" → "Ensure tests pass before and after." + +For multi-step tasks, state a brief plan: + +```text +1. [Step] → verify: [check] +2. [Step] → verify: [check] +3. [Step] → verify: [check] +``` + +Strong success criteria let you loop independently. Weak criteria like "make it work" require clarification. +EOF + +# ── 7. minimal auth + trust stubs ───────────────────────────────────────────── +# auth.json empty object is fine; keys live in models.json for custom providers +if [[ ! -f "$AGENT_DIR/auth.json" || $FORCE -eq 1 ]]; then + echo '{}' > "$AGENT_DIR/auth.json" + ok "wrote $AGENT_DIR/auth.json" +else + warn "skip existing: $AGENT_DIR/auth.json" +fi + +if [[ ! -f "$AGENT_DIR/trust.json" || $FORCE -eq 1 ]]; then + # Trust the pi home dir by default; add project paths later via pi UI + cat > "$AGENT_DIR/trust.json" </dev/null; then + ok "PATH already configured in $rc" + return 0 + fi + + # Append without command-substitution (avoids ')' inside case breaking $()) + { + echo "" + echo "# >>> pi / bun >>>" + echo 'export BUN_INSTALL="${BUN_INSTALL:-$HOME/.bun}"' + echo 'if [[ ":$PATH:" != *":$BUN_INSTALL/bin:"* ]]; then' + echo ' export PATH="$BUN_INSTALL/bin:$PATH"' + echo 'fi' + echo "# <<< pi / bun <<<" + } >> "$rc" + ok "appended bun PATH to $rc" +} +ensure_path_hint + +# ── done ────────────────────────────────────────────────────────────────────── +cat </dev/null || echo unknown) + Config : $AGENT_DIR + + Next steps: + 1. Edit API keys: + $EDITOR "$AGENT_DIR/models.json" + Replace: + YOUR_LLM_GW_API_KEY + YOUR_MBBANK_API_KEY + + 2. Verify models: + pi --list-models + + 3. Start: + pi + # or pin model: + pi --provider llm-gw --model code + + Re-run with --force to overwrite settings/models/APPEND_SYSTEM. + Optional later: + pi install npm:context-mode + pi install npm:pi-mcp-adapter + # ...other packages from the full machine profile +──────────────────────────────────────────────────────── +EOF