refactor: make mergegate gate-first
This commit is contained in:
parent
29c72fee83
commit
427b99f400
7 changed files with 239 additions and 2244 deletions
1000
Cargo.lock
generated
1000
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
14
Cargo.toml
14
Cargo.toml
|
|
@ -2,7 +2,6 @@
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
members = [
|
members = [
|
||||||
"crates/mergegate-cli",
|
"crates/mergegate-cli",
|
||||||
"crates/mergegate-tui",
|
|
||||||
"crates/mergegate-core",
|
"crates/mergegate-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -14,8 +13,8 @@ authors = ["Miyabi Team"]
|
||||||
license = "BUSL-1.1"
|
license = "BUSL-1.1"
|
||||||
repository = "https://github.com/ShunsukeHayashi/mergegate"
|
repository = "https://github.com/ShunsukeHayashi/mergegate"
|
||||||
homepage = "https://github.com/ShunsukeHayashi/mergegate"
|
homepage = "https://github.com/ShunsukeHayashi/mergegate"
|
||||||
description = "MergeGate - Deterministic task execution and merge workflow for AI-assisted development"
|
description = "MergeGate - Engine-agnostic gate CLI for deterministic task execution in AI-assisted development"
|
||||||
keywords = ["ai", "cli", "tui", "autonomous", "development"]
|
keywords = ["ai", "cli", "workflow", "merge", "development"]
|
||||||
categories = ["command-line-utilities", "development-tools"]
|
categories = ["command-line-utilities", "development-tools"]
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
|
|
@ -24,15 +23,6 @@ tokio = { version = "1", features = ["rt-multi-thread", "macros", "io-std", "syn
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
async-trait = "0.1"
|
async-trait = "0.1"
|
||||||
|
|
||||||
# TUI Framework
|
|
||||||
ratatui = { version = "0.29.0", features = [
|
|
||||||
"scrolling-regions",
|
|
||||||
"unstable-backend-writer",
|
|
||||||
"unstable-rendered-line-info",
|
|
||||||
"unstable-widget-ref",
|
|
||||||
] }
|
|
||||||
crossterm = { version = "0.29.0", features = ["bracketed-paste", "event-stream"] }
|
|
||||||
|
|
||||||
# Text Processing
|
# Text Processing
|
||||||
textwrap = "0.16"
|
textwrap = "0.16"
|
||||||
unicode-width = "0.2"
|
unicode-width = "0.2"
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,22 @@
|
||||||
# MergeGate
|
# MergeGate
|
||||||
Deterministic execution protocol for AI-assisted development.
|
Engine-agnostic gate CLI for AI-assisted development.
|
||||||
|
|
||||||
Execution layer for GitNexus-style code intelligence:
|
Execution layer for GitNexus-style code intelligence:
|
||||||
- `GitNexus`: understand the codebase
|
- `GitNexus`: understand the codebase
|
||||||
- `MergeGate`: execute changes safely
|
- `MergeGate`: execute changes safely
|
||||||
|
|
||||||
Current CLI entrypoints: `miyabi` and `mergegate`
|
Core product:
|
||||||
|
- `mergegate gate ...`
|
||||||
|
- `miyabi gate ...` (compatibility alias)
|
||||||
|
|
||||||
- `miyabi tui` / `mergegate tui`: terminal assistant
|
MergeGate is designed to sit in front of Claude Code, Codex, Gemini CLI, and other coding agents. The engine can change. The gate protocol should not.
|
||||||
- `miyabi gate` / `mergegate gate`: deterministic task execution, file locks, and PR/merge workflow
|
|
||||||
|
Start with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo build --release
|
||||||
|
./target/release/mergegate gate status
|
||||||
|
./target/release/mergegate gate init
|
||||||
|
./target/release/mergegate gate guide
|
||||||
|
```
|
||||||
|
|
||||||
Start with `cargo build --release`, then run `./target/release/mergegate --help` or `./target/release/mergegate gate guide`.
|
|
||||||
|
|
|
||||||
575
README.md
575
README.md
|
|
@ -1,55 +1,68 @@
|
||||||
# MergeGate
|
# MergeGate
|
||||||
|
|
||||||
MergeGate is a deterministic execution protocol for AI-assisted development.
|
MergeGate is an engine-agnostic gate CLI for AI-assisted development.
|
||||||
It is the execution layer for GitNexus-style code intelligence: GitNexus helps agents understand what will break, and MergeGate makes them execute that work in a safe, verifiable order.
|
|
||||||
|
It does not need to be your coding agent, your chat runtime, or your terminal UI. Its job is simpler and more durable:
|
||||||
|
|
||||||
|
- register work
|
||||||
|
- record impact
|
||||||
|
- lock files
|
||||||
|
- assign execution
|
||||||
|
- track branch and PR state
|
||||||
|
- verify completion
|
||||||
|
|
||||||
In short:
|
In short:
|
||||||
|
|
||||||
- `GitNexus`: understand the codebase
|
- `GitNexus`: understand the codebase
|
||||||
- `MergeGate`: execute changes safely
|
- `MergeGate`: execute changes safely
|
||||||
|
|
||||||
The project currently supports both `miyabi` and `mergegate` as CLI entrypoints. `miyabi` remains the legacy/default command, and `mergegate` is the product-aligned alias.
|
MergeGate is designed to sit in front of coding agents such as Claude Code, Codex, and Gemini CLI. The execution engine can change. The gate protocol should not.
|
||||||
|
|
||||||
This repository has two common entry points:
|
## What This Project Is
|
||||||
|
|
||||||
- `miyabi tui` / `mergegate tui`: interactive terminal assistant
|
MergeGate is a repo workflow tool for deterministic execution.
|
||||||
- `miyabi gate` / `mergegate gate`: deterministic task execution and file-lock workflow for repo work
|
|
||||||
|
|
||||||
If you arrived here because of deterministic execution, task locks, PR gates, or agent-safe repo work, start with `mergegate gate` or `miyabi gate`, not the TUI.
|
The core product is:
|
||||||
|
|
||||||
|
- `miyabi gate ...`
|
||||||
|
- `mergegate gate ...`
|
||||||
|
|
||||||
|
The binary still supports both `miyabi` and `mergegate` entrypoints today. `mergegate` is the product-aligned command. `miyabi` remains as a compatibility alias.
|
||||||
|
|
||||||
## 60-Second Setup
|
## 60-Second Setup
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 1. Clone and build
|
|
||||||
git clone https://github.com/ShunsukeHayashi/mergegate.git
|
git clone https://github.com/ShunsukeHayashi/mergegate.git
|
||||||
cd mergegate
|
cd mergegate
|
||||||
cargo build --release
|
cargo build --release
|
||||||
|
|
||||||
# 2. Set API key
|
./target/release/mergegate gate status
|
||||||
export ANTHROPIC_API_KEY="sk-ant-..."
|
./target/release/mergegate gate init
|
||||||
|
./target/release/mergegate gate guide
|
||||||
# 3. Run
|
|
||||||
./target/release/mergegate tui
|
|
||||||
```
|
```
|
||||||
|
|
||||||
That's it. Start with the TUI, or jump straight into `mergegate gate` for repo workflow control.
|
No API key is required for gate workflow.
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Why MergeGate
|
## Why MergeGate
|
||||||
|
|
||||||
- **Execution layer for code intelligence** - Pair blast-radius understanding with deterministic execution, not chat-only automation
|
- **Engine agnostic**: Use Claude Code, Codex, Gemini CLI, or another agent runtime
|
||||||
- **Deterministic task execution** - Register, analyze, lock, review, and merge in a verifiable order
|
- **Deterministic execution**: Register, analyze, lock, implement, review, and merge in a verifiable order
|
||||||
- **Repo-safe agent workflow** - File locks and gate checks reduce accidental overlap and unsafe edits
|
- **Repo-safe coordination**: Reduce accidental overlap with file locks and explicit task ownership
|
||||||
- **Interactive TUI** - Terminal assistant for chat, prompts, and agent execution
|
- **Execution ledger**: Keep branch, PR, merge, and completion state tied to actual work
|
||||||
- **Agent mode** - Autonomous execution with tool approval
|
- **Protocol over chat**: The product is the workflow gate, not a built-in assistant
|
||||||
- **Session management** - Persist and resume conversations
|
|
||||||
- **Configurable** - TOML-based configuration
|
|
||||||
|
|
||||||
## Positioning
|
## Positioning
|
||||||
|
|
||||||
MergeGate was designed for teams that already believe code understanding is not enough.
|
MergeGate exists because understanding code is not enough.
|
||||||
Knowing the blast radius of a change is only half of the problem. Agents also need a protocol for when work starts, which files are locked, what must be recorded before editing, and what counts as done.
|
|
||||||
|
Agents also need a protocol for:
|
||||||
|
|
||||||
|
- when a task starts
|
||||||
|
- which files are locked
|
||||||
|
- what impact was recorded
|
||||||
|
- who is implementing
|
||||||
|
- how branch and PR state are attached
|
||||||
|
- what counts as done
|
||||||
|
|
||||||
That is the role split:
|
That is the role split:
|
||||||
|
|
||||||
|
|
@ -63,7 +76,6 @@ If GitNexus answers "what is this change connected to?", MergeGate answers "how
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
|
|
||||||
- Rust 1.70+
|
- Rust 1.70+
|
||||||
- Anthropic API key
|
|
||||||
|
|
||||||
### Build from Source
|
### Build from Source
|
||||||
|
|
||||||
|
|
@ -77,75 +89,34 @@ Binary will be at `target/release/miyabi` and `target/release/mergegate`.
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
Choose the path that matches what you want to do.
|
### 1. Check repo status
|
||||||
|
|
||||||
### A. Use MergeGate as a terminal assistant
|
|
||||||
|
|
||||||
Run the TUI after configuring your API key.
|
|
||||||
|
|
||||||
#### 1. Generate Config
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./target/release/miyabi init
|
./target/release/mergegate gate status
|
||||||
```
|
```
|
||||||
|
|
||||||
This creates `~/.miyabi/config.toml`.
|
If you see `tasks: 0`, the ledger exists and is simply empty.
|
||||||
|
|
||||||
#### 2. Set API Key
|
### 2. Initialize gate ledger if needed
|
||||||
|
|
||||||
Edit `~/.miyabi/config.toml`:
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[api]
|
|
||||||
api_key = "sk-ant-..."
|
|
||||||
```
|
|
||||||
|
|
||||||
Or use environment variable:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
export ANTHROPIC_API_KEY="sk-ant-..."
|
./target/release/mergegate gate init
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 3. Launch TUI
|
This creates `project_memory/tasks.json`.
|
||||||
|
|
||||||
|
### 3. Read the built-in workflow guide
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./target/release/miyabi tui
|
./target/release/mergegate gate guide
|
||||||
# or simply
|
|
||||||
./target/release/miyabi
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### B. Use MergeGate as a task execution gate
|
### 4. Start a task
|
||||||
|
|
||||||
If you are working inside a repository and want task registration, impact tracking, file locks, and PR/merge recording, use `mergegate gate` or `miyabi gate`.
|
|
||||||
|
|
||||||
#### 1. Check whether the repo is already initialized
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./target/release/miyabi gate status
|
./target/release/mergegate gate register --issue 123 --title "Fix login redirect"
|
||||||
```
|
./target/release/mergegate gate impact issue-123 --risk medium --symbols 3
|
||||||
|
./target/release/mergegate gate assign issue-123 --agent codex --node macbook --files "src/auth.rs"
|
||||||
If you see `tasks: 0`, that means the ledger exists but is currently empty.
|
|
||||||
|
|
||||||
#### 2. Initialize MergeGate for this repo if needed
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./target/release/miyabi gate init
|
|
||||||
```
|
|
||||||
|
|
||||||
This creates `project_memory/tasks.json` and prepares the repo for gate-managed work.
|
|
||||||
|
|
||||||
#### 3. Read the built-in workflow guide
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./target/release/miyabi gate guide
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 4. Start a task
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./target/release/miyabi gate register --issue 123 --title "Fix login redirect"
|
|
||||||
./target/release/miyabi gate impact issue-123 --risk medium --symbols 3
|
|
||||||
./target/release/miyabi gate assign issue-123 --agent codex --node macbook --files "src/auth.rs"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Typical flow:
|
Typical flow:
|
||||||
|
|
@ -153,427 +124,83 @@ Typical flow:
|
||||||
1. `register`
|
1. `register`
|
||||||
2. `impact`
|
2. `impact`
|
||||||
3. `assign`
|
3. `assign`
|
||||||
4. implement
|
4. implement with your coding agent of choice
|
||||||
5. `branch`
|
5. `branch`
|
||||||
6. `pr`
|
6. `pr`
|
||||||
7. `merge` or `manual-complete`
|
7. `merge` or `manual-complete`
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
`MergeGate` is the product and documentation name.
|
```bash
|
||||||
Both `miyabi` and `mergegate` work today.
|
mergegate gate status
|
||||||
|
mergegate gate init
|
||||||
|
mergegate gate guide
|
||||||
|
mergegate gate register --issue 123 --title "Fix login redirect"
|
||||||
|
mergegate gate impact issue-123 --risk medium --symbols 3
|
||||||
|
mergegate gate assign issue-123 --agent codex --node macbook --files "src/auth.rs"
|
||||||
|
mergegate gate branch issue-123 codex/fix-login-redirect
|
||||||
|
mergegate gate pr issue-123 456
|
||||||
|
mergegate gate merge issue-123 <sha>
|
||||||
|
```
|
||||||
|
|
||||||
### CLI Commands
|
Compatibility alias:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
miyabi # Start TUI (default)
|
miyabi gate status
|
||||||
miyabi tui # Start TUI explicitly
|
|
||||||
miyabi status # Show status
|
|
||||||
miyabi init # Generate default config
|
|
||||||
miyabi sessions # List sessions
|
|
||||||
miyabi sessions -d <id> # Delete session
|
|
||||||
miyabi sessions -e <id> # Export session to JSON
|
|
||||||
miyabi version # Show version info
|
|
||||||
miyabi agent <prompt> # Run autonomous agent
|
|
||||||
miyabi gate status # Show task ledger status
|
|
||||||
miyabi gate init # Initialize MergeGate in the current repo
|
|
||||||
miyabi gate guide # Show the full gate workflow guide
|
|
||||||
mergegate gate status # Same gate workflow with product-aligned command
|
|
||||||
mergegate tui # Same TUI with product-aligned command
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### CLI Options
|
## Core Commands
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
miyabi --model claude-sonnet-4-5-20250929 # Override model
|
mergegate gate status
|
||||||
miyabi --max-tokens 16384 # Override max tokens
|
mergegate gate init
|
||||||
miyabi --thinking # Enable extended thinking
|
mergegate gate guide
|
||||||
miyabi --config /path/to/config.toml # Custom config
|
mergegate gate register --issue 123 --title "Fix login redirect"
|
||||||
miyabi --session <id> # Resume session
|
mergegate gate assign issue-123 --agent codex --node macbook --files "src/auth.rs"
|
||||||
|
mergegate gate impact issue-123 --risk medium --symbols 3
|
||||||
|
mergegate gate branch issue-123 codex/fix-login-redirect
|
||||||
|
mergegate gate pr issue-123 456
|
||||||
|
mergegate gate merge issue-123 <sha>
|
||||||
|
mergegate gate manual-complete issue-123 --reason "docs-only change" --operator shunsuke
|
||||||
|
mergegate gate locks
|
||||||
|
mergegate gate dispatchable
|
||||||
|
mergegate gate dag
|
||||||
```
|
```
|
||||||
|
|
||||||
### TUI Keybindings
|
## Product Direction
|
||||||
|
|
||||||
| Key | Action |
|
MergeGate is intentionally moving away from:
|
||||||
|-----|--------|
|
|
||||||
| `Enter` | Send message |
|
|
||||||
| `Ctrl+P` | Command palette |
|
|
||||||
| `F1` | Help |
|
|
||||||
| `Esc` | Close overlay / Cancel |
|
|
||||||
| `Ctrl+C` | Quit |
|
|
||||||
| `j/k` | Scroll down/up |
|
|
||||||
| `Page Up/Down` | Page scroll |
|
|
||||||
|
|
||||||
## Configuration
|
- built-in TUI as the product center
|
||||||
|
- built-in agent runtime as the product center
|
||||||
|
- vendor-specific backend identity
|
||||||
|
|
||||||
Config file: `~/.miyabi/config.toml`
|
The durable surface is the gate CLI.
|
||||||
|
|
||||||
```toml
|
## Workspace Layout
|
||||||
[api]
|
|
||||||
api_key = "sk-ant-..." # Anthropic API key
|
|
||||||
model = "claude-sonnet-4-5-20250929" # Model to use
|
|
||||||
max_tokens = 8192 # Max response tokens
|
|
||||||
thinking = false # Extended thinking
|
|
||||||
system_prompt = "You are a helpful assistant" # System prompt
|
|
||||||
timeout_secs = 120 # Request timeout
|
|
||||||
max_retries = 3 # Retry attempts
|
|
||||||
|
|
||||||
[ui]
|
```text
|
||||||
show_sidebar = false # Show sidebar
|
crates/
|
||||||
show_status_bar = true # Show status bar
|
mergegate-cli/ # CLI entrypoint
|
||||||
show_breadcrumb = true # Show breadcrumb
|
mergegate-core/ # Gate protocol, store, locks, workflow logic
|
||||||
theme = "tokyo-night" # Color theme
|
project_memory/
|
||||||
vim_mode = false # Vim keybindings
|
tasks.json # Execution ledger
|
||||||
show_line_numbers = true # Line numbers in code
|
skills/
|
||||||
|
mergegate-cli/
|
||||||
[session]
|
mergegate-ops/
|
||||||
auto_save = true # Auto-save sessions
|
|
||||||
auto_save_interval = 30 # Save interval (seconds)
|
|
||||||
max_sessions = 100 # Max stored sessions
|
|
||||||
|
|
||||||
[tools]
|
|
||||||
enable_bash = true # Enable bash tool
|
|
||||||
enable_file_tools = true # Enable file read/write
|
|
||||||
enable_search_tools = true # Enable glob/grep
|
|
||||||
auto_approve_low_risk = false # Auto-approve safe tools
|
|
||||||
bash_timeout = 120 # Bash command timeout
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Environment Variables
|
|
||||||
|
|
||||||
Override config with environment variables:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ANTHROPIC_API_KEY=... # API key
|
|
||||||
MIYABI_MODEL=... # Model name
|
|
||||||
MIYABI_MAX_TOKENS=... # Max tokens
|
|
||||||
MIYABI_THINKING=true # Enable thinking
|
|
||||||
```
|
|
||||||
|
|
||||||
## Agent Mode
|
|
||||||
|
|
||||||
Run autonomous tasks with tool execution:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Basic usage
|
|
||||||
miyabi agent "Create a hello world Python script"
|
|
||||||
|
|
||||||
# With options
|
|
||||||
miyabi agent "Refactor the utils module" \
|
|
||||||
--max-iterations 20 \
|
|
||||||
--auto-approve \
|
|
||||||
--system "You are an expert Rust developer"
|
|
||||||
```
|
|
||||||
|
|
||||||
Agent mode features:
|
|
||||||
- Autonomous tool execution (bash, file operations, search)
|
|
||||||
- Approval workflow for risky operations
|
|
||||||
- Iteration limits for safety
|
|
||||||
- JSON output format option
|
|
||||||
|
|
||||||
## Core Library Features
|
|
||||||
|
|
||||||
The `mergegate-core` crate provides powerful utilities for building AI applications.
|
|
||||||
|
|
||||||
### Git Utilities
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use miyabi_core::{find_git_root, get_current_branch, is_in_git_repo};
|
|
||||||
|
|
||||||
// Find repository root
|
|
||||||
let root = find_git_root()?;
|
|
||||||
|
|
||||||
// Get current branch
|
|
||||||
let branch = get_current_branch(&root)?;
|
|
||||||
|
|
||||||
// Check if in git repo
|
|
||||||
if is_in_git_repo(&path) {
|
|
||||||
println!("In a git repository");
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Logger System
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use miyabi_core::{init_logger, LogLevel, LogFormat};
|
|
||||||
|
|
||||||
// Initialize with defaults
|
|
||||||
init_logger();
|
|
||||||
|
|
||||||
// Or with custom config
|
|
||||||
use miyabi_core::LoggerConfig;
|
|
||||||
let config = LoggerConfig {
|
|
||||||
level: LogLevel::Debug,
|
|
||||||
format: LogFormat::Json,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
init_logger_with_config(config);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Retry with Backoff
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use miyabi_core::{retry_with_backoff, BackoffRetryConfig};
|
|
||||||
|
|
||||||
let config = BackoffRetryConfig::default();
|
|
||||||
let result = retry_with_backoff(config, || async {
|
|
||||||
// Your operation that might fail
|
|
||||||
make_api_call().await
|
|
||||||
}).await?;
|
|
||||||
```
|
|
||||||
|
|
||||||
### Circuit Breaker
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use miyabi_core::{CircuitBreaker, CircuitState};
|
|
||||||
|
|
||||||
let breaker = CircuitBreaker::default();
|
|
||||||
|
|
||||||
let result = breaker.call(|| {
|
|
||||||
Box::pin(async {
|
|
||||||
// Your operation
|
|
||||||
Ok::<_, std::io::Error>(())
|
|
||||||
})
|
|
||||||
}).await;
|
|
||||||
|
|
||||||
// Check state
|
|
||||||
match breaker.state().await {
|
|
||||||
CircuitState::Closed => println!("Normal operation"),
|
|
||||||
CircuitState::Open => println!("Circuit open - blocking calls"),
|
|
||||||
CircuitState::HalfOpen => println!("Testing recovery"),
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Rules System (.miyabirules)
|
|
||||||
|
|
||||||
Support for project-specific rules via `.miyabirules` files:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# .miyabirules
|
|
||||||
version: 1
|
|
||||||
rules:
|
|
||||||
- name: "no-unwrap"
|
|
||||||
pattern: ".unwrap()"
|
|
||||||
suggestion: "Use ? operator or proper error handling"
|
|
||||||
file_extensions: ["rs"]
|
|
||||||
severity: "warning"
|
|
||||||
|
|
||||||
agent_preferences:
|
|
||||||
codegen:
|
|
||||||
style: "functional"
|
|
||||||
error_handling: "result"
|
|
||||||
```
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use miyabi_core::{RulesLoader, MiyabiRules};
|
|
||||||
|
|
||||||
let loader = RulesLoader::new(project_root);
|
|
||||||
let rules = loader.load_or_default()?;
|
|
||||||
|
|
||||||
// Get rules for a file
|
|
||||||
let applicable = rules.rules_for_file(Path::new("src/main.rs"));
|
|
||||||
```
|
|
||||||
|
|
||||||
### Cache System
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use miyabi_core::{create_llm_cache, create_api_cache, LLMCacheKey};
|
|
||||||
|
|
||||||
// LLM response cache (1 hour TTL)
|
|
||||||
let cache = create_llm_cache();
|
|
||||||
let key = LLMCacheKey::new("prompt", "model", Some(0.7));
|
|
||||||
|
|
||||||
cache.insert(key.clone(), "response".to_string()).await;
|
|
||||||
let cached = cache.get(&key).await;
|
|
||||||
|
|
||||||
// API cache (30 min TTL)
|
|
||||||
let api_cache = create_api_cache();
|
|
||||||
```
|
|
||||||
|
|
||||||
### Plugin System
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use miyabi_core::{Plugin, PluginManager, PluginMetadata, PluginContext, PluginResult};
|
|
||||||
use anyhow::Result;
|
|
||||||
|
|
||||||
struct MyPlugin;
|
|
||||||
|
|
||||||
impl Plugin for MyPlugin {
|
|
||||||
fn metadata(&self) -> PluginMetadata {
|
|
||||||
PluginMetadata {
|
|
||||||
name: "my-plugin".to_string(),
|
|
||||||
version: "1.0.0".to_string(),
|
|
||||||
description: Some("My custom plugin".to_string()),
|
|
||||||
author: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn init(&mut self) -> Result<()> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn execute(&self, ctx: &PluginContext) -> Result<PluginResult> {
|
|
||||||
Ok(PluginResult {
|
|
||||||
success: true,
|
|
||||||
message: Some("Done".to_string()),
|
|
||||||
data: None,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register and execute
|
|
||||||
let manager = PluginManager::new();
|
|
||||||
manager.register(Box::new(MyPlugin))?;
|
|
||||||
let result = manager.execute("my-plugin", &PluginContext::default())?;
|
|
||||||
```
|
|
||||||
|
|
||||||
### Feature Flags
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use miyabi_core::{FeatureFlagManager, FeatureFlag};
|
|
||||||
|
|
||||||
let flags = FeatureFlagManager::new();
|
|
||||||
|
|
||||||
// Simple flag
|
|
||||||
flags.set_flag("new_feature", true);
|
|
||||||
|
|
||||||
if flags.is_enabled("new_feature") {
|
|
||||||
// Use new feature
|
|
||||||
}
|
|
||||||
|
|
||||||
// With rollout percentage
|
|
||||||
flags.set_flag_with_options(
|
|
||||||
"beta_feature",
|
|
||||||
true,
|
|
||||||
Some("Beta testing".to_string()),
|
|
||||||
Some(0.5), // 50% rollout
|
|
||||||
);
|
|
||||||
|
|
||||||
// Load from config
|
|
||||||
use std::collections::HashMap;
|
|
||||||
let mut config = HashMap::new();
|
|
||||||
config.insert("flag1".to_string(), true);
|
|
||||||
flags.load_from_map(config);
|
|
||||||
```
|
|
||||||
|
|
||||||
## Project Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
mergegate/
|
|
||||||
├── crates/
|
|
||||||
│ ├── mergegate-cli/ # CLI entry point
|
|
||||||
│ ├── mergegate-core/ # Core library
|
|
||||||
│ │ ├── agent.rs # Agent system
|
|
||||||
│ │ ├── anthropic.rs # Anthropic API client
|
|
||||||
│ │ ├── cache.rs # TTL cache system
|
|
||||||
│ │ ├── config.rs # Configuration
|
|
||||||
│ │ ├── error_policy.rs # Circuit breaker
|
|
||||||
│ │ ├── feature_flags.rs # Feature flag management
|
|
||||||
│ │ ├── git.rs # Git utilities
|
|
||||||
│ │ ├── logger.rs # Logging system
|
|
||||||
│ │ ├── plugin.rs # Plugin system
|
|
||||||
│ │ ├── retry.rs # Retry with backoff
|
|
||||||
│ │ ├── rules.rs # .miyabirules support
|
|
||||||
│ │ ├── session.rs # Session management
|
|
||||||
│ │ ├── tools.rs # Built-in tools
|
|
||||||
│ │ └── ...
|
|
||||||
│ └── mergegate-tui/ # TUI implementation
|
|
||||||
│ ├── app.rs # Main application
|
|
||||||
│ ├── views.rs # UI views
|
|
||||||
│ └── ...
|
|
||||||
├── .miyabi/ # Local config
|
|
||||||
├── Cargo.toml # Workspace config
|
|
||||||
└── README.md
|
|
||||||
```
|
|
||||||
|
|
||||||
## Development
|
|
||||||
|
|
||||||
### Build
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cargo build # Debug build
|
|
||||||
cargo build --release # Release build
|
|
||||||
```
|
|
||||||
|
|
||||||
### Test
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cargo test --all # Run all tests
|
|
||||||
```
|
|
||||||
|
|
||||||
### Lint
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cargo clippy --all-targets -- -D warnings
|
|
||||||
cargo fmt --all --check
|
|
||||||
```
|
|
||||||
|
|
||||||
## Models
|
|
||||||
|
|
||||||
Supported models:
|
|
||||||
- `claude-sonnet-4-5-20250929` (default)
|
|
||||||
- `claude-haiku-4-5-20251001`
|
|
||||||
- `claude-sonnet-4-20250514`
|
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
### Common Issues
|
### `gate status` says `tasks: 0`
|
||||||
|
|
||||||
#### "API key not found"
|
That is not an error. It means the ledger exists but no tasks have been registered yet.
|
||||||
```bash
|
|
||||||
# Check if environment variable is set
|
|
||||||
echo $ANTHROPIC_API_KEY
|
|
||||||
|
|
||||||
# Or add to config file
|
### `gate init` says the project is already initialized
|
||||||
vim ~/.miyabi/config.toml
|
|
||||||
# [api]
|
|
||||||
# api_key = "sk-ant-..."
|
|
||||||
```
|
|
||||||
|
|
||||||
#### "Device not configured" error on TUI start
|
That is usually safe. It means `project_memory/tasks.json` already exists.
|
||||||
This usually means the terminal doesn't support the required features. Try:
|
|
||||||
```bash
|
|
||||||
# Use a different terminal emulator (iTerm2, Alacritty, etc.)
|
|
||||||
# Or run with explicit terminal type
|
|
||||||
TERM=xterm-256color ./target/release/miyabi tui
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Build errors
|
### I want to use another coding agent
|
||||||
```bash
|
|
||||||
# Make sure Rust is up to date
|
|
||||||
rustup update
|
|
||||||
|
|
||||||
# Clean and rebuild
|
That is the intended model. MergeGate is the gate, not the engine.
|
||||||
cargo clean
|
|
||||||
cargo build --release
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Session not saving
|
|
||||||
```bash
|
|
||||||
# Check permissions on sessions directory
|
|
||||||
ls -la ~/.miyabi/sessions/
|
|
||||||
|
|
||||||
# Create if missing
|
|
||||||
mkdir -p ~/.miyabi/sessions
|
|
||||||
```
|
|
||||||
|
|
||||||
### Debug Mode
|
|
||||||
|
|
||||||
For verbose logging:
|
|
||||||
```bash
|
|
||||||
RUST_LOG=debug ./target/release/miyabi tui
|
|
||||||
```
|
|
||||||
|
|
||||||
### Getting Help
|
|
||||||
|
|
||||||
- Check `miyabi --help` for CLI options
|
|
||||||
- Press `F1` in TUI for keybindings
|
|
||||||
- Open an issue: https://github.com/ShunsukeHayashi/mergegate/issues
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
MIT
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Built with Rust, Ratatui, and Claude API.
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ authors.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
repository.workspace = true
|
repository.workspace = true
|
||||||
homepage.workspace = true
|
homepage.workspace = true
|
||||||
description = "MergeGate CLI - Main command-line interface for deterministic task execution and agent-assisted development"
|
description = "MergeGate CLI - Engine-agnostic gate workflow for deterministic task execution"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "miyabi"
|
name = "miyabi"
|
||||||
|
|
@ -20,15 +20,10 @@ path = "src/bin/mergegate.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# Workspace crates
|
# Workspace crates
|
||||||
miyabi-core = { package = "mergegate-core", path = "../mergegate-core" }
|
miyabi-core = { package = "mergegate-core", path = "../mergegate-core" }
|
||||||
miyabi-tui = { package = "mergegate-tui", path = "../mergegate-tui" }
|
|
||||||
|
|
||||||
# CLI
|
# CLI
|
||||||
clap = { workspace = true }
|
clap = { workspace = true }
|
||||||
|
|
||||||
# TUI Framework
|
|
||||||
ratatui = { workspace = true }
|
|
||||||
crossterm = { workspace = true }
|
|
||||||
|
|
||||||
# Async Runtime
|
# Async Runtime
|
||||||
tokio = { workspace = true }
|
tokio = { workspace = true }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,36 +62,14 @@ fn agent_guide() -> String {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
#[command(author, version, about = "MergeGate - Deterministic task execution and merge workflow for AI-assisted development", long_about = None)]
|
#[command(author, version, about = "MergeGate - Engine-agnostic gate CLI for AI-assisted development", long_about = None)]
|
||||||
struct Cli {
|
struct Cli {
|
||||||
/// Model to use (overrides config)
|
|
||||||
#[arg(short, long)]
|
|
||||||
model: Option<String>,
|
|
||||||
|
|
||||||
/// Maximum tokens for responses (overrides config)
|
|
||||||
#[arg(long)]
|
|
||||||
max_tokens: Option<u32>,
|
|
||||||
|
|
||||||
/// Enable Extended Thinking (Claude 4.5+)
|
|
||||||
#[arg(long)]
|
|
||||||
thinking: bool,
|
|
||||||
|
|
||||||
/// Path to config file
|
|
||||||
#[arg(short, long)]
|
|
||||||
config: Option<PathBuf>,
|
|
||||||
|
|
||||||
/// Session ID to load on startup
|
|
||||||
#[arg(short, long)]
|
|
||||||
session: Option<String>,
|
|
||||||
|
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
command: Option<Commands>,
|
command: Option<Commands>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Subcommand)]
|
#[derive(Subcommand)]
|
||||||
enum Commands {
|
enum Commands {
|
||||||
/// Start the TUI interface
|
|
||||||
Tui,
|
|
||||||
/// Show status
|
/// Show status
|
||||||
Status,
|
Status,
|
||||||
/// Generate default config file
|
/// Generate default config file
|
||||||
|
|
@ -116,23 +94,6 @@ enum Commands {
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
verbose: bool,
|
verbose: bool,
|
||||||
},
|
},
|
||||||
/// Run agent with a prompt (autonomous execution)
|
|
||||||
Agent {
|
|
||||||
/// The prompt to execute
|
|
||||||
prompt: String,
|
|
||||||
/// Maximum iterations (default: 10)
|
|
||||||
#[arg(long, default_value = "10")]
|
|
||||||
max_iterations: usize,
|
|
||||||
/// Auto-approve all tool executions
|
|
||||||
#[arg(long)]
|
|
||||||
auto_approve: bool,
|
|
||||||
/// Output format: text or json
|
|
||||||
#[arg(long, default_value = "text")]
|
|
||||||
format: String,
|
|
||||||
/// System prompt for the agent
|
|
||||||
#[arg(long)]
|
|
||||||
system: Option<String>,
|
|
||||||
},
|
|
||||||
#[command(
|
#[command(
|
||||||
about = "Deterministic Task Protocol gate controls",
|
about = "Deterministic Task Protocol gate controls",
|
||||||
long_about = "Run the gate init command to set up a new project.\n\nDeterministic Task Protocol gate controls"
|
long_about = "Run the gate init command to set up a new project.\n\nDeterministic Task Protocol gate controls"
|
||||||
|
|
@ -452,78 +413,35 @@ async fn main() -> anyhow::Result<()> {
|
||||||
let cli = Cli::from_arg_matches(&matches).unwrap_or_else(|error| error.exit());
|
let cli = Cli::from_arg_matches(&matches).unwrap_or_else(|error| error.exit());
|
||||||
|
|
||||||
match cli.command {
|
match cli.command {
|
||||||
Some(Commands::Tui) | None => {
|
None => {
|
||||||
// Run TUI
|
let mut command = Cli::command();
|
||||||
use crossterm::{
|
command = command.name(current_binary_name());
|
||||||
event::{DisableMouseCapture, EnableMouseCapture},
|
command.print_help()?;
|
||||||
execute,
|
println!();
|
||||||
terminal::{
|
println!();
|
||||||
disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen,
|
println!("Start here:");
|
||||||
},
|
println!(" {}", gate_command("status"));
|
||||||
};
|
println!(" {}", gate_command("init"));
|
||||||
use miyabi_core::config::Config;
|
println!(" {}", gate_command("guide"));
|
||||||
use miyabi_tui::App;
|
|
||||||
use ratatui::prelude::*;
|
|
||||||
use std::io;
|
|
||||||
|
|
||||||
// Load config (from custom path or default)
|
|
||||||
let mut config = if let Some(config_path) = &cli.config {
|
|
||||||
Config::load_from(config_path)?
|
|
||||||
} else {
|
|
||||||
Config::load().unwrap_or_default()
|
|
||||||
};
|
|
||||||
|
|
||||||
// Apply CLI overrides
|
|
||||||
if let Some(model) = &cli.model {
|
|
||||||
config.api.model = model.clone();
|
|
||||||
}
|
|
||||||
if let Some(max_tokens) = cli.max_tokens {
|
|
||||||
config.api.max_tokens = max_tokens;
|
|
||||||
}
|
|
||||||
if cli.thinking {
|
|
||||||
config.api.thinking = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
enable_raw_mode()?;
|
|
||||||
let mut stdout = io::stdout();
|
|
||||||
execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
|
|
||||||
let backend = CrosstermBackend::new(stdout);
|
|
||||||
let mut terminal = Terminal::new(backend)?;
|
|
||||||
|
|
||||||
let mut app = App::with_config(config);
|
|
||||||
|
|
||||||
// Load session if specified
|
|
||||||
if let Some(session_id) = &cli.session {
|
|
||||||
if let Err(e) = app.load_session(session_id) {
|
|
||||||
eprintln!("Warning: Failed to load session {}: {}", session_id, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let res = app.run(&mut terminal).await;
|
|
||||||
|
|
||||||
disable_raw_mode()?;
|
|
||||||
execute!(
|
|
||||||
terminal.backend_mut(),
|
|
||||||
LeaveAlternateScreen,
|
|
||||||
DisableMouseCapture
|
|
||||||
)?;
|
|
||||||
terminal.show_cursor()?;
|
|
||||||
|
|
||||||
if let Err(err) = res {
|
|
||||||
eprintln!("Error: {}", err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Some(Commands::Status) => {
|
Some(Commands::Status) => {
|
||||||
use miyabi_core::config::Config;
|
use miyabi_core::config::Config;
|
||||||
|
|
||||||
let config = Config::load().unwrap_or_default();
|
let config = Config::load().unwrap_or_default();
|
||||||
|
|
||||||
println!("Miyabi Status: Ready");
|
println!("MergeGate Status: Ready");
|
||||||
println!();
|
println!();
|
||||||
|
println!("Binary: {}", current_binary_name());
|
||||||
println!("Config: {}", Config::default_path().display());
|
println!("Config: {}", Config::default_path().display());
|
||||||
println!("Sessions: {}", config.sessions_dir().display());
|
|
||||||
println!("Model: {}", config.api.model);
|
|
||||||
println!();
|
println!();
|
||||||
|
println!("Core workflow:");
|
||||||
|
println!(" {}", gate_command("status"));
|
||||||
|
println!(" {}", gate_command("init"));
|
||||||
|
println!(" {}", gate_command("guide"));
|
||||||
|
println!();
|
||||||
|
println!("Direct runtime config remains on disk for compatibility.");
|
||||||
|
println!("Model: {}", config.api.model);
|
||||||
|
println!("Sessions: {}", config.sessions_dir().display());
|
||||||
|
|
||||||
// Load and show rules info
|
// Load and show rules info
|
||||||
let cwd = std::env::current_dir().unwrap_or_default();
|
let cwd = std::env::current_dir().unwrap_or_default();
|
||||||
|
|
@ -766,152 +684,6 @@ async fn main() -> anyhow::Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(Commands::Agent {
|
|
||||||
prompt,
|
|
||||||
max_iterations,
|
|
||||||
auto_approve,
|
|
||||||
format,
|
|
||||||
system,
|
|
||||||
}) => {
|
|
||||||
use miyabi_core::{
|
|
||||||
config::Config, Agent, AgentConfig, AgentEvent, AnthropicClient, ExecutorRegistry,
|
|
||||||
};
|
|
||||||
use tokio::sync::mpsc;
|
|
||||||
|
|
||||||
// Load config
|
|
||||||
let mut config = if let Some(config_path) = &cli.config {
|
|
||||||
Config::load_from(config_path)?
|
|
||||||
} else {
|
|
||||||
Config::load().unwrap_or_default()
|
|
||||||
};
|
|
||||||
|
|
||||||
// Apply CLI overrides
|
|
||||||
if let Some(model) = &cli.model {
|
|
||||||
config.api.model = model.clone();
|
|
||||||
}
|
|
||||||
if let Some(max_tokens) = cli.max_tokens {
|
|
||||||
config.api.max_tokens = max_tokens;
|
|
||||||
}
|
|
||||||
if cli.thinking {
|
|
||||||
config.api.thinking = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get API key
|
|
||||||
let api_key = config
|
|
||||||
.api
|
|
||||||
.api_key
|
|
||||||
.clone()
|
|
||||||
.or_else(|| std::env::var("ANTHROPIC_API_KEY").ok())
|
|
||||||
.ok_or_else(|| {
|
|
||||||
anyhow::anyhow!("No API key found. Set ANTHROPIC_API_KEY or add to config.")
|
|
||||||
})?;
|
|
||||||
|
|
||||||
// Create client
|
|
||||||
let client = AnthropicClient::new(api_key)?
|
|
||||||
.with_model(&config.api.model)
|
|
||||||
.with_max_tokens(config.api.max_tokens)
|
|
||||||
.with_thinking(config.api.thinking);
|
|
||||||
|
|
||||||
// Create executor registry with standard tools
|
|
||||||
let registry = ExecutorRegistry::with_standard_tools();
|
|
||||||
|
|
||||||
// Configure agent
|
|
||||||
let agent_config = AgentConfig {
|
|
||||||
max_iterations,
|
|
||||||
max_tokens_per_turn: config.api.max_tokens,
|
|
||||||
require_approval: !auto_approve,
|
|
||||||
auto_approve_patterns: if auto_approve {
|
|
||||||
vec![
|
|
||||||
"read".to_string(),
|
|
||||||
"glob".to_string(),
|
|
||||||
"grep".to_string(),
|
|
||||||
"write".to_string(),
|
|
||||||
"edit".to_string(),
|
|
||||||
"bash".to_string(),
|
|
||||||
]
|
|
||||||
} else {
|
|
||||||
vec!["read".to_string(), "glob".to_string(), "grep".to_string()]
|
|
||||||
},
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
// Create agent
|
|
||||||
let mut agent = Agent::new(client, registry).with_config(agent_config);
|
|
||||||
|
|
||||||
// Set system prompt
|
|
||||||
if let Some(sys) = system {
|
|
||||||
agent = agent.with_system_prompt(sys);
|
|
||||||
} else if let Some(sys) = config.api.system_prompt {
|
|
||||||
agent = agent.with_system_prompt(sys);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create event channel for progress
|
|
||||||
let (tx, mut rx) = mpsc::channel(100);
|
|
||||||
let agent = agent.with_event_channel(tx);
|
|
||||||
|
|
||||||
// Spawn agent execution
|
|
||||||
let agent_handle = tokio::spawn(async move { agent.run(&prompt).await });
|
|
||||||
|
|
||||||
// Process events
|
|
||||||
while let Some(event) = rx.recv().await {
|
|
||||||
match &event {
|
|
||||||
AgentEvent::Started { prompt } => {
|
|
||||||
if format != "json" {
|
|
||||||
eprintln!("🚀 Agent started with prompt: {}", truncate_str(prompt, 50));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AgentEvent::Thinking { iteration } => {
|
|
||||||
if format != "json" {
|
|
||||||
eprintln!("💭 Iteration {}", iteration + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AgentEvent::ToolDetected { name, .. } => {
|
|
||||||
if format != "json" {
|
|
||||||
eprintln!("🔧 Tool detected: {}", name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AgentEvent::ToolExecuting { name, .. } => {
|
|
||||||
if format != "json" {
|
|
||||||
eprintln!("⚡ Executing: {}", name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AgentEvent::ToolCompleted { name, .. } => {
|
|
||||||
if format != "json" {
|
|
||||||
eprintln!("✅ Completed: {}", name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AgentEvent::ToolFailed { name, error } => {
|
|
||||||
if format != "json" {
|
|
||||||
eprintln!("❌ Failed {}: {}", name, error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AgentEvent::Completed { result } => {
|
|
||||||
if format == "json" {
|
|
||||||
println!("{}", serde_json::to_string_pretty(&result)?);
|
|
||||||
} else {
|
|
||||||
println!("\n{}", result.output);
|
|
||||||
eprintln!(
|
|
||||||
"\n📊 Stats: {} iterations, {} tool calls, {} tokens",
|
|
||||||
result.iterations, result.tool_calls, result.total_tokens
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AgentEvent::Failed { error } => {
|
|
||||||
eprintln!("❌ Agent failed: {}", error);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait for agent to complete
|
|
||||||
match agent_handle.await? {
|
|
||||||
Ok(_) => {}
|
|
||||||
Err(e) => {
|
|
||||||
eprintln!("Agent error: {}", e);
|
|
||||||
std::process::exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some(Commands::Gate {
|
Some(Commands::Gate {
|
||||||
format,
|
format,
|
||||||
emit_event,
|
emit_event,
|
||||||
|
|
|
||||||
|
|
@ -1,578 +1,172 @@
|
||||||
# MergeGate ユーザーマニュアル
|
# MergeGate ユーザーマニュアル
|
||||||
|
|
||||||
**Version**: 0.1.0
|
**Version**: 0.1.0
|
||||||
**Last Updated**: 2025-11-23
|
**Last Updated**: 2026-04-10
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 目次
|
|
||||||
|
|
||||||
1. [はじめに](#はじめに)
|
|
||||||
2. [インストール](#インストール)
|
|
||||||
3. [初期設定](#初期設定)
|
|
||||||
4. [基本的な使い方](#基本的な使い方)
|
|
||||||
5. [TUIモード](#tuiモード)
|
|
||||||
6. [Agentモード](#agentモード)
|
|
||||||
7. [セッション管理](#セッション管理)
|
|
||||||
8. [設定ファイル](#設定ファイル)
|
|
||||||
9. [プロジェクトルール](#プロジェクトルール)
|
|
||||||
10. [トラブルシューティング](#トラブルシューティング)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## はじめに
|
## はじめに
|
||||||
|
|
||||||
MergeGate は、AI-assisted development 向けの deterministic task execution and merge workflow です。CLI では `miyabi` と `mergegate` の両方を使え、対話型の TUI と `gate` ベースの repo workflow を提供します。
|
MergeGate は、AI-assisted development 向けの engine-agnostic gate CLI です。
|
||||||
|
|
||||||
設計思想はシンプルです。
|
このツールはエージェント本体ではありません。TUI や direct backend を前提にせず、repo 作業を安全に進めるための protocol を提供します。
|
||||||
|
|
||||||
|
役割は次の通りです。
|
||||||
|
|
||||||
|
- task を登録する
|
||||||
|
- impact を記録する
|
||||||
|
- file lock を取る
|
||||||
|
- branch / PR / merge 状態を結び付ける
|
||||||
|
- completion を記録する
|
||||||
|
|
||||||
|
設計思想:
|
||||||
|
|
||||||
- `GitNexus`: コードベースを理解する
|
- `GitNexus`: コードベースを理解する
|
||||||
- `MergeGate`: 変更を安全に実行する
|
- `MergeGate`: 変更を安全に実行する
|
||||||
|
|
||||||
影響範囲が分かるだけでは、AI エージェントは安全に開発できません。どの task を登録し、どのファイルを lock し、どの順序で branch / PR / merge まで進めるかを protocol として固定するのが MergeGate の役割です。
|
## 何をするツールか
|
||||||
|
|
||||||
### 主な機能
|
MergeGate の中心機能は `gate` です。
|
||||||
|
|
||||||
- **TUIモード**: 美しいターミナルUIでの対話
|
```bash
|
||||||
- **Agentモード**: ファイル操作やコマンド実行を含む自律実行
|
mergegate gate ...
|
||||||
- **セッション管理**: 会話履歴の保存・再開
|
```
|
||||||
- **プロジェクトルール**: .miyabirulesによるカスタムルール
|
|
||||||
|
|
||||||
---
|
または互換 alias として:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
miyabi gate ...
|
||||||
|
```
|
||||||
|
|
||||||
|
実行エンジンは Claude Code、Codex、Gemini CLI など、どれでも構いません。MergeGate はその前後で repo workflow を制御します。
|
||||||
|
|
||||||
## インストール
|
## インストール
|
||||||
|
|
||||||
### 必要要件
|
### 必要要件
|
||||||
|
|
||||||
- Rust 1.70以上
|
- Rust 1.70以上
|
||||||
- Anthropic APIキー
|
|
||||||
|
|
||||||
### ビルド手順
|
### ビルド
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 1. リポジトリをクローン
|
|
||||||
git clone https://github.com/ShunsukeHayashi/mergegate.git
|
git clone https://github.com/ShunsukeHayashi/mergegate.git
|
||||||
cd mergegate
|
cd mergegate
|
||||||
|
|
||||||
# 2. リリースビルド
|
|
||||||
cargo build --release
|
cargo build --release
|
||||||
|
|
||||||
# 3. バイナリの確認
|
|
||||||
ls -la target/release/miyabi target/release/mergegate
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### パスを通す(オプション)
|
## 最初にやること
|
||||||
|
|
||||||
|
### 1. repo の状態確認
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# ~/.bashrc または ~/.zshrc に追加
|
./target/release/mergegate gate status
|
||||||
export PATH="$PATH:/path/to/mergegate/target/release"
|
|
||||||
|
|
||||||
# 設定を反映
|
|
||||||
source ~/.bashrc # または source ~/.zshrc
|
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
`tasks: 0` は正常です。ledger はあるが task がまだ無い状態です。
|
||||||
|
|
||||||
## 初期設定
|
### 2. 初期化
|
||||||
|
|
||||||
### 1. 設定ファイルの生成
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./target/release/miyabi init
|
./target/release/mergegate gate init
|
||||||
```
|
```
|
||||||
|
|
||||||
これにより `~/.miyabi/config.toml` が作成されます。
|
これで `project_memory/tasks.json` が作成されます。
|
||||||
|
|
||||||
### 2. APIキーの設定
|
### 3. ガイド確認
|
||||||
|
|
||||||
**方法1: 環境変数(推奨)**
|
|
||||||
```bash
|
|
||||||
export ANTHROPIC_API_KEY="sk-ant-api03-..."
|
|
||||||
```
|
|
||||||
|
|
||||||
永続化する場合は `~/.bashrc` や `~/.zshrc` に追加:
|
|
||||||
```bash
|
|
||||||
echo 'export ANTHROPIC_API_KEY="sk-ant-api03-..."' >> ~/.zshrc
|
|
||||||
```
|
|
||||||
|
|
||||||
**方法2: 設定ファイル**
|
|
||||||
```bash
|
|
||||||
vim ~/.miyabi/config.toml
|
|
||||||
```
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[api]
|
|
||||||
api_key = "sk-ant-api03-..."
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. 設定の確認
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./target/release/miyabi status
|
./target/release/mergegate gate guide
|
||||||
```
|
```
|
||||||
|
|
||||||
出力例:
|
## 基本フロー
|
||||||
```
|
|
||||||
Miyabi Status: Ready
|
|
||||||
|
|
||||||
Config: /Users/you/.miyabi/config.toml
|
```bash
|
||||||
Sessions: /Users/you/.miyabi/sessions
|
./target/release/mergegate gate register --issue 123 --title "Fix login redirect"
|
||||||
Model: claude-sonnet-4-5-20250929
|
./target/release/mergegate gate impact issue-123 --risk medium --symbols 3
|
||||||
|
./target/release/mergegate gate assign issue-123 --agent codex --node macbook --files "src/auth.rs"
|
||||||
Rules: 0 rules loaded
|
./target/release/mergegate gate branch issue-123 codex/fix-login-redirect
|
||||||
|
./target/release/mergegate gate pr issue-123 456
|
||||||
|
./target/release/mergegate gate merge issue-123 <sha>
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
典型的な順番:
|
||||||
|
|
||||||
## 基本的な使い方
|
1. `register`
|
||||||
|
2. `impact`
|
||||||
|
3. `assign`
|
||||||
|
4. 実装
|
||||||
|
5. `branch`
|
||||||
|
6. `pr`
|
||||||
|
7. `merge` または `manual-complete`
|
||||||
|
|
||||||
### コマンド一覧
|
## コマンド一覧
|
||||||
|
|
||||||
| コマンド | 説明 |
|
| コマンド | 説明 |
|
||||||
|---------|------|
|
|---------|------|
|
||||||
| `miyabi tui` | TUIモードを起動 |
|
| `mergegate gate status` | ledger 全体または task 状態を表示 |
|
||||||
| `miyabi agent <prompt>` | Agentモードで実行 |
|
| `mergegate gate init` | ledger を初期化 |
|
||||||
| `miyabi status` | ステータス表示 |
|
| `mergegate gate guide` | workflow ガイドを表示 |
|
||||||
| `miyabi version` | バージョン情報 |
|
| `mergegate gate register` | task を登録 |
|
||||||
| `miyabi init` | 設定ファイル生成 |
|
| `mergegate gate impact` | impact を記録 |
|
||||||
| `miyabi sessions` | セッション一覧 |
|
| `mergegate gate assign` | task を割り当てて lock を取得 |
|
||||||
| `miyabi rules` | プロジェクトルール表示 |
|
| `mergegate gate branch` | branch を記録 |
|
||||||
|
| `mergegate gate pr` | PR 番号を記録 |
|
||||||
|
| `mergegate gate merge` | merge を記録 |
|
||||||
|
| `mergegate gate manual-complete` | 手動完了を記録 |
|
||||||
|
| `mergegate gate locks` | active lock を表示 |
|
||||||
|
| `mergegate gate dispatchable` | 今着手できる task を表示 |
|
||||||
|
| `mergegate gate dag` | 依存順序を表示 |
|
||||||
|
|
||||||
### グローバルオプション
|
## 実行エンジンとの関係
|
||||||
|
|
||||||
| オプション | 説明 |
|
MergeGate は coding agent を置き換えるものではありません。
|
||||||
|-----------|------|
|
|
||||||
| `-m, --model <MODEL>` | 使用するモデルを指定 |
|
|
||||||
| `--max-tokens <N>` | 最大トークン数 |
|
|
||||||
| `--thinking` | Extended Thinking有効化 |
|
|
||||||
| `-c, --config <PATH>` | 設定ファイルパス |
|
|
||||||
| `-s, --session <ID>` | セッションID指定 |
|
|
||||||
|
|
||||||
### 使用例
|
想定している使い方:
|
||||||
|
|
||||||
```bash
|
- Claude Code が実装する
|
||||||
# バージョン確認
|
- Codex が実装する
|
||||||
./target/release/miyabi version
|
- Gemini CLI が実装する
|
||||||
|
- MergeGate が task / lock / merge discipline を管理する
|
||||||
|
|
||||||
# ステータス確認
|
つまり:
|
||||||
./target/release/miyabi status
|
|
||||||
|
|
||||||
# モデル指定でTUI起動
|
- エージェントは交換可能
|
||||||
./target/release/miyabi tui --model claude-sonnet-4-5-20250929
|
- gate protocol は固定
|
||||||
|
|
||||||
# Extended Thinking有効でTUI起動
|
## よくある質問
|
||||||
./target/release/miyabi tui --thinking
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
### API キーは必要ですか
|
||||||
|
|
||||||
## TUIモード
|
`gate` workflow だけなら不要です。
|
||||||
|
|
||||||
### 起動
|
### TUI は必要ですか
|
||||||
|
|
||||||
```bash
|
不要です。MergeGate の本体ではありません。
|
||||||
./target/release/miyabi tui
|
|
||||||
```
|
|
||||||
|
|
||||||
### キーバインド
|
### built-in backend は必要ですか
|
||||||
|
|
||||||
#### 基本操作
|
不要です。MergeGate の本体ではありません。
|
||||||
|
|
||||||
| キー | 動作 |
|
### `miyabi` と `mergegate` のどちらを使えばいいですか
|
||||||
|------|------|
|
|
||||||
| `Enter` | メッセージ送信 |
|
|
||||||
| `Ctrl+C` | 終了 |
|
|
||||||
| `Esc` | オーバーレイを閉じる / キャンセル |
|
|
||||||
| `F1` | ヘルプ表示 |
|
|
||||||
|
|
||||||
#### ナビゲーション
|
新規利用では `mergegate` を推奨します。`miyabi` は互換 alias です。
|
||||||
|
|
||||||
| キー | 動作 |
|
|
||||||
|------|------|
|
|
||||||
| `j` / `↓` | 下にスクロール |
|
|
||||||
| `k` / `↑` | 上にスクロール |
|
|
||||||
| `Page Down` | ページ下へ |
|
|
||||||
| `Page Up` | ページ上へ |
|
|
||||||
| `g` | 先頭へ |
|
|
||||||
| `G` | 末尾へ |
|
|
||||||
|
|
||||||
#### コマンド
|
|
||||||
|
|
||||||
| キー | 動作 |
|
|
||||||
|------|------|
|
|
||||||
| `Ctrl+P` | コマンドパレット |
|
|
||||||
| `Ctrl+N` | 新規セッション |
|
|
||||||
| `Ctrl+O` | セッションを開く |
|
|
||||||
| `Ctrl+S` | セッション保存 |
|
|
||||||
|
|
||||||
### Vimモード
|
|
||||||
|
|
||||||
設定で有効化できます:
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[ui]
|
|
||||||
vim_mode = true
|
|
||||||
```
|
|
||||||
|
|
||||||
有効にすると、テキスト入力でVimキーバインドが使用可能になります。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Agentモード
|
|
||||||
|
|
||||||
Agentモードは、プロンプトに基づいて自律的にタスクを実行します。
|
|
||||||
|
|
||||||
### 基本使用
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./target/release/miyabi agent "タスクの説明"
|
|
||||||
```
|
|
||||||
|
|
||||||
### オプション
|
|
||||||
|
|
||||||
| オプション | 説明 | デフォルト |
|
|
||||||
|-----------|------|-----------|
|
|
||||||
| `--max-iterations <N>` | 最大イテレーション数 | 10 |
|
|
||||||
| `--auto-approve` | ツール実行を自動承認 | false |
|
|
||||||
| `--format <FORMAT>` | 出力形式 (text/json) | text |
|
|
||||||
| `--system <PROMPT>` | システムプロンプト | なし |
|
|
||||||
|
|
||||||
### 使用例
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 基本的な実行
|
|
||||||
./target/release/miyabi agent "Create a Python script that prints hello world"
|
|
||||||
|
|
||||||
# 自動承認モード(注意して使用)
|
|
||||||
./target/release/miyabi agent --auto-approve "List all .rs files in src/"
|
|
||||||
|
|
||||||
# イテレーション数を増やす
|
|
||||||
./target/release/miyabi agent --max-iterations 20 "Refactor the utils module"
|
|
||||||
|
|
||||||
# JSON出力
|
|
||||||
./target/release/miyabi agent --format json "Show current directory"
|
|
||||||
|
|
||||||
# カスタムシステムプロンプト
|
|
||||||
./target/release/miyabi agent --system "You are an expert Rust developer" "Review main.rs"
|
|
||||||
```
|
|
||||||
|
|
||||||
### 利用可能なツール
|
|
||||||
|
|
||||||
Agentモードでは以下のツールが使用可能です:
|
|
||||||
|
|
||||||
- **Bash**: シェルコマンドの実行
|
|
||||||
- **Read**: ファイルの読み取り
|
|
||||||
- **Write**: ファイルの書き込み
|
|
||||||
- **Edit**: ファイルの編集
|
|
||||||
- **Glob**: ファイルパターン検索
|
|
||||||
- **Grep**: テキスト検索
|
|
||||||
|
|
||||||
### セキュリティ
|
|
||||||
|
|
||||||
- デフォルトでは危険な操作は承認を求められます
|
|
||||||
- `--auto-approve` は信頼できるタスクのみに使用してください
|
|
||||||
- `--max-iterations` で無限ループを防止
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## セッション管理
|
|
||||||
|
|
||||||
### セッション一覧の表示
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./target/release/miyabi sessions
|
|
||||||
```
|
|
||||||
|
|
||||||
出力例:
|
|
||||||
```
|
|
||||||
ID Title Messages Tokens Updated
|
|
||||||
------------------------------------------------------------------------------------------
|
|
||||||
133b91bf-99c9-4097-974c-c60c9abd2495 test 6 246 2025-11-22 14:36
|
|
||||||
19af5958-183f-4b39-be2e-b14b0809181c test 2 21 2025-11-22 14:03
|
|
||||||
```
|
|
||||||
|
|
||||||
### セッションの操作
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# セッションを削除
|
|
||||||
./target/release/miyabi sessions -d <session-id>
|
|
||||||
|
|
||||||
# JSONにエクスポート
|
|
||||||
./target/release/miyabi sessions -e <session-id>
|
|
||||||
|
|
||||||
# Markdownにエクスポート
|
|
||||||
./target/release/miyabi sessions -m <session-id>
|
|
||||||
```
|
|
||||||
|
|
||||||
### セッションの再開
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 特定のセッションからTUIを起動
|
|
||||||
./target/release/miyabi tui -s <session-id>
|
|
||||||
```
|
|
||||||
|
|
||||||
### 保存場所
|
|
||||||
|
|
||||||
セッションは `~/.miyabi/sessions/` に保存されます。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 設定ファイル
|
|
||||||
|
|
||||||
### 設定ファイルの場所
|
|
||||||
|
|
||||||
```
|
|
||||||
~/.miyabi/config.toml
|
|
||||||
```
|
|
||||||
|
|
||||||
### 完全な設定例
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[api]
|
|
||||||
# Anthropic APIキー(環境変数ANTHROPIC_API_KEYでも設定可能)
|
|
||||||
api_key = "sk-ant-api03-..."
|
|
||||||
|
|
||||||
# 使用するモデル
|
|
||||||
model = "claude-sonnet-4-5-20250929"
|
|
||||||
|
|
||||||
# 最大トークン数
|
|
||||||
max_tokens = 8192
|
|
||||||
|
|
||||||
# Extended Thinking(Claude 4.5+)
|
|
||||||
thinking = false
|
|
||||||
|
|
||||||
# システムプロンプト
|
|
||||||
system_prompt = "You are a helpful AI assistant."
|
|
||||||
|
|
||||||
# リクエストタイムアウト(秒)
|
|
||||||
timeout_secs = 120
|
|
||||||
|
|
||||||
# 最大リトライ回数
|
|
||||||
max_retries = 3
|
|
||||||
|
|
||||||
[ui]
|
|
||||||
# サイドバー表示
|
|
||||||
show_sidebar = false
|
|
||||||
|
|
||||||
# ステータスバー表示
|
|
||||||
show_status_bar = true
|
|
||||||
|
|
||||||
# パンくずリスト表示
|
|
||||||
show_breadcrumb = true
|
|
||||||
|
|
||||||
# カラーテーマ
|
|
||||||
theme = "tokyo-night"
|
|
||||||
|
|
||||||
# Vimモード
|
|
||||||
vim_mode = false
|
|
||||||
|
|
||||||
# コードブロックの行番号
|
|
||||||
show_line_numbers = true
|
|
||||||
|
|
||||||
[session]
|
|
||||||
# セッションの自動保存
|
|
||||||
auto_save = true
|
|
||||||
|
|
||||||
# 自動保存間隔(秒)
|
|
||||||
auto_save_interval = 30
|
|
||||||
|
|
||||||
# 最大セッション数
|
|
||||||
max_sessions = 100
|
|
||||||
|
|
||||||
[tools]
|
|
||||||
# Bashツールを有効化
|
|
||||||
enable_bash = true
|
|
||||||
|
|
||||||
# ファイルツール(read/write/edit)を有効化
|
|
||||||
enable_file_tools = true
|
|
||||||
|
|
||||||
# 検索ツール(glob/grep)を有効化
|
|
||||||
enable_search_tools = true
|
|
||||||
|
|
||||||
# 低リスクツールの自動承認
|
|
||||||
auto_approve_low_risk = false
|
|
||||||
|
|
||||||
# Bashコマンドのタイムアウト(秒)
|
|
||||||
bash_timeout = 120
|
|
||||||
```
|
|
||||||
|
|
||||||
### 環境変数による上書き
|
|
||||||
|
|
||||||
| 環境変数 | 説明 |
|
|
||||||
|---------|------|
|
|
||||||
| `ANTHROPIC_API_KEY` | APIキー |
|
|
||||||
| `MIYABI_MODEL` | モデル名 |
|
|
||||||
| `MIYABI_MAX_TOKENS` | 最大トークン数 |
|
|
||||||
| `MIYABI_THINKING` | Extended Thinking (true/false) |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## プロジェクトルール
|
|
||||||
|
|
||||||
### .miyabirulesファイル
|
|
||||||
|
|
||||||
プロジェクトルートに `.miyabirules` ファイルを作成することで、プロジェクト固有のルールを定義できます。
|
|
||||||
|
|
||||||
### ファイル形式
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: 1
|
|
||||||
|
|
||||||
rules:
|
|
||||||
- name: "no-unwrap"
|
|
||||||
pattern: ".unwrap()"
|
|
||||||
suggestion: "Use ? operator or proper error handling"
|
|
||||||
file_extensions: ["rs"]
|
|
||||||
severity: "warning"
|
|
||||||
|
|
||||||
- name: "no-println-debug"
|
|
||||||
pattern: "println!"
|
|
||||||
suggestion: "Use tracing macros for logging"
|
|
||||||
file_extensions: ["rs"]
|
|
||||||
severity: "info"
|
|
||||||
|
|
||||||
agent_preferences:
|
|
||||||
codegen:
|
|
||||||
style: "functional"
|
|
||||||
error_handling: "result"
|
|
||||||
min_score: 80
|
|
||||||
review:
|
|
||||||
min_score: 70
|
|
||||||
```
|
|
||||||
|
|
||||||
### ルールの確認
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./target/release/miyabi rules
|
|
||||||
```
|
|
||||||
|
|
||||||
### 重要度レベル
|
|
||||||
|
|
||||||
| レベル | 説明 |
|
|
||||||
|--------|------|
|
|
||||||
| `error` | 重大な問題(赤) |
|
|
||||||
| `warning` | 警告(黄) |
|
|
||||||
| `info` | 情報(青) |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## トラブルシューティング
|
## トラブルシューティング
|
||||||
|
|
||||||
### "API key not found" エラー
|
### `tasks: 0`
|
||||||
|
|
||||||
|
異常ではありません。task が未登録なだけです。
|
||||||
|
|
||||||
|
### どの task から始めればよいか分からない
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 環境変数を確認
|
./target/release/mergegate gate dispatchable
|
||||||
echo $ANTHROPIC_API_KEY
|
./target/release/mergegate gate dag
|
||||||
|
./target/release/mergegate gate guide
|
||||||
# 設定されていない場合
|
|
||||||
export ANTHROPIC_API_KEY="sk-ant-..."
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### "Device not configured" エラー
|
### 既存 repo に導入済みか分からない
|
||||||
|
|
||||||
ターミナルがTUIをサポートしていない可能性があります:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 別のターミナルを試す(iTerm2, Alacritty等)
|
./target/release/mergegate gate status
|
||||||
|
|
||||||
# または明示的にTERM設定
|
|
||||||
TERM=xterm-256color ./target/release/miyabi tui
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### ビルドエラー
|
ledger が無ければ `gate init` に進めます。
|
||||||
|
|
||||||
```bash
|
|
||||||
# Rustを最新版に更新
|
|
||||||
rustup update
|
|
||||||
|
|
||||||
# クリーンビルド
|
|
||||||
cargo clean
|
|
||||||
cargo build --release
|
|
||||||
```
|
|
||||||
|
|
||||||
### セッションが保存されない
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# ディレクトリの確認
|
|
||||||
ls -la ~/.miyabi/sessions/
|
|
||||||
|
|
||||||
# なければ作成
|
|
||||||
mkdir -p ~/.miyabi/sessions
|
|
||||||
```
|
|
||||||
|
|
||||||
### デバッグモード
|
|
||||||
|
|
||||||
詳細なログを表示:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
RUST_LOG=debug ./target/release/miyabi tui
|
|
||||||
```
|
|
||||||
|
|
||||||
### ネットワークエラー
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# タイムアウトを延長
|
|
||||||
# ~/.miyabi/config.toml
|
|
||||||
[api]
|
|
||||||
timeout_secs = 300
|
|
||||||
max_retries = 5
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## サポート
|
|
||||||
|
|
||||||
### ヘルプの確認
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 全体のヘルプ
|
|
||||||
./target/release/miyabi --help
|
|
||||||
|
|
||||||
# サブコマンドのヘルプ
|
|
||||||
./target/release/miyabi agent --help
|
|
||||||
./target/release/miyabi sessions --help
|
|
||||||
```
|
|
||||||
|
|
||||||
### 問題報告
|
|
||||||
|
|
||||||
GitHub Issues: https://github.com/ShunsukeHayashi/mergegate/issues
|
|
||||||
|
|
||||||
### TUIでのヘルプ
|
|
||||||
|
|
||||||
TUI起動中に `F1` キーでヘルプを表示できます。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 付録
|
|
||||||
|
|
||||||
### 対応モデル
|
|
||||||
|
|
||||||
- `claude-sonnet-4-5-20250929` (デフォルト)
|
|
||||||
- `claude-haiku-4-5-20251001`
|
|
||||||
- `claude-sonnet-4-20250514`
|
|
||||||
|
|
||||||
### ファイル構成
|
|
||||||
|
|
||||||
```
|
|
||||||
~/.miyabi/
|
|
||||||
├── config.toml # 設定ファイル
|
|
||||||
└── sessions/ # セッションデータ
|
|
||||||
├── xxx.json
|
|
||||||
└── yyy.json
|
|
||||||
```
|
|
||||||
|
|
||||||
### ショートカット早見表
|
|
||||||
|
|
||||||
| 操作 | キー |
|
|
||||||
|------|------|
|
|
||||||
| 送信 | Enter |
|
|
||||||
| 終了 | Ctrl+C |
|
|
||||||
| ヘルプ | F1 |
|
|
||||||
| コマンドパレット | Ctrl+P |
|
|
||||||
| 新規セッション | Ctrl+N |
|
|
||||||
| セッションを開く | Ctrl+O |
|
|
||||||
| 保存 | Ctrl+S |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Built with Rust, Ratatui, and Claude API**
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue