Commit 87b899149ac6
Changed files (4)
dots
pi
dots/pi/agent/auth-keys.json
@@ -0,0 +1,26 @@
+{
+ "google": {
+ "type": "api_key",
+ "key": "!passage show ai/gemini/api_key"
+ },
+ "openrouter": {
+ "type": "api_key",
+ "key": "!passage show ai/openroute/api_key"
+ },
+ "deepseek": {
+ "type": "api_key",
+ "key": "!passage show ai/deepseek/api_key"
+ },
+ "groq": {
+ "type": "api_key",
+ "key": "!passage show ai/groq/wakasu"
+ },
+ "mistral": {
+ "type": "api_key",
+ "key": "!passage show ai/mistralai/api_key"
+ },
+ "zai": {
+ "type": "api_key",
+ "key": "!passage show ai/zai/api_key"
+ }
+}
dots/pi/agent/ensure-auth.sh
@@ -0,0 +1,68 @@
+#!/usr/bin/env bash
+# Ensure pi agent auth.json has API keys from passage without overwriting OAuth tokens
+# This script merges declarative API keys into ~/.pi/agent/auth.json while preserving
+# OAuth tokens that pi manages automatically (github-copilot, vertex-anthropic, etc.)
+
+set -euo pipefail
+
+RUNTIME_AUTH="$HOME/.pi/agent/auth.json"
+API_KEYS_FILE="$(dirname "$0")/auth-keys.json"
+
+# Required for merging JSON
+if ! command -v jq >/dev/null 2>&1; then
+ echo "⚠️ jq not found - cannot manage auth.json automatically"
+ echo " Install jq or manually configure API keys in $RUNTIME_AUTH"
+ exit 1
+fi
+
+# Required for passage-based secret retrieval
+if ! command -v passage >/dev/null 2>&1; then
+ echo "⚠️ passage not found - API keys use passage for secret management"
+ echo " Install passage (pass fork with age encryption) or update auth-keys.json"
+ exit 1
+fi
+
+# Create runtime auth directory if it doesn't exist
+mkdir -p "$(dirname "$RUNTIME_AUTH")"
+
+# Initialize with empty object if auth.json doesn't exist
+if [ ! -f "$RUNTIME_AUTH" ]; then
+ echo "�� Creating $RUNTIME_AUTH..."
+ echo '{}' > "$RUNTIME_AUTH"
+ chmod 600 "$RUNTIME_AUTH"
+fi
+
+# Extract OAuth tokens (preserve these - managed by pi)
+# These are set via /login in pi and should never be declaratively managed
+TEMP_OAUTH=$(mktemp)
+jq -r '
+ {
+ "github-copilot": .["github-copilot"],
+ "vertex-anthropic": .["vertex-anthropic"],
+ "claude-pro": .["claude-pro"],
+ "chatgpt": .["chatgpt"],
+ "gemini-cli": .["gemini-cli"],
+ "antigravity": .["antigravity"]
+ } | with_entries(select(.value != null))
+' "$RUNTIME_AUTH" > "$TEMP_OAUTH"
+
+# Merge OAuth tokens with declarative API keys
+# API keys override any existing keys, but OAuth tokens are preserved
+TEMP_MERGED=$(mktemp)
+jq -s '.[0] * .[1]' "$TEMP_OAUTH" "$API_KEYS_FILE" > "$TEMP_MERGED"
+
+# Atomic update
+mv "$TEMP_MERGED" "$RUNTIME_AUTH"
+chmod 600 "$RUNTIME_AUTH"
+rm -f "$TEMP_OAUTH"
+
+echo "✅ Pi agent auth.json updated with API keys:"
+jq -r 'to_entries | .[] | select(.value.type == "api_key") | " - \(.key): \(.value.key)"' "$RUNTIME_AUTH"
+
+# Show preserved OAuth tokens
+OAUTH_COUNT=$(jq -r '[to_entries | .[] | select(.value.type == "oauth")] | length' "$RUNTIME_AUTH")
+if [ "$OAUTH_COUNT" -gt 0 ]; then
+ echo ""
+ echo "�� Preserved OAuth tokens:"
+ jq -r 'to_entries | .[] | select(.value.type == "oauth") | " - \(.key)"' "$RUNTIME_AUTH"
+fi
dots/pi/agent/README.md
@@ -1,70 +1,167 @@
-# Pi Coding Agent Configuration
+# Pi Agent Configuration
-Configuration for [pi-coding-agent](https://github.com/badlogic/pi-mono/tree/main/packages/coding-agent),
-a minimal terminal coding agent.
+Declarative configuration for [pi coding agent](https://github.com/badlogic/pi-mono/tree/main/packages/coding-agent).
-## Structure
+## Files
-```
-~/.pi/agent/
-├── settings.json # Global settings (provider, model, thinking)
-├── extensions/ # TypeScript extensions
-│ ├── ai-storage/ # Unified AI storage (sessions, research, plans, learnings)
-│ ├── org-todos/ # Org-mode TODO management via emacsclient
-│ ├── path-validator/ # Validate file paths and filenames
-│ ├── terminal-status.ts # Terminal title updates
-│ └── validate-git-push.ts # Block unsafe git push
-├── AGENTS.md # Global agent instructions
-└── README.md
+### Declarative (Version Controlled)
+
+- **`auth-keys.json`** - API key providers with passage secret references
+- **`settings.json`** - Default settings template
+- **`AGENTS.md`** - Global agent instructions
+- **`keybindings.json`** - Custom keybindings
+- **`agents/`** - Project-agnostic subagents
+- **`extensions/`** - Custom pi extensions
+- **`prompts/`** - Custom prompt templates
+
+### Runtime (Not Version Controlled)
+
+- **`~/.pi/agent/auth.json`** - Generated, merges OAuth + API keys
+- **`~/.pi/agent/settings.json`** - Generated, merges template + user prefs
+- **`~/.pi/agent/sessions/`** - Symlinked to `~/.local/share/ai-sync/pi-sessions/`
+
+## Setup
+
+```bash
+# Install dotfiles (includes pi-agent target)
+cd ~/src/home
+make dots
+
+# Or manually:
+cd ~/src/home/dots
+make pi-agent pi-agent-settings pi-agent-auth
```
-## Extensions
+## Auth Management
-### ai-storage
-
-Unified AI storage extension. Saves sessions, research, plans, and learnings
-to `~/.local/share/ai/` with consistent `YYYY-MM-DD-description.md` naming.
-Shared across pi, claude, and opencode.
-
-### org-todos
-
-Org-mode TODO management via emacsclient. Provides the `org_todo` tool for
-listing, searching, creating, and managing TODOs without direct file edits.
-
-### path-validator
-
-Validates file paths and filenames against policies in `~/.config/ai/path-policies.json`.
-Blocks writes to old storage locations and enforces naming conventions.
-
-### validate-git-push.ts
-
-Blocks unsafe git commands: bare `git push` (no refspec), `git add .`, etc.
-
-### terminal-status.ts
-
-Updates terminal title with project and context info after tool calls.
-
-## Skills
-
-Pi loads Claude Code skills via `settings.json`:
+API keys are declared in `auth-keys.json` with passage references:
```json
{
- "skills": [
- "~/.config/claude/skills"
+ "google": {
+ "type": "api_key",
+ "key": "!passage show gemini/api_key"
+ },
+ "openrouter": {
+ "type": "api_key",
+ "key": "!passage show openroute/api_key"
+ }
+}
+```
+
+OAuth tokens (GitHub Copilot, Vertex, etc.) are managed by pi via `/login` command and preserved automatically.
+
+The `ensure-auth.sh` script:
+1. Extracts existing OAuth tokens from `~/.pi/agent/auth.json`
+2. Merges with declarative API keys from `auth-keys.json`
+3. Writes atomically with secure permissions (600)
+
+### Adding New API Keys
+
+1. Store secret in passage:
+ ```bash
+ passage insert provider-name/api_key
+ ```
+
+2. Add to `auth-keys.json`:
+ ```json
+ {
+ "provider-name": {
+ "type": "api_key",
+ "key": "!passage show provider-name/api_key"
+ }
+ }
+ ```
+
+3. Re-run setup:
+ ```bash
+ make pi-agent-auth
+ ```
+
+### Available Providers
+
+Current passage-based API keys:
+- **`google`** - Gemini API (`ai/gemini/api_key`)
+- **`openrouter`** - OpenRouter API (`ai/openroute/api_key`)
+- **`deepseek`** - DeepSeek API (`ai/deepseek/api_key`)
+- **`groq`** - Groq API (`ai/groq/wakasu`)
+- **`mistral`** - Mistral API (`ai/mistralai/api_key`)
+- **`zai`** - Z.AI/GLM API (`ai/zai/api_key`) - *Optional, GLM models also available via OpenRouter*
+
+OAuth providers (managed by pi):
+- **`github-copilot`** - via `/login github-copilot`
+- **`vertex-anthropic`** - via `/login vertex-anthropic`
+
+**Note:** Z.AI (GLM-5, GLM-4.7) models are accessible via OpenRouter without a direct Z.AI API key.
+
+## Settings Management
+
+Required settings are declared in `settings.json` and merged into runtime config:
+
+```json
+{
+ "hideThinkingBlock": true,
+ "quietStartup": true,
+ "skills": ["~/.config/claude/skills"],
+ "subagentProviderPreference": [
+ "google-vertex-claude",
+ "vertex",
+ "google",
+ "llama-cpp"
]
}
```
-## Usage
+The `ensure-settings.sh` script merges these with user preferences, preserving:
+- Model selections
+- Custom providers
+- Theme preferences
+- Other user-specific settings
-```bash
-# Start pi in current directory
-pi
+## Session Storage
-# Start with specific prompt
-pi "explain this codebase"
+Pi sessions are symlinked to syncthing-managed directory:
+- **Source:** `~/.local/share/ai-sync/pi-sessions/`
+- **Link:** `~/.pi/agent/sessions` → source
+- **Purpose:** Sync raw JSONL conversation logs across machines
-# Use a specific skill
-pi "/Git:commit"
-```
+Curated markdown session summaries go to `~/.local/share/ai/sessions/` (also synced).
+
+## Extensions
+
+Custom extensions in `extensions/`:
+- **`github/`** - Enhanced GitHub integration
+- **`jira/`** - Jira issue management
+- **`org-todos/`** - Org-mode TODO integration
+- **`vertex-claude/`** - Google Vertex AI Claude models
+- **`defaults/`** - Default extensions wrapper
+- **`lsp/`** - LSP integration
+- **`filter-output/`** - Output filtering
+- **`shell-completions/`** - Shell completion enhancements
+- **`threads/`** - Thread/session management
+
+Extensions are symlinked to `~/.pi/agent/extensions/` and npm dependencies are auto-installed.
+
+## Skills
+
+Skills are shared with Claude Code via `~/.config/claude/skills/`:
+- Pi loads via `settings.json`: `"skills": ["~/.config/claude/skills"]`
+- Enables unified skill library across AI coding tools
+
+## Keybindings
+
+Custom keybindings in `keybindings.json`:
+- Ctrl+R: Reapply last edit
+- Ctrl+D: Show diff
+- See `KEYBINDINGS.md` for full documentation
+
+## Agents
+
+Global agent instructions in `AGENTS.md`:
+- Core principles
+- Stack preferences
+- Response patterns
+- Git safety rules
+- Skills integration
+
+Project-specific agents can be added to `.pi/agents/` (not in dots).
dots/Makefile
@@ -61,13 +61,15 @@ gh-news : ~/.config/gh-news/config.toml
all += github-notif-manager
github-notif-manager : ~/.config/github-notif-manager/config.yaml
-all += git-template copilot-hooks opencode-plugin pi-agent pi-agent-settings agent-skills agent-skill-manager-bin ai-config
+all += git-template copilot-hooks opencode-plugin pi-agent pi-agent-settings pi-agent-auth agent-skills agent-skill-manager-bin ai-config
git-template : ~/.config/git/template
copilot-hooks : ~/.config/copilot-hooks
opencode-plugin : ~/.config/opencode/plugin
pi-agent : ~/.pi/agent/extensions ~/.pi/agent/agents ~/.pi/agent/AGENTS.md ~/.pi/agent/README.md ~/.pi/agent/keybindings.json ~/.pi/agent/sessions
pi-agent-settings : pi-agent
@$(dotfiles)/pi/agent/ensure-settings.sh
+pi-agent-auth : pi-agent
+ @$(dotfiles)/pi/agent/ensure-auth.sh
agent-skills : ~/.config/agent-skills
agent-skill-manager-bin : ~/bin/agent-skill-manager
ai-config : ~/.config/ai/skills ~/.config/ai/path-policies.json