please is a natural language interface for the terminal that translates plain English requests into shell commands using Claude AI. It provides an interactive, safe-by-default command generation workflow with iterative refinement and history tracking.
- Safety First: Always show commands before execution and ask for confirmation
- Iterative Refinement: Allow users to modify commands with natural language
- Simplicity: Hide complexity, expose natural language interface
- Portability: Work across macOS, Linux, and Windows
┌─────────────────────────────────────────────────────────────┐
│ User Input │
│ "find large files over 100MB" │
└────────────────────┬────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ cmd/please/main.go (Cobra CLI) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Commands: │ │
│ │ - Root command: Natural language → shell command │ │
│ │ - configure: Setup wizard (Claude + Custom Cmds) │ │
│ │ - index: Index custom command documentation │ │
│ │ - list-commands: Show all custom commands │ │
│ └──────────────────────────────────────────────────────┘ │
└────────────┬────────────────────────────┬───────────────────┘
│ │
▼ ▼
┌────────────────────────┐ ┌──────────────────────────┐
│ internal/config/ │ │ internal/history/ │
│ ┌──────────────────┐ │ │ ┌────────────────────┐ │
│ │ ~/.please/ │ │ │ │ ~/.please/ │ │
│ │ config.json │ │ │ │ history.json │ │
│ │ - Agent type │ │ │ │ - Past commands │ │
│ │ - Custom cmds │ │ │ │ - Modifications │ │
│ │ - Provider │ │ │ │ - Execution status │ │
│ │ - Matching │ │ │ └────────────────────┘ │
│ └──────────────────┘ │ └──────────────────────────┘
└───────────┬────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ internal/customcmd/ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Custom Command Manager (RAG System) │ │
│ │ - Loader: Scans ~/.please/commands/*.md │ │
│ │ - Parser: Extracts YAML frontmatter + examples │ │
│ │ - Matcher: Keyword-based or hybrid semantic search │ │
│ │ - Embeddings: Ollama (local) or OpenAI (API) │ │
│ │ - VectorStore: In-memory cosine similarity search │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ internal/agent/agent.go (Interface) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ type Agent interface { │ │
│ │ TranslateToCommand(ctx, request) (command, err) │ │
│ │ RefineCommand(ctx, cmd, modification) (cmd, err) │ │
│ │ } │ │
│ └──────────────────────────────────────────────────────┘ │
└────────────────────┬────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ internal/agent/claude.go (Implementation) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ - Calls Claude CLI via exec.Command() │ │
│ │ - Builds context-aware system prompts │ │
│ │ - Handles OS/shell detection │ │
│ │ - Enforces safety guidelines │ │
│ └──────────────────────────────────────────────────────┘ │
└────────────────────┬────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ internal/ui/prompt.go │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Interactive prompts using AlecAivazis/survey: │ │
│ │ - ConfirmCommand: Run it / Modify it / Cancel │ │
│ │ - PromptForModification: Natural language refinement │ │
│ │ - Colorized output with fatih/color │ │
│ └──────────────────────────────────────────────────────┘ │
└────────────────────┬────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ internal/executor/executor.go │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ - Detects user's shell (SHELL env or /bin/sh) │ │
│ │ - Executes: shell -c "command" │ │
│ │ - Streams stdout/stderr to user's terminal │ │
│ │ - Cross-platform (Unix shells, Windows cmd) │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Purpose: CLI entry point using spf13/cobra framework
Key Files:
main.go: Defines commands, orchestrates workflow
Responsibilities:
- Parse command-line arguments
- Initialize configuration and history
- Coordinate agent, UI, and executor interactions
- Handle main command loop (generate → review → modify/run/cancel)
Purpose: LLM agent abstraction and implementations
Key Files:
agent.go: Agent interface definitionclaude.go: Claude CLI implementation
Responsibilities:
- Define agent interface for future LLM providers
- Implement Claude CLI integration
- Build context-aware prompts
- Handle LLM communication and error handling
See: internal/agent/CLAUDE.md for detailed guidance
Purpose: Configuration management
Key Files:
config.go: Config struct, load/save operations
Responsibilities:
- Manage ~/.please/config.json
- Define configuration schema
- Handle config migrations (future)
- Provide config validation
- Custom command configuration (embedding provider, matching strategy)
See: internal/config/CLAUDE.md for extension patterns
Purpose: RAG-powered custom command documentation system
Key Files:
customcmd.go: Manager for loading and retrieving custom commandsloader.go: Scans and loads .md files from ~/.please/commands/parser.go: Parses YAML frontmatter and examplesmatcher.go: Keyword-based matching with scoringsemantic.go: Hybrid semantic search (keyword + embeddings)setup.go: Automated setup for Ollama and OpenAIembeddings/: Embedding providers (Ollama, OpenAI)vectorstore/: In-memory vector storage with cosine similarity
Responsibilities:
- Load custom command documentation from markdown files
- Parse YAML frontmatter (command, aliases, keywords, priority, etc.)
- Extract user request → command examples
- Match user requests to relevant custom commands
- Provide context to LLM agent for proprietary/internal tools
- Support keyword-only or hybrid semantic matching
- Manage embedding generation (local or API-based)
- Handle auto-indexing and manual reindexing
See: internal/customcmd/CLAUDE.md for detailed implementation guide
Purpose: Safe command execution
Key Files:
executor.go: Execute shell commands
Responsibilities:
- Detect user's shell environment
- Execute commands in appropriate shell
- Stream output to user's terminal
- Handle cross-platform compatibility
See: internal/executor/CLAUDE.md for security patterns
Purpose: Command history tracking
Key Files:
history.go: History struct, persistence
Responsibilities:
- Track all command generation attempts
- Record modifications and execution status
- Persist to ~/.please/history.json
- Enable future features (suggestions, analytics)
Purpose: User interaction and display
Key Files:
prompt.go: Interactive prompts and displays
Responsibilities:
- Show generated commands with formatting
- Prompt for user action (run/modify/cancel)
- Collect modification requests
- Display success/error/info messages
The custom commands feature allows users to teach please about proprietary, internal, or specialized tools by providing documentation in simple markdown files. This uses RAG (Retrieval Augmented Generation) to enhance the LLM's knowledge with your custom tool documentation.
Key Benefits:
- 🎯 Support for internal/proprietary tools unknown to Claude
- 📚 Document-based knowledge (no code changes needed)
- 🔍 Smart matching: keyword-based (fast) or semantic (accurate)
- 🏠 Privacy options: local embeddings (Ollama) or API (OpenAI)
- 🚀 Auto-indexing with staleness detection
User Request: "deploy my app to staging"
↓
┌───────────────────────────────┐
│ Custom Command Matcher │
│ - Scans ~/.please/commands/ │
│ - Keyword or semantic search │
└───────────────┬───────────────┘
↓
┌───────────────────────────────┐
│ Finds: deploy-tool.md │
│ - Command: deploy-tool │
│ - Keywords: deploy, staging │
│ - Examples: 15 request→cmd │
└───────────────┬───────────────┘
↓
┌───────────────────────────────┐
│ Agent receives context: │
│ "The user has deploy-tool... │
│ Example: 'deploy to staging' │
│ → 'deploy-tool --env=staging'│
└───────────────┬───────────────┘
↓
Generates accurate command using custom context!
Step 1: Configure Custom Commands
please configure
# Select: "Would you like to configure custom commands?"
# Choose provider:
# - None (keyword-only matching)
# - Ollama (local embeddings, private)
# - OpenAI (API-based, accurate)Ollama Setup (Recommended for privacy):
- Tool offers to install Ollama via Homebrew (macOS) or script (Linux)
- Automatically downloads
nomic-embed-textmodel (384 dimensions) - Tests connection to localhost:11434
OpenAI Setup (Recommended for accuracy):
- Enter API key (or use
OPENAI_API_KEYenv var) - Choose to store in config or use env var
- Tests connection and validates key
Step 2: Create Command Documentation
# Directory is auto-created during setup
cd ~/.please/commands/
# Create a markdown file for your tool
# Filename: {command-name}.mdExample: kubectl.md
---
command: kubectl
aliases: ["k8s", "kube"]
keywords: ["kubernetes", "pods", "deployments", "services"]
categories: ["devops", "containers"]
priority: high
version: "1.28"
---
# Kubernetes kubectl
kubectl is the Kubernetes command-line tool.
## Common Patterns
- List pods: `kubectl get pods`
- Describe resource: `kubectl describe {type} {name}`
- Apply manifest: `kubectl apply -f {file}`
## Examples
**User**: "show me all pods"
**Command**: `kubectl get pods`
**User**: "get logs from nginx pod"
**Command**: `kubectl logs nginx`
**User**: "deploy from manifest.yaml"
**Command**: `kubectl apply -f manifest.yaml`Step 3: Index Your Commands
# Manual indexing
please index
# Auto-indexing
# Happens automatically on first use or when files changeStep 4: Use Custom Commands
please "show all pods"
# Will match kubectl.md and generate: kubectl get pods
please "deploy my app to staging"
# If you have deploy-tool.md, will use that context1. Keyword-Only (Default, No Embeddings)
Fast, no dependencies, works offline.
Scoring algorithm:
- Command name match: 100 points
- Alias match: 80 points
- Keyword match: 10 points each
- Example similarity: 15 points per word overlap
- Priority multipliers: high=1.3x, medium=1.1x
2. Hybrid (Keyword + Semantic)
Best accuracy, requires Ollama or OpenAI.
Strategy:
- Try keyword matching first (fast path)
- If scores meet threshold, use keyword results
- Otherwise, fall back to semantic search
- Semantic uses vector embeddings + cosine similarity
Configuration (in ~/.please/config.json):
{
"customCommands": {
"enabled": true,
"provider": "ollama", // or "openai" or "none"
"matching": {
"strategy": "hybrid", // or "keyword" or "semantic"
"maxDocsToRetrieve": 3,
"scoreThreshold": 50
},
"ollama": {
"baseURL": "http://localhost:11434",
"model": "nomic-embed-text"
}
}
}YAML Frontmatter (required):
---
command: tool-name # Primary command name (required)
aliases: ["alt1", "alt2"] # Alternative names (optional)
keywords: ["key1", "key2"] # Keywords for matching (optional)
categories: ["cat1"] # Categories (optional)
priority: high # high/medium/low (optional)
version: "1.0" # Tool version (optional)
---Markdown Content:
- Headers, paragraphs, code blocks (all indexed)
- Examples section (special parsing):
## Examples
**User**: "natural language request"
**Command**: `actual command`
**User**: "another request"
**Command**: `another command`Parsing:
- Lines starting with
**User**:→ user request - Lines starting with
**Command**:→ command (backticks removed) - Up to 5 examples per command sent to LLM (token budget)
To keep prompts efficient:
- Max 3 commands matched per request
- Max 5 examples per command sent to LLM
- Max 10 common patterns extracted from content
- Automatic truncation if content is too long
# Index custom commands
please index
# Output:
# ✓ Indexed 5 commands from ~/.please/commands/
# - kubectl (15 examples)
# - docker (12 examples)
# - ...
# List all custom commands
please list-commands
# Output:
# Custom Commands (Provider: ollama)
#
# kubectl (k8s, kube)
# Categories: devops, containers
# Priority: high
# Examples: 15
# File: kubectl.md
#
# docker
# Categories: devops, containers
# Examples: 12
# File: docker.md
# Reconfigure custom commands
please configureThe manager automatically detects when indexing is needed:
- First Use: No index exists → prompts to run
please index - Stale Index: Files modified since last index → prompts to reindex
- Manual: User runs
please indexexplicitly
Detection Logic:
func (m *Manager) NeedsReindex() bool {
// Check if any .md file is newer than index timestamp
// Return true if stale
}Ollama (Local, Private):
- Model:
nomic-embed-text(384 dimensions) - API:
http://localhost:11434/api/embeddings - Cost: Free, runs locally
- Latency: ~50-100ms per embedding
- Privacy: 100% local, no data sent externally
OpenAI (API, Accurate):
- Model:
text-embedding-3-small(1536 dimensions) - API:
https://api.openai.com/v1/embeddings - Cost: $0.02 per 1M tokens (~$0.0001 per index)
- Latency: ~100-200ms per embedding
- Privacy: Data sent to OpenAI
Vector Store:
- In-memory storage (no persistence yet)
- Cosine similarity for search
- Thread-safe with sync.RWMutex
Similarity Calculation:
func cosineSimilarity(a, b []float32) float32 {
dotProduct := sum(a[i] * b[i])
normA := sqrt(sum(a[i] * a[i]))
normB := sqrt(sum(b[i] * b[i]))
return dotProduct / (normA * normB)
}"No custom commands found":
- Run
please indexto index your commands - Check
~/.please/commands/has .md files - Ensure files have valid YAML frontmatter
"Failed to connect to Ollama":
- Verify Ollama is running:
ollama serveor check if service is active - Test manually:
curl http://localhost:11434/api/embeddings -d '{"model":"nomic-embed-text","prompt":"test"}' - Check config has correct base URL
"OpenAI API error":
- Verify API key is valid
- Check
OPENAI_API_KEYenv var or config - Ensure account has credits
"Commands not matching":
- Check keywords in frontmatter match your query words
- Add more examples to your .md files
- Try hybrid or semantic strategy if using keyword-only
- Increase
scoreThresholdin config if getting too many irrelevant results
- Comprehensive Examples: Add 10-15 diverse examples per command
- Good Keywords: Include synonyms, abbreviations, related terms
- Clear Aliases: Add common alternative names
- Priority Levels: Set priority=high for most-used tools
- Categories: Group related commands for future features
- Regular Updates: Keep docs current as tools evolve
- Test Matching: Use
please list-commandsto verify indexing
# Clone the repository
git clone https://github.com/iishyfishyy/please.git
cd please
# Install dependencies
go mod download
# Build
go build -o please ./cmd/please
# Test (run tests when available)
go test ./...
# Install locally
go install ./cmd/please- Identify affected packages
- Update interfaces if needed (maintain backward compatibility)
- Implement feature
- Add tests (see Testing Strategy below)
- Update relevant CLAUDE.md files
- Test manually with
please configureand various commands - Update README.md if user-facing
See internal/agent/CLAUDE.md for detailed guide. Summary:
- Create new file:
internal/agent/{provider}.go - Implement
Agentinterface - Add agent type to
internal/config/config.go - Update configuration wizard in
cmd/please/main.go - Add detection/validation for provider's CLI
# Build with debug info
go build -o please ./cmd/please
# Run with verbose output (add to code as needed)
PLEASE_DEBUG=1 ./please "your command"
# Check configuration
cat ~/.please/config.json
# Check history
cat ~/.please/history.json
# Test Claude CLI directly
claude "echo hello"- Always use
fmt.Errorf("context: %w", err)to wrap errors - Provide user-friendly error messages in UI
- Log technical details for debugging
- Never panic in user-facing code
- Pass
context.Contextto all LLM calls - Support cancellation for long-running operations
- Use
context.Background()at CLI entry points - Consider timeouts for future enhancements
please/
├── cmd/please/
│ └── main_test.go # Integration tests
├── internal/agent/
│ ├── agent_test.go # Interface contract tests
│ ├── claude_test.go # Claude agent tests (mocked)
│ └── testdata/ # Test fixtures
├── internal/config/
│ └── config_test.go # Config load/save/validation
├── internal/executor/
│ └── executor_test.go # Shell execution tests (safe)
├── internal/history/
│ └── history_test.go # History persistence tests
└── internal/ui/
└── prompt_test.go # UI logic tests (mocked survey)
Testing Principles:
- Mock external dependencies (Claude CLI, survey prompts)
- Test error paths thoroughly
- Use table-driven tests for multiple scenarios
- Test cross-platform behavior with build tags
- Never execute dangerous commands in tests
- Follow standard Go conventions (gofmt, golint)
- Keep functions focused and small
- Use descriptive variable names
- Comment complex logic, not obvious code
- Prefer composition over inheritance
- Keep interfaces small and focused
- Always Confirm: Never execute without user approval
- Display Clearly: Show exact command before running
- No Hidden Execution: All commands visible to user
- Shell Injection: Trust LLM output is safe, but warn users
- Destructive Commands: Rely on user review
- No API keys stored (authentication via Claude CLI)
- Config files in user's home directory (0644)
- No sensitive data in history
- Add command allowlist/denylist
- Implement dry-run mode
- Add command explanation before execution
- Pattern detection for dangerous operations (rm -rf, dd, etc.)
- github.com/spf13/cobra: CLI framework
- github.com/AlecAivazis/survey/v2: Interactive prompts
- github.com/fatih/color: Terminal colors
- Claude CLI: Required for LLM functionality
- Install: https://github.com/anthropics/claude-cli
- Authentication via
claude auth - Called via
exec.Command("claude", prompt)
See RELEASING.md for detailed guide. Summary:
- Tag Version:
git tag -a v1.0.0 -m "Release v1.0.0" - Push Tag:
git push origin v1.0.0 - Automated: GitHub Actions runs GoReleaser
- Outputs:
- GitHub release with binaries (macOS, Linux, Windows)
- Homebrew formula update (requires setup)
- Checksums and changelog
- Read internal/agent/CLAUDE.md
- Create internal/agent/{provider}.go
- Implement Agent interface
- Update config.go with new agent type
- Update configure command in main.go
- Test with provider's CLI
- Enhance buildSystemPrompt() in claude.go
- Add context gathering (see internal/agent/CLAUDE.md)
- Test with various command types
- Consider token efficiency
- Create ~/.please/commands/{tool}.md
- Add YAML frontmatter (command, keywords, aliases, priority)
- Add 10-15 diverse examples with User/Command pattern
- Run
please indexto index the new documentation - Test with
please "{natural language query}" - Verify with
please list-commands
- Read internal/customcmd/embeddings/embedder.go interface
- Create internal/customcmd/embeddings/{provider}.go
- Implement Embedder interface (Embed, EmbedBatch, Dimensions, Name)
- Add provider type to config.go EmbeddingProvider enum
- Update setup.go with provider-specific setup logic
- Add connection testing
- Test with
please configure
- Review matcher.go scoring algorithm
- Add more weight to certain match types
- Consider adding fuzzy matching for typos
- Test with edge cases (synonyms, abbreviations)
- Monitor false positives/negatives
- Read internal/config/CLAUDE.md
- Update Config struct
- Update Load/Save logic
- Handle backward compatibility
- Update configure wizard
- Check internal/executor/CLAUDE.md
- Test on target platform
- Use runtime.GOOS for platform detection
- Consider shell differences
- Create {package}_test.go
- Follow testing patterns in this file
- Mock external dependencies
- Use table-driven tests
- Run with
go test ./...
- Custom commands with RAG (Week 1-2 implementation)
- Keyword-based matching
- Hybrid semantic search (Ollama + OpenAI)
- Auto-indexing with staleness detection
- Command documentation via markdown files
- Setup wizard for embedding providers
- Add comprehensive test suite
- Unit tests for keyword matcher
- Unit tests for embedders (mocked)
- Integration tests for hybrid matcher
- End-to-end tests for custom commands
- Persistent vector store (save index to disk)
- Support for additional LLM providers (Codex, Goose)
- Command explanation mode
- Dry-run mode
- Shell completion
- Additional embedding providers (Cohere, local models)
- Command history-based suggestions
- Alias creation for frequent commands
- Multi-step command workflows
- Context-aware suggestions (based on directory contents)
- Custom command sharing/marketplace
- Chunking strategy for long documentation
- Incremental indexing (only index changed files)
- Command usage analytics
- Learning from user corrections
- Integration with system package managers
- Plugin system for custom agents
- Web dashboard for history/analytics
- Collaborative custom command repositories
- Auto-discovery of tools in PATH
- Integration with man pages and --help output
- Documentation: README.md, RELEASING.md, package CLAUDE.md files
- Issues: https://github.com/iishyfishyy/please/issues
- Code Examples: Read existing implementations in internal/
When working on this project:
- Read package CLAUDE.md first for specific guidance
- Check existing patterns in similar code
- Test manually with
please configureand various commands - Consider cross-platform compatibility (macOS, Linux, Windows)
- Think about token efficiency in prompt engineering
- Prioritize user safety in command execution
- Add tests when implementing new features