Compare commits
55 Commits
736fe4fcd6
...
ffc840ca5b
| Author | SHA1 | Date | |
|---|---|---|---|
| ffc840ca5b | |||
| cd47686679 | |||
| 2116a62a5a | |||
| bb3f968711 | |||
| 383d28a91a | |||
| 4603a1ec7a | |||
| 685b0f40d7 | |||
| a36f3585f4 | |||
| 3d9d1cd722 | |||
| 66d52917c0 | |||
| d74c613e0f | |||
| f9d99527e0 | |||
| 7e4bdbc21c | |||
| b2172b8546 | |||
| 64fb748897 | |||
| 63e640c022 | |||
| aedf9cdf03 | |||
| 8efca62109 | |||
| 0912aa7b89 | |||
| babc6e8599 | |||
| fbf40e2f79 | |||
| f36722ad2c | |||
| 213a9869e6 | |||
| 757f422765 | |||
| ae8a199ece | |||
| 8c14977ec6 | |||
| f5c73ab291 | |||
| 1c79abce8d | |||
| 0e234419f4 | |||
| 7ffbf352bc | |||
| 019ce1e95a | |||
| 95deb65f06 | |||
| 18bbb67789 | |||
| 405286abd2 | |||
| a8208da4c1 | |||
| 0b5aa5eb57 | |||
| 7cb9eb3eb7 | |||
| d4f3e3adbc | |||
| c5bdd44e55 | |||
| b2b8c1a482 | |||
| 40d40f7669 | |||
| 7b415f8e26 | |||
| 852142730a | |||
| 824bbcb85f | |||
| b9de35f48b | |||
| 5d0aec721d | |||
| 0ba427aaf6 | |||
| d1ebd2af79 | |||
| 5c67f78c27 | |||
| ec692b2086 | |||
| 2cc728eed4 | |||
| dcac119e57 | |||
| 8e414faa10 | |||
| 6bd72aad25 | |||
| aa38e92fb5 |
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,10 +1,11 @@
|
||||
.idea/
|
||||
.grok/
|
||||
.junie/
|
||||
.claude/
|
||||
build/
|
||||
grokkit
|
||||
*.bak
|
||||
*.log
|
||||
*.tmp
|
||||
.env
|
||||
*.patch
|
||||
chat_history.json
|
||||
@ -1,3 +0,0 @@
|
||||
{
|
||||
"model": "grok-code-fast-1"
|
||||
}
|
||||
76
.grokkit/recipes/result-refactor.md
Normal file
76
.grokkit/recipes/result-refactor.md
Normal file
@ -0,0 +1,76 @@
|
||||
---
|
||||
name: result-refactor
|
||||
description: Convert traditional Go error handling to Result[T] monadic style
|
||||
version: 1.0
|
||||
|
||||
parameters:
|
||||
package_path:
|
||||
type: string
|
||||
default: internal/git
|
||||
description: Package to refactor
|
||||
dry_run:
|
||||
type: bool
|
||||
default: true
|
||||
description: If true, only generate patches
|
||||
|
||||
project_languages:
|
||||
- go
|
||||
|
||||
extensions:
|
||||
go:
|
||||
- .go
|
||||
|
||||
search_pattern: "if err != nil"
|
||||
|
||||
allowed_shell_commands:
|
||||
- go test ./...
|
||||
- go fmt ./...
|
||||
- go vet ./...
|
||||
- rg --files
|
||||
- git diff --name-only
|
||||
- jq
|
||||
|
||||
---
|
||||
|
||||
# Result[T] Refactoring Recipe
|
||||
|
||||
**Overview**
|
||||
Refactors all error handling in the target package to use the new Result[T] pattern.
|
||||
|
||||
## Execution Steps
|
||||
|
||||
### Step 1: Read-Only Shell: Explore project structure
|
||||
**Objective:** Get a clear view of the current project layout.
|
||||
**Instructions:** Use safe read-only shell commands to show the directory tree and key files.
|
||||
**Expected output:** A tree view and relevant file contents.
|
||||
|
||||
### Step 2: Discover files
|
||||
**Objective:** Find every file that needs changing.
|
||||
**Instructions:** Recursively scan `{{.package_path}}` for `.go` files containing `if err != nil`.
|
||||
**Expected output:** A clean list of full file paths (one per line). If none, say "No files found matching the criteria."
|
||||
|
||||
### Step 3: Refactor each file
|
||||
**Objective:** Generate the updated code.
|
||||
**Instructions:** For each file from Step 1:
|
||||
- Read the full original content.
|
||||
- Refactor it to use `Result[T]` instead of naked errors (follow existing style, preserve all comments).
|
||||
- Return **ONLY** a single JSON array in this exact format (no extra text, no markdown):
|
||||
```json
|
||||
[
|
||||
{
|
||||
"file": "internal/example.go",
|
||||
"content": "the complete refactored file here"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### Step 4: Apply or patch
|
||||
**Objective:**
|
||||
Safely write changes or create reviewable output.
|
||||
**Instructions:**
|
||||
- If dry_run is true → create a unified diff patch file for review.
|
||||
- If false → write the new files (backup originals as .bak).
|
||||
**Expected output:** Confirmation of what was written + full path to any patch file.
|
||||
|
||||
### Final Summary
|
||||
Give me a concise executive summary: number of files changed, any warnings or patterns you noticed, and your recommended next step.
|
||||
67
.grokkit/recipes/template-recipe.md
Normal file
67
.grokkit/recipes/template-recipe.md
Normal file
@ -0,0 +1,67 @@
|
||||
---
|
||||
name: my-awesome-recipe
|
||||
description: Short description of what this recipe does
|
||||
version: 1.0
|
||||
|
||||
parameters:
|
||||
package_path:
|
||||
type: string
|
||||
default: internal
|
||||
description: Directory or package to operate on
|
||||
dry_run:
|
||||
type: bool
|
||||
default: true
|
||||
description: If true, only generate a patch
|
||||
|
||||
project_languages:
|
||||
- go
|
||||
|
||||
extensions:
|
||||
go:
|
||||
- .go
|
||||
|
||||
search_pattern: "if err != nil"
|
||||
|
||||
allowed_shell_commands:
|
||||
- go test ./...
|
||||
- go fmt ./...
|
||||
- go vet ./...
|
||||
|
||||
---
|
||||
|
||||
# My Awesome Recipe
|
||||
|
||||
**Overview**
|
||||
One-sentence summary of what the whole recipe accomplishes.
|
||||
|
||||
## Execution Steps
|
||||
|
||||
### Step 1: Discover files
|
||||
**Objective:** Find every file that needs changing.
|
||||
**Instructions:** Recursively scan `{{.package_path}}` for files containing the search pattern.
|
||||
**Expected output:** A clean list of full file paths (one per line). If none, say "No files found matching the criteria."
|
||||
|
||||
### Step 2: Do the work
|
||||
**Objective:** Perform the main task on each discovered file.
|
||||
**Instructions:** For each file from Step 1:
|
||||
- Read the full original content.
|
||||
- Do whatever transformation is needed.
|
||||
- Return **ONLY** this exact JSON (no extra text, no markdown):
|
||||
|
||||
```json
|
||||
{
|
||||
"file": "path/to/file.ext",
|
||||
"content": "the complete new file content here"
|
||||
}
|
||||
```
|
||||
**Expected output:** A JSON array containing one object per file.
|
||||
|
||||
### Step 3: Apply or patch
|
||||
**Objective:** Safely write changes or create reviewable output.
|
||||
**Instructions:**
|
||||
- If dry_run is true → create a unified diff patch file for review.
|
||||
- If false → write the new files (backup originals as .bak).
|
||||
- Expected output: Confirmation of what was written + full path to any patch file.
|
||||
|
||||
### Final Summary
|
||||
Give me a concise executive summary: number of files changed, any warnings or patterns you noticed, and your recommended next step.
|
||||
562
README.md
562
README.md
@ -7,8 +7,21 @@ Grokkit is a fast Go CLI integrating Grok AI with git workflows and general chat
|
||||
[]()
|
||||
[]()
|
||||
|
||||
## 🚀 Quick Start
|
||||
## Requirements
|
||||
|
||||
- Go 1.24.2 (for building)
|
||||
- Git (for git-related commands)
|
||||
- XAI API key
|
||||
|
||||
## 🚀 Quick Start Installation
|
||||
|
||||
### From pre-built release (recommended)
|
||||
```bash
|
||||
VERSION=0.1.3 # Replace with latest version tag (omit 'v')
|
||||
curl -L https://repos.gmgauthier.com/gmgauthier/grokkit/releases/download/v${VERSION}/grokkit-install.sh | VERSION=${VERSION} bash -
|
||||
```
|
||||
|
||||
### From Source (for development)
|
||||
```bash
|
||||
# Set your API key
|
||||
export XAI_API_KEY=sk-...
|
||||
@ -16,321 +29,23 @@ export XAI_API_KEY=sk-...
|
||||
# Install from source
|
||||
git clone https://repos.gmgauthier.com/gmgauthier/grokkit.git
|
||||
cd grokkit
|
||||
make install
|
||||
|
||||
# Or build locally
|
||||
make test
|
||||
make build
|
||||
make install
|
||||
````
|
||||
|
||||
# Verify installation
|
||||
grokkit --help
|
||||
|
||||
### From pre-built release (recommended)
|
||||
```bash
|
||||
VERSION=0.1.3 # Replace with latest version tag (omit 'v')
|
||||
curl -L https://repos.gmgauthier.com/gmgauthier/grokkit/releases/download/v${VERSION}/grokkit-install.sh | VERSION=${VERSION} bash -
|
||||
```
|
||||
Verify:
|
||||
### Verify:
|
||||
```bash
|
||||
grokkit version
|
||||
```
|
||||
|
||||
## 📋 Table of Contents
|
||||
|
||||
- [Commands](#commands)
|
||||
- [chat](#-grokkit-chat)
|
||||
- [query](#-grokkit-query)
|
||||
- [edit](#-grokkit-edit-file-instruction)
|
||||
- [commit / commitmsg](#-grokkit-commitmsg)
|
||||
- [review](#-grokkit-review)
|
||||
- [pr-describe](#-grokkit-pr-describe)
|
||||
- [history](#-grokkit-history)
|
||||
- [changelog](#-grokkit-changelog)
|
||||
- [lint](#-grokkit-lint-file)
|
||||
- [docs](#-grokkit-docs-file)
|
||||
- [testgen](#-grokkit-testgen)
|
||||
- [agent](#-grokkit-agent)
|
||||
- [Configuration](#configuration)
|
||||
- [Workflows](#workflows)
|
||||
- [Shell Completions](#shell-completions)
|
||||
- [Features](#features)
|
||||
- [Development](#development)
|
||||
- [Documentation](#documentation)
|
||||
- [License](#license)
|
||||
|
||||
## Commands
|
||||
|
||||
### 💬 `grokkit chat`
|
||||
Interactive CLI chat with Grok. Features persistent history across sessions.
|
||||
|
||||
```bash
|
||||
grokkit chat # Start chat session
|
||||
grokkit chat -m grok-beta # Use specific model
|
||||
grokkit chat --debug # Enable debug logging
|
||||
```
|
||||
|
||||
**Tips:**
|
||||
- Type `/quit`, `/q`, or `exit` to exit
|
||||
- History is saved automatically between sessions
|
||||
- Use `--debug` to see API request timing
|
||||
|
||||
### 🤖 `grokkit query`
|
||||
|
||||
One-shot technical question answering. Perfect for quick programming or engineering questions.
|
||||
|
||||
```bash
|
||||
# Basic usage
|
||||
grokkit query "How do I sort a slice of structs by a field in Go?"
|
||||
|
||||
# Longer, more detailed answer
|
||||
grokkit query --wordy "Explain how Go's context package works with cancellation"
|
||||
```
|
||||
Features:
|
||||
|
||||
Default mode is concise, factual, and actionable
|
||||
--wordy flag gives longer, more explanatory answers
|
||||
Uses the fast non-reasoning model by default for speed
|
||||
No persistent history or interactive chat UI
|
||||
|
||||
|
||||
### ✏️ `grokkit edit FILE "instruction"`
|
||||
AI-powered file editing with preview.
|
||||
|
||||
```bash
|
||||
# Basic usage
|
||||
grokkit edit main.go "add error handling to all functions"
|
||||
|
||||
# Complex refactoring
|
||||
grokkit edit server.go "convert this to use context for cancellation"
|
||||
|
||||
# Add features
|
||||
grokkit edit api.go "add rate limiting middleware"
|
||||
|
||||
# Documentation
|
||||
grokkit edit utils.go "add detailed docstrings to all exported functions"
|
||||
```
|
||||
|
||||
**Safety features:**
|
||||
- Shows preview with diff-style output
|
||||
- Requires confirmation before applying
|
||||
- Uses silent streaming (no console spam)
|
||||
|
||||
### 📝 `grokkit commitmsg`
|
||||
Generate conventional commit messages from staged changes.
|
||||
|
||||
```bash
|
||||
git add .
|
||||
grokkit commitmsg # Generate message only
|
||||
grokkit commitmsg -m grok-4 # Use specific model
|
||||
```
|
||||
|
||||
Output format: `type(scope): subject\n\nbody`
|
||||
|
||||
### ✅ `grokkit commit`
|
||||
Generate commit message and commit in one step.
|
||||
|
||||
```bash
|
||||
git add .
|
||||
grokkit commit # Generate + confirm + commit
|
||||
```
|
||||
|
||||
### 🔍 `grokkit review`
|
||||
AI code review of staged or unstaged changes.
|
||||
|
||||
```bash
|
||||
# Review staged changes
|
||||
git add feature.go
|
||||
grokkit review
|
||||
|
||||
# Review all changes
|
||||
grokkit review
|
||||
|
||||
# Get detailed review
|
||||
grokkit review --debug # See API timing info
|
||||
```
|
||||
|
||||
Output includes:
|
||||
- Summary of changes
|
||||
- 3-5 actionable improvements
|
||||
- Potential bugs or issues
|
||||
- Best practice suggestions
|
||||
|
||||
### 📋 `grokkit pr-describe`
|
||||
Generate comprehensive PR descriptions.
|
||||
|
||||
```bash
|
||||
# From current branch vs main
|
||||
grokkit pr-describe
|
||||
|
||||
# With specific model
|
||||
grokkit pr-describe -m grok-4
|
||||
```
|
||||
|
||||
Output includes:
|
||||
- Title suggestion
|
||||
- Summary of changes
|
||||
- Motivation/context
|
||||
- Testing notes
|
||||
|
||||
### 📜 `grokkit history`
|
||||
Summarize recent git commits.
|
||||
|
||||
```bash
|
||||
grokkit history # Last 10 commits
|
||||
```
|
||||
|
||||
### 🗒️ `grokkit changelog`
|
||||
|
||||
Generate a clean `CHANGELOG.md` section from git history, designed specifically so the output can be pasted directly into Gitea release notes.
|
||||
|
||||
```bash
|
||||
# 1. Create your version tag first
|
||||
git tag v0.2.0
|
||||
|
||||
# 2. Generate preview + write (with safety confirmation)
|
||||
grokkit changelog
|
||||
|
||||
# 3. Output ONLY the new section (perfect for Gitea "Release notes")
|
||||
grokkit changelog --stdout
|
||||
|
||||
# 4. Write file + get commit reminder
|
||||
grokkit changelog --commit
|
||||
```
|
||||
|
||||
### 📖 `grokkit docs <file> [file...]`
|
||||
Generate language-appropriate documentation comments using Grok AI.
|
||||
|
||||
```bash
|
||||
# Preview and confirm
|
||||
grokkit docs main.go
|
||||
|
||||
# Auto-apply without confirmation
|
||||
grokkit docs handlers.go models.go --auto-apply
|
||||
|
||||
# Document multiple files at once
|
||||
grokkit docs cmd/*.go --auto-apply
|
||||
|
||||
# Use specific model
|
||||
grokkit docs app.py -m grok-4
|
||||
```
|
||||
|
||||
**Supported doc styles by language:**
|
||||
|
||||
| Language | Style |
|
||||
|----------|-------|
|
||||
| Go | godoc (`// FuncName does...`) |
|
||||
| Python | PEP 257 docstrings (`"""Summary\n\nArgs:..."""`) |
|
||||
| C / C++ | Doxygen (`/** @brief ... @param ... @return ... */`) |
|
||||
| JavaScript / TypeScript | JSDoc (`/** @param {type} name ... */`) |
|
||||
| Rust | rustdoc (`/// Summary\n/// # Arguments`) |
|
||||
| Ruby | YARD (`# @param [Type] name`) |
|
||||
| Java | Javadoc (`/** @param ... @return ... */`) |
|
||||
| Shell | Shell comments (`# function: desc, # Args: ...`) |
|
||||
|
||||
**Safety features:**
|
||||
- Shows first 50 lines of documented code as preview
|
||||
- Requires confirmation (unless `--auto-apply`)
|
||||
|
||||
### 🧪 `grokkit testgen PATHS...`
|
||||
|
||||
**Description**: Generate comprehensive unit tests for Go/Python/C/C++ files using AI.
|
||||
|
||||
**Benefits**:
|
||||
- Go: Table-driven `t.Parallel()` matching codebase.
|
||||
- Python: Pytest with `@parametrize`.
|
||||
- C: Check framework suites.
|
||||
- C++: Google Test `EXPECT_*`.
|
||||
- Boosts coverage; safe preview.
|
||||
|
||||
**CLI examples**:
|
||||
```bash
|
||||
grokkit testgen internal/grok/client.go
|
||||
grokkit testgen app.py --yes
|
||||
grokkit testgen foo.c bar.cpp
|
||||
```
|
||||
|
||||
**Safety features**:
|
||||
- Lang detection via `internal/linter`.
|
||||
- Unified diff preview.
|
||||
- Y/N (--yes auto).
|
||||
|
||||
### 🤖 `grokkit agent`
|
||||
Multi-file agent for complex refactoring (experimental).
|
||||
|
||||
```bash
|
||||
grokkit agent "refactor authentication to use JWT"
|
||||
```
|
||||
|
||||
### 🔧 `grokkit lint FILE`
|
||||
Automatically detect language, run linter, and apply AI-suggested fixes.
|
||||
|
||||
```bash
|
||||
# Just check for issues (no fixes)
|
||||
grokkit lint main.go --dry-run
|
||||
|
||||
# Interactive fix (preview + confirmation)
|
||||
grokkit lint app.py
|
||||
|
||||
# Auto-fix without confirmation
|
||||
grokkit lint server.js --auto-fix
|
||||
|
||||
# Use specific model
|
||||
grokkit lint script.rb -m grok-4
|
||||
```
|
||||
|
||||
**Supported languages:**
|
||||
- **Go** (golangci-lint, go vet)
|
||||
- **Python** (pylint, flake8, ruff)
|
||||
- **JavaScript/JSX** (eslint)
|
||||
- **TypeScript/TSX** (eslint, tsc)
|
||||
- **Rust** (clippy)
|
||||
- **Ruby** (rubocop)
|
||||
- **Java** (checkstyle)
|
||||
- **C/C++** (clang-tidy)
|
||||
- **Shell** (shellcheck)
|
||||
|
||||
**Safety features:**
|
||||
- Shows preview of fixes
|
||||
- Verifies fixes by re-running linter
|
||||
- Requires confirmation (unless `--auto-fix`)
|
||||
|
||||
## Safety & Change Management
|
||||
|
||||
Grokkit is designed to work seamlessly with Git. Rather than creating redundant `.bak` files, we lean on Git's powerful version control to manage changes and rollbacks.
|
||||
|
||||
### The Safety Workflow
|
||||
|
||||
1. **Preview**: Every command that modifies files (like `edit`, `lint`, `docs`) shows a diff-style preview first.
|
||||
2. **Confirm**: You must explicitly confirm (`y/N`) before any changes are written to disk.
|
||||
3. **Git Integration**: Use Git to manage the "pre-staged," "staged," and "committed" degrees of change.
|
||||
|
||||
### Managing Undesired Changes
|
||||
|
||||
If you've applied a change that you don't like, Git makes it easy to roll back:
|
||||
|
||||
- **Unstaged changes**: If you haven't `git add`-ed the changes yet:
|
||||
```bash
|
||||
git restore <file>
|
||||
```
|
||||
- **Staged changes**: If you've already staged the changes:
|
||||
```bash
|
||||
git restore --staged <file>
|
||||
git restore <file>
|
||||
```
|
||||
- **Committed changes**: If you've already committed the changes:
|
||||
```bash
|
||||
git revert HEAD
|
||||
# or to reset to a previous state:
|
||||
git reset --hard HEAD~1
|
||||
```
|
||||
|
||||
By using Git, you have a complete audit trail and multiple levels of undo, ensuring your codebase remains stable even when experimenting with AI-driven refactors.
|
||||
|
||||
## Configuration
|
||||
|
||||
### Environment Variables
|
||||
|
||||
```bash
|
||||
export XAI_API_KEY=sk-... # Required: Your xAI API key
|
||||
export XAI_API_KEY=$(vault read -field=key secret/grokkit) # Recommended for secure storage
|
||||
```
|
||||
|
||||
### Config File (Optional)
|
||||
@ -351,7 +66,19 @@ fast = "grok-4-1-fast-non-reasoning"
|
||||
history_file = "~/.config/grokkit/chat_history.json"
|
||||
```
|
||||
|
||||
**See also:** [docs/CONFIGURATION.md](docs/CONFIGURATION.md) for advanced configuration options.
|
||||
**See also:** [docs/developer-guide/CONFIGURATION.md](docs/developer-guide/CONFIGURATION.md) for advanced configuration options.
|
||||
|
||||
|
||||
## 📖 Commands
|
||||
|
||||
See [The User Guide](docs/user-guide/index.md) for complete details on command usage.
|
||||
|
||||
## 🛡️ Safety & Change Management
|
||||
|
||||
Grokkit is designed to work seamlessly with Git, using version control instead of redundant backup files to manage changes and rollbacks.
|
||||
|
||||
[Read the Safety & Change Management Guide](docs/user-guide/safety.md)
|
||||
|
||||
|
||||
### Logging
|
||||
|
||||
@ -370,121 +97,15 @@ cat ~/.config/grokkit/grokkit.log | jq 'select(.msg=="API request completed") |
|
||||
|
||||
## Workflows
|
||||
|
||||
### Git Workflow Integration
|
||||
Common usage patterns to integrate Grokkit into your development cycle.
|
||||
|
||||
```bash
|
||||
# 1. Make changes
|
||||
vim src/api.go
|
||||
|
||||
# 2. Review with AI
|
||||
git add src/api.go
|
||||
grokkit review
|
||||
|
||||
# 3. Fix issues, then commit
|
||||
git add src/api.go
|
||||
grokkit commit
|
||||
|
||||
# 4. Generate PR description
|
||||
grokkit pr-describe
|
||||
```
|
||||
|
||||
### Code Refactoring Workflow
|
||||
|
||||
```bash
|
||||
# 1. Chat to plan approach
|
||||
grokkit chat
|
||||
> "How should I refactor this authentication code to use middleware?"
|
||||
|
||||
# 2. Apply changes with edit
|
||||
grokkit edit auth.go "implement middleware pattern as discussed"
|
||||
|
||||
# 3. Review changes
|
||||
grokkit review
|
||||
|
||||
# 4. Commit
|
||||
grokkit commit
|
||||
```
|
||||
|
||||
### Debugging Workflow
|
||||
|
||||
```bash
|
||||
# 1. Describe issue in chat
|
||||
grokkit chat --debug
|
||||
> "I'm getting a nil pointer error in handler.go:42"
|
||||
|
||||
# 2. Apply suggested fixes
|
||||
grokkit edit handler.go "add nil checks before dereferencing user object"
|
||||
|
||||
# 3. Verify and commit
|
||||
grokkit review
|
||||
grokkit commit
|
||||
```
|
||||
|
||||
### Batch File Editing
|
||||
|
||||
```bash
|
||||
# Edit multiple files with consistent changes
|
||||
for file in src/*.go; do
|
||||
grokkit edit "$file" "add context parameter to all exported functions"
|
||||
done
|
||||
|
||||
# Review all changes together
|
||||
grokkit review
|
||||
```
|
||||
|
||||
### Code Quality Workflow
|
||||
|
||||
```bash
|
||||
# 1. Check a file for linting issues
|
||||
grokkit lint app.py --dry-run
|
||||
|
||||
# 2. Apply AI-suggested fixes with preview
|
||||
grokkit lint app.py
|
||||
|
||||
# 3. Auto-fix multiple files
|
||||
for file in src/*.js; do
|
||||
grokkit lint "$file" --auto-fix
|
||||
done
|
||||
|
||||
# 4. Review and commit
|
||||
grokkit review
|
||||
grokkit commit
|
||||
```
|
||||
|
||||
### Documentation Generation Workflow
|
||||
|
||||
```bash
|
||||
# 1. Preview docs for a single file
|
||||
grokkit docs internal/api/handler.go
|
||||
|
||||
# 2. Batch-document a package
|
||||
grokkit docs cmd/*.go --auto-apply
|
||||
|
||||
# 3. Document across languages in one pass
|
||||
grokkit docs lib/utils.py src/helpers.ts --auto-apply
|
||||
|
||||
# 4. Review and commit
|
||||
grokkit review
|
||||
grokkit commit
|
||||
```
|
||||
[Read the Workflows Guide](docs/user-guide/workflows.md)
|
||||
|
||||
## Shell Completions
|
||||
|
||||
Generate shell completions for faster command entry:
|
||||
|
||||
```bash
|
||||
# Bash
|
||||
grokkit completion bash | sudo tee /etc/bash_completion.d/grokkit
|
||||
|
||||
# Zsh (oh-my-zsh)
|
||||
grokkit completion zsh > ~/.oh-my-zsh/completions/_grokkit
|
||||
|
||||
# Fish
|
||||
grokkit completion fish > ~/.config/fish/completions/grokkit.fish
|
||||
|
||||
# PowerShell
|
||||
grokkit completion powershell | Out-String | Invoke-Expression
|
||||
```
|
||||
[Read the full Completion Guide](docs/user-guide/completion.md)
|
||||
|
||||
## Flags
|
||||
|
||||
@ -523,6 +144,9 @@ grokkit review -v
|
||||
- ✅ **Git workflow integration** - Commit messages, reviews, PR descriptions
|
||||
- ✅ **Multi-language linting** - 9 languages supported with AI-powered fixes
|
||||
- ✅ **AI documentation generation** - 8 doc styles (godoc, PEP 257, Doxygen, JSDoc, rustdoc, YARD, Javadoc, shell)
|
||||
- ✅ **AI unit test generation** - Go (table-driven), Python (pytest), C (Check), C++ (GTest)
|
||||
- ✅ **AI file scaffolding** - Create new files with project-aware style matching
|
||||
- ✅ **Transactional Recipes** - Markdown-based multi-step AI workflows
|
||||
|
||||
### Quality & Testing
|
||||
- ✅ **Test coverage 68%+** - Comprehensive unit tests including all command message builders
|
||||
@ -556,108 +180,9 @@ grokkit review -v
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
# All tests pass without XAI_API_KEY (unit tests only)
|
||||
Comprehensive build instructions, project structure details, and the Grokkit development workflow.
|
||||
|
||||
# Run tests
|
||||
make test
|
||||
|
||||
# Agent-specific tests
|
||||
make test-agent
|
||||
|
||||
# Run tests with coverage report
|
||||
make test-cover
|
||||
open build/coverage.html
|
||||
|
||||
# Linting (matches CI, uses .golangci.yml config)
|
||||
make lint
|
||||
# Install golangci-lint if needed:
|
||||
# go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
|
||||
|
||||
# Run specific tests
|
||||
go test -run TestEditCommand ./cmd -v
|
||||
|
||||
# Build binary
|
||||
make build
|
||||
|
||||
# Install locally
|
||||
make install
|
||||
|
||||
# Clean build artifacts
|
||||
make clean
|
||||
```
|
||||
|
||||
### Project Structure
|
||||
|
||||
```
|
||||
grokkit/
|
||||
├── cmd/ # CLI commands (Cobra)
|
||||
│ ├── docs.go # grokkit docs — AI documentation generation
|
||||
│ ├── lint.go # grokkit lint — AI-powered linting
|
||||
│ └── ... # chat, edit, commit, review, history, pr-describe, agent
|
||||
├── config/ # Viper configuration
|
||||
├── docs/ # Documentation
|
||||
├── todo/ # TODO tracking: queued/ (pending) and completed/ (historical record)
|
||||
│ ├── queued/ # Pending TODO items
|
||||
│ └── completed/ # Completed TODO items with history
|
||||
├── internal/
|
||||
│ ├── errors/ # Custom error types
|
||||
│ ├── git/ # Git operations
|
||||
│ ├── grok/ # xAI Grok API client
|
||||
│ ├── linter/ # Multi-language linting
|
||||
│ ├── logger/ # Structured slog logging
|
||||
│ └── version/ # Build/version info
|
||||
├── main.go # Application entrypoint
|
||||
├── go.mod # Dependencies
|
||||
├── Makefile # Build automation
|
||||
├── .golangci.yml # Golangci-lint configuration
|
||||
└── scripts/ # Install scripts
|
||||
```
|
||||
|
||||
### TODO Workflow
|
||||
|
||||
**Policy:**
|
||||
From now on, the only thing to be committed directly to the `master` branch will be to-do items (.md files in `todo/queued/`).
|
||||
|
||||
**Process:**
|
||||
1. When deciding to work on a to-do item: create a branch, implement on the branch, submit PR to `master`.
|
||||
2. After PR merge: move the item to `todo/completed/`.
|
||||
|
||||
**Example workflow:**
|
||||
```bash
|
||||
git checkout -b feature/some-todo
|
||||
# Implement changes, test with make test lint
|
||||
git add .
|
||||
git commit -m "feat: implement some-todo"
|
||||
git push -u origin feature/some-todo
|
||||
# Create and merge PR to master
|
||||
|
||||
# Post-merge:
|
||||
git checkout master
|
||||
git pull
|
||||
mv "todo/queued/SOME_TODO.md" "todo/completed/SOME_TODO.md"
|
||||
git add todo/
|
||||
git commit -m "chore: complete some-todo"
|
||||
git push origin master
|
||||
```
|
||||
|
||||
### Gitea Actions Automation *(automates post-merge above)*
|
||||
|
||||
[`.gitea/workflows/auto-complete-todo.yml`](.gitea/workflows/auto-complete-todo.yml) triggers on PR `opened`/`synchronize`:
|
||||
|
||||
- Branches `feature/some-todo`: moves `todo/queued/some-todo.md` → `completed/`.
|
||||
|
||||
**One-time setup** (Gitea → Repo → Settings → Secrets & Variables → Actions):
|
||||
- New Secret: `PAT_TOKEN` = [Personal Access Token](https://gitea.example.com/user/settings/tokens) (scope: `repo`).
|
||||
- Optional: Branch protection → Require "Auto-complete TODO" status check.
|
||||
|
||||
**Result**: No manual post-merge steps needed!
|
||||
|
||||
## Documentation
|
||||
|
||||
- 📖 [Troubleshooting Guide](docs/TROUBLESHOOTING.md) - Common issues and solutions
|
||||
- 🏗️ [Architecture Overview](docs/ARCHITECTURE.md) - System design and patterns
|
||||
- ⚙️ [Configuration Guide](docs/CONFIGURATION.md) - Advanced configuration options
|
||||
[Read the Development Overview Guide](docs/developer-guide/overview.md)
|
||||
|
||||
## API Usage & Costs
|
||||
|
||||
@ -667,11 +192,6 @@ Grokkit uses the xAI Grok API. Be aware:
|
||||
- Streaming reduces perceived latency
|
||||
- Consider using model aliases for different use cases (fast/expensive)
|
||||
|
||||
## Requirements
|
||||
|
||||
- Go 1.24.2 (for building)
|
||||
- Git (for git-related commands)
|
||||
- XAI API key
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
@ -690,7 +210,7 @@ Error: Request failed: context deadline exceeded
|
||||
→ Solution: chmod 644 ~/.config/grokkit/grokkit.log
|
||||
```
|
||||
|
||||
**See [docs/TROUBLESHOOTING.md](docs/TROUBLESHOOTING.md) for more details.**
|
||||
**See [docs/developer-guide/TROUBLESHOOTING.md](docs/developer-guide/TROUBLESHOOTING.md) for more details.**
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@ -19,7 +19,6 @@ Default mode is factual and brief. Use --wordy for longer, more explanatory answ
|
||||
|
||||
func init() {
|
||||
queryCmd.Flags().Bool("wordy", false, "Give a longer, more detailed answer")
|
||||
rootCmd.AddCommand(queryCmd)
|
||||
}
|
||||
|
||||
func runQuery(cmd *cobra.Command, args []string) {
|
||||
|
||||
139
cmd/recipe.go
Normal file
139
cmd/recipe.go
Normal file
@ -0,0 +1,139 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"gmgauthier.com/grokkit/config"
|
||||
"gmgauthier.com/grokkit/internal/grok"
|
||||
"gmgauthier.com/grokkit/internal/recipe"
|
||||
)
|
||||
|
||||
var recipeCmd = &cobra.Command{
|
||||
Use: "recipe",
|
||||
Short: "Run a recipe (transactional sous-chef mode)",
|
||||
}
|
||||
|
||||
var runCmd = &cobra.Command{
|
||||
Use: "run [recipe-name|recipe.md]",
|
||||
Short: "Execute a recipe",
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
RunE: runRecipe,
|
||||
}
|
||||
|
||||
var paramFlags []string
|
||||
|
||||
func init() {
|
||||
runCmd.Flags().StringSliceVarP(¶mFlags, "param", "p", nil, "key=value parameters for the recipe (can be repeated)")
|
||||
recipeCmd.AddCommand(runCmd)
|
||||
rootCmd.AddCommand(recipeCmd)
|
||||
}
|
||||
|
||||
func runRecipe(cmd *cobra.Command, args []string) error {
|
||||
nameOrPath := args[0]
|
||||
|
||||
recipePath, err := resolveRecipePath(nameOrPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Parse --param key=value into map
|
||||
params := make(map[string]any)
|
||||
for _, p := range paramFlags {
|
||||
if kv := strings.SplitN(p, "=", 2); len(kv) == 2 {
|
||||
key := strings.TrimSpace(kv[0])
|
||||
value := strings.TrimSpace(kv[1])
|
||||
|
||||
// Clean bool handling that satisfies staticcheck
|
||||
switch strings.ToLower(value) {
|
||||
case "true", "1", "yes", "on":
|
||||
params[key] = true
|
||||
case "false", "0", "no", "off":
|
||||
params[key] = false
|
||||
default:
|
||||
params[key] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
r, err := recipe.Load(recipePath, params)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to load recipe: %w", err)
|
||||
}
|
||||
|
||||
flagModel, _ := cmd.Flags().GetString("model")
|
||||
model := config.GetModel("recipe", flagModel)
|
||||
|
||||
client := grok.NewClient()
|
||||
|
||||
runner := recipe.NewRunner(r, client, model)
|
||||
return runner.Run()
|
||||
}
|
||||
|
||||
// resolveRecipePath and findProjectRoot stay exactly as you have them
|
||||
func resolveRecipePath(nameOrPath string) (string, error) {
|
||||
if strings.Contains(nameOrPath, "/") || strings.HasSuffix(nameOrPath, ".md") {
|
||||
if _, err := os.Stat(nameOrPath); err == nil {
|
||||
return nameOrPath, nil
|
||||
}
|
||||
return "", fmt.Errorf("recipe file not found: %s", nameOrPath)
|
||||
}
|
||||
|
||||
if !strings.HasSuffix(nameOrPath, ".md") {
|
||||
nameOrPath += ".md"
|
||||
}
|
||||
|
||||
projectRoot, err := findProjectRoot()
|
||||
if err == nil {
|
||||
local := filepath.Join(projectRoot, ".grokkit", "recipes", nameOrPath)
|
||||
if _, err := os.Stat(local); err == nil {
|
||||
return local, nil
|
||||
}
|
||||
}
|
||||
|
||||
global := filepath.Join(os.Getenv("HOME"), ".local", "share", "grokkit", "recipes", nameOrPath)
|
||||
if _, err := os.Stat(global); err == nil {
|
||||
fmt.Printf("Recipe %q not found in project.\nFound globally at %s\nUse this one? [y/N] ", nameOrPath, global)
|
||||
var answer string
|
||||
if _, err := fmt.Scanln(&answer); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if strings.HasPrefix(strings.ToLower(answer), "y") {
|
||||
return global, nil
|
||||
}
|
||||
return "", fmt.Errorf("user declined global recipe")
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("recipe %q not found in project or global store", nameOrPath)
|
||||
}
|
||||
|
||||
func findProjectRoot() (string, error) {
|
||||
dir, err := os.Getwd()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
for {
|
||||
if _, err := os.Stat(filepath.Join(dir, ".git")); err == nil {
|
||||
return dir, nil
|
||||
}
|
||||
if _, err := os.Stat(filepath.Join(dir, ".gitignore")); err == nil {
|
||||
return dir, nil
|
||||
}
|
||||
if _, err := os.Stat(filepath.Join(dir, ".grokkit")); err == nil {
|
||||
return dir, nil
|
||||
}
|
||||
if _, err := os.Stat(filepath.Join(dir, "go.mod")); err == nil {
|
||||
return dir, nil
|
||||
}
|
||||
parent := filepath.Dir(dir)
|
||||
if parent == dir {
|
||||
break
|
||||
}
|
||||
dir = parent
|
||||
}
|
||||
return "", fmt.Errorf("not in a project")
|
||||
}
|
||||
@ -16,28 +16,33 @@ This document describes the design principles, architecture patterns, and implem
|
||||
|
||||
Grokkit follows these core principles:
|
||||
|
||||
### 1. **Simplicity First**
|
||||
### 1. **The Developer Is The Agent**
|
||||
- The developer is in control of the code, not the LLM.
|
||||
- The LLM should *enhance the developer experience*, not *replace* it.
|
||||
- The developer is the one who makes **informed judgments** about the code, not the LLM.
|
||||
|
||||
### 2. **Simplicity First**
|
||||
- Minimal dependencies (stdlib + well-known libs)
|
||||
- Minimal interface surface (CLI commands over TUI interactions)
|
||||
- Clear, readable code over clever solutions
|
||||
- Single responsibility per package
|
||||
|
||||
### 2. **Safety by Default**
|
||||
### 3. **Safety by Default**
|
||||
- Git-based version control for change management
|
||||
- Confirmation prompts for destructive actions
|
||||
- Comprehensive error handling
|
||||
|
||||
### 3. **Observability**
|
||||
### 4. **Observability**
|
||||
- Structured logging for all operations
|
||||
- Request/response timing
|
||||
- Contextual error messages
|
||||
|
||||
### 4. **Testability**
|
||||
### 5. **Testability**
|
||||
- Interface-based design
|
||||
- Dependency injection where needed
|
||||
- Unit tests for pure functions
|
||||
|
||||
### 5. **User Experience**
|
||||
### 6. **User Experience**
|
||||
- Streaming responses for immediate feedback
|
||||
- Persistent history
|
||||
- Shell completions
|
||||
@ -77,9 +82,13 @@ grokkit/
|
||||
│ ├── logger.go # Logger setup + helpers
|
||||
│ └── logger_test.go
|
||||
├── docs/ # Documentation
|
||||
│ ├── TROUBLESHOOTING.md
|
||||
│ └── developer-guide/ # Technical documentation
|
||||
│ ├── ARCHITECTURE.md # This file
|
||||
│ └── CONFIGURATION.md
|
||||
│ ├── CONFIGURATION.md # Configuration guide
|
||||
│ ├── TROUBLESHOOTING.md # Troubleshooting guide
|
||||
│ └── index.md # Developer guide index
|
||||
│ ├── user-guide/ # End-user documentation
|
||||
│ └── index.md # Main documentation index
|
||||
├── .gitea/workflows/ # CI/CD
|
||||
│ ├── ci.yml # Test + lint + build
|
||||
│ └── release.yml # Multi-platform releases
|
||||
11
docs/developer-guide/index.md
Normal file
11
docs/developer-guide/index.md
Normal file
@ -0,0 +1,11 @@
|
||||
# Developer Guide
|
||||
|
||||
Welcome to the Grokkit Developer Guide. This section contains resources and guidelines for those who want to contribute to Grokkit's development or understand its internal workings.
|
||||
|
||||
## Resources
|
||||
|
||||
- **[Development Overview](overview.md)** — Build instructions, project structure, and the standard TODO workflow.
|
||||
- **[Architecture Overview](ARCHITECTURE.md)** — Deep dive into the design principles, project structure, and technical implementation of Grokkit.
|
||||
- **[Configuration Guide](CONFIGURATION.md)** — Detailed information on how to configure Grokkit via environment variables and config files.
|
||||
- **[Troubleshooting](TROUBLESHOOTING.md)** — Common issues and their solutions encountered during development or deployment.
|
||||
- **[Back to Documentation Index](../index.md)**
|
||||
107
docs/developer-guide/overview.md
Normal file
107
docs/developer-guide/overview.md
Normal file
@ -0,0 +1,107 @@
|
||||
# 🛠️ Development Overview
|
||||
|
||||
This document provides a comprehensive overview of the development process for Grokkit, including build instructions, project structure, and the standard TODO workflow.
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
# All tests pass without XAI_API_KEY (unit tests only)
|
||||
|
||||
# Run tests
|
||||
make test
|
||||
|
||||
# Agent-specific tests
|
||||
make test-agent
|
||||
|
||||
# Run tests with coverage report
|
||||
make test-cover
|
||||
open build/coverage.html
|
||||
|
||||
# Linting (matches CI, uses .golangci.yml config)
|
||||
make lint
|
||||
# Install golangci-lint if needed:
|
||||
# go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
|
||||
|
||||
# Run specific tests
|
||||
go test -run TestEditCommand ./cmd -v
|
||||
|
||||
# Build binary
|
||||
make build
|
||||
|
||||
# Install locally
|
||||
make install
|
||||
|
||||
# Clean build artifacts
|
||||
make clean
|
||||
```
|
||||
|
||||
### Project Structure
|
||||
|
||||
```
|
||||
grokkit/
|
||||
├── cmd/ # CLI commands (Cobra)
|
||||
│ ├── docs.go # grokkit docs — AI documentation generation
|
||||
│ ├── lint.go # grokkit lint — AI-powered linting
|
||||
│ ├── recipe.go # grokkit recipe — transactional recipe runner
|
||||
│ ├── scaffold.go # grokkit scaffold — project-aware file generation
|
||||
│ └── ... # chat, edit, commit, review, history, pr-describe, agent
|
||||
├── config/ # Viper configuration
|
||||
├── docs/ # Documentation
|
||||
├── .grokkit/ # Project-local Grokkit data
|
||||
│ └── recipes/ # Custom AI workflows (recipes)
|
||||
├── todo/ # TODO tracking: queued/ (pending) and completed/ (historical record)
|
||||
│ ├── queued/ # Pending TODO items
|
||||
│ └── completed/ # Completed TODO items with history
|
||||
├── internal/
|
||||
│ ├── errors/ # Custom error types
|
||||
│ ├── git/ # Git operations
|
||||
│ ├── grok/ # xAI Grok API client
|
||||
│ ├── linter/ # Multi-language linting
|
||||
│ ├── logger/ # Structured slog logging
|
||||
│ ├── recipe/ # Recipe loading and execution engine
|
||||
│ └── version/ # Build/version info
|
||||
├── main.go # Application entrypoint
|
||||
├── go.mod # Dependencies
|
||||
├── Makefile # Build automation
|
||||
├── .golangci.yml # Golangci-lint configuration
|
||||
└── scripts/ # Install scripts
|
||||
```
|
||||
|
||||
## TODO Workflow
|
||||
|
||||
**Policy:**
|
||||
From now on, the only thing to be committed directly to the `master` branch will be to-do items (.md files in `todo/queued/`).
|
||||
|
||||
**Process:**
|
||||
1. When deciding to work on a to-do item: create a branch, implement on the branch, submit PR to `master`.
|
||||
2. After PR merge: move the item to `todo/completed/`.
|
||||
|
||||
**Example workflow:**
|
||||
```bash
|
||||
git checkout -b feature/some-todo
|
||||
# Implement changes, test with make test lint
|
||||
git add .
|
||||
git commit -m "feat: implement some-todo"
|
||||
git push -u origin feature/some-todo
|
||||
# Create and merge PR to master
|
||||
|
||||
# Post-merge:
|
||||
git checkout master
|
||||
git pull
|
||||
mv "todo/queued/SOME_TODO.md" "todo/completed/SOME_TODO.md"
|
||||
git add todo/
|
||||
git commit -m "chore: complete some-todo"
|
||||
git push origin master
|
||||
```
|
||||
|
||||
### Gitea Actions Automation *(automates post-merge above)*
|
||||
|
||||
[`.gitea/workflows/auto-complete-todo.yml`](../../.gitea/workflows/auto-complete-todo.yml) triggers on PR `opened`/`synchronize`:
|
||||
|
||||
- Branches `feature/some-todo`: moves `todo/queued/some-todo.md` → `completed/`.
|
||||
|
||||
**One-time setup** (Gitea → Repo → Settings → Secrets & Variables → Actions):
|
||||
- New Secret: `PAT_TOKEN` = [Personal Access Token](https://gitea.example.com/user/settings/tokens) (scope: `repo`).
|
||||
- Optional: Branch protection → Require "Auto-complete TODO" status check.
|
||||
|
||||
**Result**: No manual post-merge steps needed!
|
||||
24
docs/index.md
Normal file
24
docs/index.md
Normal file
@ -0,0 +1,24 @@
|
||||
# Grokkit Documentation
|
||||
|
||||
Welcome to the Grokkit documentation. Grokkit is a fast, native Go CLI that integrates Grok AI into your daily development and git workflows.
|
||||
|
||||
Whether you're looking for quick answers, AI-powered file editing, or complex multi-step automated workflows, Grokkit provides the tools to enhance your productivity.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- **[User Guide](user-guide/index.md)** — Comprehensive documentation for all Grokkit commands and features.
|
||||
- **[Grokkit Workflows](user-guide/workflows.md)** — Learn how to integrate Grokkit into your development cycle effectively.
|
||||
- **[Safety & Change Management](user-guide/safety.md)** — Learn how Grokkit integrates with Git to keep your codebase stable and safe.
|
||||
- **[Configuration Guide](developer-guide/CONFIGURATION.md)** — Detailed information on how to configure Grokkit via environment variables and config files.
|
||||
- **[Developer Guide](developer-guide/index.md)** — Resources and guidelines for contributing to Grokkit development.
|
||||
- **[Development Overview](developer-guide/overview.md)** — Build instructions, project structure, and the standard TODO workflow.
|
||||
- **[Architecture Overview](developer-guide/ARCHITECTURE.md)** — Deep dive into the design principles, project structure, and technical implementation of Grokkit.
|
||||
- **[Troubleshooting](developer-guide/TROUBLESHOOTING.md)** — Common issues and their solutions.
|
||||
|
||||
---
|
||||
|
||||
## Quick Links
|
||||
|
||||
- [Grokkit Repository](https://repos.gmgauthier.com/gmgauthier/grokkit)
|
||||
- [Grokkit Releases](https://repos.gmgauthier.com/gmgauthier/grokkit/releases)
|
||||
- [Main README](../README.md)
|
||||
49
docs/user-guide/agent.md
Normal file
49
docs/user-guide/agent.md
Normal file
@ -0,0 +1,49 @@
|
||||
# 🤖 Agent Guide
|
||||
|
||||
The `agent` command is a multi-file autonomous agent that allows you to perform complex refactorings or feature implementations across multiple files using natural language instructions.
|
||||
|
||||
> [!WARNING]
|
||||
> This command is currently experimental. Always ensure you have a clean git state before running the agent.
|
||||
|
||||
### Why use Agent?
|
||||
|
||||
- **Multi-file awareness**: Unlike the `edit` command, the `agent` command scans your project to understand the context and identifies which files need to be changed.
|
||||
- **Autonomous Planning**: Grok generates a high-level plan for the entire task before proposing any code changes.
|
||||
- **Interactive Execution**: You review the plan first, then review and approve changes for each file individually or all at once.
|
||||
- **Project-wide Refactoring**: Ideal for tasks like "refactor authentication to use JWT" or "add a new field to the User struct across all layers".
|
||||
|
||||
### Usage
|
||||
|
||||
Multi-file agent for complex refactoring (experimental).
|
||||
|
||||
```bash
|
||||
grokkit agent "refactor authentication to use JWT"
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
| Flag | Description |
|
||||
|------|-------------|
|
||||
| `--model`, `-m` | Override the default model (e.g., `grok-4`) |
|
||||
|
||||
### Workflow
|
||||
|
||||
1. **Project Scan**: The agent scans the current directory for relevant files (currently focused on `.go` files).
|
||||
2. **Plan Generation**: Grok analyzes your instruction and the file list to create a step-by-step plan.
|
||||
3. **Plan Review**: You review the proposed plan and decide whether to proceed.
|
||||
4. **Iterative Editing**:
|
||||
- For each file in the plan, Grok generates the updated content.
|
||||
- You see a diff-style preview of the proposed changes for that specific file.
|
||||
- You can choose to:
|
||||
- `y`: Apply changes to this file and move to the next.
|
||||
- `n`: Skip changes for this file and move to the next.
|
||||
- `a`: Apply changes to this file and all remaining files in the plan without further confirmation.
|
||||
5. **Completion**: Once all files are processed, the agent provides a summary of the actions taken.
|
||||
|
||||
### Safety & Best Practices
|
||||
|
||||
- **Clean Git State**: Always run the agent on a clean git branch. This allows you to easily `git reset --hard` or `git restore` if the AI makes undesired changes.
|
||||
- **Review the Plan**: Pay close attention to the initial plan. If it seems off, abort and try again with a more specific instruction.
|
||||
- **Incremental Approval**: For complex tasks, approve files one by one (`y`) rather than using the "apply all" (`a`) option.
|
||||
- **Verify Results**: After the agent finishes, run your tests (`make test`) and linter (`make lint`) to ensure the changes are correct and follow project standards.
|
||||
- **Specific Instructions**: Provide as much context as possible in your instruction to help the agent understand the scope of the change.
|
||||
51
docs/user-guide/changelog.md
Normal file
51
docs/user-guide/changelog.md
Normal file
@ -0,0 +1,51 @@
|
||||
# 🗒️ Changelog Guide
|
||||
|
||||
The `changelog` command automatically generates a `CHANGELOG.md` section based on your git history. It's designed to create professional, categorized changelogs that can be used directly for releases.
|
||||
|
||||
### Key Features
|
||||
|
||||
- **Categorized Changes**: Automatically groups commits into `Added`, `Changed`, and `Fixed`.
|
||||
- **Gitea Compatible**: The output is formatted for easy pasting into Gitea release notes.
|
||||
- **Project Maintenance**: Automatically updates your existing `CHANGELOG.md` file.
|
||||
- **Smart Summaries**: Grok creates concise, imperative bullet points for each change.
|
||||
|
||||
### Usage
|
||||
|
||||
Generate a clean `CHANGELOG.md` section from git history, designed specifically so the output can be pasted directly into Gitea release notes.
|
||||
|
||||
```bash
|
||||
# 1. Create your version tag first
|
||||
git tag v0.2.0
|
||||
|
||||
# 2. Generate preview + write (with safety confirmation)
|
||||
grokkit changelog
|
||||
|
||||
# 3. Output ONLY the new section (perfect for Gitea "Release notes")
|
||||
grokkit changelog --stdout
|
||||
|
||||
# 4. Write file + get commit reminder
|
||||
grokkit changelog --commit
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
| Flag | Description |
|
||||
|------|-------------|
|
||||
| `--since` | Start from this tag/ref (default: previous tag) |
|
||||
| `--version`, `-V` | Override the version number for the header (default: latest git tag) |
|
||||
| `--stdout` | Print ONLY the new section (useful for pasting into release notes) |
|
||||
| `--commit` | Reminds you to commit the changes after updating the file |
|
||||
| `--model`, `-m` | Override the default model (e.g., `grok-4`) |
|
||||
|
||||
### How it Works
|
||||
|
||||
1. **History Retrieval**: Grokkit finds the commits since the last tag.
|
||||
2. **Categorization**: It sends the commit history to Grok to be categorized and summarized.
|
||||
3. **Markdown Generation**: Grok returns a formatted markdown section.
|
||||
4. **File Update**: Grokkit prepends the new section to your `CHANGELOG.md` or creates it if it doesn't exist.
|
||||
|
||||
### Best Practices
|
||||
|
||||
- **Conventional Commits**: Use conventional commit messages to help the AI categorize changes more accurately.
|
||||
- **Use tags**: Ensure your project uses git tags so Grokkit can correctly identify the changes since the last version.
|
||||
- **Review before writing**: Always review the proposed changelog update before confirming.
|
||||
45
docs/user-guide/chat.md
Normal file
45
docs/user-guide/chat.md
Normal file
@ -0,0 +1,45 @@
|
||||
# 💬 Chat Guide
|
||||
|
||||
The `chat` command starts a full interactive session with Grok. Unlike other commands that are one-shot, `chat` maintains a conversation history, allowing for multi-turn dialogues and context-aware responses.
|
||||
|
||||
### Key Features
|
||||
|
||||
- **Interactive**: Real-time conversation with Grok.
|
||||
- **Streaming**: Responses are streamed to your terminal as they are generated.
|
||||
- **History**: Grokkit automatically saves and reloads your chat history from `~/.config/grokkit/chat_history.json`.
|
||||
- **System Prompt**: Grok is configured with a project-aware system prompt to provide relevant answers.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
grokkit chat # Start chat session
|
||||
grokkit chat -m grok-beta # Use specific model
|
||||
grokkit chat --debug # Enable debug logging
|
||||
```
|
||||
|
||||
### Tips
|
||||
|
||||
- Type `/quit`, `/q`, or `exit` to exit
|
||||
- History is saved automatically between sessions
|
||||
- Use `--debug` to see API request timing
|
||||
|
||||
### Commands within Chat
|
||||
|
||||
- `/quit` or `/q`: Exit the chat session.
|
||||
- `exit`: Exit the chat session.
|
||||
- `Ctrl+C`: Exit the chat session.
|
||||
|
||||
### Options
|
||||
|
||||
| Flag | Description |
|
||||
|------|-------------|
|
||||
| `--model`, `-m` | Override the default model (e.g., `grok-4`) |
|
||||
|
||||
### Configuration
|
||||
|
||||
You can configure the location of the history file in your `config.toml`:
|
||||
|
||||
```toml
|
||||
[chat]
|
||||
history_file = "~/.config/grokkit/my_custom_history.json"
|
||||
```
|
||||
62
docs/user-guide/commit-msg.md
Normal file
62
docs/user-guide/commit-msg.md
Normal file
@ -0,0 +1,62 @@
|
||||
# 📝 Commit Message Guide
|
||||
|
||||
The `commit-msg` command generates a conventional commit message based on your currently staged changes. Unlike the `commit` command, it only outputs the suggested message without actually performing the git commit.
|
||||
|
||||
### Why use Commit Message?
|
||||
|
||||
- **Consistency**: Automatically generate messages following the [Conventional Commits](https://www.conventionalcommits.org/) specification (e.g., `feat(api): add JWT authentication`).
|
||||
- **Convenience**: Quickly get a descriptive summary of your changes without manually reviewing the diff.
|
||||
- **Workflow flexibility**: Useful when you want to review, edit, or use the generated message in a custom git command or GUI.
|
||||
|
||||
### Basic Usage
|
||||
|
||||
```bash
|
||||
git add .
|
||||
grokkit commit-msg # Generate message only
|
||||
grokkit commit-msg -m grok-4 # Use specific model
|
||||
```
|
||||
|
||||
**Output format:** `type(scope): subject\n\nbody`
|
||||
|
||||
### Options
|
||||
|
||||
| Flag | Description |
|
||||
|------|-------------|
|
||||
| `--model`, `-m` | Override the default model (e.g., `grok-4`) |
|
||||
|
||||
### How it Works
|
||||
|
||||
1. **Diff Retrieval**: Grokkit runs `git diff --cached --no-color` to get all staged changes.
|
||||
2. **AI Analysis**: It sends the diff to Grok with instructions to generate a conventional commit message.
|
||||
3. **Streaming Output**: The generated message is streamed directly to your terminal.
|
||||
|
||||
### Workflow Example
|
||||
|
||||
1. Stage your changes:
|
||||
```bash
|
||||
git add main.go internal/grok/client.go
|
||||
```
|
||||
2. Generate the message:
|
||||
```bash
|
||||
grokkit commit-msg
|
||||
```
|
||||
3. Use the output to commit:
|
||||
```bash
|
||||
git commit -m "$(grokkit commit-msg)"
|
||||
```
|
||||
|
||||
### Comparison with `commit` command
|
||||
|
||||
| Feature | `commit-msg` | `commit` |
|
||||
|---------|--------------|----------|
|
||||
| Generates AI message | Yes | Yes |
|
||||
| Shows diff-based summary | Yes | Yes |
|
||||
| Asks for confirmation | No | Yes |
|
||||
| Performs `git commit` | No | Yes |
|
||||
| Use case | Scripting / Manual control | Interactive git workflow |
|
||||
|
||||
### Best Practices
|
||||
|
||||
- **Stage only related changes**: To get the most accurate commit message, stage only the changes that belong to a single logical unit of work.
|
||||
- **Review the output**: AI-generated messages are usually good but may need minor tweaks for complex changes.
|
||||
- **Model Choice**: Use a reasoning model (`grok-4`) for complex architectural changes to get more detailed body descriptions in the commit message.
|
||||
58
docs/user-guide/commit.md
Normal file
58
docs/user-guide/commit.md
Normal file
@ -0,0 +1,58 @@
|
||||
# ✅ Commit Guide
|
||||
|
||||
Grokkit provides two commands to help you generate high-quality, conventional commit messages from your staged changes: `commit-msg` and `commit`.
|
||||
|
||||
### Commit-msg
|
||||
|
||||
The `commit-msg` command generates a conventional commit message based on your currently staged changes (`git add`). It's perfect for when you want to review the message before using it in your commit.
|
||||
|
||||
#### Usage
|
||||
|
||||
```bash
|
||||
git add .
|
||||
grokkit commit-msg
|
||||
```
|
||||
|
||||
**Output Example:**
|
||||
```text
|
||||
feat(git): add support for custom commit message templates
|
||||
|
||||
Implemented a new system for defining custom templates for commit messages, allowing for project-specific conventions.
|
||||
```
|
||||
|
||||
### Commit
|
||||
|
||||
The `commit` command generates a commit message and commits in one step.
|
||||
|
||||
#### Usage
|
||||
|
||||
```bash
|
||||
git add .
|
||||
grokkit commit # Generate + confirm + commit
|
||||
```
|
||||
|
||||
**Interactive Workflow:**
|
||||
1. Grokkit analyzes your staged changes.
|
||||
2. It generates a conventional commit message.
|
||||
3. It shows you the proposed message.
|
||||
4. It asks for confirmation: `Commit with this message? (y/n): `.
|
||||
5. If you confirm, it runs `git commit -m "<message>"`.
|
||||
|
||||
### Why use AI for Commits?
|
||||
|
||||
- **Conventional Format**: Automatically follows the `type(scope): subject` format.
|
||||
- **Accurate Descriptions**: Grok analyzes the actual diff to provide a meaningful summary of your changes.
|
||||
- **Consistency**: Ensures that all commit messages in your project follow the same high standard.
|
||||
- **Save Time**: No more staring at a blank screen trying to remember everything you changed.
|
||||
|
||||
### Options
|
||||
|
||||
| Flag | Description |
|
||||
|------|-------------|
|
||||
| `--model`, `-m` | Override the default model (e.g., `grok-4`) |
|
||||
|
||||
### Best Practices
|
||||
|
||||
- **Stage only relevant changes**: For the best commit message, only stage the changes that belong in a single commit.
|
||||
- **Review before committing**: Always read the generated message to ensure it accurately reflects your intent.
|
||||
- **Model selection**: For complex changes, use a more powerful model like `grok-4` to get a better summary.
|
||||
42
docs/user-guide/completion.md
Normal file
42
docs/user-guide/completion.md
Normal file
@ -0,0 +1,42 @@
|
||||
# Completion Guide
|
||||
|
||||
The `completion` command generates shell completion scripts for Grokkit, making it faster and easier to use the CLI by providing tab-completion for commands and flags.
|
||||
|
||||
### Supported Shells
|
||||
|
||||
- **Bash**
|
||||
- **Zsh**
|
||||
- **Fish**
|
||||
- **PowerShell**
|
||||
|
||||
### Installation
|
||||
|
||||
To enable completions, you need to generate the script for your shell and source it.
|
||||
|
||||
#### Bash
|
||||
|
||||
```bash
|
||||
grokkit completion bash | sudo tee /etc/bash_completion.d/grokkit
|
||||
```
|
||||
|
||||
#### Zsh (oh-my-zsh)
|
||||
|
||||
```zsh
|
||||
grokkit completion zsh > ~/.oh-my-zsh/completions/_grokkit
|
||||
```
|
||||
|
||||
#### Fish
|
||||
|
||||
```fish
|
||||
grokkit completion fish > ~/.config/fish/completions/grokkit.fish
|
||||
```
|
||||
|
||||
#### PowerShell
|
||||
|
||||
```powershell
|
||||
grokkit completion powershell | Out-String | Invoke-Expression
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
Once installed, you can simply type `grokkit ` followed by `Tab` to see available commands, or `grokkit <command> --` followed by `Tab` to see available flags.
|
||||
60
docs/user-guide/docs.md
Normal file
60
docs/user-guide/docs.md
Normal file
@ -0,0 +1,60 @@
|
||||
# 📖 Docs Guide
|
||||
|
||||
The `docs` command uses AI to generate language-appropriate documentation comments for your source files. It supports a wide range of programming languages and documentation styles.
|
||||
|
||||
### Usage
|
||||
|
||||
Generate language-appropriate documentation comments using Grok AI.
|
||||
|
||||
```bash
|
||||
# Preview and confirm
|
||||
grokkit docs main.go
|
||||
|
||||
# Auto-apply without confirmation
|
||||
grokkit docs handlers.go models.go --auto-apply
|
||||
|
||||
# Document multiple files at once
|
||||
grokkit docs cmd/*.go --auto-apply
|
||||
|
||||
# Use specific model
|
||||
grokkit docs app.py -m grok-4
|
||||
```
|
||||
|
||||
### Supported doc styles by language
|
||||
|
||||
| Language | Style |
|
||||
|----------|-------|
|
||||
| Go | godoc (`// FuncName does...`) |
|
||||
| Python | PEP 257 docstrings (`"""Summary\n\nArgs:..."""`) |
|
||||
| C / C++ | Doxygen (`/** @brief ... @param ... @return ... */`) |
|
||||
| JavaScript / TypeScript | JSDoc (`/** @param {type} name ... */`) |
|
||||
| Rust | rustdoc (`/// Summary\n/// # Arguments`) |
|
||||
| Ruby | YARD (`# @param [Type] name`) |
|
||||
| Java | Javadoc (`/** @param ... @return ... */`) |
|
||||
| Shell | Shell comments (`# function: desc, # Args: ...`) |
|
||||
|
||||
### Safety features
|
||||
|
||||
- Shows first 50 lines of documented code as preview
|
||||
- Requires confirmation (unless `--auto-apply`)
|
||||
|
||||
### Options
|
||||
|
||||
| Flag | Description |
|
||||
|------|-------------|
|
||||
| `--auto-apply` | Apply documentation without confirmation |
|
||||
| `--model`, `-m` | Override the default model (e.g., `grok-4`) |
|
||||
|
||||
### How it Works
|
||||
|
||||
1. **Language Detection**: Grokkit detects the language of each file to select the appropriate documentation style.
|
||||
2. **Contextual Analysis**: It reads the file and prepares a prompt for Grok.
|
||||
3. **AI Generation**: Grok generates the documentation comments for all public functions, methods, and types.
|
||||
4. **Interactive Preview**: Grokkit shows you a preview of the documented code.
|
||||
5. **Confirmation**: You review and confirm before the changes are applied to your file (unless you use `--auto-apply`).
|
||||
|
||||
### Best Practices
|
||||
|
||||
- **Document public APIs**: Use `docs` to ensure your project's public interface is well-documented.
|
||||
- **Review for Accuracy**: Always read the generated documentation to ensure it accurately reflects the function's purpose and behavior.
|
||||
- **Use for complex code**: For particularly complex functions, AI-generated documentation can be very helpful for clarifying logic.
|
||||
53
docs/user-guide/edit.md
Normal file
53
docs/user-guide/edit.md
Normal file
@ -0,0 +1,53 @@
|
||||
# ✏️ Edit Guide
|
||||
|
||||
The `edit` command allows you to modify an existing file in-place using natural language instructions. It's a quick and efficient way to refactor code, fix bugs, or add features without manually editing the file.
|
||||
|
||||
### Why use Edit?
|
||||
|
||||
- **Natural Language**: Just tell Grok what you want to change (e.g., "Add a new parameter to the `NewClient` function").
|
||||
- **Interactive Preview**: See the proposed changes in a unified diff format before they are applied.
|
||||
- **Refactoring made easy**: Effortlessly refactor large functions or rewrite entire blocks of code.
|
||||
- **Cleanup**: `edit` automatically removes unnecessary comments, last modified timestamps, and ownership headers for a cleaner codebase.
|
||||
|
||||
### Basic Usage
|
||||
|
||||
```bash
|
||||
# Basic usage
|
||||
grokkit edit main.go "add error handling to all functions"
|
||||
|
||||
# Complex refactoring
|
||||
grokkit edit server.go "convert this to use context for cancellation"
|
||||
|
||||
# Add features
|
||||
grokkit edit api.go "add rate limiting middleware"
|
||||
|
||||
# Documentation
|
||||
grokkit edit utils.go "add detailed docstrings to all exported functions"
|
||||
```
|
||||
|
||||
### Safety Features
|
||||
|
||||
- **Diff-style Preview**: Shows exactly what will change.
|
||||
- **Confirmation Required**: Nothing is written without your `y/N`.
|
||||
- **Silent Streaming**: No console spam while waiting.
|
||||
|
||||
### Options
|
||||
|
||||
| Flag | Description |
|
||||
|------|-------------|
|
||||
| `--model`, `-m` | Override the default model (e.g., `grok-4`) |
|
||||
|
||||
### How it Works
|
||||
|
||||
1. **File Retrieval**: Grokkit reads the content of the target file.
|
||||
2. **Contextual Analysis**: It prepares a prompt for Grok with the original file content and your instructions.
|
||||
3. **AI Generation**: Grok processes the request and returns the updated file content.
|
||||
4. **Interactive Preview**: Grokkit shows you a preview of the changes in a unified diff format.
|
||||
5. **Confirmation**: You review the changes and confirm before the file is overwritten.
|
||||
|
||||
### Best Practices
|
||||
|
||||
- **Specific Instructions**: The more specific you are, the better the result. Instead of "Fix the bug", try "Fix the race condition in the `UpdateState` method".
|
||||
- **Review carefully**: Always review the diff before applying changes, especially for complex refactors.
|
||||
- **Git workflow**: Commit your changes before using `edit` so you can easily revert if you're not happy with the result.
|
||||
- **Combine with Lint**: After editing, run `grokkit lint` to ensure the new code meets your project's standards.
|
||||
33
docs/user-guide/history.md
Normal file
33
docs/user-guide/history.md
Normal file
@ -0,0 +1,33 @@
|
||||
# 📜 History Guide
|
||||
|
||||
The `history` command provides a concise, AI-generated summary of your recent git history. It analyzes the last 10 commits to give you a high-level overview of recent developments.
|
||||
|
||||
### Key Features
|
||||
|
||||
- **Quick Summaries**: Get a quick catch-up on what's been happening in the repo.
|
||||
- **AI-Powered Analysis**: Grok translates individual commit messages into 3-5 high-level bullet points.
|
||||
- **Fast and Efficient**: A one-shot command for immediate results.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
grokkit history # Last 10 commits
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
| Flag | Description |
|
||||
|------|-------------|
|
||||
| `--model`, `-m` | Override the default model (e.g., `grok-4`) |
|
||||
|
||||
### How it Works
|
||||
|
||||
1. **Commit Log**: Grokkit runs `git log --oneline -10` to get the 10 most recent commits.
|
||||
2. **AI Analysis**: It sends this log to Grok with a prompt to summarize the history.
|
||||
3. **Bullet Point Summary**: Grok returns a 3-5 point summary of the most important changes.
|
||||
|
||||
### When to use History
|
||||
|
||||
- **Catching up**: Use `history` after pulling from the remote to see what's changed.
|
||||
- **Branch review**: Use it to quickly recall what you've worked on recently.
|
||||
- **Project overview**: Great for getting a quick status update on a project you haven't touched in a few days.
|
||||
52
docs/user-guide/index.md
Normal file
52
docs/user-guide/index.md
Normal file
@ -0,0 +1,52 @@
|
||||
# Grokkit User's Guide
|
||||
|
||||
Welcome to the full user documentation for **Grokkit** — a fast, native Go CLI for Grok that supercharges your coding workflow.
|
||||
|
||||
## Quick Navigation
|
||||
|
||||
### 🛡️ Safety & Change Management
|
||||
- **[Safety & Change Management](safety.md)** — Learn how Grokkit integrates with Git to keep your codebase stable and safe.
|
||||
|
||||
### 🔄 Workflows
|
||||
- **[Grokkit Workflows](workflows.md)** — Learn how to integrate Grokkit into your development cycle effectively.
|
||||
|
||||
### Core Commands
|
||||
- **[👨🍳 Recipe](recipe.md)** — The star of the show. Run powerful, transactional, multi-step LLM workflows defined in simple markdown files.
|
||||
- **[🤖 Agent](agent.md)** — Multi-file agent for complex refactorings and project-wide changes.
|
||||
- **[🏗️ Scaffold](scaffold.md)** — Safely generate new files with Grok preview + confirmation.
|
||||
- **[🧪 Testgen](testgen.md)** — Generate high-quality unit tests for Go, Python, C/C++, etc.
|
||||
- **[✏️ Edit](edit.md)** — In-place file editing with Grok (safe preview mode).
|
||||
|
||||
### Git Workflow Commands
|
||||
- **[✅ Commit](commit.md)** — AI-powered conventional commit messages with direct git commit.
|
||||
- **[📝 Commit-Msg](commit-msg.md)** — Generate AI-suggested conventional commit messages.
|
||||
- **[🗒️ Changelog](changelog.md)** — Generate CHANGELOG.md from git history.
|
||||
- **[📋 PR-Describe](pr-describe.md)** — Generate full PR descriptions.
|
||||
- **[📜 History](history.md)** — Summarize recent git history.
|
||||
|
||||
### Other Useful Commands
|
||||
- **[💬 Chat](chat.md)** — Full interactive chat with history and streaming
|
||||
- **[🤖 Query](query.md)** — One-shot programming-focused queries
|
||||
- **[🔍 Review](review.md)** — AI code review of the current repo/directory
|
||||
- **[🔧 Lint](lint.md)** — Lint + AI-suggested fixes
|
||||
- **[📖 Docs](docs.md)** — Generate documentation comments
|
||||
- **[Completion](completion.md)** — Generate shell completion scripts
|
||||
- **[🏷️ Version](version.md)** — Print version information
|
||||
|
||||
---
|
||||
|
||||
## Getting Started
|
||||
|
||||
See the [main README](../README.md) for installation and basic usage.
|
||||
|
||||
See the [Configuration Guide](../developer-guide/CONFIGURATION.md) for detailed information on how to configure Grokkit via environment variables and config files.
|
||||
|
||||
Want to dive deep? Start with the **[Recipe Guide](recipe.md)** — it's the most powerful and unique feature of Grokkit.
|
||||
|
||||
---
|
||||
|
||||
## Contributing to the Docs
|
||||
|
||||
Found something missing or unclear? Feel free to open a PR or issue on the repo.
|
||||
|
||||
Happy hacking!
|
||||
52
docs/user-guide/lint.md
Normal file
52
docs/user-guide/lint.md
Normal file
@ -0,0 +1,52 @@
|
||||
# 🔧 Lint Guide
|
||||
|
||||
The `lint` command is an AI-powered linter that identifies issues in your code and optionally provides AI-suggested fixes. It's designed to work with multiple languages and provide actionable suggestions.
|
||||
|
||||
### Key Features
|
||||
|
||||
- **Multi-language Support**: Automatically detects and lints Go, Python, C/C++, JS/TS, Rust, and more.
|
||||
- **AI-Suggested Fixes**: Not only finds issues but can also suggest how to fix them.
|
||||
- **Interactive Preview**: See the proposed fixes in a diff format before applying them.
|
||||
- **Clean Code**: Grok is instructed to provide minimal, idiomatic fixes that match your project's style.
|
||||
|
||||
### Usage
|
||||
|
||||
Automatically detect language, run linter, and apply AI-suggested fixes.
|
||||
|
||||
```bash
|
||||
# Just check for issues (no fixes)
|
||||
grokkit lint main.go --dry-run
|
||||
|
||||
# Interactive fix (preview + confirmation)
|
||||
grokkit lint app.py
|
||||
|
||||
# Auto-fix without confirmation
|
||||
grokkit lint server.js --auto-fix
|
||||
|
||||
# Use specific model
|
||||
grokkit lint script.rb -m grok-4
|
||||
```
|
||||
|
||||
### Supported languages
|
||||
|
||||
- **Go** (golangci-lint, go vet)
|
||||
- **Python** (pylint, flake8, ruff)
|
||||
- **JavaScript/JSX** (eslint)
|
||||
- **TypeScript/TSX** (eslint, tsc)
|
||||
- **Rust** (clippy)
|
||||
- **Ruby** (rubocop)
|
||||
- **Java** (checkstyle)
|
||||
- **C/C++** (clang-tidy)
|
||||
- **Shell** (shellcheck)
|
||||
|
||||
### Safety features
|
||||
|
||||
- Shows preview of fixes
|
||||
- Verifies fixes by re-running linter
|
||||
- Requires confirmation (unless `--auto-fix`)
|
||||
|
||||
### Best Practices
|
||||
|
||||
- **Lint early and often**: Catching issues early is much easier than fixing them later.
|
||||
- **Review fixes carefully**: AI-suggested fixes are usually excellent, but always review them to ensure they align with your project's specific requirements.
|
||||
- **Combine with Review**: Use `lint` for basic issues and `grokkit review` for deeper logic analysis.
|
||||
49
docs/user-guide/pr-describe.md
Normal file
49
docs/user-guide/pr-describe.md
Normal file
@ -0,0 +1,49 @@
|
||||
# 📋 PR-Describe Guide
|
||||
|
||||
The `pr-describe` command generates a professional Pull Request title and a detailed body by analyzing the diff between your current branch and a base branch.
|
||||
|
||||
### Key Features
|
||||
|
||||
- **Automated PR Descriptions**: Saves time by drafting the entire PR description for you.
|
||||
- **Context-Aware**: Analyzes every change on your branch to explain the "what" and "why."
|
||||
- **Professional Format**: Includes sections for changes, motivation, and testing notes.
|
||||
- **Customizable Base**: Compare against any branch (defaults to `master`).
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
# From current branch vs master
|
||||
grokkit pr-describe
|
||||
|
||||
# Compare against a specific base branch
|
||||
grokkit pr-describe --base main
|
||||
|
||||
# With specific model
|
||||
grokkit pr-describe -m grok-4
|
||||
```
|
||||
|
||||
**Output includes:**
|
||||
- Title suggestion
|
||||
- Summary of changes
|
||||
- Motivation/context
|
||||
- Testing notes
|
||||
|
||||
### Options
|
||||
|
||||
| Flag | Description |
|
||||
|------|-------------|
|
||||
| `--base`, `-b` | Base branch to compare against (default: `master`) |
|
||||
| `--model`, `-m` | Override the default model (e.g., `grok-4`) |
|
||||
|
||||
### How it Works
|
||||
|
||||
1. **Diff Generation**: Grokkit runs `git diff <base>..HEAD` to identify all changes on your current branch.
|
||||
2. **AI Analysis**: It sends the full diff to Grok with a specialized prompt for PR generation.
|
||||
3. **Structured Output**: Grok returns a professional PR title and body.
|
||||
4. **Streaming Results**: You see the description as it's being generated.
|
||||
|
||||
### Best Practices
|
||||
|
||||
- **Keep branches focused**: PR descriptions are most effective when the branch addresses a single feature or fix.
|
||||
- **Review and edit**: Use the AI-generated description as a strong starting point, then add any specific internal context or links (e.g., Jira tickets).
|
||||
- **Model selection**: For large PRs with many changes, use a more powerful model like `grok-4` for a better high-level summary.
|
||||
38
docs/user-guide/query.md
Normal file
38
docs/user-guide/query.md
Normal file
@ -0,0 +1,38 @@
|
||||
# 🤖 Query Guide
|
||||
|
||||
The `query` command is a one-shot, non-interactive interface for asking Grok programming-focused questions. It's ideal for quick inquiries where you don't need a full chat history.
|
||||
|
||||
### Why use Query?
|
||||
|
||||
- **Fast**: Get a direct answer to a single question.
|
||||
- **Minimalist**: No chat history or context overhead.
|
||||
- **Focused**: Perfect for "How do I do X in Go?" or "Explain this regex."
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
# Basic usage
|
||||
grokkit query "How do I sort a slice of structs by a field in Go?"
|
||||
|
||||
# Longer, more detailed answer
|
||||
grokkit query --wordy "Explain how Go's context package works with cancellation"
|
||||
```
|
||||
|
||||
### Features
|
||||
|
||||
- **Default mode** is concise, factual, and actionable.
|
||||
- **`--wordy` flag** gives longer, more explanatory answers.
|
||||
- **Fast model** used by default for speed (non-reasoning).
|
||||
- **No persistent history** or interactive chat UI.
|
||||
|
||||
### Options
|
||||
|
||||
| Flag | Description |
|
||||
|------|-------------|
|
||||
| `--wordy` | Give a longer, more detailed answer |
|
||||
| `--model`, `-m` | Override the default model (e.g., `grok-4`) |
|
||||
|
||||
### When to use Query vs. Chat
|
||||
|
||||
- Use **Query** for simple, independent questions that don't require follow-up.
|
||||
- Use **Chat** when you need to have a back-and-forth conversation or want Grok to remember previous context.
|
||||
102
docs/user-guide/recipe.md
Normal file
102
docs/user-guide/recipe.md
Normal file
@ -0,0 +1,102 @@
|
||||
# 👨🍳 Recipe Guide
|
||||
|
||||
The `recipe` command is the most powerful feature in Grokkit. It lets you define sophisticated, multi-step, transactional workflows that Grok executes step-by-step with full transparency and user approval.
|
||||
|
||||
### What is a Recipe?
|
||||
|
||||
A recipe is a plain markdown file (`.md`) that lives in:
|
||||
- `.grokkit/recipes/` (project-local, preferred)
|
||||
- `~/.local/share/grokkit/recipes/` (global)
|
||||
|
||||
Each recipe contains:
|
||||
- YAML frontmatter (metadata + parameters)
|
||||
- Clear, numbered steps written in natural language
|
||||
- Optional final summary
|
||||
|
||||
### Usage
|
||||
|
||||
Execute transactional "recipes" for complex, multi-step AI workflows.
|
||||
|
||||
```bash
|
||||
# Run a project-local recipe
|
||||
grokkit recipe run result-refactor
|
||||
|
||||
# Pass parameters to the recipe
|
||||
grokkit recipe run result-refactor -p package_path=internal/git -p dry_run=false
|
||||
|
||||
# Run a specific recipe file
|
||||
grokkit recipe run ./my-custom-recipe.md
|
||||
```
|
||||
|
||||
### Recipe System
|
||||
|
||||
- **Local Recipes**: Stored in `.grokkit/recipes/*.md`.
|
||||
- **Global Recipes**: Stored in `~/.local/share/grokkit/recipes/*.md`.
|
||||
- Recipes are **markdown-based** with YAML frontmatter for parameters and configuration.
|
||||
|
||||
### Anatomy of a Recipe
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: result-refactor
|
||||
description: Convert naked errors to Result[T] pattern
|
||||
version: 1.0
|
||||
|
||||
parameters:
|
||||
package_path:
|
||||
type: string
|
||||
default: internal
|
||||
description: Package to refactor
|
||||
|
||||
project_languages:
|
||||
- go
|
||||
|
||||
extensions:
|
||||
go:
|
||||
- .go
|
||||
|
||||
search_pattern: "if err != nil"
|
||||
|
||||
allowed_shell_commands:
|
||||
- go test
|
||||
- go vet
|
||||
---
|
||||
|
||||
# Result[T] Refactoring
|
||||
|
||||
**Overview**
|
||||
Converts traditional Go error handling to the modern Result[T] monadic style.
|
||||
|
||||
## Execution Steps
|
||||
|
||||
### Step 1: Discover files
|
||||
**Objective:** Find files that need refactoring.
|
||||
**Instructions:** Recursively scan `{{.package_path}}`...
|
||||
**Expected output:** Clean list of full file paths.
|
||||
|
||||
### Step 2: Read-Only Shell: Explore project structure
|
||||
**Objective:** Get additional context if needed.
|
||||
**Instructions:** Use safe read-only commands...
|
||||
|
||||
### Step 3: Refactor each file
|
||||
...
|
||||
|
||||
### Step 4: Apply or patch
|
||||
...
|
||||
```
|
||||
|
||||
### Key Features
|
||||
|
||||
* Parameters — override with --param key=value
|
||||
* Read-only shell access — use steps titled "Read-Only Shell..." for safe ls, cat, tree, find, rg, jq, etc.
|
||||
* User confirmation — you approve every shell command
|
||||
* Dry-run safety — most recipes support dry_run=true by default
|
||||
* Transactional — you see every step and can stop at any time
|
||||
|
||||
### Best Practices
|
||||
|
||||
* Keep recipes focused (one clear goal)
|
||||
* Use "Read-Only Shell" steps when the LLM needs context
|
||||
* Always include a good search_pattern for discovery
|
||||
* Document expected output clearly in each step
|
||||
|
||||
48
docs/user-guide/review.md
Normal file
48
docs/user-guide/review.md
Normal file
@ -0,0 +1,48 @@
|
||||
# 🔍 Review Guide
|
||||
|
||||
The `review` command provides an AI-powered code review of your current repository or a specific directory. It analyzes your changes (git diff) and repository status to provide meaningful feedback.
|
||||
|
||||
### Key Features
|
||||
|
||||
- **Automated Code Review**: Get an instant review of your changes without waiting for a teammate.
|
||||
- **Context-Aware**: Analyzes your staged and unstaged changes using `git diff` and `git status`.
|
||||
- **Actionable Feedback**: Provides a concise summary and 3-5 specific, actionable improvements.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
# Review staged changes
|
||||
git add feature.go
|
||||
grokkit review
|
||||
|
||||
# Review all changes
|
||||
grokkit review
|
||||
|
||||
# Get detailed review
|
||||
grokkit review --debug # See API timing info
|
||||
```
|
||||
|
||||
**Output includes:**
|
||||
- Summary of changes
|
||||
- 3-5 actionable improvements
|
||||
- Potential bugs or issues
|
||||
- Best practice suggestions
|
||||
|
||||
### Options
|
||||
|
||||
| Flag | Description |
|
||||
|------|-------------|
|
||||
| `--model`, `-m` | Override the default model (e.g., `grok-4`) |
|
||||
|
||||
### How it Works
|
||||
|
||||
1. **Change Analysis**: Grokkit runs `git status` and `git diff` to see what you've changed.
|
||||
2. **Review Request**: It sends these changes to Grok with a specialized code review prompt.
|
||||
3. **AI Evaluation**: Grok reviews the code for logic errors, style issues, and potential bugs.
|
||||
4. **Summary and Tips**: You get a high-level summary and specific suggestions for improvement.
|
||||
|
||||
### Best Practices
|
||||
|
||||
- **Review small diffs**: For the most focused and useful feedback, run `review` frequently on smaller sets of changes.
|
||||
- **Combine with Lint**: Run `grokkit lint` first to catch basic syntax and style issues, then use `review` for deeper logic analysis.
|
||||
- **Model selection**: More complex changes may benefit from the deeper reasoning capabilities of `grok-4`.
|
||||
31
docs/user-guide/safety.md
Normal file
31
docs/user-guide/safety.md
Normal file
@ -0,0 +1,31 @@
|
||||
# 🛡️ Safety & Change Management
|
||||
|
||||
Grokkit is designed to work seamlessly with Git. Rather than creating redundant `.bak` files, we lean on Git's powerful version control to manage changes and rollbacks.
|
||||
|
||||
## The Safety Workflow
|
||||
|
||||
1. **Preview**: Every command that modifies files (like `edit`, `lint`, `docs`) shows a diff-style preview first.
|
||||
2. **Confirm**: You must explicitly confirm (`y/N`) before any changes are written to disk.
|
||||
3. **Git Integration**: Use Git to manage the "pre-staged," "staged," and "committed" degrees of change.
|
||||
|
||||
## Managing Undesired Changes
|
||||
|
||||
If you've applied a change that you don't like, Git makes it easy to roll back:
|
||||
|
||||
- **Unstaged changes**: If you haven't `git add`-ed the changes yet:
|
||||
```bash
|
||||
git restore <file>
|
||||
```
|
||||
- **Staged changes**: If you've already staged the changes:
|
||||
```bash
|
||||
git restore --staged <file>
|
||||
git restore <file>
|
||||
```
|
||||
- **Committed changes**: If you've already committed the changes:
|
||||
```bash
|
||||
git revert HEAD
|
||||
# or to reset to a previous state:
|
||||
git reset --hard HEAD~1
|
||||
```
|
||||
|
||||
By using Git, you have a complete audit trail and multiple levels of undo, ensuring your codebase remains stable even when experimenting with AI-driven refactors.
|
||||
50
docs/user-guide/scaffold.md
Normal file
50
docs/user-guide/scaffold.md
Normal file
@ -0,0 +1,50 @@
|
||||
# 🏗️ Scaffold Guide
|
||||
|
||||
The `scaffold` command allows you to quickly generate new files using AI that matches your project's existing coding style, naming conventions, and patterns.
|
||||
|
||||
### Features
|
||||
|
||||
- **Project context harvesting**: Analyzes siblings and directory structure for style matching.
|
||||
- **Optional test generation**: Use `--with-tests` to generate a basic test file.
|
||||
- **Safety checks**: Won't overwrite existing files without `--force`.
|
||||
- **Language detection** and overrides (`--lang`).
|
||||
|
||||
### Usage
|
||||
|
||||
Scaffold a new file with Grok using project context for style matching.
|
||||
|
||||
```bash
|
||||
# Basic usage
|
||||
grokkit scaffold internal/git/utils.go "git wrapper for listing tags"
|
||||
|
||||
# Scaffold with a basic test file
|
||||
grokkit scaffold app.py "Flask route for health checks" --with-tests
|
||||
|
||||
# Preview without writing
|
||||
grokkit scaffold main.go "simple CLI entrypoint" --dry-run
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
| Flag | Description |
|
||||
|------|-------------|
|
||||
| `--with-tests` | Also generate a basic test file (e.g., `utils_test.go`) |
|
||||
| `--dry-run` | Preview the generated code without writing any files |
|
||||
| `--yes`, `-y` | Skip the confirmation prompt and write files immediately |
|
||||
| `--force` | Overwrite the destination file if it already exists |
|
||||
| `--lang` | Manually specify the language (e.g., "Go", "Python", "TypeScript") |
|
||||
| `--model`, `-m` | Override the default model (e.g., `grok-4`) |
|
||||
|
||||
### How it Works
|
||||
|
||||
1. **Context Harvesting**: Grokkit reads existing files in the same directory to understand your project's "vibe."
|
||||
2. **Language Detection**: It automatically detects the language based on the file extension.
|
||||
3. **AI Generation**: It sends the description and project context to Grok.
|
||||
4. **Style Matching**: Grok is instructed to match the project's exact style.
|
||||
5. **Confirmation**: You review the code and confirm before it's saved.
|
||||
|
||||
### Tips for Better Results
|
||||
|
||||
- **Be descriptive**: Instead of "a logger", try "a structured logger using slog that writes to a rotating file".
|
||||
- **Use extensions**: Ensure your file path has the correct extension so Grokkit can detect the language.
|
||||
- **Project layout**: Run `scaffold` in a directory that already contains some code for best style matching.
|
||||
49
docs/user-guide/testgen.md
Normal file
49
docs/user-guide/testgen.md
Normal file
@ -0,0 +1,49 @@
|
||||
# 🧪 Testgen Guide
|
||||
|
||||
The `testgen` command generates high-quality unit tests for your existing code files using AI. It's designed to match your project's testing conventions and use the most modern practices for each language.
|
||||
|
||||
### Benefits
|
||||
|
||||
- **Go**: Table-driven `t.Parallel()` matching codebase.
|
||||
- **Python**: Pytest with `@parametrize`.
|
||||
- **C**: Check framework suites.
|
||||
- **C++**: Google Test `EXPECT_*`.
|
||||
- **Boosts coverage**; safe preview.
|
||||
|
||||
### Usage
|
||||
|
||||
Generate comprehensive unit tests for Go/Python/C/C++ files using AI.
|
||||
|
||||
```bash
|
||||
grokkit testgen internal/grok/client.go
|
||||
grokkit testgen app.py --yes
|
||||
grokkit testgen foo.c bar.cpp
|
||||
```
|
||||
|
||||
### Safety Features
|
||||
|
||||
- **Lang detection** via `internal/linter`.
|
||||
- **Unified diff preview**.
|
||||
- **Y/N confirmation** (`--yes` to auto-confirm).
|
||||
|
||||
### Options
|
||||
|
||||
| Flag | Description |
|
||||
|------|-------------|
|
||||
| `--yes`, `-y` | Skip the confirmation prompt and write tests immediately |
|
||||
| `--model`, `-m` | Override the default model (e.g., `grok-4`) |
|
||||
|
||||
### How it Works
|
||||
|
||||
1. **Language Detection**: Grokkit detects the language using its internal linter.
|
||||
2. **Context Analysis**: It reads the source file and any existing test file.
|
||||
3. **AI Generation**: It sends the source code to Grok with a language-specific system prompt.
|
||||
4. **Style Matching**: Grok is instructed to use modern idioms and match the project's testing style.
|
||||
5. **Interactive Diff**: If a test file already exists, it shows a diff of the proposed changes.
|
||||
|
||||
### Best Practices
|
||||
|
||||
- **Start with unit tests**: Test individual functions and methods.
|
||||
- **Run tests immediately**: After `testgen` completes, run `make test` or your language-specific test runner to verify the generated tests.
|
||||
- **Review for accuracy**: AI-generated tests are a great starting point, but always review them to ensure the logic and assertions are correct.
|
||||
- **Coverage**: Use `make test-cover` (for Go) to see how much your new tests have improved your coverage.
|
||||
21
docs/user-guide/version.md
Normal file
21
docs/user-guide/version.md
Normal file
@ -0,0 +1,21 @@
|
||||
# 🏷️ Version Guide
|
||||
|
||||
The `version` command prints the version, commit hash, and build date for the `grokkit` binary.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
grokkit version
|
||||
```
|
||||
|
||||
### Output
|
||||
|
||||
```bash
|
||||
grokkit version v0.1.0 (commit ab12cd3)
|
||||
```
|
||||
|
||||
### Why use Version?
|
||||
|
||||
- **Troubleshooting**: When reporting an issue, providing the version helps maintainers identify the state of the code you are using.
|
||||
- **Verification**: Confirm that you have successfully installed the latest version or that your local build is up-to-date.
|
||||
- **Consistency**: Ensure all team members are using the same version of the tool for reproducible results.
|
||||
113
docs/user-guide/workflows.md
Normal file
113
docs/user-guide/workflows.md
Normal file
@ -0,0 +1,113 @@
|
||||
# 🔄 Grokkit Workflows
|
||||
|
||||
Learn how to integrate Grokkit into your development cycle effectively.
|
||||
|
||||
## Git Workflow Integration
|
||||
|
||||
The standard way to use Grokkit for your daily git tasks:
|
||||
|
||||
```bash
|
||||
# 1. Make changes
|
||||
vim src/api.go
|
||||
|
||||
# 2. Review with AI
|
||||
git add src/api.go
|
||||
grokkit review
|
||||
|
||||
# 3. Fix issues, then commit
|
||||
git add src/api.go
|
||||
grokkit commit
|
||||
|
||||
# 4. Generate PR description
|
||||
grokkit pr-describe
|
||||
```
|
||||
|
||||
## Code Refactoring Workflow
|
||||
|
||||
Use Grokkit to plan and execute larger code changes:
|
||||
|
||||
```bash
|
||||
# 1. Chat to plan approach
|
||||
grokkit chat
|
||||
> "How should I refactor this authentication code to use middleware?"
|
||||
|
||||
# 2. Apply changes with edit
|
||||
grokkit edit auth.go "implement middleware pattern as discussed"
|
||||
|
||||
# 3. Review changes
|
||||
grokkit review
|
||||
|
||||
# 4. Commit
|
||||
grokkit commit
|
||||
```
|
||||
|
||||
## Debugging Workflow
|
||||
|
||||
Quickly identify and fix bugs using a combination of chat and editing:
|
||||
|
||||
```bash
|
||||
# 1. Describe issue in chat
|
||||
grokkit chat --debug
|
||||
> "I'm getting a nil pointer error in handler.go:42"
|
||||
|
||||
# 2. Apply suggested fixes
|
||||
grokkit edit handler.go "add nil checks before dereferencing user object"
|
||||
|
||||
# 3. Verify and commit
|
||||
grokkit review
|
||||
grokkit commit
|
||||
```
|
||||
|
||||
## Batch File Editing
|
||||
|
||||
Automate repetitive edits across many files:
|
||||
|
||||
```bash
|
||||
# Edit multiple files with consistent changes
|
||||
for file in src/*.go; do
|
||||
grokkit edit "$file" "add context parameter to all exported functions"
|
||||
done
|
||||
|
||||
# Review all changes together
|
||||
grokkit review
|
||||
```
|
||||
|
||||
## Code Quality Workflow
|
||||
|
||||
Maintain high standards with AI-assisted linting and documentation:
|
||||
|
||||
```bash
|
||||
# 1. Check a file for linting issues
|
||||
grokkit lint app.py --dry-run
|
||||
|
||||
# 2. Apply AI-suggested fixes with preview
|
||||
grokkit lint app.py
|
||||
|
||||
# 3. Auto-fix multiple files
|
||||
for file in src/*.js; do
|
||||
grokkit lint "$file" --auto-fix
|
||||
done
|
||||
|
||||
# 4. Review and commit
|
||||
grokkit review
|
||||
grokkit commit
|
||||
```
|
||||
|
||||
## Documentation Generation Workflow
|
||||
|
||||
Generate comprehensive documentation for your project in seconds:
|
||||
|
||||
```bash
|
||||
# 1. Preview docs for a single file
|
||||
grokkit docs internal/api/handler.go
|
||||
|
||||
# 2. Batch-document a package
|
||||
grokkit docs cmd/*.go --auto-apply
|
||||
|
||||
# 3. Document across languages in one pass
|
||||
grokkit docs lib/utils.py src/helpers.ts --auto-apply
|
||||
|
||||
# 4. Review and commit
|
||||
grokkit review
|
||||
grokkit commit
|
||||
```
|
||||
183
internal/recipe/loader.go
Normal file
183
internal/recipe/loader.go
Normal file
@ -0,0 +1,183 @@
|
||||
package recipe
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"text/template"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// Global safe read-only whitelist
|
||||
// LoadSafeCommands reads the user's safe shell commands config (with fallback)
|
||||
var safeCommands = sync.OnceValue(func() map[string]bool {
|
||||
cfgPath := filepath.Join(os.Getenv("HOME"), ".config", "grokkit", "safe_shell_commands.yaml")
|
||||
|
||||
data, err := os.ReadFile(cfgPath)
|
||||
if err != nil {
|
||||
// Fallback to a built-in safe list
|
||||
fmt.Println("Could not read safe shell commands config, using built-in fallback")
|
||||
return map[string]bool{
|
||||
"ls": true, "pwd": true, "cat": true, "tree": true,
|
||||
"find": true, "grep": true, "rg": true,
|
||||
"git status": true, "git log": true, "git diff": true, "git branch": true,
|
||||
"go test": true, "go vet": true, "go fmt": true, "go mod tidy": true,
|
||||
"make test": true,
|
||||
"pytest": true, "poetry run pytest": true, "ctest": true,
|
||||
"python -m pytest": true, "python": true, "poetry": true,
|
||||
}
|
||||
|
||||
}
|
||||
fmt.Println("Using safe shell commands config:", cfgPath)
|
||||
|
||||
var cfg struct {
|
||||
SafeCommands []string `yaml:"safe_commands"`
|
||||
}
|
||||
err = yaml.Unmarshal(data, &cfg)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
m := make(map[string]bool)
|
||||
for _, c := range cfg.SafeCommands {
|
||||
m[strings.ToLower(strings.TrimSpace(c))] = true
|
||||
}
|
||||
return m
|
||||
})
|
||||
|
||||
var (
|
||||
// stepRe still finds the headings (this one is solid)
|
||||
stepRe = regexp.MustCompile(`(?m)^### Step (\d+): (.+)$`)
|
||||
)
|
||||
|
||||
func Load(path string, userParams map[string]any) (*Recipe, error) {
|
||||
b, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
parts := bytes.SplitN(b, []byte("---"), 3)
|
||||
if len(parts) < 3 {
|
||||
return nil, fmt.Errorf("missing YAML frontmatter")
|
||||
}
|
||||
|
||||
var r Recipe
|
||||
if err := yaml.Unmarshal(parts[1], &r); err != nil {
|
||||
return nil, fmt.Errorf("yaml parse: %w", err)
|
||||
}
|
||||
|
||||
// === SAFETY CHECK using user-configurable whitelist ===
|
||||
safeMap := safeCommands()
|
||||
for _, cmd := range r.AllowedShellCommands {
|
||||
trimmed := strings.ToLower(strings.TrimSpace(cmd))
|
||||
|
||||
allowed := false
|
||||
for safe := range safeMap {
|
||||
safeTrim := strings.ToLower(strings.TrimSpace(safe))
|
||||
|
||||
// Match exact command OR command followed by space + arguments
|
||||
if trimmed == safeTrim || strings.HasPrefix(trimmed, safeTrim+" ") {
|
||||
allowed = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !allowed {
|
||||
return nil, fmt.Errorf("\u001B[31mRecipe contains unsafe shell command: %q. "+
|
||||
"Remove or replace the dangerous command in your recipe.\u001B[0m", cmd)
|
||||
}
|
||||
}
|
||||
|
||||
// Apply defaults + user --param overrides
|
||||
if r.Parameters == nil {
|
||||
r.Parameters = make(map[string]Parameter)
|
||||
}
|
||||
r.ResolvedParams = make(map[string]any)
|
||||
for name, p := range r.Parameters {
|
||||
if v, ok := userParams[name]; ok {
|
||||
r.ResolvedParams[name] = v
|
||||
} else if p.Default != nil {
|
||||
r.ResolvedParams[name] = p.Default
|
||||
}
|
||||
}
|
||||
|
||||
// Render templates with resolved values
|
||||
tpl, err := template.New("recipe").Parse(string(parts[2]))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var rendered bytes.Buffer
|
||||
if err := tpl.Execute(&rendered, r.ResolvedParams); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
body := rendered.String()
|
||||
|
||||
// Extract Overview
|
||||
if idx := strings.Index(body, "## Execution Steps"); idx != -1 {
|
||||
r.Overview = strings.TrimSpace(body[:idx])
|
||||
}
|
||||
|
||||
// Extract steps with robust multi-line parsing
|
||||
matches := stepRe.FindAllStringSubmatch(body, -1)
|
||||
for i, m := range matches {
|
||||
stepNum := i + 1
|
||||
title := m[2]
|
||||
|
||||
start := strings.Index(body, m[0])
|
||||
end := len(body)
|
||||
if i+1 < len(matches) {
|
||||
nextStart := strings.Index(body[start:], matches[i+1][0])
|
||||
end = start + nextStart
|
||||
}
|
||||
|
||||
section := body[start:end]
|
||||
|
||||
step := Step{Number: stepNum, Title: title}
|
||||
|
||||
// Simple, reliable label-based parsing (handles multi-line + blank lines)
|
||||
labels := []string{"**Objective:**", "**Instructions:**", "**Expected output:**"}
|
||||
for _, label := range labels {
|
||||
labelStart := strings.Index(section, label)
|
||||
if labelStart == -1 {
|
||||
continue
|
||||
}
|
||||
contentStart := labelStart + len(label)
|
||||
contentEnd := len(section)
|
||||
|
||||
// Find next label or end of section
|
||||
for _, nextLabel := range labels {
|
||||
next := strings.Index(section[contentStart:], nextLabel)
|
||||
if next != -1 {
|
||||
contentEnd = contentStart + next
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
content := strings.TrimSpace(section[contentStart:contentEnd])
|
||||
|
||||
switch label {
|
||||
case "**Objective:**":
|
||||
step.Objective = content
|
||||
case "**Instructions:**":
|
||||
step.Instructions = content
|
||||
case "**Expected output:**":
|
||||
step.Expected = content
|
||||
}
|
||||
}
|
||||
|
||||
r.Steps = append(r.Steps, step)
|
||||
}
|
||||
|
||||
// Final summary (everything after last step)
|
||||
if len(matches) > 0 {
|
||||
lastMatch := matches[len(matches)-1][0]
|
||||
lastIdx := strings.LastIndex(body, lastMatch)
|
||||
r.FinalSummaryPrompt = strings.TrimSpace(body[lastIdx+len(lastMatch):])
|
||||
}
|
||||
|
||||
return &r, nil
|
||||
}
|
||||
385
internal/recipe/runner.go
Normal file
385
internal/recipe/runner.go
Normal file
@ -0,0 +1,385 @@
|
||||
package recipe
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"gmgauthier.com/grokkit/internal/grok"
|
||||
)
|
||||
|
||||
type Runner struct {
|
||||
Recipe *Recipe
|
||||
Client *grok.Client
|
||||
Model string
|
||||
}
|
||||
|
||||
func NewRunner(r *Recipe, client *grok.Client, model string) *Runner {
|
||||
return &Runner{Recipe: r, Client: client, Model: model}
|
||||
}
|
||||
|
||||
func (r *Runner) Run() error {
|
||||
fmt.Printf("🍳 Starting recipe: %s v%s\n\n", r.Recipe.Name, r.Recipe.Version)
|
||||
|
||||
workDir := r.resolveWorkDir()
|
||||
|
||||
var previousResults []string
|
||||
var refactorJSONs []string
|
||||
|
||||
for _, step := range r.Recipe.Steps {
|
||||
fmt.Printf("Step %d/%d: %s\n", step.Number, len(r.Recipe.Steps), step.Title)
|
||||
|
||||
titleLower := strings.ToLower(step.Title)
|
||||
|
||||
switch {
|
||||
case strings.Contains(titleLower, "discover") || strings.Contains(titleLower, "find"):
|
||||
files := r.discoverFiles(workDir)
|
||||
result := strings.Join(files, "\n")
|
||||
previousResults = append(previousResults, "Discovered files:\n"+result)
|
||||
fmt.Println(result)
|
||||
|
||||
case strings.Contains(titleLower, "refactor"):
|
||||
r.refactorFiles(previousResults, &refactorJSONs)
|
||||
continue
|
||||
|
||||
case strings.Contains(titleLower, "apply") || strings.Contains(titleLower, "patch"):
|
||||
r.handleApplyStep(refactorJSONs)
|
||||
continue
|
||||
|
||||
// Explicit trigger for read-only shell
|
||||
case strings.Contains(titleLower, "read-only shell") || strings.Contains(titleLower, "shell read-only"):
|
||||
r.executeReadOnlyShell(step, previousResults)
|
||||
continue
|
||||
|
||||
default:
|
||||
prompt := fmt.Sprintf(`Recipe Overview:
|
||||
%s
|
||||
|
||||
Previous step results (for context):
|
||||
%s
|
||||
|
||||
=== CURRENT STEP ===
|
||||
Objective: %s
|
||||
Instructions: %s
|
||||
Expected output format: %s
|
||||
|
||||
Execute this step now. Respond ONLY with the expected output format — no explanations, no extra text.`,
|
||||
r.Recipe.Overview,
|
||||
strings.Join(previousResults, "\n\n---\n\n"),
|
||||
step.Objective,
|
||||
step.Instructions,
|
||||
step.Expected)
|
||||
|
||||
messages := []map[string]string{
|
||||
{"role": "system", "content": "You are Grok, built by xAI. Precise expert programmer and refactoring assistant."},
|
||||
{"role": "user", "content": prompt},
|
||||
}
|
||||
|
||||
response := r.Client.Stream(messages, r.Model)
|
||||
fmt.Println()
|
||||
|
||||
previousResults = append(previousResults, fmt.Sprintf("Step %d result:\n%s", step.Number, response))
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("\n✅ Recipe complete.")
|
||||
return nil
|
||||
}
|
||||
|
||||
// resolveWorkDir expands ~ and makes absolute
|
||||
func (r *Runner) resolveWorkDir() string {
|
||||
root := "."
|
||||
if v, ok := r.Recipe.ResolvedParams["package_path"]; ok {
|
||||
if s, ok := v.(string); ok && s != "" {
|
||||
root = s
|
||||
}
|
||||
}
|
||||
|
||||
if strings.HasPrefix(root, "~/") {
|
||||
home, _ := os.UserHomeDir()
|
||||
root = filepath.Join(home, root[2:])
|
||||
} else if root == "~" {
|
||||
root, _ = os.UserHomeDir()
|
||||
}
|
||||
|
||||
abs, _ := filepath.Abs(root)
|
||||
return abs
|
||||
}
|
||||
|
||||
// discoverFiles — uses resolved workDir
|
||||
func (r *Runner) discoverFiles(workDir string) []string {
|
||||
var files []string
|
||||
|
||||
allowedExt := make(map[string]bool)
|
||||
for _, lang := range r.Recipe.ProjectLanguages {
|
||||
if exts, ok := r.Recipe.Extensions[lang]; ok {
|
||||
for _, ext := range exts {
|
||||
allowedExt[ext] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
searchFor := r.Recipe.SearchPattern
|
||||
if searchFor == "" {
|
||||
searchFor = "if err != nil"
|
||||
}
|
||||
|
||||
_ = filepath.WalkDir(workDir, func(path string, d os.DirEntry, err error) error {
|
||||
if err != nil || d.IsDir() {
|
||||
return nil
|
||||
}
|
||||
if allowedExt[filepath.Ext(path)] {
|
||||
b, _ := os.ReadFile(path)
|
||||
if strings.Contains(string(b), searchFor) {
|
||||
files = append(files, path)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if len(files) == 0 {
|
||||
files = append(files, "No files found matching the criteria.")
|
||||
}
|
||||
return files
|
||||
}
|
||||
|
||||
// refactorFiles — one file at a time
|
||||
func (r *Runner) refactorFiles(previousResults []string, refactorJSONs *[]string) {
|
||||
discoveredLine := previousResults[len(previousResults)-1]
|
||||
lines := strings.Split(discoveredLine, "\n")
|
||||
|
||||
for _, line := range lines {
|
||||
filePath := strings.TrimSpace(line)
|
||||
if filePath == "" || strings.HasPrefix(filePath, "Discovered") || filePath == "No files found matching the criteria." {
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf(" Refactoring %s...\n", filePath)
|
||||
|
||||
content, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
fmt.Printf(" ❌ Could not read %s\n", filePath)
|
||||
continue
|
||||
}
|
||||
|
||||
prompt := fmt.Sprintf(`Refactor the following file to use Result[T] instead of naked errors.
|
||||
Follow existing style and preserve all comments.
|
||||
Return ONLY this exact JSON (no extra text, no markdown):
|
||||
|
||||
{
|
||||
"file": "%s",
|
||||
"content": "the complete refactored file here"
|
||||
}
|
||||
|
||||
Original file:
|
||||
%s`, filePath, string(content))
|
||||
|
||||
messages := []map[string]string{
|
||||
{"role": "system", "content": "You are Grok, built by xAI. Precise expert programmer and refactoring assistant."},
|
||||
{"role": "user", "content": prompt},
|
||||
}
|
||||
|
||||
response := r.Client.Stream(messages, r.Model)
|
||||
fmt.Println()
|
||||
|
||||
*refactorJSONs = append(*refactorJSONs, response)
|
||||
}
|
||||
}
|
||||
|
||||
// handleApplyStep stays as you have it (or your latest version)
|
||||
func (r *Runner) handleApplyStep(refactorJSONs []string) {
|
||||
if len(refactorJSONs) == 0 {
|
||||
fmt.Println(" ⚠️ No refactored files to apply — skipping.")
|
||||
return
|
||||
}
|
||||
|
||||
var allChanges []FileChange
|
||||
for _, jsonStr := range refactorJSONs {
|
||||
start := strings.Index(jsonStr, "{")
|
||||
end := strings.LastIndex(jsonStr, "}") + 1
|
||||
if start == -1 {
|
||||
continue
|
||||
}
|
||||
|
||||
var ch FileChange
|
||||
if err := json.Unmarshal([]byte(jsonStr[start:end]), &ch); err == nil && ch.File != "" {
|
||||
allChanges = append(allChanges, ch)
|
||||
}
|
||||
}
|
||||
|
||||
if len(allChanges) == 0 {
|
||||
fmt.Println(" ⚠️ No valid file changes found — skipping.")
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(" 📄 Dry-run mode: creating patch file...")
|
||||
patchPath := filepath.Join(".", "recipe-refactor.patch")
|
||||
if err := createUnifiedPatch(allChanges, patchPath); err != nil {
|
||||
fmt.Printf(" ❌ Failed to create patch: %v\n", err)
|
||||
return
|
||||
}
|
||||
fmt.Printf(" ✅ Patch created: %s\n", patchPath)
|
||||
fmt.Println(" Review it, then run with dry_run=false to apply.")
|
||||
}
|
||||
|
||||
type FileChange struct {
|
||||
File string `json:"file"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
func createUnifiedPatch(changes []FileChange, patchPath string) error {
|
||||
f, err := os.Create(patchPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func(f *os.File) {
|
||||
err := f.Close()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}(f)
|
||||
|
||||
for _, ch := range changes {
|
||||
_, err := fmt.Fprintf(f, "--- %s\n+++ %s\n@@ -0,0 +1,%d @@\n", ch.File, ch.File, strings.Count(ch.Content, "\n")+1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, line := range strings.Split(ch.Content, "\n") {
|
||||
_, err := fmt.Fprintf(f, "+%s\n", line)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// executeReadOnlyShell — safe, whitelisted, read-only shell execution with user confirmation
|
||||
func (r *Runner) executeReadOnlyShell(step Step, previousResults []string) {
|
||||
prompt := fmt.Sprintf(`You need additional context from the filesystem for this step.
|
||||
|
||||
Recipe Overview:
|
||||
%s
|
||||
|
||||
Previous step results:
|
||||
%s
|
||||
|
||||
=== CURRENT STEP ===
|
||||
Objective: %s
|
||||
Instructions: %s
|
||||
|
||||
Return ONLY a JSON array of read-only commands. Example:
|
||||
|
||||
[
|
||||
{
|
||||
"command": "ls",
|
||||
"args": ["-la"]
|
||||
},
|
||||
{
|
||||
"command": "tree",
|
||||
"args": [".", "-L", 3]
|
||||
}
|
||||
]
|
||||
|
||||
Only use safe read-only commands.`,
|
||||
r.Recipe.Overview,
|
||||
strings.Join(previousResults, "\n\n---\n\n"),
|
||||
step.Objective,
|
||||
step.Instructions)
|
||||
|
||||
messages := []map[string]string{
|
||||
{"role": "system", "content": "You are Grok, built by xAI. Precise expert programmer and refactoring assistant."},
|
||||
{"role": "user", "content": prompt},
|
||||
}
|
||||
|
||||
response := r.Client.Stream(messages, r.Model)
|
||||
fmt.Println()
|
||||
|
||||
// Robust JSON extraction
|
||||
start := strings.Index(response, "[")
|
||||
end := strings.LastIndex(response, "]") + 1
|
||||
if start == -1 {
|
||||
fmt.Println(" ⚠️ No valid read-only commands returned — skipping.")
|
||||
return
|
||||
}
|
||||
|
||||
jsonStr := response[start:end]
|
||||
jsonStr = strings.ReplaceAll(jsonStr, "\\\"", "\"")
|
||||
|
||||
type ShellCommand struct {
|
||||
Command string `json:"command"`
|
||||
Args []interface{} `json:"args"`
|
||||
}
|
||||
|
||||
var cmds []ShellCommand
|
||||
if err := json.Unmarshal([]byte(jsonStr), &cmds); err != nil {
|
||||
fmt.Printf(" ⚠️ Could not parse commands: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Use the GLOBAL safe list for the security check
|
||||
safeMap := safeCommands()
|
||||
|
||||
for _, cmd := range cmds {
|
||||
// Build argument list, converting numbers to strings
|
||||
args := make([]string, len(cmd.Args))
|
||||
for i, arg := range cmd.Args {
|
||||
switch v := arg.(type) {
|
||||
case string:
|
||||
args[i] = v
|
||||
case float64:
|
||||
args[i] = strconv.FormatFloat(v, 'f', -1, 64)
|
||||
default:
|
||||
args[i] = fmt.Sprintf("%v", v)
|
||||
}
|
||||
}
|
||||
|
||||
fullCmd := cmd.Command
|
||||
if len(args) > 0 {
|
||||
fullCmd += " " + strings.Join(args, " ")
|
||||
}
|
||||
|
||||
fmt.Printf(" Grok wants to run: %s\n Allow this command? [y/N] ", fullCmd)
|
||||
|
||||
var answer string
|
||||
_, err := fmt.Scanln(&answer)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if !strings.HasPrefix(strings.ToLower(answer), "y") {
|
||||
fmt.Println(" ❌ Cancelled by user.")
|
||||
continue
|
||||
}
|
||||
|
||||
// FINAL SECURITY CHECK — use the global safe list
|
||||
allowed := false
|
||||
trimmedCmd := strings.ToLower(strings.TrimSpace(cmd.Command))
|
||||
for safe := range safeMap {
|
||||
if strings.HasPrefix(trimmedCmd, strings.ToLower(safe)) {
|
||||
allowed = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !allowed {
|
||||
fmt.Printf(" ❌ Command not allowed by global safety policy: %s\n", cmd.Command)
|
||||
continue
|
||||
}
|
||||
|
||||
// Run with strict cwd
|
||||
execCmd := exec.Command(cmd.Command, args...)
|
||||
execCmd.Dir = r.resolveWorkDir()
|
||||
output, err := execCmd.CombinedOutput()
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf(" ❌ Failed: %v\n%s\n", err, string(output))
|
||||
} else {
|
||||
fmt.Printf(" ✅ Success\n%s\n", string(output))
|
||||
previousResults = append(previousResults, fmt.Sprintf("Command output:\n%s", string(output)))
|
||||
}
|
||||
}
|
||||
}
|
||||
36
internal/recipe/types.go
Normal file
36
internal/recipe/types.go
Normal file
@ -0,0 +1,36 @@
|
||||
package recipe
|
||||
|
||||
type Recipe struct {
|
||||
Name string `yaml:"name"`
|
||||
Description string `yaml:"description"`
|
||||
Version string `yaml:"version"`
|
||||
Parameters map[string]Parameter `yaml:"parameters"`
|
||||
AllowedShellCommands []string `yaml:"allowed_shell_commands"`
|
||||
|
||||
// Generic discovery support (option 2)
|
||||
ProjectLanguages []string `yaml:"project_languages"`
|
||||
Extensions map[string][]string `yaml:"extensions"`
|
||||
SearchPattern string `yaml:"search_pattern"` // new
|
||||
|
||||
// Resolved runtime values from --param flags
|
||||
ResolvedParams map[string]any `yaml:"-"`
|
||||
|
||||
// Internal fields populated by loader
|
||||
Overview string `yaml:"-"`
|
||||
Steps []Step `yaml:"-"`
|
||||
FinalSummaryPrompt string `yaml:"-"`
|
||||
}
|
||||
|
||||
type Parameter struct {
|
||||
Type string `yaml:"type"`
|
||||
Default any `yaml:"default"`
|
||||
Description string `yaml:"description"`
|
||||
}
|
||||
|
||||
type Step struct {
|
||||
Number int
|
||||
Title string
|
||||
Objective string
|
||||
Instructions string
|
||||
Expected string
|
||||
}
|
||||
27
safe_shell_commands.yaml.example
Normal file
27
safe_shell_commands.yaml.example
Normal file
@ -0,0 +1,27 @@
|
||||
# Grokkit safe shell commands whitelist
|
||||
# Only commands listed here (or prefixed by these) are allowed in recipes.
|
||||
# This is a safety boundary — never add rm, mv, cd, sudo, etc.
|
||||
# This file should be placed in ~/.config/grokkit/safe_shell_commands.yaml
|
||||
# customize it as you see fit.
|
||||
|
||||
safe_commands:
|
||||
- ls
|
||||
- pwd
|
||||
- cat
|
||||
- tree
|
||||
- find
|
||||
- grep
|
||||
- rg # ripgrep
|
||||
- git status
|
||||
- git log
|
||||
- git diff
|
||||
- git branch
|
||||
- go test
|
||||
- go vet
|
||||
- go fmt
|
||||
- go mod tidy
|
||||
- make test
|
||||
- pytest
|
||||
- poetry run pytest
|
||||
- ctest
|
||||
- python -m pytest
|
||||
42
todo/doing/recipe-feature.md
Normal file
42
todo/doing/recipe-feature.md
Normal file
@ -0,0 +1,42 @@
|
||||
# Recipe Feature Overview
|
||||
|
||||
The `feature/recipe_implementation` branch introduces a "Recipe" system to `grokkit`. This system allows for complex, multi-step refactorings or tasks to be defined in Markdown files and executed sequentially by an LLM.
|
||||
|
||||
## Key Components
|
||||
|
||||
### 1. Recipe Definitions
|
||||
Recipes are stored as Markdown files (e.g., `.grokkit/recipes/result-refactor.md`) with:
|
||||
- **YAML Frontmatter**: Metadata like `name`, `description`, `version`, and `parameters`.
|
||||
- **Structured Steps**: Defined using `### Step N: Title` headings.
|
||||
- **Step Details**: Each step includes `**Objective:**`, `**Instructions:**`, and `**Expected output:**` sections.
|
||||
|
||||
### 2. Internal Recipe Package (`internal/recipe/`)
|
||||
- **`types.go`**: Defines the data structures for `Recipe`, `Step`, and `Parameter`.
|
||||
- **`loader.go`**:
|
||||
- Parses Markdown files and extracts YAML frontmatter.
|
||||
- Uses regular expressions (`stepRe`, `subRe`) to extract step details.
|
||||
- Supports basic `text/template` rendering for parameter substitution in instructions.
|
||||
- **`runner.go`**:
|
||||
- Orchestrates recipe execution.
|
||||
- Currently implements a dry-run/preview mode that prints steps to the console.
|
||||
- Placeholder for future LLM integration.
|
||||
|
||||
### 3. CLI Integration (`cmd/recipe.go`)
|
||||
- **`grokkit recipe run [recipe-name|recipe.md]`**: The main entry point for users.
|
||||
- **Path Resolution**:
|
||||
1. **Explicit Path**: Checks if the argument is a direct file path.
|
||||
2. **Project Local**: Looks in `.grokkit/recipes/` within the project root.
|
||||
3. **Global Share**: Falls back to `~/.local/share/grokkit/recipes/` (XDG-compliant).
|
||||
|
||||
## Technical Details
|
||||
- **Go Version**: 1.24.2.
|
||||
- **Dependencies**: `gopkg.in/yaml.v3` for frontmatter, `github.com/spf13/cobra` for CLI.
|
||||
- **Parsing**: Uses multi-line regex for robust section extraction even with varied Markdown formatting.
|
||||
|
||||
## Current Progress & Next Steps
|
||||
- [x] Recipe data structures and YAML frontmatter parsing.
|
||||
- [x] Markdown step extraction and template rendering.
|
||||
- [x] CLI command with project-local/global path resolution.
|
||||
- [ ] Integration with LLM for actual step execution.
|
||||
- [ ] Support for `--param` flags in the CLI.
|
||||
- [ ] Shell command execution within steps (if allowed).
|
||||
Loading…
Reference in New Issue
Block a user