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"
|
||||
members = [
|
||||
"crates/mergegate-cli",
|
||||
"crates/mergegate-tui",
|
||||
"crates/mergegate-core",
|
||||
]
|
||||
|
||||
|
|
@ -14,8 +13,8 @@ authors = ["Miyabi Team"]
|
|||
license = "BUSL-1.1"
|
||||
repository = "https://github.com/ShunsukeHayashi/mergegate"
|
||||
homepage = "https://github.com/ShunsukeHayashi/mergegate"
|
||||
description = "MergeGate - Deterministic task execution and merge workflow for AI-assisted development"
|
||||
keywords = ["ai", "cli", "tui", "autonomous", "development"]
|
||||
description = "MergeGate - Engine-agnostic gate CLI for deterministic task execution in AI-assisted development"
|
||||
keywords = ["ai", "cli", "workflow", "merge", "development"]
|
||||
categories = ["command-line-utilities", "development-tools"]
|
||||
|
||||
[workspace.dependencies]
|
||||
|
|
@ -24,15 +23,6 @@ tokio = { version = "1", features = ["rt-multi-thread", "macros", "io-std", "syn
|
|||
futures = "0.3"
|
||||
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
|
||||
textwrap = "0.16"
|
||||
unicode-width = "0.2"
|
||||
|
|
|
|||
|
|
@ -1,13 +1,22 @@
|
|||
# MergeGate
|
||||
Deterministic execution protocol for AI-assisted development.
|
||||
Engine-agnostic gate CLI for AI-assisted development.
|
||||
|
||||
Execution layer for GitNexus-style code intelligence:
|
||||
- `GitNexus`: understand the codebase
|
||||
- `MergeGate`: execute changes safely
|
||||
|
||||
Current CLI entrypoints: `miyabi` and `mergegate`
|
||||
Core product:
|
||||
- `mergegate gate ...`
|
||||
- `miyabi gate ...` (compatibility alias)
|
||||
|
||||
- `miyabi tui` / `mergegate tui`: terminal assistant
|
||||
- `miyabi gate` / `mergegate gate`: deterministic task execution, file locks, and PR/merge workflow
|
||||
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.
|
||||
|
||||
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 is a deterministic execution protocol 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.
|
||||
MergeGate is an engine-agnostic gate CLI for AI-assisted development.
|
||||
|
||||
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:
|
||||
|
||||
- `GitNexus`: understand the codebase
|
||||
- `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
|
||||
- `miyabi gate` / `mergegate gate`: deterministic task execution and file-lock workflow for repo work
|
||||
MergeGate is a repo workflow tool for deterministic execution.
|
||||
|
||||
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
|
||||
|
||||
```bash
|
||||
# 1. Clone and build
|
||||
git clone https://github.com/ShunsukeHayashi/mergegate.git
|
||||
cd mergegate
|
||||
cargo build --release
|
||||
|
||||
# 2. Set API key
|
||||
export ANTHROPIC_API_KEY="sk-ant-..."
|
||||
|
||||
# 3. Run
|
||||
./target/release/mergegate tui
|
||||
./target/release/mergegate gate status
|
||||
./target/release/mergegate gate init
|
||||
./target/release/mergegate gate guide
|
||||
```
|
||||
|
||||
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
|
||||
|
||||
- **Execution layer for code intelligence** - Pair blast-radius understanding with deterministic execution, not chat-only automation
|
||||
- **Deterministic task execution** - Register, analyze, lock, review, and merge in a verifiable order
|
||||
- **Repo-safe agent workflow** - File locks and gate checks reduce accidental overlap and unsafe edits
|
||||
- **Interactive TUI** - Terminal assistant for chat, prompts, and agent execution
|
||||
- **Agent mode** - Autonomous execution with tool approval
|
||||
- **Session management** - Persist and resume conversations
|
||||
- **Configurable** - TOML-based configuration
|
||||
- **Engine agnostic**: Use Claude Code, Codex, Gemini CLI, or another agent runtime
|
||||
- **Deterministic execution**: Register, analyze, lock, implement, review, and merge in a verifiable order
|
||||
- **Repo-safe coordination**: Reduce accidental overlap with file locks and explicit task ownership
|
||||
- **Execution ledger**: Keep branch, PR, merge, and completion state tied to actual work
|
||||
- **Protocol over chat**: The product is the workflow gate, not a built-in assistant
|
||||
|
||||
## Positioning
|
||||
|
||||
MergeGate was designed for teams that already believe code understanding 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.
|
||||
MergeGate exists because understanding code is not enough.
|
||||
|
||||
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:
|
||||
|
||||
|
|
@ -63,7 +76,6 @@ If GitNexus answers "what is this change connected to?", MergeGate answers "how
|
|||
### Prerequisites
|
||||
|
||||
- Rust 1.70+
|
||||
- Anthropic API key
|
||||
|
||||
### Build from Source
|
||||
|
||||
|
|
@ -77,75 +89,34 @@ Binary will be at `target/release/miyabi` and `target/release/mergegate`.
|
|||
|
||||
## Quick Start
|
||||
|
||||
Choose the path that matches what you want to do.
|
||||
|
||||
### A. Use MergeGate as a terminal assistant
|
||||
|
||||
Run the TUI after configuring your API key.
|
||||
|
||||
#### 1. Generate Config
|
||||
### 1. Check repo status
|
||||
|
||||
```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
|
||||
|
||||
Edit `~/.miyabi/config.toml`:
|
||||
|
||||
```toml
|
||||
[api]
|
||||
api_key = "sk-ant-..."
|
||||
```
|
||||
|
||||
Or use environment variable:
|
||||
### 2. Initialize gate ledger if needed
|
||||
|
||||
```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
|
||||
./target/release/miyabi tui
|
||||
# or simply
|
||||
./target/release/miyabi
|
||||
./target/release/mergegate gate guide
|
||||
```
|
||||
|
||||
### B. Use MergeGate as a task execution gate
|
||||
|
||||
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
|
||||
### 4. Start a task
|
||||
|
||||
```bash
|
||||
./target/release/miyabi gate status
|
||||
```
|
||||
|
||||
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"
|
||||
./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"
|
||||
```
|
||||
|
||||
Typical flow:
|
||||
|
|
@ -153,427 +124,83 @@ Typical flow:
|
|||
1. `register`
|
||||
2. `impact`
|
||||
3. `assign`
|
||||
4. implement
|
||||
4. implement with your coding agent of choice
|
||||
5. `branch`
|
||||
6. `pr`
|
||||
7. `merge` or `manual-complete`
|
||||
|
||||
## Usage
|
||||
|
||||
`MergeGate` is the product and documentation name.
|
||||
Both `miyabi` and `mergegate` work today.
|
||||
```bash
|
||||
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
|
||||
miyabi # Start TUI (default)
|
||||
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
|
||||
miyabi gate status
|
||||
```
|
||||
|
||||
### CLI Options
|
||||
## Core Commands
|
||||
|
||||
```bash
|
||||
miyabi --model claude-sonnet-4-5-20250929 # Override model
|
||||
miyabi --max-tokens 16384 # Override max tokens
|
||||
miyabi --thinking # Enable extended thinking
|
||||
miyabi --config /path/to/config.toml # Custom config
|
||||
miyabi --session <id> # Resume session
|
||||
mergegate gate status
|
||||
mergegate gate init
|
||||
mergegate gate guide
|
||||
mergegate gate register --issue 123 --title "Fix login redirect"
|
||||
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 |
|
||||
|-----|--------|
|
||||
| `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 |
|
||||
MergeGate is intentionally moving away from:
|
||||
|
||||
## 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
|
||||
[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
|
||||
## Workspace Layout
|
||||
|
||||
[ui]
|
||||
show_sidebar = false # Show sidebar
|
||||
show_status_bar = true # Show status bar
|
||||
show_breadcrumb = true # Show breadcrumb
|
||||
theme = "tokyo-night" # Color theme
|
||||
vim_mode = false # Vim keybindings
|
||||
show_line_numbers = true # Line numbers in code
|
||||
|
||||
[session]
|
||||
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
|
||||
```text
|
||||
crates/
|
||||
mergegate-cli/ # CLI entrypoint
|
||||
mergegate-core/ # Gate protocol, store, locks, workflow logic
|
||||
project_memory/
|
||||
tasks.json # Execution ledger
|
||||
skills/
|
||||
mergegate-cli/
|
||||
mergegate-ops/
|
||||
```
|
||||
|
||||
### 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
|
||||
|
||||
### Common Issues
|
||||
### `gate status` says `tasks: 0`
|
||||
|
||||
#### "API key not found"
|
||||
```bash
|
||||
# Check if environment variable is set
|
||||
echo $ANTHROPIC_API_KEY
|
||||
That is not an error. It means the ledger exists but no tasks have been registered yet.
|
||||
|
||||
# Or add to config file
|
||||
vim ~/.miyabi/config.toml
|
||||
# [api]
|
||||
# api_key = "sk-ant-..."
|
||||
```
|
||||
### `gate init` says the project is already initialized
|
||||
|
||||
#### "Device not configured" error on TUI start
|
||||
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
|
||||
```
|
||||
That is usually safe. It means `project_memory/tasks.json` already exists.
|
||||
|
||||
#### Build errors
|
||||
```bash
|
||||
# Make sure Rust is up to date
|
||||
rustup update
|
||||
### I want to use another coding agent
|
||||
|
||||
# Clean and rebuild
|
||||
cargo clean
|
||||
cargo build --release
|
||||
```
|
||||
That is the intended model. MergeGate is the gate, not the engine.
|
||||
|
||||
#### 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
|
||||
repository.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]]
|
||||
name = "miyabi"
|
||||
|
|
@ -20,15 +20,10 @@ path = "src/bin/mergegate.rs"
|
|||
[dependencies]
|
||||
# Workspace crates
|
||||
miyabi-core = { package = "mergegate-core", path = "../mergegate-core" }
|
||||
miyabi-tui = { package = "mergegate-tui", path = "../mergegate-tui" }
|
||||
|
||||
# CLI
|
||||
clap = { workspace = true }
|
||||
|
||||
# TUI Framework
|
||||
ratatui = { workspace = true }
|
||||
crossterm = { workspace = true }
|
||||
|
||||
# Async Runtime
|
||||
tokio = { workspace = true }
|
||||
|
||||
|
|
|
|||
|
|
@ -62,36 +62,14 @@ fn agent_guide() -> String {
|
|||
}
|
||||
|
||||
#[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 {
|
||||
/// 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: Option<Commands>,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
enum Commands {
|
||||
/// Start the TUI interface
|
||||
Tui,
|
||||
/// Show status
|
||||
Status,
|
||||
/// Generate default config file
|
||||
|
|
@ -116,23 +94,6 @@ enum Commands {
|
|||
#[arg(short, long)]
|
||||
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(
|
||||
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"
|
||||
|
|
@ -452,78 +413,35 @@ async fn main() -> anyhow::Result<()> {
|
|||
let cli = Cli::from_arg_matches(&matches).unwrap_or_else(|error| error.exit());
|
||||
|
||||
match cli.command {
|
||||
Some(Commands::Tui) | None => {
|
||||
// Run TUI
|
||||
use crossterm::{
|
||||
event::{DisableMouseCapture, EnableMouseCapture},
|
||||
execute,
|
||||
terminal::{
|
||||
disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen,
|
||||
},
|
||||
};
|
||||
use miyabi_core::config::Config;
|
||||
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);
|
||||
}
|
||||
None => {
|
||||
let mut command = Cli::command();
|
||||
command = command.name(current_binary_name());
|
||||
command.print_help()?;
|
||||
println!();
|
||||
println!();
|
||||
println!("Start here:");
|
||||
println!(" {}", gate_command("status"));
|
||||
println!(" {}", gate_command("init"));
|
||||
println!(" {}", gate_command("guide"));
|
||||
}
|
||||
Some(Commands::Status) => {
|
||||
use miyabi_core::config::Config;
|
||||
|
||||
let config = Config::load().unwrap_or_default();
|
||||
|
||||
println!("Miyabi Status: Ready");
|
||||
println!("MergeGate Status: Ready");
|
||||
println!();
|
||||
println!("Binary: {}", current_binary_name());
|
||||
println!("Config: {}", Config::default_path().display());
|
||||
println!("Sessions: {}", config.sessions_dir().display());
|
||||
println!("Model: {}", config.api.model);
|
||||
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
|
||||
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 {
|
||||
format,
|
||||
emit_event,
|
||||
|
|
|
|||
|
|
@ -1,578 +1,172 @@
|
|||
# MergeGate ユーザーマニュアル
|
||||
|
||||
**Version**: 0.1.0
|
||||
**Last Updated**: 2025-11-23
|
||||
|
||||
---
|
||||
|
||||
## 目次
|
||||
|
||||
1. [はじめに](#はじめに)
|
||||
2. [インストール](#インストール)
|
||||
3. [初期設定](#初期設定)
|
||||
4. [基本的な使い方](#基本的な使い方)
|
||||
5. [TUIモード](#tuiモード)
|
||||
6. [Agentモード](#agentモード)
|
||||
7. [セッション管理](#セッション管理)
|
||||
8. [設定ファイル](#設定ファイル)
|
||||
9. [プロジェクトルール](#プロジェクトルール)
|
||||
10. [トラブルシューティング](#トラブルシューティング)
|
||||
|
||||
---
|
||||
**Last Updated**: 2026-04-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`: コードベースを理解する
|
||||
- `MergeGate`: 変更を安全に実行する
|
||||
|
||||
影響範囲が分かるだけでは、AI エージェントは安全に開発できません。どの task を登録し、どのファイルを lock し、どの順序で branch / PR / merge まで進めるかを protocol として固定するのが MergeGate の役割です。
|
||||
## 何をするツールか
|
||||
|
||||
### 主な機能
|
||||
MergeGate の中心機能は `gate` です。
|
||||
|
||||
- **TUIモード**: 美しいターミナルUIでの対話
|
||||
- **Agentモード**: ファイル操作やコマンド実行を含む自律実行
|
||||
- **セッション管理**: 会話履歴の保存・再開
|
||||
- **プロジェクトルール**: .miyabirulesによるカスタムルール
|
||||
```bash
|
||||
mergegate gate ...
|
||||
```
|
||||
|
||||
---
|
||||
または互換 alias として:
|
||||
|
||||
```bash
|
||||
miyabi gate ...
|
||||
```
|
||||
|
||||
実行エンジンは Claude Code、Codex、Gemini CLI など、どれでも構いません。MergeGate はその前後で repo workflow を制御します。
|
||||
|
||||
## インストール
|
||||
|
||||
### 必要要件
|
||||
|
||||
- Rust 1.70以上
|
||||
- Anthropic APIキー
|
||||
|
||||
### ビルド手順
|
||||
### ビルド
|
||||
|
||||
```bash
|
||||
# 1. リポジトリをクローン
|
||||
git clone https://github.com/ShunsukeHayashi/mergegate.git
|
||||
cd mergegate
|
||||
|
||||
# 2. リリースビルド
|
||||
cargo build --release
|
||||
|
||||
# 3. バイナリの確認
|
||||
ls -la target/release/miyabi target/release/mergegate
|
||||
```
|
||||
|
||||
### パスを通す(オプション)
|
||||
## 最初にやること
|
||||
|
||||
### 1. repo の状態確認
|
||||
|
||||
```bash
|
||||
# ~/.bashrc または ~/.zshrc に追加
|
||||
export PATH="$PATH:/path/to/mergegate/target/release"
|
||||
|
||||
# 設定を反映
|
||||
source ~/.bashrc # または source ~/.zshrc
|
||||
./target/release/mergegate gate status
|
||||
```
|
||||
|
||||
---
|
||||
`tasks: 0` は正常です。ledger はあるが task がまだ無い状態です。
|
||||
|
||||
## 初期設定
|
||||
|
||||
### 1. 設定ファイルの生成
|
||||
### 2. 初期化
|
||||
|
||||
```bash
|
||||
./target/release/miyabi init
|
||||
./target/release/mergegate gate init
|
||||
```
|
||||
|
||||
これにより `~/.miyabi/config.toml` が作成されます。
|
||||
これで `project_memory/tasks.json` が作成されます。
|
||||
|
||||
### 2. APIキーの設定
|
||||
|
||||
**方法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. 設定の確認
|
||||
### 3. ガイド確認
|
||||
|
||||
```bash
|
||||
./target/release/miyabi status
|
||||
./target/release/mergegate gate guide
|
||||
```
|
||||
|
||||
出力例:
|
||||
```
|
||||
Miyabi Status: Ready
|
||||
## 基本フロー
|
||||
|
||||
Config: /Users/you/.miyabi/config.toml
|
||||
Sessions: /Users/you/.miyabi/sessions
|
||||
Model: claude-sonnet-4-5-20250929
|
||||
|
||||
Rules: 0 rules loaded
|
||||
```bash
|
||||
./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"
|
||||
./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モードを起動 |
|
||||
| `miyabi agent <prompt>` | Agentモードで実行 |
|
||||
| `miyabi status` | ステータス表示 |
|
||||
| `miyabi version` | バージョン情報 |
|
||||
| `miyabi init` | 設定ファイル生成 |
|
||||
| `miyabi sessions` | セッション一覧 |
|
||||
| `miyabi rules` | プロジェクトルール表示 |
|
||||
| `mergegate gate status` | ledger 全体または task 状態を表示 |
|
||||
| `mergegate gate init` | ledger を初期化 |
|
||||
| `mergegate gate guide` | workflow ガイドを表示 |
|
||||
| `mergegate gate register` | task を登録 |
|
||||
| `mergegate gate impact` | impact を記録 |
|
||||
| `mergegate gate assign` | task を割り当てて lock を取得 |
|
||||
| `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` | 依存順序を表示 |
|
||||
|
||||
### グローバルオプション
|
||||
## 実行エンジンとの関係
|
||||
|
||||
| オプション | 説明 |
|
||||
|-----------|------|
|
||||
| `-m, --model <MODEL>` | 使用するモデルを指定 |
|
||||
| `--max-tokens <N>` | 最大トークン数 |
|
||||
| `--thinking` | Extended Thinking有効化 |
|
||||
| `-c, --config <PATH>` | 設定ファイルパス |
|
||||
| `-s, --session <ID>` | セッションID指定 |
|
||||
MergeGate は coding agent を置き換えるものではありません。
|
||||
|
||||
### 使用例
|
||||
想定している使い方:
|
||||
|
||||
```bash
|
||||
# バージョン確認
|
||||
./target/release/miyabi version
|
||||
- Claude Code が実装する
|
||||
- Codex が実装する
|
||||
- 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
|
||||
./target/release/miyabi tui
|
||||
```
|
||||
不要です。MergeGate の本体ではありません。
|
||||
|
||||
### キーバインド
|
||||
### built-in backend は必要ですか
|
||||
|
||||
#### 基本操作
|
||||
不要です。MergeGate の本体ではありません。
|
||||
|
||||
| キー | 動作 |
|
||||
|------|------|
|
||||
| `Enter` | メッセージ送信 |
|
||||
| `Ctrl+C` | 終了 |
|
||||
| `Esc` | オーバーレイを閉じる / キャンセル |
|
||||
| `F1` | ヘルプ表示 |
|
||||
### `miyabi` と `mergegate` のどちらを使えばいいですか
|
||||
|
||||
#### ナビゲーション
|
||||
|
||||
| キー | 動作 |
|
||||
|------|------|
|
||||
| `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` | 情報(青) |
|
||||
|
||||
---
|
||||
新規利用では `mergegate` を推奨します。`miyabi` は互換 alias です。
|
||||
|
||||
## トラブルシューティング
|
||||
|
||||
### "API key not found" エラー
|
||||
### `tasks: 0`
|
||||
|
||||
異常ではありません。task が未登録なだけです。
|
||||
|
||||
### どの task から始めればよいか分からない
|
||||
|
||||
```bash
|
||||
# 環境変数を確認
|
||||
echo $ANTHROPIC_API_KEY
|
||||
|
||||
# 設定されていない場合
|
||||
export ANTHROPIC_API_KEY="sk-ant-..."
|
||||
./target/release/mergegate gate dispatchable
|
||||
./target/release/mergegate gate dag
|
||||
./target/release/mergegate gate guide
|
||||
```
|
||||
|
||||
### "Device not configured" エラー
|
||||
|
||||
ターミナルがTUIをサポートしていない可能性があります:
|
||||
### 既存 repo に導入済みか分からない
|
||||
|
||||
```bash
|
||||
# 別のターミナルを試す(iTerm2, Alacritty等)
|
||||
|
||||
# または明示的にTERM設定
|
||||
TERM=xterm-256color ./target/release/miyabi tui
|
||||
./target/release/mergegate gate status
|
||||
```
|
||||
|
||||
### ビルドエラー
|
||||
|
||||
```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**
|
||||
ledger が無ければ `gate init` に進めます。
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue