chore: Initialize Miyabi project with full planning

- Add .claude/ configuration (agents, commands, prompts, templates)
- Add comprehensive documentation:
  - WBS.md - Work Breakdown Structure
  - SPRINT_PLANNING.md - 4-sprint detailed plan
  - OPERATION_PLAN.md - Execution procedures
  - PRODUCT_SPEC.md - Product requirements
  - PREPARATION_OPS.md - Pre-sprint checklist
- Add PlantUML diagrams (wbs-diagram, gantt-chart)
- Configure Miyabi (.miyabi.yml)
- Set up Rust workspace structure

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Shunsuke Hayashi 2025-11-22 17:45:08 +09:00
parent 0eb74b7af1
commit 00d5d4d4e9
53 changed files with 6950 additions and 0 deletions

37
.claude/QUICK_START.md Normal file
View file

@ -0,0 +1,37 @@
# miyabi-cli-standalone - Quick Start Guide
## 🚀 3分で始めるMiyabi
### 1. 環境変数設定
```bash
export GITHUB_TOKEN=ghp_xxx
export ANTHROPIC_API_KEY=sk-xxx
```
### 2. ステータス確認
```bash
miyabi status
```
### 3. Issue作成
GitHubでIssueを作成し、以下のラベルを付与
- `type:feature` または `type:bug`
- `priority:P1-High`
### 4. Agent実行
```bash
miyabi agent coordinator --issue 1
```
## 📚 詳細ドキュメント
- [CLAUDE.md](../CLAUDE.md) - プロジェクトコンテキスト
- [.claude/README.md](./README.md) - .claudeディレクトリ説明
---
**Miyabi** - Beauty in Autonomous Development 🌸

53
.claude/README.md Normal file
View file

@ -0,0 +1,53 @@
# .claude Directory
Claude Code設定ディレクトリ
## 構造
```
.claude/
├── agents/
│ ├── specs/ # Agent仕様定義
│ ├── prompts/ # 実行プロンプト
│ └── README.md
├── commands/ # カスタムスラッシュコマンド
├── prompts/ # 汎用プロンプト
└── templates/ # テンプレート
```
## カスタムコマンド
`commands/` 配下に `*.md` ファイルを作成:
```markdown
# commands/build.md
プロジェクトをビルドして、エラーがあれば修正してください。
cargo build --release
```
使用: `/project:build`
## Agent仕様
`agents/specs/` でAgent定義:
- 役割・責任範囲
- 使用可能ツール
- エスカレーション条件
## プロンプト
`prompts/` に再利用可能プロンプト:
- コードレビュー
- リファクタリング
- テスト生成
## 使い方
```bash
# カスタムコマンド実行
/project:build
# Agent実行
miyabi agent run <agent-name> --issue <番号>
```

59
.claude/agents/README.md Normal file
View file

@ -0,0 +1,59 @@
# Miyabi Agents
このディレクトリには、Miyabiプロジェクトで使用するAgent仕様とプロンプトを配置します。
## 📁 ディレクトリ構造
```
agents/
├── specs/ # Agent仕様定義
│ ├── coding/ # コーディング系Agent7種類
│ └── business/ # ビジネス系Agent14種類
└── prompts/ # 実行プロンプト
├── coding/ # コーディング系Agentプロンプト
└── business/ # ビジネス系Agentプロンプト
```
## 🤖 Coding Agents7種類
1. **CoordinatorAgent** - タスク統括・DAG分解
2. **CodeGenAgent** - AI駆動コード生成
3. **ReviewAgent** - コード品質レビュー
4. **IssueAgent** - Issue分析・ラベリング
5. **PRAgent** - Pull Request自動作成
6. **DeploymentAgent** - CI/CDデプロイ自動化
7. **RefresherAgent** - Issue状態監視・更新
## 💼 Business Agents14種類
### 戦略・企画系6種類
- AIEntrepreneurAgent, ProductConceptAgent, ProductDesignAgent
- FunnelDesignAgent, PersonaAgent, SelfAnalysisAgent
### マーケティング系5種類
- MarketResearchAgent, MarketingAgent, ContentCreationAgent
- SNSStrategyAgent, YouTubeAgent
### 営業・顧客管理系3種類
- SalesAgent, CRMAgent, AnalyticsAgent
## 📝 Agent仕様の書き方
詳細は各ディレクトリのREADME.mdを参照してください
- [specs/coding/README.md](specs/coding/README.md)
- [specs/business/README.md](specs/business/README.md)
## 🚀 Agent実行方法
```bash
# CoordinatorAgentでIssue処理
miyabi agent run coordinator --issue 123
# 複数Issue並列処理
miyabi agent run coordinator --issues 123,124,125 --concurrency 3
```
## 🔗 参考リンク
- [Miyabi Agent SDK](https://docs.rs/miyabi-agents)
- [CLAUDE.md](../../CLAUDE.md) - プロジェクトコンテキスト

View file

@ -0,0 +1,135 @@
# Issue Creation Workflow Example
このファイルは、miyabi-cli-standaloneプロジェクトでの標準的なIssue作成フローです。
## ステップ1: Issue作成
### GitHub Web UIで作成
1. リポジトリの"Issues"タブをクリック
2. "New issue"をクリック
3. Issueテンプレートを使用推奨
### GitHub CLIで作成推奨
```bash
gh issue create \
--title "✨ Add user authentication" \
--body "$(cat <<'EOF'
## 概要
ユーザー認証機能を追加する
## 要件
- [ ] JWT トークン認証
- [ ] ログイン/ログアウトエンドポイント
- [ ] トークンリフレッシュ機能
## 期待される成果
- 認証付きAPIエンドポイント
- テストカバレッジ90%以上
- セキュリティ監査パス
EOF
)" \
--label "type:feature,priority:P1-High,state:pending"
```
## ステップ2: Agent実行
### 方法1: 新しいwork-onコマンド推奨
```bash
# Issue番号で実行
miyabi work-on 1
# または作業説明で実行Issue作成を提案
miyabi work-on "Add user authentication"
```
### 方法2: 従来のagentコマンド
```bash
miyabi agent run coordinator --issue 1
```
### 方法3: 並列実行
```bash
miyabi parallel --issues 1,2,3 --concurrency 2
```
## ステップ3: 進捗確認
```bash
# プロジェクトステータス確認
miyabi status
# Issue状態確認
gh issue view 1
# Worktree確認
git worktree list
# ログ確認
tail -f logs/miyabi-$(date +%Y%m%d).log
```
## ステップ4: レビュー
Agentが自動的に
1. コード生成
2. テスト作成
3. Linter実行
4. PR作成
あなたがすべきこと:
1. PRレビュー
2. 追加修正(必要なら)
3. マージ
## 実際の例
### 成功例: Issue #42 "Setup CI/CD pipeline"
```bash
$ miyabi work-on 42
🚀 Let's work on it!
📋 Issue #42
🤖 CoordinatorAgent starting...
✅ Analyzed issue
✅ Created 3 tasks
✅ Assigned CodeGenAgent, ReviewAgent, DeploymentAgent
⏱️ Estimated time: 15 minutes
🌳 Created worktree: .worktrees/issue-42
[15 minutes later]
✅ All tasks completed!
📊 Quality score: 95/100
🔗 PR created: #43
```
## トラブルシューティング
### Agentがスタックした場合
```bash
# ログ確認
grep -i "error" logs/miyabi-*.log
# Worktreeクリーンアップ
git worktree prune
# 再実行
miyabi work-on 42
```
### より詳しいヘルプ
```bash
# トラブルシューティングガイド
cat docs/TROUBLESHOOTING.md
# Agent仕様確認
cat .claude/agents/README.md
```
---
**miyabi-cli-standaloneプロジェクトの標準ワークフロー**
**Miyabi - Beauty in Autonomous Development 🌸**

View file

@ -0,0 +1,53 @@
# Example Agent Prompt
このファイルは、Agentプロンプトのサンプルです。
## プロンプト構造
```markdown
# [Task名]
## Context
プロジェクトのコンテキスト情報
## Objective
このAgentが達成すべき目標
## Inputs
- Issue URL: https://github.com/user/repo/issues/123
- Task ID: TASK-456
- Dependencies: TASK-123, TASK-124
## Instructions
1. ステップ1を実行
2. ステップ2を実行
3. ...
## Output Format
期待される出力形式JSON, Markdown, Code等
## Success Criteria
- 基準1
- 基準2
```
## 使用方法
Worktree内でClaude Codeセッションを起動する際、このプロンプトが自動的に読み込まれます。
```bash
cd .worktrees/issue-123
# Claude Codeがこのプロンプトを参照して実行
```
## カスタマイズ
プロジェクト固有のプロンプトを作成する場合:
1. このファイルをコピー
2. 内容をカスタマイズ
3. `.claude/agents/prompts/coding/` に配置
## 🔗 参考
実際のプロンプト例は、Miyabiプロジェクトの `.claude/agents/prompts/coding/` を参照してください。

View file

@ -0,0 +1,64 @@
# Business Agent 仕様
このディレクトリには、ビジネス系Agent14種類の仕様を配置します。
## Agent仕様ファイルのフォーマット
各Agentの仕様は以下の構造で記述します
```markdown
# [Agent名] 仕様
## 概要
Agentの役割とビジネス目標
## 入力
- ユーザー要求市場情報、目標KPI等
- 必須パラメータ
## 実行フェーズ
1. Phase 1: データ収集
2. Phase 2: 分析
3. Phase 3: 戦略立案
4. ...
## 出力
- 生成するビジネスドキュメント
- レポート形式
## 品質基準
- 検証項目
- スコアリング基準100点満点
## 実行例
\`\`\`bash
miyabi agent run ai-entrepreneur --output business-plan.md
\`\`\`
```
## 📊 Business Agent一覧
### 戦略・企画系
- **AIEntrepreneurAgent** - 包括的ビジネスプラン作成
- **ProductConceptAgent** - 製品コンセプト設計
- **ProductDesignAgent** - サービス詳細設計
- **FunnelDesignAgent** - 導線設計
- **PersonaAgent** - ターゲット顧客ペルソナ
- **SelfAnalysisAgent** - 自己分析
### マーケティング系
- **MarketResearchAgent** - 市場調査
- **MarketingAgent** - マーケティング戦略
- **ContentCreationAgent** - コンテンツ制作
- **SNSStrategyAgent** - SNS戦略
- **YouTubeAgent** - YouTube運用最適化
### 営業・顧客管理系
- **SalesAgent** - セールスプロセス最適化
- **CRMAgent** - 顧客関係管理
- **AnalyticsAgent** - データ分析・PDCA
## 🔗 参考
- [SaaS Business Model Guide](https://github.com/ShunsukeHayashi/Miyabi/blob/main/docs/SAAS_BUSINESS_MODEL.md)
- [Business Agents User Guide](https://github.com/ShunsukeHayashi/Miyabi/blob/main/docs/BUSINESS_AGENTS_USER_GUIDE.md)

View file

@ -0,0 +1,33 @@
# Coordinator Agent Spec
## Role
タスク調整とAgent間連携を担当
## Responsibilities
- Issue分析と分解
- Agent割り当て
- 進捗管理
- 品質ゲートチェック
## Tools
- GitHub (Issues, PRs)
- Agent invocation
- Read/Grep
## Workflow
1. Issue受領
2. 要件分析
3. タスク分解
4. Agent割り当て
5. 進捗監視
6. PR作成
## Escalation
- ブロッカー発生 → User
- 優先度判断 → User
- スコープ変更 → User
## Output
- タスク計画
- 進捗レポート
- PR

View file

@ -0,0 +1,50 @@
# Coding Agent 仕様
このディレクトリには、コーディング系Agent7種類の仕様を配置します。
## Agent仕様ファイルのフォーマット
各Agentの仕様は以下の構造で記述します
```markdown
# [Agent名] 仕様
## 概要
Agentの役割と責任範囲
## 入力
- 受け取るTask/Issueの形式
- 必須パラメータ
## 処理フロー
1. ステップ1
2. ステップ2
3. ...
## 出力
- 生成する成果物
- 更新するIssue/PR
## エスカレーション条件
- 上位Agentへのエスカレーション基準
- エラーハンドリング
## 実行例
\`\`\`bash
miyabi agent run [agent-type] --issue 123
\`\`\`
```
## 📋 テンプレート
新しいAgent仕様を作成する場合、以下のテンプレートを使用してください
```bash
cp example-agent-spec.md my-custom-agent.md
```
## 🔗 参考
既存のAgent仕様は以下を参照
- Miyabiプロジェクトの `.claude/agents/specs/coding/` ディレクトリ
- [Agent Operations Manual](https://github.com/ShunsukeHayashi/Miyabi/blob/main/docs/AGENT_OPERATIONS_MANUAL.md)

View file

@ -0,0 +1,87 @@
# CodeGenAgent Specification
## 概要
CodeGenAgentは、AI駆動のコード生成を担当するSpecialist Agentです。
Claude Sonnet 4を使用して、型安全で高品質なRustコードを生成します。
## 入力
- **Task**: CoordinatorAgentから受け取ったTask
- Task ID
- 依存関係Dependencies
- 生成すべきコードの仕様
- **Issue Context**: 元のIssue情報
## 処理フロー
### 1. 要件分析
- Taskの内容を解析
- 必要なモジュール・トレイト・構造体を特定
- 既存コードとの整合性確認
### 2. コード生成
```rust
// 例: 新しいAgent構造体の生成
pub struct NewAgent {
config: AgentConfig,
}
#[async_trait]
impl BaseAgent for NewAgent {
async fn execute(&self, task: Task) -> Result<AgentResult> {
// Implementation
Ok(AgentResult::success(data))
}
}
```
### 3. テスト生成
```rust
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_new_agent() {
let agent = NewAgent::new(config);
let result = agent.execute(task).await.unwrap();
assert_eq!(result.status, ResultStatus::Success);
}
}
```
### 4. ドキュメント生成
- Rustdocコメント`///`)の追加
- 使用例の記述
- パラメータ・戻り値の説明
## 出力
- **生成コード**: Rust source files
- **テスト**: `#[cfg(test)]` mod
- **ドキュメント**: Rustdoc comments
- **Commit**: Conventional Commits形式
## エスカレーション条件
- 既存コードとの大規模なコンフリクト
- セキュリティ上の懸念unsafe使用等
- 外部依存の追加が必要
## 品質基準
- ✅ Clippy警告0件
- ✅ テストカバレッジ80%以上
- ✅ すべてのpublic APIにRustdoc
- ✅ エラーハンドリング完備
## 実行例
```bash
miyabi agent run codegen --issue 123
```
または簡易コマンド:
```bash
miyabi work-on 123
```
---
**このファイルはClaude Codeが参照する実際のAgent仕様です。**
**プロジェクト固有の要件に合わせてカスタマイズしてください。**

View file

@ -0,0 +1,30 @@
# Developer Agent Spec
## Role
Rustコード実装を担当する開発Agent
## Responsibilities
- 機能実装
- バグ修正
- コードレビュー対応
- テスト作成
## Tools
- Read/Write/Edit
- Bash (cargo commands)
- Grep/Glob
## Constraints
- Conventional Commits準拠
- `cargo clippy` 警告ゼロ
- テストカバレッジ維持
## Escalation
- アーキテクチャ変更 → Architect Agent
- 要件不明確 → User
- 外部依存の問題 → User
## Output
- 実装コード
- テストコード
- コミットメッセージ

View file

@ -0,0 +1,32 @@
# Reviewer Agent Spec
## Role
コードレビューを担当するAgent
## Responsibilities
- コード品質チェック
- セキュリティレビュー
- パフォーマンス分析
- ベストプラクティス適用
## Tools
- Read
- Grep/Glob
- Bash (lint/test)
## Review Checklist
- [ ] 可読性
- [ ] エラーハンドリング
- [ ] テストカバレッジ
- [ ] ドキュメント
- [ ] セキュリティ
- [ ] パフォーマンス
## Escalation
- 重大なセキュリティ問題 → User
- アーキテクチャ懸念 → Architect Agent
## Output
- レビューコメント
- 改善提案
- 承認/要修正判定

View file

@ -0,0 +1,35 @@
# Tester Agent Spec
## Role
テスト作成・実行を担当するAgent
## Responsibilities
- ユニットテスト作成
- 統合テスト作成
- テスト実行・分析
- カバレッジ向上
## Tools
- Read/Write/Edit
- Bash (cargo test)
- Grep/Glob
## Test Types
- Unit tests
- Integration tests
- Property-based tests
- Benchmark tests
## Constraints
- AAA pattern (Arrange-Act-Assert)
- 意味のあるテスト名
- エッジケース網羅
## Escalation
- テスト環境の問題 → User
- 仕様不明確 → Developer Agent
## Output
- テストコード
- カバレッジレポート
- 失敗分析

View file

@ -0,0 +1,7 @@
プロジェクトをビルドしてください。
```bash
cargo build --release
```
エラーがあれば修正してください。

8
.claude/commands/lint.md Normal file
View file

@ -0,0 +1,8 @@
Lintを実行してコード品質をチェックしてください。
```bash
cargo clippy --all-targets -- -D warnings
cargo fmt --all --check
```
警告やエラーがあれば修正してください。

View file

@ -0,0 +1,14 @@
現在の変更をコードレビューしてください。
```bash
git diff
```
以下の観点でレビュー:
- コード品質
- パフォーマンス
- セキュリティ
- エラーハンドリング
- テストカバレッジ
改善点があれば提案してください。

View file

@ -0,0 +1,11 @@
プロジェクトの状態を確認してください。
1. Gitステータス
2. Miyabiステータス
3. 未完了のTODO
4. 最近のコミット
```bash
git status
miyabi status
```

7
.claude/commands/test.md Normal file
View file

@ -0,0 +1,7 @@
全てのテストを実行してください。
```bash
cargo test --all
```
失敗したテストがあれば原因を分析し、修正してください。

31
.claude/prompts/debug.md Normal file
View file

@ -0,0 +1,31 @@
# Debug Prompt
問題をデバッグして修正してください。
## プロセス
1. **問題の再現** - 症状の確認
2. **原因調査** - ログ、スタックトレース分析
3. **仮説立案** - 可能性のある原因
4. **検証** - 仮説のテスト
5. **修正** - 根本原因の解決
6. **回帰テスト** - 再発防止の確認
## デバッグツール
```bash
# ログ確認
RUST_LOG=debug cargo run
# バックトレース
RUST_BACKTRACE=1 cargo run
# テスト
cargo test <test_name> -- --nocapture
```
## 出力
- 根本原因の説明
- 修正コード
- 再発防止策

View file

@ -0,0 +1,30 @@
# Feature Implementation Prompt
新機能を実装してください。
## プロセス
1. **要件理解** - 仕様の確認と質問
2. **設計** - アーキテクチャ決定
3. **実装** - コード作成
4. **テスト** - ユニット/統合テスト
5. **ドキュメント** - 必要に応じて
## コーディング規約
### Rust
- `cargo fmt` でフォーマット
- `cargo clippy` 警告ゼロ
- Result型でエラーハンドリング
- 適切なドキュメントコメント
### 構造
- 単一責任の関数/構造体
- 適切な抽象化レベル
- テスト可能な設計
## 出力
- 実装コード
- テストコード
- 使用例

View file

@ -0,0 +1,22 @@
# Refactoring Prompt
対象コードをリファクタリングしてください。
## 方針
1. **可読性向上** - 命名、構造の改善
2. **DRY原則** - 重複コードの排除
3. **SOLID原則** - 責務の分離
4. **パフォーマンス** - 不要な処理の削除
## 制約
- 既存の機能を維持
- テストが通ること
- 破壊的変更を避ける
## 出力
- 変更内容の説明
- 改善点のリスト
- 必要に応じてテストの追加

View file

@ -0,0 +1,24 @@
# Issue Template
## Title
[type]: Short description
## Description
明確で簡潔な説明
## Acceptance Criteria
- [ ] Criterion 1
- [ ] Criterion 2
- [ ] Criterion 3
## Technical Notes
実装に関する技術的な注意点
## Labels
- `type:feature` / `type:bug` / `type:refactor`
- `priority:high` / `priority:medium` / `priority:low`
- `component:tui` / `component:cli` / `component:core`
## Related
- Related Issue: #xxx
- Related PR: #xxx

33
.claude/templates/pr.md Normal file
View file

@ -0,0 +1,33 @@
# Pull Request Template
## Summary
変更内容の要約1-3行
## Changes
- Change 1
- Change 2
- Change 3
## Type
- [ ] Feature
- [ ] Bug Fix
- [ ] Refactor
- [ ] Documentation
- [ ] Test
## Testing
- [ ] Unit tests added/updated
- [ ] Integration tests added/updated
- [ ] Manual testing performed
## Checklist
- [ ] `cargo fmt` passed
- [ ] `cargo clippy` passed
- [ ] `cargo test` passed
- [ ] Documentation updated
## Screenshots
(if applicable)
## Related Issues
Closes #xxx

View file

@ -0,0 +1,52 @@
# Rust Module Template
```rust
//! Module description
//!
//! # Examples
//!
//! ```rust
//! use crate::module_name;
//!
//! // Example usage
//! ```
use anyhow::Result;
/// Description
pub struct StructName {
/// Field description
field: Type,
}
impl StructName {
/// Creates a new instance
pub fn new() -> Self {
Self {
field: Default::default(),
}
}
/// Method description
pub fn method(&self) -> Result<()> {
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_example() {
// Arrange
let instance = StructName::new();
// Act
let result = instance.method();
// Assert
assert!(result.is_ok());
}
}
```

25
.env.example Normal file
View file

@ -0,0 +1,25 @@
# GitHub Configuration
# Get token at: https://github.com/settings/tokens
# Required scopes: repo, workflow, admin:org (for Projects)
GITHUB_TOKEN=ghp_your_github_token_here
# Repository Information
# Format: owner/repo (e.g., YourUsername/my-project)
REPOSITORY=ShunsukeHayashi/miyabi-cli-standalone
# Anthropic API Key (optional for local development)
# Get key at: https://console.anthropic.com/
# Required for running agents locally
ANTHROPIC_API_KEY=sk-ant-your_anthropic_key_here
# Device Identifier (for logging)
DEVICE_IDENTIFIER=MyComputer
# Agent Configuration
LOG_DIRECTORY=.ai/logs
REPORT_DIRECTORY=.ai/parallel-reports
DEFAULT_CONCURRENCY=2
# Development Options
USE_TASK_TOOL=false
USE_WORKTREE=false

33
.gitignore vendored
View file

@ -137,3 +137,36 @@ dist
# Vite logs files
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
# Agentic OS
# Dependencies
node_modules/
package-lock.json
# Build output
dist/
*.tsbuildinfo
# Environment variables
.env
.env.local
# IDE
.vscode/
.idea/
# OS
.DS_Store
Thumbs.db
# Test coverage
coverage/
# Logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.worktrees/
.ai/
.env

21
.miyabi.yml Normal file
View file

@ -0,0 +1,21 @@
# Miyabi Configuration
project_name: miyabi-cli-standalone
version: "0.1.0"
# GitHub settings (use environment variables for sensitive data)
# github_token: ${{ GITHUB_TOKEN }}
# Agent settings
agents:
enabled: true
use_worktree: true
worktree_base_path: ".worktrees"
# Logging
logging:
level: info
directory: "./logs"
# Reporting
reporting:
directory: "./reports"

119
CLAUDE.md Normal file
View file

@ -0,0 +1,119 @@
ターゲットとする機能のベースライン: codex cli Ref_URL=https://github.com/openai/codex.git
ターゲットとする機能をベースに拡張すべき機能を有するPJ: /Users/shunsuke/dev/01-miyabi/_core/miyabi-private
===
# miyabi-cli-standalone
**Miyabi CLI Standalone** - 軽量スタンドアロン版 Miyabi CLI/TUI
## プロジェクト概要
Miyabi本体から独立した軽量CLIツール。TUI (Terminal User Interface) とCLI機能を提供。
## 技術スタック
- **言語**: Rust 2021 Edition, TypeScript
- **TUIフレームワーク**: Ratatui + Crossterm
- **CLIフレームワーク**: Clap
- **非同期ランタイム**: Tokio
## ディレクトリ構造
```
miyabi-cli-standalone/
├── crates/
│ ├── miyabi-cli/ # CLI実装
│ ├── miyabi-core/ # コアライブラリ
│ └── miyabi-tui/ # TUI実装
├── src/ # TypeScriptソース
│ └── index.ts
├── tests/ # テスト
├── .claude/ # Claude Code設定
│ ├── agents/ # Agent仕様
│ ├── commands/ # カスタムコマンド
│ └── prompts/ # プロンプト
├── docs/ # ドキュメント
├── logs/ # ログ
├── reports/ # レポート
├── Cargo.toml # Rustワークスペース設定
├── package.json # Node.js設定
└── .miyabi.yml # Miyabi設定
```
## 開発コマンド
### Rust
```bash
# ビルド
cargo build --release
# テスト
cargo test --all
# Lint
cargo clippy --all-targets -- -D warnings
# フォーマット
cargo fmt --all
```
### TypeScript
```bash
# インストール
npm install
# ビルド
npm run build
# Lint
npm run lint
```
## コミット規約
Conventional Commits準拠:
- `feat:` - 新機能
- `fix:` - バグ修正
- `refactor:` - リファクタリング
- `docs:` - ドキュメント
- `test:` - テスト
- `chore:` - その他
## 環境変数
```bash
GITHUB_TOKEN=ghp_xxx # GitHub PAT
RUST_LOG=info # ログレベル
RUST_BACKTRACE=1 # バックトレース
```
## Miyabi統合
```bash
# ステータス確認
miyabi status
# Agent実行
miyabi agent run coordinator --issue <番号>
```
## コーディング規約
### Rust
- `cargo fmt` でフォーマット
- `cargo clippy` 警告ゼロ
- Result型でエラーハンドリング
- async/awaitでの非同期処理
### TypeScript
- ESLint設定に従う
- 厳格な型付け
---
**このファイルはClaude Codeが自動参照します。**

1463
Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

56
Cargo.toml Normal file
View file

@ -0,0 +1,56 @@
[workspace]
resolver = "2"
members = [
"crates/miyabi-cli",
"crates/miyabi-tui",
"crates/miyabi-core",
]
[workspace.package]
version = "0.1.0"
edition = "2021"
rust-version = "1.75"
authors = ["Miyabi Team"]
license = "MIT"
repository = "https://github.com/ShunsukeHayashi/miyabi-cli-standalone"
homepage = "https://github.com/ShunsukeHayashi/miyabi-cli-standalone"
description = "Miyabi - Autonomous AI Development Framework"
keywords = ["ai", "cli", "tui", "autonomous", "development"]
categories = ["command-line-utilities", "development-tools"]
[workspace.dependencies]
# Async Runtime
tokio = { version = "1", features = ["rt-multi-thread", "macros", "io-std", "sync", "process", "signal"] }
futures = "0.3"
# 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"
# CLI
clap = { version = "4", features = ["derive"] }
# Error Handling
anyhow = "1"
thiserror = "2"
# Serialization
serde = { version = "1", features = ["derive"] }
serde_json = "1"
# Logging
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
# Utilities
chrono = { version = "0.4", features = ["serde"] }
uuid = { version = "1", features = ["v4", "serde"] }

188
GOALS.md Normal file
View file

@ -0,0 +1,188 @@
# Miyabi CLI - Development Goals
## Reference Projects
### Baseline
- **Codex CLI**: https://github.com/openai/codex.git
### Extension Source
- **Miyabi Private**: /Users/shunsuke/dev/01-miyabi/_core/miyabi-private
---
## Mission
**Codex CLI同等の品質を持つ、Production-Ready Miyabi CLIを構築する**
---
## Gap Analysis Summary
| Metric | Codex CLI | Current Miyabi | Target |
|--------|-----------|----------------|--------|
| Total Lines | 20,969 | 1,200 | 15,000+ |
| Files | 50+ | 10 | 40+ |
| Features | Complete | Basic | Full Parity |
---
## Phase 1: Core TUI Foundation ✅ COMPLETED
**Status**: Done (1,200 lines)
- [x] Cargo workspace setup
- [x] wrapping.rs - Text wrapping with textwrap
- [x] history_cell.rs - Card design UI
- [x] markdown_render.rs - Basic markdown
- [x] app.rs - Main TUI loop
- [x] event.rs - Event handling
---
## Phase 2: Advanced Text Rendering 🔄 IN PROGRESS
**Target**: +1,500 lines
### 2.1 markdown_stream.rs (690 lines)
- [ ] Streaming markdown rendering
- [ ] Progressive display during generation
- [ ] Cursor position tracking
- [ ] Partial code block handling
### 2.2 diff_render.rs (715 lines)
- [ ] Git diff visualization
- [ ] Syntax highlighting for diffs
- [ ] Line number display
- [ ] Add/Remove/Change indicators
---
## Phase 3: Chat Composer Separation
**Target**: +4,000 lines
### 3.1 chat_composer.rs (3,938 lines)
- [ ] Separate input handling from main app
- [ ] Multi-line input support
- [ ] Command history
- [ ] Auto-completion
- [ ] Syntax highlighting in input
### 3.2 textarea.rs (2,213 lines)
- [ ] Full-featured text area widget
- [ ] Selection support
- [ ] Copy/paste
- [ ] Undo/redo
---
## Phase 4: Approval & Feedback
**Target**: +1,500 lines
### 4.1 approval_overlay.rs (656 lines)
- [ ] Tool execution approval UI
- [ ] Y/N/Always/Never options
- [ ] Risk level display
- [ ] Preview of changes
### 4.2 feedback_view.rs (555 lines)
- [ ] User feedback collection
- [ ] Rating system
- [ ] Comment input
---
## Phase 5: Advanced Navigation
**Target**: +2,500 lines
### 5.1 resume_picker.rs (1,580 lines)
- [ ] Session resume selection
- [ ] Conversation history browser
- [ ] Search functionality
- [ ] Preview pane
### 5.2 pager_overlay.rs (913 lines)
- [ ] Full-screen content viewer
- [ ] Scroll and search
- [ ] Jump to line
- [ ] Keyboard shortcuts
---
## Phase 6: LLM Integration
**Target**: +2,000 lines
### 6.1 Claude API Integration
- [ ] Anthropic API client
- [ ] Streaming responses
- [ ] Token counting
- [ ] Rate limiting
- [ ] Error handling
### 6.2 Conversation Management
- [ ] Context window management
- [ ] Message history
- [ ] System prompts
- [ ] Tool definitions
---
## Phase 7: Tool Execution
**Target**: +2,500 lines
### 7.1 A2A Bridge Integration
- [ ] Tool registry
- [ ] Execution engine
- [ ] Result formatting
- [ ] Error recovery
### 7.2 Built-in Tools
- [ ] File operations (Read, Write, Edit)
- [ ] Bash execution
- [ ] Search (Glob, Grep)
- [ ] Web fetch
---
## Success Criteria
### Functional Requirements
- [ ] Real Claude API conversations
- [ ] Tool execution with approval
- [ ] Session persistence and resume
- [ ] Markdown rendering with streaming
- [ ] Full keyboard navigation
### Quality Requirements
- [ ] 15,000+ lines of code
- [ ] 90%+ test coverage
- [ ] < 100ms response latency
- [ ] Memory efficient (< 100MB)
- [ ] Cross-platform (macOS, Linux)
### User Experience
- [ ] Intuitive keyboard shortcuts
- [ ] Clear visual feedback
- [ ] Smooth scrolling
- [ ] Proper error messages
- [ ] Help system
---
## Timeline
| Phase | Duration | Deliverable |
|-------|----------|-------------|
| Phase 1 | ✅ Done | Core TUI |
| Phase 2 | 1 week | Streaming Markdown |
| Phase 3 | 2 weeks | Chat Composer |
| Phase 4 | 1 week | Approval System |
| Phase 5 | 1 week | Navigation |
| Phase 6 | 2 weeks | LLM Integration |
| Phase 7 | 2 weeks | Tool Execution |
**Total**: ~10 weeks to Production-Ready
---
## Next Action
**Phase 2.1: Implement markdown_stream.rs**
Create streaming markdown renderer that can display partial content during LLM generation.

View file

@ -0,0 +1,36 @@
[package]
name = "miyabi-cli"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
authors.workspace = true
license.workspace = true
repository.workspace = true
homepage.workspace = true
description = "Miyabi CLI - Main command-line interface"
[[bin]]
name = "miyabi"
path = "src/main.rs"
[dependencies]
# Workspace crates
miyabi-core = { path = "../miyabi-core" }
miyabi-tui = { path = "../miyabi-tui" }
# CLI
clap = { workspace = true }
# TUI Framework
ratatui = { workspace = true }
crossterm = { workspace = true }
# Async Runtime
tokio = { workspace = true }
# Error Handling
anyhow = { workspace = true }
# Logging
tracing = { workspace = true }
tracing-subscriber = { workspace = true }

View file

@ -0,0 +1,70 @@
//! Miyabi CLI - Main entry point
use clap::{Parser, Subcommand};
use tracing_subscriber::EnvFilter;
#[derive(Parser)]
#[command(name = "miyabi")]
#[command(author, version, about = "Miyabi - Autonomous AI Development Framework", long_about = None)]
struct Cli {
#[command(subcommand)]
command: Option<Commands>,
}
#[derive(Subcommand)]
enum Commands {
/// Start the TUI interface
Tui,
/// Show status
Status,
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Initialize logging
tracing_subscriber::fmt()
.with_env_filter(EnvFilter::from_default_env())
.init();
let cli = Cli::parse();
match cli.command {
Some(Commands::Tui) | None => {
// Run TUI
use miyabi_tui::App;
use crossterm::{
event::{DisableMouseCapture, EnableMouseCapture},
execute,
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
};
use ratatui::prelude::*;
use std::io;
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::new();
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) => {
println!("Miyabi Status: Ready");
}
}
Ok(())
}

View file

@ -0,0 +1,20 @@
[package]
name = "miyabi-core"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
authors.workspace = true
license.workspace = true
repository.workspace = true
homepage.workspace = true
description = "Miyabi Core - Shared types and utilities"
[dependencies]
tokio = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
anyhow = { workspace = true }
thiserror = { workspace = true }
tracing = { workspace = true }
chrono = { workspace = true }
uuid = { workspace = true }

View file

@ -0,0 +1,23 @@
//! Error types for Miyabi
use thiserror::Error;
#[derive(Error, Debug)]
pub enum Error {
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
#[error("JSON error: {0}")]
Json(#[from] serde_json::Error),
#[error("Configuration error: {0}")]
Config(String),
#[error("Agent error: {0}")]
Agent(String),
#[error("{0}")]
Other(String),
}
pub type Result<T> = std::result::Result<T, Error>;

View file

@ -0,0 +1,9 @@
//! Miyabi Core - Shared types and utilities
//!
//! This crate provides core types and utilities shared across the Miyabi framework.
pub mod error;
pub mod types;
pub use error::Error;
pub use types::*;

View file

@ -0,0 +1,77 @@
//! Core types for Miyabi
use serde::{Deserialize, Serialize};
use chrono::{DateTime, Utc};
/// Message role in a conversation
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum Role {
User,
Assistant,
System,
Tool,
}
/// Chat message
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChatMessage {
pub role: Role,
pub content: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub tool_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tool_call_id: Option<String>,
pub timestamp: DateTime<Utc>,
}
impl ChatMessage {
pub fn user(content: impl Into<String>) -> Self {
Self {
role: Role::User,
content: content.into(),
tool_name: None,
tool_call_id: None,
timestamp: Utc::now(),
}
}
pub fn assistant(content: impl Into<String>) -> Self {
Self {
role: Role::Assistant,
content: content.into(),
tool_name: None,
tool_call_id: None,
timestamp: Utc::now(),
}
}
pub fn system(content: impl Into<String>) -> Self {
Self {
role: Role::System,
content: content.into(),
tool_name: None,
tool_call_id: None,
timestamp: Utc::now(),
}
}
pub fn tool(name: impl Into<String>, content: impl Into<String>, call_id: impl Into<String>) -> Self {
Self {
role: Role::Tool,
content: content.into(),
tool_name: Some(name.into()),
tool_call_id: Some(call_id.into()),
timestamp: Utc::now(),
}
}
}
/// Tool execution result
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ToolResult {
pub name: String,
pub content: String,
pub success: bool,
pub execution_time_ms: u64,
}

View file

@ -0,0 +1,45 @@
[package]
name = "miyabi-tui"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
authors.workspace = true
license.workspace = true
repository.workspace = true
homepage.workspace = true
description = "Miyabi TUI - Terminal User Interface following Codex patterns"
[[bin]]
name = "miyabi-tui"
path = "src/main.rs"
[lib]
name = "miyabi_tui"
path = "src/lib.rs"
[dependencies]
# Workspace dependencies
miyabi-core = { path = "../miyabi-core" }
# TUI Framework
ratatui = { workspace = true }
crossterm = { workspace = true }
# Text Processing
textwrap = { workspace = true }
unicode-width = { workspace = true }
# Async Runtime
tokio = { workspace = true }
futures = { workspace = true }
# Error Handling
anyhow = { workspace = true }
thiserror = { workspace = true }
# Serialization
serde = { workspace = true }
serde_json = { workspace = true }
# Utilities
chrono = { workspace = true }

View file

@ -0,0 +1,223 @@
//! Main TUI Application
use ratatui::{
layout::{Constraint, Direction, Layout, Rect},
style::{Color, Modifier, Style},
text::{Line, Span},
widgets::{Block, Borders, Paragraph, Scrollbar, ScrollbarOrientation, ScrollbarState},
Frame,
};
use crossterm::event::{KeyCode, KeyModifiers};
use crate::event::{Event, EventHandler};
use crate::history_cell::{
HistoryCell, UserMessageCell, AssistantMessageCell, SystemMessageCell, SystemMessageType,
};
/// Main application state
pub struct App {
/// Whether the app should quit
pub should_quit: bool,
/// Current input buffer
pub input: String,
/// Chat history cells
pub cells: Vec<Box<dyn HistoryCell>>,
/// Scroll position
pub scroll: u16,
/// Maximum scroll
pub max_scroll: u16,
}
impl App {
/// Create a new app
pub fn new() -> Self {
let timestamp = chrono::Local::now().format("%H:%M").to_string();
let welcome_cell: Box<dyn HistoryCell> = Box::new(SystemMessageCell {
content: "Welcome to Miyabi CLI! Type your message and press Enter.".to_string(),
timestamp: timestamp.clone(),
message_type: SystemMessageType::Info,
});
Self {
should_quit: false,
input: String::new(),
cells: vec![welcome_cell],
scroll: 0,
max_scroll: 0,
}
}
/// Run the main app loop
pub async fn run(
&mut self,
terminal: &mut ratatui::Terminal<impl ratatui::backend::Backend>,
) -> anyhow::Result<()> {
let mut events = EventHandler::new(100);
loop {
terminal.draw(|f| self.draw(f))?;
if let Some(event) = events.next().await {
match event {
Event::Key(key) => {
if key.modifiers.contains(KeyModifiers::CONTROL) && key.code == KeyCode::Char('c') {
self.should_quit = true;
} else {
match key.code {
KeyCode::Enter => {
if !self.input.is_empty() {
self.send_message();
}
}
KeyCode::Char(c) => {
self.input.push(c);
}
KeyCode::Backspace => {
self.input.pop();
}
KeyCode::Esc => {
self.should_quit = true;
}
KeyCode::Up => {
self.scroll = self.scroll.saturating_sub(1);
}
KeyCode::Down => {
if self.scroll < self.max_scroll {
self.scroll += 1;
}
}
KeyCode::PageUp => {
self.scroll = self.scroll.saturating_sub(10);
}
KeyCode::PageDown => {
self.scroll = (self.scroll + 10).min(self.max_scroll);
}
_ => {}
}
}
}
Event::Resize(_, _) => {}
Event::Tick => {}
Event::Mouse(_) => {}
}
}
if self.should_quit {
break;
}
}
Ok(())
}
/// Draw the UI
fn draw(&mut self, frame: &mut Frame) {
let chunks = Layout::default()
.direction(Direction::Vertical)
.constraints([
Constraint::Length(3), // Header
Constraint::Min(1), // Chat area
Constraint::Length(3), // Input
])
.split(frame.area());
self.draw_header(frame, chunks[0]);
self.draw_chat(frame, chunks[1]);
self.draw_input(frame, chunks[2]);
}
fn draw_header(&self, frame: &mut Frame, area: Rect) {
let title = Paragraph::new(Line::from(vec![
Span::styled(" Miyabi ", Style::default().fg(Color::Magenta).add_modifier(Modifier::BOLD)),
Span::styled("CLI", Style::default().fg(Color::Cyan)),
]))
.block(Block::default().borders(Borders::ALL).border_style(Style::default().fg(Color::Rgb(86, 95, 137))));
frame.render_widget(title, area);
}
fn draw_chat(&mut self, frame: &mut Frame, area: Rect) {
let block = Block::default()
.borders(Borders::ALL)
.border_style(Style::default().fg(Color::Rgb(86, 95, 137)))
.title(Span::styled(" Chat ", Style::default().fg(Color::Rgb(192, 202, 245))));
let inner = block.inner(area);
frame.render_widget(block, area);
// Render cells
let mut lines: Vec<Line<'static>> = Vec::new();
let width = inner.width.saturating_sub(4);
for cell in &self.cells {
lines.push(Line::from(""));
lines.extend(cell.render(width));
}
let total_lines = lines.len() as u16;
self.max_scroll = total_lines.saturating_sub(inner.height);
let paragraph = Paragraph::new(lines)
.scroll((self.scroll, 0));
frame.render_widget(paragraph, inner);
// Scrollbar
if self.max_scroll > 0 {
let scrollbar = Scrollbar::default()
.orientation(ScrollbarOrientation::VerticalRight)
.thumb_style(Style::default().fg(Color::Magenta));
let mut scrollbar_state = ScrollbarState::new(self.max_scroll as usize)
.position(self.scroll as usize);
frame.render_stateful_widget(scrollbar, area, &mut scrollbar_state);
}
}
fn draw_input(&self, frame: &mut Frame, area: Rect) {
let input = Paragraph::new(Line::from(vec![
Span::styled(" ", Style::default().fg(Color::Cyan)),
Span::raw(self.input.clone()),
Span::styled("", Style::default().fg(Color::Cyan)),
]))
.block(
Block::default()
.borders(Borders::ALL)
.border_style(Style::default().fg(Color::Rgb(86, 95, 137)))
.title(Span::styled(" Input ", Style::default().fg(Color::Rgb(192, 202, 245)))),
);
frame.render_widget(input, area);
}
/// Send a message
fn send_message(&mut self) {
let message = std::mem::take(&mut self.input);
let timestamp = chrono::Local::now().format("%H:%M").to_string();
// Add user message
self.cells.push(Box::new(UserMessageCell {
content: message.clone(),
timestamp: timestamp.clone(),
}));
// Add demo assistant response
let response = format!("You said: {}\n\nThis is a **demo response** with `markdown` support!", message);
self.cells.push(Box::new(AssistantMessageCell {
content: response,
timestamp,
streaming: false,
}));
// Auto-scroll to bottom
self.scroll = self.max_scroll;
}
}
impl Default for App {
fn default() -> Self {
Self::new()
}
}

View file

@ -0,0 +1,75 @@
//! Event handling for the TUI
use crossterm::event::{self, Event as CrosstermEvent, KeyEvent, MouseEvent};
use std::time::Duration;
use tokio::sync::mpsc;
/// Terminal events
#[derive(Debug, Clone)]
pub enum Event {
/// Terminal tick
Tick,
/// Key press
Key(KeyEvent),
/// Mouse event
Mouse(MouseEvent),
/// Terminal resize
Resize(u16, u16),
}
/// Event handler for terminal events
pub struct EventHandler {
/// Event sender
#[allow(dead_code)]
sender: mpsc::UnboundedSender<Event>,
/// Event receiver
receiver: mpsc::UnboundedReceiver<Event>,
}
impl EventHandler {
/// Create a new event handler with the given tick rate
pub fn new(tick_rate: u64) -> Self {
let tick_rate = Duration::from_millis(tick_rate);
let (sender, receiver) = mpsc::unbounded_channel();
let sender_clone = sender.clone();
// Spawn event polling task
tokio::spawn(async move {
loop {
if event::poll(tick_rate).unwrap_or(false) {
match event::read() {
Ok(CrosstermEvent::Key(key)) => {
if sender_clone.send(Event::Key(key)).is_err() {
break;
}
}
Ok(CrosstermEvent::Mouse(mouse)) => {
if sender_clone.send(Event::Mouse(mouse)).is_err() {
break;
}
}
Ok(CrosstermEvent::Resize(w, h)) => {
if sender_clone.send(Event::Resize(w, h)).is_err() {
break;
}
}
_ => {}
}
} else {
// Send tick event
if sender_clone.send(Event::Tick).is_err() {
break;
}
}
}
});
Self { sender, receiver }
}
/// Get the next event
pub async fn next(&mut self) -> Option<Event> {
self.receiver.recv().await
}
}

View file

@ -0,0 +1,272 @@
//! History Cell Abstraction - Premium Card Design
//!
//! Following OpenAI Codex TUI patterns with functional colors:
//! - Cyan: User input, tool names
//! - Green: Success
//! - Red: Errors
//! - Magenta: Assistant/Miyabi brand
//! - Dim: Secondary, timestamps
use ratatui::{
style::{Color, Modifier, Style},
text::{Line, Span},
};
use crate::markdown_render::MarkdownRenderer;
use crate::wrapping::wrap_text;
/// Trait for renderable history items
pub trait HistoryCell: Send + Sync {
fn render(&self, width: u16) -> Vec<Line<'static>>;
fn timestamp(&self) -> &str;
fn is_streaming(&self) -> bool {
false
}
}
/// User message cell - Cyan accented card
pub struct UserMessageCell {
pub content: String,
pub timestamp: String,
}
impl HistoryCell for UserMessageCell {
fn render(&self, width: u16) -> Vec<Line<'static>> {
let mut lines = Vec::new();
let inner_width = (width as usize).saturating_sub(6).min(70);
let border = "".repeat(inner_width);
// Top border
lines.push(Line::from(vec![
Span::styled("", Style::default().fg(Color::Cyan)),
Span::styled(border.clone(), Style::default().fg(Color::Cyan)),
Span::styled("", Style::default().fg(Color::Cyan)),
]));
// Header
lines.push(Line::from(vec![
Span::styled("", Style::default().fg(Color::Cyan)),
Span::styled("You", Style::default().fg(Color::Cyan).add_modifier(Modifier::BOLD)),
Span::styled(
format!("{:>width$}", self.timestamp, width = inner_width - 4),
Style::default().add_modifier(Modifier::DIM)
),
Span::styled("", Style::default().fg(Color::Cyan)),
]));
// Content with proper text wrapping
let content_width = inner_width.saturating_sub(2);
for line in self.content.lines() {
let wrapped = wrap_text(line, content_width);
for wrapped_line in wrapped {
let content_str: String = wrapped_line.spans.iter()
.map(|s| s.content.as_ref())
.collect();
let padded = format!("{:<width$}", content_str, width = content_width);
lines.push(Line::from(vec![
Span::styled("", Style::default().fg(Color::Cyan)),
Span::raw(padded),
Span::styled("", Style::default().fg(Color::Cyan)),
]));
}
}
// Bottom border
lines.push(Line::from(vec![
Span::styled("", Style::default().fg(Color::Cyan)),
Span::styled(border, Style::default().fg(Color::Cyan)),
Span::styled("", Style::default().fg(Color::Cyan)),
]));
lines
}
fn timestamp(&self) -> &str {
&self.timestamp
}
}
/// Assistant message cell - Magenta accented card with markdown
pub struct AssistantMessageCell {
pub content: String,
pub timestamp: String,
pub streaming: bool,
}
impl HistoryCell for AssistantMessageCell {
fn render(&self, width: u16) -> Vec<Line<'static>> {
let mut lines = Vec::new();
let inner_width = (width as usize).saturating_sub(6).min(70);
let border = "".repeat(inner_width);
// Top border
lines.push(Line::from(vec![
Span::styled("", Style::default().fg(Color::Magenta)),
Span::styled(border.clone(), Style::default().fg(Color::Magenta)),
Span::styled("", Style::default().fg(Color::Magenta)),
]));
// Header with streaming indicator
let header_text = if self.streaming { "Assistant ●" } else { "Assistant" };
let header_style = Style::default().fg(Color::Magenta).add_modifier(Modifier::BOLD);
lines.push(Line::from(vec![
Span::styled("", Style::default().fg(Color::Magenta)),
Span::styled(header_text, header_style),
Span::styled(
format!("{:>width$}", self.timestamp, width = inner_width - header_text.len() - 1),
Style::default().add_modifier(Modifier::DIM)
),
Span::styled("", Style::default().fg(Color::Magenta)),
]));
// Markdown rendered content
let renderer = MarkdownRenderer::new();
let md_lines = renderer.render(&self.content);
if md_lines.is_empty() && self.streaming {
lines.push(Line::from(vec![
Span::styled("", Style::default().fg(Color::Magenta)),
Span::styled("...", Style::default().add_modifier(Modifier::DIM)),
Span::styled(
format!("{:>width$}", "", width = inner_width - 5),
Style::default()
),
Span::styled("", Style::default().fg(Color::Magenta)),
]));
} else {
for md_line in md_lines {
let mut content_spans = vec![
Span::styled("", Style::default().fg(Color::Magenta)),
];
content_spans.extend(md_line.spans);
content_spans.push(Span::styled("", Style::default().fg(Color::Magenta)));
lines.push(Line::from(content_spans));
}
}
// Bottom border
lines.push(Line::from(vec![
Span::styled("", Style::default().fg(Color::Magenta)),
Span::styled(border, Style::default().fg(Color::Magenta)),
Span::styled("", Style::default().fg(Color::Magenta)),
]));
lines
}
fn timestamp(&self) -> &str {
&self.timestamp
}
fn is_streaming(&self) -> bool {
self.streaming
}
}
/// Tool result cell - Green/Red based on success
pub struct ToolResultCell {
pub tool_name: String,
pub content: String,
pub timestamp: String,
pub execution_time_ms: u64,
pub success: bool,
}
impl HistoryCell for ToolResultCell {
fn render(&self, width: u16) -> Vec<Line<'static>> {
let mut lines = Vec::new();
let inner_width = (width as usize).saturating_sub(8).min(68);
let border = "".repeat(inner_width);
let border_color = if self.success { Color::Green } else { Color::Red };
// Top border (double line for tool)
lines.push(Line::from(vec![
Span::styled("", Style::default().fg(border_color)),
Span::styled(border.clone(), Style::default().fg(border_color)),
Span::styled("", Style::default().fg(border_color)),
]));
// Header with status icon
let icon = if self.success { "" } else { "" };
let time_str = format!("{}ms", self.execution_time_ms);
lines.push(Line::from(vec![
Span::styled("", Style::default().fg(border_color)),
Span::styled(format!("{} ", icon), Style::default().fg(border_color)),
Span::styled(self.tool_name.clone(), Style::default().fg(Color::Cyan).add_modifier(Modifier::BOLD)),
Span::styled(
format!("{:>width$}", time_str, width = inner_width - self.tool_name.len() - 4),
Style::default().add_modifier(Modifier::DIM)
),
Span::styled("", Style::default().fg(border_color)),
]));
// Content with proper text wrapping
let content_width = inner_width.saturating_sub(2);
for line in self.content.lines() {
let wrapped = wrap_text(line, content_width);
for wrapped_line in wrapped {
let content_str: String = wrapped_line.spans.iter()
.map(|s| s.content.as_ref())
.collect();
let padded = format!("{:<width$}", content_str, width = content_width);
lines.push(Line::from(vec![
Span::styled("", Style::default().fg(border_color)),
Span::styled(padded, Style::default().add_modifier(Modifier::DIM)),
Span::styled("", Style::default().fg(border_color)),
]));
}
}
// Bottom border
lines.push(Line::from(vec![
Span::styled("", Style::default().fg(border_color)),
Span::styled(border, Style::default().fg(border_color)),
Span::styled("", Style::default().fg(border_color)),
]));
lines
}
fn timestamp(&self) -> &str {
&self.timestamp
}
}
/// System message cell
pub struct SystemMessageCell {
pub content: String,
pub timestamp: String,
pub message_type: SystemMessageType,
}
#[derive(Clone, Copy)]
pub enum SystemMessageType {
Info,
Warning,
Error,
Success,
}
impl HistoryCell for SystemMessageCell {
fn render(&self, _width: u16) -> Vec<Line<'static>> {
let (icon, color) = match self.message_type {
SystemMessageType::Info => ("", Color::Cyan),
SystemMessageType::Warning => ("", Color::Yellow),
SystemMessageType::Error => ("", Color::Red),
SystemMessageType::Success => ("", Color::Green),
};
vec![
Line::from(vec![
Span::styled(format!("{} ", icon), Style::default().fg(color)),
Span::styled(self.content.clone(), Style::default().add_modifier(Modifier::DIM)),
]),
]
}
fn timestamp(&self) -> &str {
&self.timestamp
}
}

View file

@ -0,0 +1,16 @@
//! Miyabi TUI - Terminal User Interface
//!
//! A premium TUI following the OpenAI Codex patterns for clean,
//! functional design with proper text wrapping and markdown rendering.
pub mod app;
pub mod event;
pub mod wrapping;
pub mod history_cell;
pub mod markdown_render;
pub use app::App;
pub use event::{Event, EventHandler};
pub use wrapping::{word_wrap_line, wrap_text, display_width, WrapOptions};
pub use history_cell::{HistoryCell, UserMessageCell, AssistantMessageCell, ToolResultCell, SystemMessageCell};
pub use markdown_render::{MarkdownRenderer, MarkdownStyles};

View file

@ -0,0 +1,41 @@
//! Miyabi TUI - Terminal User Interface
//!
//! A premium terminal interface following OpenAI Codex patterns.
use miyabi_tui::App;
use crossterm::{
event::{DisableMouseCapture, EnableMouseCapture},
execute,
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
};
use ratatui::prelude::*;
use std::io;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Setup terminal
enable_raw_mode()?;
let mut stdout = io::stdout();
execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
let backend = CrosstermBackend::new(stdout);
let mut terminal = Terminal::new(backend)?;
// Create app and run
let mut app = App::new();
let res = app.run(&mut terminal).await;
// Restore terminal
disable_raw_mode()?;
execute!(
terminal.backend_mut(),
LeaveAlternateScreen,
DisableMouseCapture
)?;
terminal.show_cursor()?;
if let Err(err) = res {
eprintln!("Error: {}", err);
}
Ok(())
}

View file

@ -0,0 +1,241 @@
//! Markdown to Terminal Renderer
//!
//! Converts markdown text to styled ratatui Lines/Spans
use ratatui::{
style::{Color, Modifier, Style},
text::{Line, Span},
};
/// Markdown styling configuration
pub struct MarkdownStyles {
pub h1: Style,
pub h2: Style,
pub h3: Style,
pub bold: Style,
pub italic: Style,
pub code: Style,
pub code_block: Style,
pub link: Style,
pub list_marker: Style,
pub blockquote: Style,
}
impl Default for MarkdownStyles {
fn default() -> Self {
Self {
h1: Style::default()
.fg(Color::Rgb(224, 175, 104))
.add_modifier(Modifier::BOLD | Modifier::UNDERLINED),
h2: Style::default()
.fg(Color::Rgb(224, 175, 104))
.add_modifier(Modifier::BOLD),
h3: Style::default()
.fg(Color::Rgb(192, 202, 245))
.add_modifier(Modifier::ITALIC),
bold: Style::default().add_modifier(Modifier::BOLD),
italic: Style::default().add_modifier(Modifier::ITALIC),
code: Style::default().fg(Color::Rgb(125, 207, 255)),
code_block: Style::default().fg(Color::Rgb(125, 207, 255)),
link: Style::default()
.fg(Color::Rgb(125, 207, 255))
.add_modifier(Modifier::UNDERLINED),
list_marker: Style::default().fg(Color::Rgb(158, 206, 106)),
blockquote: Style::default().fg(Color::Rgb(158, 206, 106)),
}
}
}
/// Markdown renderer
pub struct MarkdownRenderer {
styles: MarkdownStyles,
}
impl MarkdownRenderer {
pub fn new() -> Self {
Self {
styles: MarkdownStyles::default(),
}
}
pub fn with_styles(styles: MarkdownStyles) -> Self {
Self { styles }
}
/// Render markdown text to styled Lines
pub fn render(&self, text: &str) -> Vec<Line<'static>> {
let mut lines = Vec::new();
let mut in_code_block = false;
let mut code_block_content: Vec<String> = Vec::new();
for line in text.lines() {
if line.trim().starts_with("```") {
if in_code_block {
// End code block
lines.push(Line::from(Span::styled(
"┌─────────────────────────────────────────────────────────────┐",
Style::default().fg(Color::Rgb(86, 95, 137)),
)));
for code_line in &code_block_content {
lines.push(Line::from(vec![
Span::styled("", Style::default().fg(Color::Rgb(86, 95, 137))),
Span::styled(code_line.clone(), self.styles.code_block),
]));
}
lines.push(Line::from(Span::styled(
"└─────────────────────────────────────────────────────────────┘",
Style::default().fg(Color::Rgb(86, 95, 137)),
)));
code_block_content.clear();
in_code_block = false;
} else {
in_code_block = true;
}
continue;
}
if in_code_block {
code_block_content.push(line.to_string());
continue;
}
let rendered = self.render_line(line);
lines.push(rendered);
}
lines
}
fn render_line(&self, line: &str) -> Line<'static> {
let trimmed = line.trim();
// Headers
if trimmed.starts_with("### ") {
return Line::from(vec![
Span::styled(" ", Style::default()),
Span::styled(trimmed[4..].to_string(), self.styles.h3),
]);
}
if trimmed.starts_with("## ") {
return Line::from(vec![
Span::styled(" ", Style::default()),
Span::styled(trimmed[3..].to_string(), self.styles.h2),
]);
}
if trimmed.starts_with("# ") {
return Line::from(vec![
Span::styled(" ", Style::default()),
Span::styled(trimmed[2..].to_string(), self.styles.h1),
]);
}
// Blockquotes
if trimmed.starts_with("> ") {
return Line::from(vec![
Span::styled(" > ", self.styles.blockquote),
Span::styled(trimmed[2..].to_string(), Style::default().fg(Color::Rgb(192, 202, 245))),
]);
}
// Unordered lists
if trimmed.starts_with("- ") || trimmed.starts_with("* ") {
let indent = line.len() - line.trim_start().len();
let prefix = " ".repeat(indent / 2);
return Line::from(vec![
Span::raw(prefix),
Span::styled("", self.styles.list_marker),
Span::styled(trimmed[2..].to_string(), Style::default()),
]);
}
// Horizontal rule
if trimmed == "---" || trimmed == "***" || trimmed == "___" {
return Line::from(Span::styled(
"────────────────────────────────────────────────────────────",
Style::default().fg(Color::Rgb(86, 95, 137)),
));
}
// Regular paragraph with inline formatting
self.render_inline_line(line)
}
fn render_inline_line(&self, line: &str) -> Line<'static> {
let mut spans = Vec::new();
let mut current = String::new();
let mut chars = line.chars().peekable();
let mut in_bold = false;
let mut in_italic = false;
let mut in_code = false;
while let Some(c) = chars.next() {
match c {
'`' if !in_bold && !in_italic => {
if !current.is_empty() {
spans.push(Span::styled(
current.clone(),
if in_code { self.styles.code } else { Style::default().fg(Color::Rgb(192, 202, 245)) },
));
current.clear();
}
in_code = !in_code;
}
'*' if chars.peek() == Some(&'*') && !in_code => {
chars.next();
if !current.is_empty() {
let style = if in_bold {
self.styles.bold
} else if in_italic {
self.styles.italic
} else {
Style::default().fg(Color::Rgb(192, 202, 245))
};
spans.push(Span::styled(current.clone(), style));
current.clear();
}
in_bold = !in_bold;
}
'*' | '_' if !in_code && !in_bold => {
if !current.is_empty() {
let style = if in_italic {
self.styles.italic
} else {
Style::default().fg(Color::Rgb(192, 202, 245))
};
spans.push(Span::styled(current.clone(), style));
current.clear();
}
in_italic = !in_italic;
}
_ => {
current.push(c);
}
}
}
if !current.is_empty() {
let style = if in_code {
self.styles.code
} else if in_bold {
self.styles.bold
} else if in_italic {
self.styles.italic
} else {
Style::default().fg(Color::Rgb(192, 202, 245))
};
spans.push(Span::styled(current, style));
}
if spans.is_empty() {
Line::from("")
} else {
Line::from(spans)
}
}
}
impl Default for MarkdownRenderer {
fn default() -> Self {
Self::new()
}
}

View file

@ -0,0 +1,268 @@
//! Text Wrapping Module
//!
//! Provides intelligent text wrapping for terminal display,
//! following the OpenAI Codex TUI pattern with textwrap integration.
use ratatui::text::{Line, Span};
use std::borrow::Cow;
use textwrap::{wrap_algorithms::Penalties, Options, WordSeparator, WordSplitter, WrapAlgorithm};
use unicode_width::UnicodeWidthStr;
/// Wrapping options configuration
pub struct WrapOptions<'a> {
/// Target width for wrapping
pub width: usize,
/// Prefix for the first line
pub initial_indent: Cow<'a, str>,
/// Prefix for subsequent lines
pub subsequent_indent: Cow<'a, str>,
/// Whether to break words that exceed width
pub break_words: bool,
}
impl<'a> Default for WrapOptions<'a> {
fn default() -> Self {
Self {
width: 80,
initial_indent: Cow::Borrowed(""),
subsequent_indent: Cow::Borrowed(""),
break_words: false,
}
}
}
impl<'a> WrapOptions<'a> {
/// Create options with specified width
pub fn new(width: usize) -> Self {
Self {
width,
..Default::default()
}
}
/// Set initial indent
pub fn initial_indent(mut self, indent: impl Into<Cow<'a, str>>) -> Self {
self.initial_indent = indent.into();
self
}
/// Set subsequent indent
pub fn subsequent_indent(mut self, indent: impl Into<Cow<'a, str>>) -> Self {
self.subsequent_indent = indent.into();
self
}
/// Set word breaking behavior
pub fn break_words(mut self, break_words: bool) -> Self {
self.break_words = break_words;
self
}
/// Convert to textwrap Options
fn to_textwrap_options(&self) -> Options<'_> {
Options::new(self.width)
.initial_indent(&self.initial_indent)
.subsequent_indent(&self.subsequent_indent)
.break_words(self.break_words)
.word_separator(WordSeparator::UnicodeBreakProperties)
.word_splitter(WordSplitter::NoHyphenation)
.wrap_algorithm(WrapAlgorithm::OptimalFit(Penalties::default()))
}
}
/// Wrap a single line of text into multiple lines
pub fn word_wrap_line(line: &Line<'_>, width: usize) -> Vec<Line<'static>> {
let options = WrapOptions::new(width);
word_wrap_line_with_options(line, &options)
}
/// Wrap a single line with custom options
pub fn word_wrap_line_with_options(
line: &Line<'_>,
options: &WrapOptions<'_>,
) -> Vec<Line<'static>> {
if line.spans.is_empty() {
return vec![Line::from("")];
}
// Track spans with their byte ranges in the flattened string
let mut flat_text = String::new();
let mut span_ranges: Vec<(usize, usize, ratatui::style::Style)> = Vec::new();
for span in &line.spans {
let start = flat_text.len();
flat_text.push_str(&span.content);
let end = flat_text.len();
span_ranges.push((start, end, span.style));
}
if flat_text.is_empty() {
return vec![Line::from("")];
}
// Use textwrap to compute line breaks
let textwrap_opts = options.to_textwrap_options();
let wrapped = textwrap::wrap(&flat_text, textwrap_opts);
let mut result = Vec::new();
let mut current_pos = 0;
for wrapped_line in wrapped {
let line_str = wrapped_line.trim_start();
if line_str.is_empty() {
result.push(Line::from(""));
continue;
}
// Find position in original text (skip leading whitespace)
let skip_ws = wrapped_line.len() - line_str.len();
let line_start = current_pos + skip_ws;
let line_end = line_start + line_str.len();
// Build spans for this wrapped line
let mut line_spans = Vec::new();
for &(span_start, span_end, style) in &span_ranges {
// Check if this span overlaps with current line
if span_end <= line_start || span_start >= line_end {
continue;
}
// Calculate overlap
let overlap_start = span_start.max(line_start);
let overlap_end = span_end.min(line_end);
if overlap_start < overlap_end {
let text = &flat_text[overlap_start..overlap_end];
line_spans.push(Span::styled(text.to_string(), style));
}
}
if line_spans.is_empty() {
result.push(Line::from(line_str.to_string()));
} else {
result.push(Line::from(line_spans));
}
current_pos = line_end;
}
if result.is_empty() {
vec![Line::from("")]
} else {
result
}
}
/// Wrap multiple lines of text
pub fn word_wrap_lines<'a, I>(lines: I, width: usize) -> Vec<Line<'static>>
where
I: IntoIterator<Item = Line<'a>>,
{
let mut result = Vec::new();
for line in lines {
result.extend(word_wrap_line(&line, width));
}
result
}
/// Wrap plain text string into styled lines
pub fn wrap_text(text: &str, width: usize) -> Vec<Line<'static>> {
let options = WrapOptions::new(width);
let textwrap_opts = options.to_textwrap_options();
let wrapped = textwrap::wrap(text, textwrap_opts);
wrapped
.into_iter()
.map(|s| Line::from(s.into_owned()))
.collect()
}
/// Calculate display width of text (Unicode-aware)
pub fn display_width(text: &str) -> usize {
UnicodeWidthStr::width(text)
}
/// Truncate text to fit within width, adding ellipsis if needed
pub fn truncate_with_ellipsis(text: &str, width: usize) -> String {
let text_width = display_width(text);
if text_width <= width {
return text.to_string();
}
if width < 3 {
return "...".chars().take(width).collect();
}
let target_width = width - 3;
let mut result = String::new();
let mut current_width = 0;
for ch in text.chars() {
let ch_width = UnicodeWidthStr::width(ch.to_string().as_str());
if current_width + ch_width > target_width {
break;
}
result.push(ch);
current_width += ch_width;
}
result.push_str("...");
result
}
/// Pad text to specified width
pub fn pad_to_width(text: &str, width: usize) -> String {
let text_width = display_width(text);
if text_width >= width {
return text.to_string();
}
let padding = width - text_width;
format!("{}{}", text, " ".repeat(padding))
}
#[cfg(test)]
mod tests {
use super::*;
use ratatui::style::{Color, Style};
#[test]
fn test_wrap_simple_text() {
let result = wrap_text("hello world", 5);
assert_eq!(result.len(), 2);
}
#[test]
fn test_wrap_empty() {
let result = wrap_text("", 10);
assert_eq!(result.len(), 1);
}
#[test]
fn test_display_width() {
assert_eq!(display_width("hello"), 5);
assert_eq!(display_width("日本語"), 6);
}
#[test]
fn test_truncate_with_ellipsis() {
assert_eq!(truncate_with_ellipsis("hello world", 8), "hello...");
assert_eq!(truncate_with_ellipsis("short", 10), "short");
}
#[test]
fn test_pad_to_width() {
assert_eq!(pad_to_width("hello", 10), "hello ");
assert_eq!(pad_to_width("hello", 5), "hello");
}
#[test]
fn test_word_wrap_line_preserves_style() {
let style = Style::default().fg(Color::Cyan);
let line = Line::from(vec![Span::styled("hello world foo bar", style)]);
let wrapped = word_wrap_line(&line, 10);
assert!(wrapped.len() >= 2);
}
}

244
docs/GETTING_STARTED.md Normal file
View file

@ -0,0 +1,244 @@
# Getting Started with miyabi-cli-standalone
Miyabiプロジェクトへようこそこのガイドでは、ゼロからMiyabiを使い始めるまでの手順を詳しく解説します。
## 📋 前提条件
### 必須
- **Rust**: 1.75.0以上
```bash
rustc --version # 確認
```
- **Git**: バージョン管理用
```bash
git --version
```
- **GitHubアカウント**: Issue/PR管理用
### 推奨
- **GitHub CLI (`gh`)**: GitHub操作を簡単に
```bash
brew install gh # macOS
gh --version
```
## 🚀 セットアップ手順
### Step 1: 環境変数の設定
#### 1.1 GitHub Personal Access Token取得
1. https://github.com/settings/tokens/new にアクセス
2. Token名を入力例: "Miyabi Local Dev"
3. 以下のスコープを選択:
- ✅ `repo` (Full control of private repositories)
- ✅ `workflow` (Update GitHub Action workflows)
4. "Generate token"をクリック
5. トークンをコピー(**一度しか表示されません!**
#### 1.2 環境変数をシェルプロファイルに追加
**Bash (.bashrc / .bash_profile):**
```bash
echo 'export GITHUB_TOKEN=ghp_xxxxx' >> ~/.bashrc
echo 'export ANTHROPIC_API_KEY=sk-ant-xxxxx' >> ~/.bashrc
source ~/.bashrc
```
**Zsh (.zshrc):**
```bash
echo 'export GITHUB_TOKEN=ghp_xxxxx' >> ~/.zshrc
echo 'export ANTHROPIC_API_KEY=sk-ant-xxxxx' >> ~/.zshrc
source ~/.zshrc
```
#### 1.3 環境変数確認
```bash
echo $GITHUB_TOKEN
echo $ANTHROPIC_API_KEY
```
### Step 2: GitHubリポジトリ作成
#### 2.1 GitHub CLI使用推奨
```bash
cd miyabi-cli-standalone
gh repo create miyabi-cli-standalone --private --source=. --remote=origin
```
#### 2.2 手動作成
1. https://github.com/new にアクセス
2. Repository nameに `miyabi-cli-standalone` を入力
3. "Private"を選択
4. "Create repository"をクリック
5. ローカルリポジトリと接続:
```bash
git remote add origin https://github.com/YOUR_USERNAME/miyabi-cli-standalone.git
git branch -M main
git add .
git commit -m "feat: initial commit 🚀"
git push -u origin main
```
### Step 3: Label体系のセットアップ
Miyabiは53ラベル体系で自動化を制御します。
#### 3.1 自動セットアップ(将来実装予定)
```bash
miyabi setup labels
```
#### 3.2 手動セットアップ
GitHubリポジトリの設定から、以下のラベルを作成
**STATE8個**:
- `📥 state:pending` (Gray)
- `🔍 state:analyzing` (Blue)
- `🏗️ state:implementing` (Yellow)
- `👀 state:reviewing` (Orange)
- `✅ state:done` (Green)
- `❌ state:blocked` (Red)
- `⏸️ state:on-hold` (Purple)
- `🔄 state:reopened` (Pink)
残り45ラベルは`.github/labels.yml`を参照)
### Step 4: 最初のIssue作成
#### 4.1 GitHub Web UIで作成
1. リポジトリの"Issues"タブをクリック
2. "New issue"をクリック
3. Title: "✨ Setup project configuration"
4. Body:
```markdown
## 概要
プロジェクトの初期設定を行う
## タスク
- [ ] .miyabi.yml の設定確認
- [ ] GitHub Actionsの設定
- [ ] 開発環境の準備
## 期待される成果
- プロジェクトが動作可能な状態
```
5. Labels:
- `✨ type:feature`
- `⚠️ priority:P1-High`
- `📥 state:pending`
6. "Submit new issue"をクリック
#### 4.2 GitHub CLIで作成
```bash
gh issue create --title "✨ Setup project configuration" \
--body "初期設定タスク" \
--label "type:feature,priority:P1-High,state:pending"
```
### Step 5: Agent実行
#### 5.1 ステータス確認
```bash
miyabi status
```
出力例:
```
📊 Project Status
Miyabi Installation:
✅ Miyabi is installed
✓ .claude/agents
✓ .github/workflows
Environment:
✅ GITHUB_TOKEN is set
✅ DEVICE_IDENTIFIER: YourMac.local
Git Repository:
✅ Git repository detected
Branch: main
Remotes: origin
```
#### 5.2 CoordinatorAgent実行
```bash
miyabi agent run coordinator --issue 1
```
Agentは以下を実行します
1. Issue分析
2. Task分解DAG構築
3. Worktree作成
4. Specialist Agent割り当て
5. 並列実行
6. 結果統合
## 🎯 よくある使い方
### Issue処理の基本フロー
```bash
# 1. Issue作成GitHub UI または gh CLI
gh issue create --title "新機能実装" --label "type:feature"
# 2. Agent実行
miyabi agent run coordinator --issue 2
# 3. ステータス確認
miyabi status
# 4. ログ確認
cat logs/miyabi-*.log
```
### 複数Issue並列処理
```bash
miyabi agent run coordinator --issues 1,2,3 --concurrency 2
```
### Worktree確認
```bash
git worktree list
```
## 📚 次に読むべきドキュメント
1. **CLAUDE.md** - プロジェクトコンテキストClaude Codeが自動参照
2. **.claude/QUICK_START.md** - 3分で始めるクイックガイド
3. **.claude/agents/README.md** - Agent一覧と使い方
4. **docs/TROUBLESHOOTING.md** - トラブルシューティング
## 🆘 困ったときは
### エラーが出た場合
1. `docs/TROUBLESHOOTING.md` を確認
2. `miyabi status` で環境確認
3. GitHub Issuesで質問: https://github.com/ShunsukeHayashi/Miyabi/issues
### ログ確認
```bash
# 最新のログファイル
tail -f logs/miyabi-$(date +%Y%m%d).log
# エラーログのみ抽出
grep -i error logs/miyabi-*.log
```
## 🎉 次のステップ
おめでとうございますMiyabiのセットアップが完了しました。
次は:
1. **独自のAgent仕様作成**: `.claude/agents/specs/coding/` にカスタムAgent追加
2. **Label体系のカスタマイズ**: プロジェクトに合わせたLabel追加
3. **GitHub Actionsの設定**: `.github/workflows/` でCI/CD自動化
4. **Worktree並列実行**: 複数Issueの同時処理
---
**Miyabi** - Beauty in Autonomous Development 🌸

341
docs/OPERATION_PLAN.md Normal file
View file

@ -0,0 +1,341 @@
# Operation Plan - miyabi-cli-standalone
**Project**: miyabi-cli-standalone
**Created**: 2025-11-22
**Execution Method**: Miyabi Autonomous Agents
---
## 🚀 Quick Start
### Prerequisites
```bash
# 1. 環境確認
miyabi status
# 2. 環境変数設定
export GITHUB_TOKEN=ghp_xxx
export ANTHROPIC_API_KEY=sk-ant-xxx
# 3. Miyabiバイナリへのパスオプション
alias miyabi='/Users/shunsuke/Dev/01-miyabi/_core/miyabi-private/target/release/miyabi'
```
---
## 📋 Execution Workflow
### Phase 1: Sprint 1 開始
#### Day 1: Parallel Foundation Tasks
```bash
# Stream A: TUI
miyabi agent run coordinator --issue 10 # Core Structure
miyabi agent run coordinator --issue 15 # Diff Core
# Stream B: LLM (CRITICAL)
miyabi agent run coordinator --issue 19 # API Client
# Stream C: Tools
miyabi agent run coordinator --issue 24 # Tool Trait
```
#### 進捗監視
```bash
# ステータス確認
miyabi status
# Issue一覧
gh issue list --repo ShunsukeHayashi/miyabi-cli-standalone \
--label "🏗️ state:implementing"
# PR確認
gh pr list --repo ShunsukeHayashi/miyabi-cli-standalone
```
---
## 🔄 Daily Operations
### Morning Routine
```bash
# 1. 前日のPRをレビュー
gh pr list --repo ShunsukeHayashi/miyabi-cli-standalone --state open
# 2. ブロッカー確認
gh issue list --label "🚫 state:blocked"
# 3. 今日のタスク開始
miyabi agent run coordinator --issue <次のissue番号>
```
### Task Execution
```bash
# 単一Issue実行
miyabi agent run coordinator --issue <番号>
# 並列実行(別ターミナルで)
miyabi agent run coordinator --issue 10 &
miyabi agent run coordinator --issue 15 &
miyabi agent run coordinator --issue 19 &
```
### Evening Review
```bash
# 完了タスク確認
gh issue list --label "✅ state:done" --state closed
# 明日の計画
gh issue list --label "📥 state:pending" --milestone "v0.2.0 - Advanced Text Rendering"
```
---
## 🎯 Sprint Execution Plan
### Sprint 1 (Week 1)
| Day | Tasks | Command |
|-----|-------|---------|
| Mon | #10, #15, #19, #24 | `miyabi agent run coordinator --issue 10` (x4 parallel) |
| Tue | Continue + Review | Review PRs, merge if ready |
| Wed | #11, #16, #20, #25 | Start dependent tasks |
| Thu | Continue + Review | Review PRs |
| Fri | Integration testing | Manual testing, bug fixes |
### Sprint 2-4
同様のパターンで継続
---
## 📊 Monitoring Commands
### Real-time Status
```bash
# Miyabiステータス
miyabi status
# GitHub Issues
gh issue list --repo ShunsukeHayashi/miyabi-cli-standalone
# ラベル別
gh issue list --label "📊 priority:P0-Critical"
gh issue list --label "🏗️ state:implementing"
gh issue list --label "👀 state:reviewing"
```
### PR Management
```bash
# PR一覧
gh pr list
# 特定PRの詳細
gh pr view <番号>
# PRをマージ
gh pr merge <番号> --squash
```
### Logs
```bash
# Miyabiログ
ls -la logs/
# 最新ログ
tail -f logs/*.log
```
---
## 🔧 Agent Commands Reference
### Coordinator Agent
```bash
# Issue分析と実装
miyabi agent run coordinator --issue <番号>
# ドライラン(実行せず計画のみ)
miyabi agent run coordinator --issue <番号> --dry-run
# 詳細ログ
RUST_LOG=debug miyabi agent run coordinator --issue <番号>
```
### CodeGen Agent (自動呼び出し)
Coordinatorが自動的にCodeGenを呼び出します。
### Review Agent (自動呼び出し)
PR作成後、自動的にレビューが実行されます。
---
## 🚨 Troubleshooting
### Agent が停止した場合
```bash
# 状態確認
miyabi status
# ログ確認
cat logs/latest.log
# Issue状態をリセット
gh issue edit <番号> --remove-label "🏗️ state:implementing"
gh issue edit <番号> --add-label "📥 state:pending"
# 再実行
miyabi agent run coordinator --issue <番号>
```
### Rate Limit エラー
```bash
# GitHub API制限確認
gh api rate_limit
# 待機後再実行
sleep 3600 # 1時間待機
miyabi agent run coordinator --issue <番号>
```
### ビルドエラー
```bash
# 手動ビルド確認
cargo build --release
# テスト実行
cargo test --all
# Lint
cargo clippy --all-targets
```
---
## 📈 Progress Tracking
### Milestone Progress
```bash
# マイルストーン一覧
gh api repos/ShunsukeHayashi/miyabi-cli-standalone/milestones
# 特定マイルストーンの進捗
gh issue list --milestone "v0.2.0 - Advanced Text Rendering"
```
### Metrics
```bash
# コード行数
find crates -name "*.rs" | xargs wc -l | tail -1
# Issue統計
gh issue list --state all --json state | jq 'group_by(.state) | map({state: .[0].state, count: length})'
```
---
## 🔄 CI/CD Integration
### GitHub Actions
PRがマージされると自動的に:
1. `cargo test` 実行
2. `cargo clippy` チェック
3. `cargo fmt` 確認
### 手動トリガー
```bash
# ワークフロー実行
gh workflow run build.yml
```
---
## 📝 Best Practices
### 1. Critical Path 優先
常にP0タスクを優先:
- #19 (API Client) → #20#22
- #24 (Tool Trait) → #25#26
### 2. 並列実行
独立したタスクは並列実行:
- Stream A (#10-14, #15-18)
- Stream B (#19-23)
- Stream C (#24-28)
### 3. 早期レビュー
PRは作成後すぐにレビュー:
```bash
gh pr review <番号> --approve
gh pr merge <番号> --squash
```
### 4. ブロッカー対応
ブロッカーは即座に対応:
```bash
gh issue list --label "🚫 state:blocked"
```
---
## 🎯 Execution Checklist
### Sprint Start
- [ ] `miyabi status` で環境確認
- [ ] 当該Sprintのタスク確認
- [ ] Critical Pathタスクを優先開始
### Daily
- [ ] PRレビュー・マージ
- [ ] ブロッカー確認
- [ ] 新タスク開始
### Sprint End
- [ ] 全PRマージ
- [ ] 統合テスト
- [ ] マイルストーン確認
- [ ] 次Sprint計画
---
## 🚀 First Execution
```bash
# 今すぐ開始
cd /Users/shunsuke/Dev/miyabi-cli-standalone
# Critical Path開始
miyabi agent run coordinator --issue 19 # API Client (最重要)
miyabi agent run coordinator --issue 10 # Core Structure
miyabi agent run coordinator --issue 24 # Tool Trait
```
---
**Happy Coding with Miyabi! 🤖**

384
docs/PREPARATION_OPS.md Normal file
View file

@ -0,0 +1,384 @@
# Preparation Operations - miyabi-cli-standalone
**Purpose**: Sprint 1開始前の準備作業チェックリスト
**Target Date**: 2025-11-25 (Sprint 1 Start)
---
## 📋 Pre-Sprint Checklist
### 1. Environment Setup
#### 1.1 Development Environment
- [ ] **Rust toolchain**
```bash
rustup update stable
rustup component add clippy rustfmt
cargo --version # 1.75+
```
- [ ] **GitHub CLI**
```bash
gh --version
gh auth status
```
- [ ] **Miyabi CLI**
```bash
/Users/shunsuke/Dev/01-miyabi/_core/miyabi-private/target/release/miyabi --version
```
#### 1.2 API Keys
- [ ] **GitHub Token**
```bash
# .env に設定
echo "GITHUB_TOKEN=ghp_xxx" >> .env
# 必要なスコープ: repo, workflow
gh auth refresh -s repo,workflow
```
- [ ] **Anthropic API Key**
```bash
echo "ANTHROPIC_API_KEY=sk-ant-xxx" >> .env
# テスト
curl https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-d '{"model":"claude-sonnet-4-20250514","max_tokens":10,"messages":[{"role":"user","content":"Hi"}]}'
```
#### 1.3 Project Dependencies
- [ ] **Node.js dependencies**
```bash
npm install
```
- [ ] **Cargo dependencies** (初回ビルドで取得)
```bash
cargo fetch
```
---
### 2. Repository Setup
#### 2.1 Labels Verification
- [ ] **必要なラベル確認**
```bash
gh label list --repo ShunsukeHayashi/miyabi-cli-standalone | wc -l
# Expected: 45+ labels
```
- [ ] **不足ラベル追加**
```bash
# 必要に応じて
gh label create "🔥 urgent" --color "d73a4a" --description "Urgent issue"
```
#### 2.2 Milestones Verification
- [ ] **マイルストーン確認**
```bash
gh api repos/ShunsukeHayashi/miyabi-cli-standalone/milestones | jq '.[].title'
```
Expected:
- v0.2.0 - Advanced Text Rendering
- v0.3.0 - Chat Composer
- v0.4.0 - Approval & Navigation
- v1.0.0 - Production Ready
#### 2.3 Issues Verification
- [ ] **Issue一覧確認**
```bash
gh issue list --repo ShunsukeHayashi/miyabi-cli-standalone --state all | wc -l
# Expected: 28 issues
```
- [ ] **Sprint 1タスク確認**
```bash
gh issue list --milestone "v0.2.0 - Advanced Text Rendering" --label "📊 priority:P0-Critical"
```
---
### 3. Codebase Preparation
#### 3.1 Directory Structure
- [ ] **必要ディレクトリ作成**
```bash
mkdir -p crates/miyabi-cli/src
mkdir -p crates/miyabi-core/src
mkdir -p crates/miyabi-tui/src
mkdir -p tests
```
#### 3.2 Cargo.toml Setup
- [ ] **ワークスペース設定確認**
```bash
cat Cargo.toml | grep "members"
```
- [ ] **各crateのCargo.toml確認**
```bash
ls crates/*/Cargo.toml
```
#### 3.3 Initial Build Test
- [ ] **ビルドテスト**
```bash
cargo build
cargo test
cargo clippy
```
---
### 4. CI/CD Setup
#### 4.1 GitHub Actions
- [ ] **ワークフロー確認**
```bash
ls .github/workflows/
```
- [ ] **CI設定** (create if not exists)
```yaml
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- run: cargo build --all
- run: cargo test --all
- run: cargo clippy --all -- -D warnings
```
#### 4.2 Branch Protection
- [ ] **main ブランチ保護**
- Require PR reviews
- Require status checks
- Require linear history
---
### 5. Documentation
#### 5.1 Required Documents
- [x] README.md
- [x] CLAUDE.md
- [x] GOALS.md
- [x] docs/WBS.md
- [x] docs/SPRINT_PLANNING.md
- [x] docs/OPERATION_PLAN.md
- [x] docs/PRODUCT_SPEC.md
- [x] docs/PREPARATION_OPS.md (this file)
#### 5.2 PlantUML Diagrams
- [x] docs/wbs-diagram.puml
- [x] docs/gantt-chart.puml
---
### 6. Reference Materials
#### 6.1 Codex CLI Reference
- [ ] **Clone Codex CLI**
```bash
git clone https://github.com/openai/codex.git /tmp/codex-reference
```
- [ ] **主要ファイル確認**
```bash
ls /tmp/codex-reference/codex-rs/tui/src/
```
- [ ] **参照用ブックマーク**
- markdown_stream.rs
- diff_render.rs
- chat_composer.rs
- textarea.rs
#### 6.2 Miyabi Private Reference
- [ ] **Agent実装参照**
```bash
ls /Users/shunsuke/Dev/01-miyabi/_core/miyabi-private/crates/
```
---
### 7. Team Communication
#### 7.1 Notification Setup
- [ ] **Slack/Discord通知** (if applicable)
- [ ] **GitHub通知設定**
- Watch repository
- Enable PR notifications
#### 7.2 Daily Standup Schedule
- [ ] **Standup時間設定**
- Time: 毎朝 9:00
- Duration: 10分
- Format: miyabi status確認
---
### 8. Monitoring Setup
#### 8.1 Miyabi Monitoring
- [ ] **ログディレクトリ確認**
```bash
mkdir -p logs
mkdir -p reports
```
- [ ] **ログローテーション設定**
```bash
# 30日以上のログを削除
find logs -mtime +30 -delete
```
#### 8.2 GitHub Insights
- [ ] **Pulse確認**
```
https://github.com/ShunsukeHayashi/miyabi-cli-standalone/pulse
```
---
### 9. Sprint 1 Kickoff Preparation
#### 9.1 First Tasks Ready
- [ ] **Issue #10 (MarkdownStream core)**
```bash
gh issue view 10 --repo ShunsukeHayashi/miyabi-cli-standalone
```
- [ ] **Issue #15 (DiffRender core)**
```bash
gh issue view 15
```
- [ ] **Issue #19 (API client)**
```bash
gh issue view 19
```
- [ ] **Issue #24 (Tool trait)**
```bash
gh issue view 24
```
#### 9.2 Agent Configuration
- [ ] **Miyabi設定確認**
```bash
cat .miyabi.yml
```
- [ ] **.claude設定確認**
```bash
ls .claude/
ls .claude/agents/specs/
```
---
## 🚀 Kickoff Commands
### Sprint 1 Day 1 (2025-11-25)
```bash
# 1. 環境確認
cd /Users/shunsuke/Dev/miyabi-cli-standalone
miyabi status
# 2. Critical Path 開始
miyabi agent run coordinator --issue 19 # API Client (CRITICAL)
# 3. Parallel tasks 開始
miyabi agent run coordinator --issue 10 # Markdown Core
miyabi agent run coordinator --issue 15 # Diff Core
miyabi agent run coordinator --issue 24 # Tool Trait
# 4. 進捗監視
watch -n 60 'gh issue list --label "🏗️ state:implementing"'
```
---
## ✅ Final Checklist
### Must Have (Sprint開始前)
- [ ] Rust toolchain ready
- [ ] API keys configured
- [ ] GitHub labels/milestones set
- [ ] Initial crate structure
- [ ] CI workflow active
### Should Have
- [ ] Codex CLI reference cloned
- [ ] PlantUML diagrams reviewed
- [ ] All documentation in place
### Nice to Have
- [ ] Notification integrations
- [ ] Performance baselines
---
## 📞 Emergency Contacts
| Issue | Action |
|-------|--------|
| API Key invalid | Regenerate at console.anthropic.com |
| GitHub rate limit | Wait 1 hour or use different token |
| Build failure | Check Cargo.toml, dependencies |
| Agent stuck | Check logs, reset issue state |
---
## 📝 Sign-off
| Item | Status | Date | Notes |
|------|--------|------|-------|
| Environment | ⬜ | | |
| Repository | ⬜ | | |
| Codebase | ⬜ | | |
| CI/CD | ⬜ | | |
| Documentation | ✅ | 2025-11-22 | Complete |
| References | ⬜ | | |
| Monitoring | ⬜ | | |
---
**Ready for Sprint 1? Let's go! 🚀**

648
docs/PRODUCT_SPEC.md Normal file
View file

@ -0,0 +1,648 @@
# Product Specification - miyabi-cli-standalone
**Version**: 1.0.0
**Status**: Draft
**Last Updated**: 2025-11-22
---
## 1. Executive Summary
### 1.1 Product Vision
OpenAI Codex CLIと同等の機能を持ち、Miyabiの拡張機能を統合した次世代AI開発CLIツール
### 1.2 Target Users
- ソフトウェア開発者
- DevOpsエンジニア
- AI/MLエンジニア
### 1.3 Core Value Proposition
- **高速**: Rust実装による100ms以下の起動時間
- **美しい**: Ratatui TUIによるリッチなターミナル体験
- **自律的**: 完全自律型タスク実行
- **拡張性**: プラグイン対応
---
## 2. Functional Requirements
### 2.1 TUI System
#### FR-TUI-001: Markdown Streaming Renderer
**Description**: LLMレスポンスをリアルタイムでレンダリング
**Requirements**:
| ID | Requirement | Priority | Status |
|----|-------------|----------|--------|
| FR-TUI-001-1 | Character-by-character streaming | Must | Pending |
| FR-TUI-001-2 | Progressive code block rendering | Must | Pending |
| FR-TUI-001-3 | Syntax highlighting (50+ languages) | Must | Pending |
| FR-TUI-001-4 | Cursor position tracking | Should | Pending |
| FR-TUI-001-5 | Auto-scroll during streaming | Should | Pending |
| FR-TUI-001-6 | User scroll override | Could | Pending |
**Acceptance Criteria**:
```gherkin
Scenario: Streaming text display
Given the LLM is generating a response
When text chunks arrive
Then each character is displayed immediately
And the display scrolls to show latest content
And there is no visible flickering
```
**Performance**:
- Render latency: < 16ms (60 FPS)
- Memory: < 10MB for 100K characters
- CPU: < 5% during streaming
---
#### FR-TUI-002: Git Diff Visualization
**Description**: Git diffの美しい視覚化
**Requirements**:
| ID | Requirement | Priority | Status |
|----|-------------|----------|--------|
| FR-TUI-002-1 | Unified diff parsing | Must | Pending |
| FR-TUI-002-2 | Color-coded additions/deletions | Must | Pending |
| FR-TUI-002-3 | Line numbers (old/new) | Must | Pending |
| FR-TUI-002-4 | Syntax highlighting in diff | Should | Pending |
| FR-TUI-002-5 | Hunk navigation (n/N) | Should | Pending |
| FR-TUI-002-6 | Split view mode | Could | Pending |
**Color Scheme**:
```
Addition: #2ea043 (Green)
Deletion: #f85149 (Red)
Context: Default
Hunk header: #8b949e (Gray)
```
**Acceptance Criteria**:
```gherkin
Scenario: View file diff
Given a unified diff output
When rendered in the TUI
Then additions are highlighted in green
And deletions are highlighted in red
And line numbers are correctly aligned
```
---
#### FR-TUI-003: Chat Composer
**Description**: マルチライン入力とコマンド補完
**Requirements**:
| ID | Requirement | Priority | Status |
|----|-------------|----------|--------|
| FR-TUI-003-1 | Multi-line text input | Must | Pending |
| FR-TUI-003-2 | Command history (Up/Down) | Must | Pending |
| FR-TUI-003-3 | Tab completion | Should | Pending |
| FR-TUI-003-4 | Syntax highlighting in input | Should | Pending |
| FR-TUI-003-5 | Vim keybindings | Could | Pending |
| FR-TUI-003-6 | Emacs keybindings | Could | Pending |
**Key Bindings**:
```
Enter : Send message (single line)
Shift+Enter : New line
Ctrl+C : Cancel
Ctrl+L : Clear screen
Up/Down : History navigation
Tab : Auto-complete
```
---
#### FR-TUI-004: Text Area Widget
**Description**: 完全機能テキストエディタ
**Requirements**:
| ID | Requirement | Priority | Status |
|----|-------------|----------|--------|
| FR-TUI-004-1 | Text selection (Shift+Arrow) | Must | Pending |
| FR-TUI-004-2 | Copy/Paste (Ctrl+C/V) | Must | Pending |
| FR-TUI-004-3 | Undo/Redo (Ctrl+Z/Y) | Must | Pending |
| FR-TUI-004-4 | Word wrap | Should | Pending |
| FR-TUI-004-5 | Find & Replace | Could | Pending |
---
#### FR-TUI-005: Approval Overlay
**Description**: ツール実行の承認UI
**Requirements**:
| ID | Requirement | Priority | Status |
|----|-------------|----------|--------|
| FR-TUI-005-1 | Show tool name and arguments | Must | Pending |
| FR-TUI-005-2 | Y/N/A/N options | Must | Pending |
| FR-TUI-005-3 | Risk level indicator | Should | Pending |
| FR-TUI-005-4 | Remember "Always" choices | Should | Pending |
| FR-TUI-005-5 | Preview changes | Could | Pending |
**Risk Levels**:
- 🟢 Low: Read operations
- 🟡 Medium: Write to files
- 🔴 High: Execute commands, delete files
---
### 2.2 LLM Integration
#### FR-LLM-001: Anthropic API Client
**Description**: Claude APIとの通信
**Requirements**:
| ID | Requirement | Priority | Status |
|----|-------------|----------|--------|
| FR-LLM-001-1 | POST /v1/messages | Must | Pending |
| FR-LLM-001-2 | SSE streaming | Must | Pending |
| FR-LLM-001-3 | API key authentication | Must | Pending |
| FR-LLM-001-4 | Error handling (4xx, 5xx) | Must | Pending |
| FR-LLM-001-5 | Retry with exponential backoff | Must | Pending |
| FR-LLM-001-6 | Request timeout (30s default) | Should | Pending |
**API Endpoint**:
```
POST https://api.anthropic.com/v1/messages
Headers:
x-api-key: $ANTHROPIC_API_KEY
anthropic-version: 2023-06-01
content-type: application/json
```
**Error Handling**:
| Code | Action |
|------|--------|
| 400 | Show error, don't retry |
| 401 | Prompt for API key |
| 429 | Wait, retry with backoff |
| 500+ | Retry up to 3 times |
---
#### FR-LLM-002: Conversation Management
**Description**: 会話履歴と状態管理
**Requirements**:
| ID | Requirement | Priority | Status |
|----|-------------|----------|--------|
| FR-LLM-002-1 | Store message history | Must | Pending |
| FR-LLM-002-2 | System prompt support | Must | Pending |
| FR-LLM-002-3 | Conversation persistence | Should | Pending |
| FR-LLM-002-4 | Resume from previous session | Should | Pending |
| FR-LLM-002-5 | Export conversation | Could | Pending |
**Data Model**:
```rust
struct Message {
role: Role, // user, assistant, system
content: Content, // text, tool_use, tool_result
timestamp: DateTime<Utc>,
}
struct Conversation {
id: Uuid,
messages: Vec<Message>,
system_prompt: Option<String>,
created_at: DateTime<Utc>,
updated_at: DateTime<Utc>,
}
```
**Storage**:
- Location: `~/.miyabi/conversations/`
- Format: JSON
- Retention: 30 days default
---
#### FR-LLM-003: Token Management
**Description**: トークンカウントとコンテキスト管理
**Requirements**:
| ID | Requirement | Priority | Status |
|----|-------------|----------|--------|
| FR-LLM-003-1 | Token estimation | Must | Pending |
| FR-LLM-003-2 | Display current usage | Must | Pending |
| FR-LLM-003-3 | Auto-prune old messages | Must | Pending |
| FR-LLM-003-4 | Warning at 80% capacity | Should | Pending |
| FR-LLM-003-5 | Manual context clear | Should | Pending |
**Limits**:
| Model | Context Window | Reserve |
|-------|----------------|---------|
| Claude Sonnet | 200K | 10K |
| Claude Haiku | 200K | 5K |
**Pruning Strategy**:
1. Keep system prompt always
2. Keep last N messages
3. Summarize old messages
---
#### FR-LLM-004: Tool Calling
**Description**: Function calling の実装
**Requirements**:
| ID | Requirement | Priority | Status |
|----|-------------|----------|--------|
| FR-LLM-004-1 | Send tool definitions | Must | Pending |
| FR-LLM-004-2 | Parse tool_use blocks | Must | Pending |
| FR-LLM-004-3 | Execute tool | Must | Pending |
| FR-LLM-004-4 | Send tool_result | Must | Pending |
| FR-LLM-004-5 | Multi-turn tool use | Must | Pending |
**Tool Schema Format**:
```json
{
"name": "read_file",
"description": "Read the contents of a file",
"input_schema": {
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Absolute path to the file"
}
},
"required": ["path"]
}
}
```
---
### 2.3 Tool System
#### FR-TOOL-001: Tool Registry
**Description**: ツールの登録と管理
**Requirements**:
| ID | Requirement | Priority | Status |
|----|-------------|----------|--------|
| FR-TOOL-001-1 | Register tool by name | Must | Pending |
| FR-TOOL-001-2 | Lookup tool | Must | Pending |
| FR-TOOL-001-3 | List all tools | Should | Pending |
| FR-TOOL-001-4 | Dynamic registration | Could | Pending |
**Tool Trait**:
```rust
#[async_trait]
pub trait Tool: Send + Sync {
fn name(&self) -> &str;
fn description(&self) -> &str;
fn input_schema(&self) -> Value;
async fn execute(&self, input: Value) -> Result<ToolResult>;
}
```
---
#### FR-TOOL-002: Read Tool
**Description**: ファイル読み込み
**Parameters**:
| Name | Type | Required | Description |
|------|------|----------|-------------|
| file_path | string | Yes | Absolute path |
| offset | number | No | Start line (0-based) |
| limit | number | No | Max lines (default: 2000) |
**Output**:
```
Line numbered content (cat -n format)
```
**Errors**:
- File not found
- Permission denied
- Binary file
---
#### FR-TOOL-003: Write Tool
**Description**: ファイル書き込み
**Parameters**:
| Name | Type | Required | Description |
|------|------|----------|-------------|
| file_path | string | Yes | Absolute path |
| content | string | Yes | Content to write |
**Behavior**:
- Create directories if needed
- Overwrite existing file
- Preserve permissions
---
#### FR-TOOL-004: Edit Tool
**Description**: ファイル編集
**Parameters**:
| Name | Type | Required | Description |
|------|------|----------|-------------|
| file_path | string | Yes | Absolute path |
| old_string | string | Yes | Text to find |
| new_string | string | Yes | Replacement |
| replace_all | bool | No | Replace all occurrences |
**Behavior**:
- Exact string match
- Fail if not unique (unless replace_all)
- Preserve indentation
---
#### FR-TOOL-005: Bash Tool
**Description**: コマンド実行
**Parameters**:
| Name | Type | Required | Description |
|------|------|----------|-------------|
| command | string | Yes | Command to execute |
| timeout | number | No | Timeout in ms (default: 120000) |
| cwd | string | No | Working directory |
**Security**:
- Timeout enforcement
- Output truncation (30K chars)
- Dangerous command warning
---
#### FR-TOOL-006: Glob Tool
**Description**: ファイルパターン検索
**Parameters**:
| Name | Type | Required | Description |
|------|------|----------|-------------|
| pattern | string | Yes | Glob pattern (e.g., "**/*.rs") |
| path | string | No | Base directory |
**Output**:
- Matching file paths
- Sorted by modification time
---
#### FR-TOOL-007: Grep Tool
**Description**: テキスト検索
**Parameters**:
| Name | Type | Required | Description |
|------|------|----------|-------------|
| pattern | string | Yes | Regex pattern |
| path | string | No | Search path |
| type | string | No | File type (e.g., "rs") |
| output_mode | string | No | content/files/count |
**Output Modes**:
- `content`: Matching lines with context
- `files_with_matches`: File paths only
- `count`: Match counts
---
## 3. Non-Functional Requirements
### 3.1 Performance
| Metric | Requirement |
|--------|-------------|
| Startup time | < 100ms |
| Memory usage | < 50MB idle, < 200MB active |
| Response latency | < 16ms (60 FPS) |
| File operation | < 100ms for 1MB file |
### 3.2 Reliability
| Metric | Requirement |
|--------|-------------|
| Crash rate | < 0.1% |
| Error recovery | Graceful degradation |
| Data integrity | No data loss on crash |
### 3.3 Security
| Area | Requirement |
|------|-------------|
| API keys | Environment variables only |
| File access | Validate paths, prevent traversal |
| Command execution | Timeout, sandboxing |
| Permissions | Follow least privilege |
### 3.4 Usability
| Aspect | Requirement |
|--------|-------------|
| Learning curve | < 5 minutes for basic use |
| Error messages | Clear, actionable |
| Help system | Built-in --help |
| Keyboard shortcuts | Discoverable, consistent |
### 3.5 Compatibility
| Platform | Support |
|----------|---------|
| macOS | 12+ (Monterey) |
| Linux | Ubuntu 20.04+, Debian 11+ |
| Windows | WSL2 |
---
## 4. Technical Specifications
### 4.1 Architecture
```
┌─────────────────────────────────────────┐
│ miyabi-cli │
│ (CLI entry point, argument parsing) │
└─────────────────┬───────────────────────┘
┌─────────────────▼───────────────────────┐
│ miyabi-tui │
│ (Terminal UI, Ratatui widgets) │
└─────────────────┬───────────────────────┘
┌─────────────────▼───────────────────────┐
│ miyabi-core │
│ (LLM client, Tool system, State) │
└─────────────────────────────────────────┘
```
### 4.2 Dependencies
**Core**:
- tokio: Async runtime
- ratatui: TUI framework
- crossterm: Terminal backend
- clap: CLI parsing
**LLM**:
- reqwest: HTTP client
- serde_json: JSON handling
**Text**:
- pulldown-cmark: Markdown parsing
- syntect: Syntax highlighting
### 4.3 Configuration
**Config File**: `~/.miyabi/config.toml`
```toml
[general]
theme = "dark"
editor = "vim"
[llm]
model = "claude-sonnet-4-20250514"
max_tokens = 4096
temperature = 0.7
[tools]
timeout = 120000
auto_approve = ["read_file", "glob"]
```
---
## 5. User Interface Specifications
### 5.1 Layout
```
┌─────────────────────────────────────────┐
│ miyabi v1.0.0 Tokens: 1.2K/200K ⚡ │ Header
├─────────────────────────────────────────┤
│ │
│ User: How do I implement... │
│ │
│ Assistant: Here's how you can... │
│ ```rust │ Chat History
│ fn main() { │
│ println!("Hello"); │
│ } │
│ ``` │
│ │
├─────────────────────────────────────────┤
│ > Type your message... │ Input
│ │
├─────────────────────────────────────────┤
│ Ctrl+C: Cancel Ctrl+L: Clear ?: Help │ Status Bar
└─────────────────────────────────────────┘
```
### 5.2 Color Palette
| Element | Light | Dark |
|---------|-------|------|
| Background | #FFFFFF | #0D1117 |
| Text | #24292F | #C9D1D9 |
| Code | #F6F8FA | #161B22 |
| Accent | #0969DA | #58A6FF |
| Success | #1A7F37 | #3FB950 |
| Error | #CF222E | #F85149 |
| Warning | #9A6700 | #D29922 |
---
## 6. API Specifications
### 6.1 CLI Interface
```bash
miyabi [OPTIONS] [COMMAND]
Commands:
chat Start interactive chat (default)
run Execute a single prompt
resume Resume previous session
config Manage configuration
version Show version
Options:
-m, --model <MODEL> Model to use
-s, --system <PROMPT> System prompt
-v, --verbose Verbose output
-h, --help Show help
```
### 6.2 Exit Codes
| Code | Meaning |
|------|---------|
| 0 | Success |
| 1 | General error |
| 2 | Invalid arguments |
| 3 | API error |
| 4 | Tool execution error |
---
## 7. Testing Requirements
### 7.1 Unit Tests
- Coverage: > 80%
- All public functions
- Edge cases covered
### 7.2 Integration Tests
- LLM API mocking
- Full conversation flow
- Tool execution
### 7.3 E2E Tests
- Complete user scenarios
- Performance benchmarks
---
## 8. Documentation Requirements
- README.md
- CHANGELOG.md
- API documentation (rustdoc)
- User guide
- Contributing guide
---
## 9. Glossary
| Term | Definition |
|------|------------|
| TUI | Terminal User Interface |
| LLM | Large Language Model |
| SSE | Server-Sent Events |
| Tool | Function callable by LLM |
---
**Document Status**: Draft
**Next Review**: Sprint 1 End

427
docs/SPRINT_PLANNING.md Normal file
View file

@ -0,0 +1,427 @@
# Sprint Planning - miyabi-cli-standalone
**Project**: miyabi-cli-standalone
**Total Sprints**: 4
**Sprint Duration**: 5 days (1 week)
**Start Date**: 2025-11-25
---
## 📊 Overview
| Sprint | Period | Milestone | Goal |
|--------|--------|-----------|------|
| 1 | Nov 25-29 | v0.2.0 | Foundation |
| 2 | Dec 2-6 | v0.2.0 | Parser & State |
| 3 | Dec 9-13 | v0.3.0/v1.0.0 | Integration |
| 4 | Dec 16-20 | v1.0.0 | Production Ready |
---
# Sprint 1: Foundation
**Period**: November 25-29, 2025
**Goal**: Core structures for all streams
## 🎯 Sprint Goal
> 全3ストリームTUI、LLM、Toolsの基盤構造を確立する
## 📋 Sprint Backlog
| Issue | Task | Priority | Points | Agent |
|-------|------|----------|--------|-------|
| #10 | MarkdownStream core structure | P0 | 3 | CodeGen |
| #15 | DiffRender core structure | P1 | 3 | CodeGen |
| #19 | Anthropic API client | P0 | 5 | CodeGen |
| #24 | Tool trait and registry | P0 | 5 | CodeGen |
**Total Points**: 16
## 📅 Daily Breakdown
### Day 1 (Mon) - Kickoff
**Morning**
```bash
# 全タスク並列開始
miyabi agent run coordinator --issue 10 &
miyabi agent run coordinator --issue 15 &
miyabi agent run coordinator --issue 19 &
miyabi agent run coordinator --issue 24 &
```
**Tasks**:
- [ ] #10 開始 - MarkdownStream struct定義
- [ ] #15 開始 - DiffRender struct定義
- [ ] #19 開始 - AnthropicClient struct定義
- [ ] #24 開始 - Tool trait定義
**End of Day**: 基本struct完成
### Day 2 (Tue) - Core Implementation
**Tasks**:
- [ ] #10 完了 - State enum、buffer管理
- [ ] #15 完了 - Diff parsing logic
- [ ] #19 継続 - Streaming SSE処理
- [ ] #24 継続 - Registry実装
**Reviews**:
```bash
gh pr list --state open
gh pr review <番号> --approve
```
### Day 3 (Wed) - Integration
**Tasks**:
- [ ] #19 完了 - Error handling、retry
- [ ] #24 完了 - Schema generation
**Code Review**:
- [ ] #10 PR レビュー・マージ
- [ ] #15 PR レビュー・マージ
### Day 4 (Thu) - Testing
**Tasks**:
- [ ] 統合テスト実行
- [ ] #19 PR レビュー・マージ
- [ ] #24 PR レビュー・マージ
```bash
cargo test --all
cargo clippy --all-targets
```
### Day 5 (Fri) - Sprint Review
**Tasks**:
- [ ] 全PRマージ確認
- [ ] デモ準備
- [ ] Sprint 2準備
## ✅ Acceptance Criteria
- [ ] `MarkdownStream` が文字を受け取り状態遷移できる
- [ ] `DiffRender` がunified diffをパースできる
- [ ] `AnthropicClient` がAPIに接続しストリーム受信できる
- [ ] `Tool` traitが定義され、registryに登録できる
- [ ] 全テストがパス
- [ ] Clippyエラーなし
## 🚧 Risks & Mitigations
| Risk | Mitigation |
|------|------------|
| API接続失敗 | モック作成、retry実装 |
| 設計変更 | 早期レビュー |
---
# Sprint 2: Parser & State
**Period**: December 2-6, 2025
**Goal**: Incremental parsing and state management
## 🎯 Sprint Goal
> パーサーと状態管理を実装し、基盤構造を完成させる
## 📋 Sprint Backlog
| Issue | Task | Priority | Points | Depends |
|-------|------|----------|--------|---------|
| #11 | Incremental markdown parser | P0 | 5 | #10 |
| #16 | Diff visualization | P1 | 5 | #15 |
| #20 | Conversation state | P0 | 5 | #19 |
| #25 | File operation tools | P0 | 5 | #24 |
**Total Points**: 20
## 📅 Daily Breakdown
### Day 1 (Mon) - Kickoff
```bash
miyabi agent run coordinator --issue 11 &
miyabi agent run coordinator --issue 16 &
miyabi agent run coordinator --issue 20 &
miyabi agent run coordinator --issue 25 &
```
**Tasks**:
- [ ] #11 開始 - pulldown-cmark統合
- [ ] #16 開始 - Color scheme実装
- [ ] #20 開始 - Message history構造
- [ ] #25 開始 - ReadTool実装
### Day 2 (Tue) - Core Features
**Tasks**:
- [ ] #11 継続 - Partial parsing
- [ ] #16 継続 - Line numbers、indicators
- [ ] #20 継続 - Serialization
- [ ] #25 継続 - WriteTool、EditTool
### Day 3 (Wed) - Completion
**Tasks**:
- [ ] #11 完了 - Event→Span変換
- [ ] #16 完了 - 全視覚要素
- [ ] #20 完了 - Persistence
- [ ] #25 完了 - 全File tools
### Day 4 (Thu) - Review
**Tasks**:
- [ ] PRレビュー
- [ ] 統合テスト
- [ ] Bug fix
### Day 5 (Fri) - Sprint Review
**Tasks**:
- [ ] 全PRマージ
- [ ] v0.2.0リリース準備
- [ ] Sprint 3準備
## ✅ Acceptance Criteria
- [ ] Markdown streaming が部分コンテンツを正しくレンダリング
- [ ] Diff表示が色分け、行番号付き
- [ ] Conversation履歴が保存・復元可能
- [ ] File tools (Read/Write/Edit) が全て動作
- [ ] 全テストパス
---
# Sprint 3: Integration
**Period**: December 9-13, 2025
**Goal**: LLM tools and advanced features
## 🎯 Sprint Goal
> LLMツール連携と高度な機能を実装する
## 📋 Sprint Backlog
| Issue | Task | Priority | Points | Depends |
|-------|------|----------|--------|---------|
| #12 | Code block handling | P1 | 3 | #11 |
| #17 | Syntax highlighting in diff | P2 | 3 | #16 |
| #21 | Token management | P1 | 5 | #20 |
| #22 | Tool definitions | P0 | 5 | #20 |
| #26 | Bash tool | P0 | 5 | #25 |
**Total Points**: 21
## 📅 Daily Breakdown
### Day 1 (Mon) - Kickoff
```bash
miyabi agent run coordinator --issue 12 &
miyabi agent run coordinator --issue 17 &
miyabi agent run coordinator --issue 21 &
miyabi agent run coordinator --issue 22 &
miyabi agent run coordinator --issue 26 &
```
### Day 2 (Tue) - Implementation
**Focus**: #22 (Tool definitions) - CRITICAL PATH
### Day 3 (Wed) - Integration
**Tasks**:
- [ ] Tool definitions と API client統合
- [ ] Bash tool と File tools統合
### Day 4 (Thu) - Testing
**Tasks**:
- [ ] End-to-end テスト
- [ ] Tool実行テスト
### Day 5 (Fri) - Sprint Review
**Milestone**: v0.3.0 機能フリーズ
## ✅ Acceptance Criteria
- [ ] Code blockがシンタックスハイライト付きでレンダリング
- [ ] DiffにもSyntax highlighting適用
- [ ] Token count表示、自動pruning動作
- [ ] Tool definitionsがAPI requestに含まれる
- [ ] Bash toolがコマンド実行、結果返却
---
# Sprint 4: Production Ready
**Period**: December 16-20, 2025
**Goal**: Polish and production readiness
## 🎯 Sprint Goal
> プロダクション品質に仕上げ、v1.0.0をリリースする
## 📋 Sprint Backlog
| Issue | Task | Priority | Points | Depends |
|-------|------|----------|--------|---------|
| #13 | Cursor tracking | P2 | 2 | #12 |
| #14 | Markdown tests | P2 | 3 | #13 |
| #18 | Diff navigation | P2 | 2 | #17 |
| #23 | Rate limiting | P2 | 3 | #22 |
| #27 | Search tools | P1 | 5 | #26 |
| #28 | Result formatting | P2 | 3 | #27 |
**Total Points**: 18
## 📅 Daily Breakdown
### Day 1 (Mon) - Kickoff
```bash
miyabi agent run coordinator --issue 13 &
miyabi agent run coordinator --issue 18 &
miyabi agent run coordinator --issue 23 &
miyabi agent run coordinator --issue 27 &
```
### Day 2 (Tue) - Completion
**Tasks**:
- [ ] #13 完了
- [ ] #14 開始・完了
- [ ] #18 完了
- [ ] #23 完了
- [ ] #27 完了
- [ ] #28 開始
### Day 3 (Wed) - Final Integration
**Tasks**:
- [ ] #28 完了
- [ ] Full integration test
- [ ] Performance testing
### Day 4 (Thu) - QA
**Tasks**:
- [ ] Bug fixes
- [ ] Documentation
- [ ] Release notes
### Day 5 (Fri) - Release
**Tasks**:
- [ ] v1.0.0 タグ作成
- [ ] Release作成
- [ ] 🎉 Celebration!
## ✅ Acceptance Criteria
- [ ] 全機能が動作
- [ ] ドキュメント完備
- [ ] パフォーマンス基準達成
- [ ] セキュリティチェック完了
- [ ] v1.0.0 リリース
---
## 📊 Sprint Metrics
### Velocity Tracking
| Sprint | Planned | Completed | Velocity |
|--------|---------|-----------|----------|
| 1 | 16 | - | - |
| 2 | 20 | - | - |
| 3 | 21 | - | - |
| 4 | 18 | - | - |
**Total**: 75 points
### Burndown
Sprint終了時に更新
---
## 🔄 Ceremonies
### Daily Standup (10min)
```bash
# 毎朝実行
miyabi status
gh issue list --label "🏗️ state:implementing"
```
### Sprint Planning (始め)
1. Sprint Goal確認
2. Backlog確定
3. タスク割り当て
4. リスク確認
### Sprint Review (終わり)
1. 完了タスクデモ
2. フィードバック収集
3. 次Sprint調整
### Sprint Retrospective
- What went well?
- What to improve?
- Action items
---
## 🚀 Execution Commands
### Sprint 1 Quick Start
```bash
cd /Users/shunsuke/Dev/miyabi-cli-standalone
# Critical Path開始
miyabi agent run coordinator --issue 19 # API Client
miyabi agent run coordinator --issue 24 # Tool Trait
# Parallel tasks
miyabi agent run coordinator --issue 10 # Markdown Core
miyabi agent run coordinator --issue 15 # Diff Core
```
### Progress Check
```bash
# 完了タスク
gh issue list --state closed --label "✅ state:done"
# 進行中
gh issue list --label "🏗️ state:implementing"
# PRs
gh pr list --state open
```
---
## 📝 Notes
- 各SprintでCritical Pathを優先
- ブロッカーは即座にエスカレーション
- PRは24時間以内にレビュー
- テストは継続的に実行
---
**Let's build something amazing! 🚀**

278
docs/TROUBLESHOOTING.md Normal file
View file

@ -0,0 +1,278 @@
# Troubleshooting Guide
Miyabi使用中に発生する可能性のある問題と解決策をまとめています。
## 🔧 環境関連
### GITHUB_TOKENが設定されていない
**症状**:
```
Error: GITHUB_TOKEN not set
```
**解決策**:
1. トークンを取得: https://github.com/settings/tokens/new
2. 環境変数を設定:
```bash
export GITHUB_TOKEN=ghp_xxxxx
```
3. シェルプロファイルに追加(永続化):
```bash
echo 'export GITHUB_TOKEN=ghp_xxxxx' >> ~/.zshrc
source ~/.zshrc
```
### ANTHROPIC_API_KEYが設定されていない
**症状**:
```
Error: ANTHROPIC_API_KEY not set
```
**解決策**:
1. Anthropic Consoleでキー取得: https://console.anthropic.com/
2. 環境変数を設定:
```bash
export ANTHROPIC_API_KEY=sk-ant-xxxxx
```
## 🐛 Git関連
### Git repositoryが見つからない
**症状**:
```
Error: Not a git repository
```
**解決策**:
```bash
cd your-project
git init
```
### Worktreeが残ったまま
**症状**:
```
Error: Worktree already exists: .worktrees/issue-123
```
**解決策**:
```bash
# Worktree一覧確認
git worktree list
# 不要なWorktreeを削除
git worktree remove .worktrees/issue-123
# すべてのstale Worktreeをクリーンアップ
git worktree prune
```
### マージコンフリクト
**症状**:
```
CONFLICT (content): Merge conflict in src/main.rs
```
**解決策**:
```bash
# コンフリクトファイルを確認
git status
# 手動でコンフリクトを解決
# エディタでファイルを開き、<<<<<<<, =======, >>>>>>> マーカーを削除
# 解決後
git add src/main.rs
git commit -m "fix: resolve merge conflict"
```
## 🤖 Agent関連
### Agent実行が失敗する
**症状**:
```
Error: Agent execution failed
```
**解決策**:
1. ログファイル確認:
```bash
tail -f logs/miyabi-$(date +%Y%m%d).log
```
2. Issue番号が正しいか確認:
```bash
gh issue list
```
3. Labelが正しく設定されているか確認
### Issue番号が見つからない
**症状**:
```
Error: Issue #123 not found
```
**解決策**:
```bash
# Issue一覧確認
gh issue list --limit 50
# 正しい番号で再実行
miyabi agent run coordinator --issue 正しい番号
```
## 📦 インストール関連
### `miyabi` コマンドが見つからない
**症状**:
```
command not found: miyabi
```
**解決策**:
```bash
# crates.ioから再インストール
cargo install miyabi-cli --force
# パス確認
which miyabi
# Cargo binディレクトリがPATHに含まれているか確認
echo $PATH | grep -o "$HOME/.cargo/bin"
# なければ追加
echo 'export PATH="$HOME/.cargo/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
```
### コンパイルエラー
**症状**:
```
error: failed to compile miyabi-cli
```
**解決策**:
```bash
# Rustを最新版にアップデート
rustup update stable
# Cargoキャッシュをクリア
rm -rf ~/.cargo/registry
rm -rf ~/.cargo/git
# 再インストール
cargo install miyabi-cli
```
## 🌐 GitHub関連
### API Rate Limit
**症状**:
```
Error: API rate limit exceeded
```
**解決策**:
1. GitHubにログイン状態か確認:
```bash
gh auth status
```
2. Personal Access Tokenのスコープ確認
3. しばらく待つRate limitは1時間でリセット
### Permission denied
**症状**:
```
Error: Resource not accessible by personal access token
```
**解決策**:
1. トークンのスコープを確認: `repo`, `workflow` が必要
2. 新しいトークンを生成
3. 環境変数を更新
## 🔍 デバッグ方法
### 詳細ログを有効化
`.miyabi.yml` でログレベルを変更:
```yaml
logging:
level: debug # info → debug
directory: "./logs"
```
### ログファイルの確認
```bash
# 最新のログ
tail -100 logs/miyabi-$(date +%Y%m%d).log
# エラーのみ抽出
grep -i "error\|fail" logs/miyabi-*.log
# 特定のAgentのログ
grep -i "CoordinatorAgent" logs/miyabi-*.log
```
### miyabi status の活用
```bash
miyabi status
# 出力例:
# Miyabi Installation: ✅ or ❌
# Environment: GITHUB_TOKEN, ANTHROPIC_API_KEY の状態
# Git Repository: ブランチ、コミット状態
# Worktrees: アクティブなWorktree数
```
## 🆘 それでも解決しない場合
### サポートを受ける
1. **GitHub Issues**: https://github.com/ShunsukeHayashi/Miyabi/issues
- 詳細なエラーメッセージを含めてください
- `miyabi status` の出力を添付
- ログファイルの関連部分を添付
2. **Discord Community**: (準備中)
3. **ドキュメント**:
- [GETTING_STARTED.md](GETTING_STARTED.md)
- [CLAUDE.md](../CLAUDE.md)
- [GitHub Discussions](https://github.com/ShunsukeHayashi/Miyabi/discussions)
### 報告に含めるべき情報
```bash
# システム情報
uname -a
# Rustバージョン
rustc --version
cargo --version
# miyabiバージョン
miyabi --version
# プロジェクト状態
miyabi status
# 直近のログ
tail -50 logs/miyabi-$(date +%Y%m%d).log
```
---
**Miyabi** - Beauty in Autonomous Development 🌸

178
docs/WBS.md Normal file
View file

@ -0,0 +1,178 @@
# Work Breakdown Structure (WBS)
**Project**: miyabi-cli-standalone
**Version**: v1.0.0
**Created**: 2025-11-22
---
## 1. TUI Foundation (v0.2.0)
### 1.1 Streaming Markdown Renderer (#2)
- **1.1.1** Core structure and state management (#10) - P0 - 4h
- **1.1.2** Incremental parser with pulldown-cmark (#11) - P0 - 6h
- **1.1.3** Code block handling with syntax highlighting (#12) - P1 - 4h
- **1.1.4** Cursor and scroll position tracking (#13) - P2 - 3h
- **1.1.5** Unit tests (#14) - P2 - 4h
**Subtotal: ~700 lines, 21h**
### 1.2 Git Diff Visualization (#3)
- **1.2.1** Core structure and diff parsing (#15) - P1 - 4h
- **1.2.2** Visualization with colors and indicators (#16) - P1 - 6h
- **1.2.3** Syntax highlighting in diff content (#17) - P2 - 4h
- **1.2.4** Scrollable view with navigation (#18) - P2 - 3h
**Subtotal: ~650 lines, 17h**
---
## 2. Chat Composer (v0.3.0)
### 2.1 Chat Input Component (#4)
- **2.1.1** Separate input handling from main app
- **2.1.2** Multi-line input support
- **2.1.3** Command history navigation
- **2.1.4** Auto-completion
- **2.1.5** Syntax highlighting in input
**Subtotal: ~3,938 lines**
### 2.2 Text Area Widget (#5)
- **2.2.1** Full-featured text area widget
- **2.2.2** Text selection support
- **2.2.3** Copy/paste functionality
- **2.2.4** Undo/redo stack
**Subtotal: ~2,213 lines**
---
## 3. Approval & Navigation (v0.4.0)
### 3.1 Approval Overlay (#6)
- **3.1.1** Tool execution approval UI
- **3.1.2** Y/N/Always/Never options
- **3.1.3** Risk level display
- **3.1.4** Preview of changes
**Subtotal: ~656 lines**
### 3.2 Session Resume (#7)
- **3.2.1** Session resume selection
- **3.2.2** Conversation history browser
- **3.2.3** Search functionality
- **3.2.4** Preview pane
**Subtotal: ~1,580 lines**
---
## 4. LLM Integration (v1.0.0)
### 4.1 Claude API Integration (#8)
- **4.1.1** Anthropic API client with streaming (#19) - P0 - 8h
- **4.1.2** Conversation state and message history (#20) - P0 - 6h
- **4.1.3** Token counting and context window (#21) - P1 - 6h
- **4.1.4** Tool definitions and function calling (#22) - P0 - 8h
- **4.1.5** Rate limiting and retry logic (#23) - P2 - 4h
**Subtotal: ~1,600 lines, 32h**
---
## 5. Tool Execution System (v1.0.0)
### 5.1 Tool System (#9)
- **5.1.1** Tool trait and registry system (#24) - P0 - 6h
- **5.1.2** File operation tools (Read, Write, Edit) (#25) - P0 - 8h
- **5.1.3** Bash tool with sandboxing (#26) - P0 - 8h
- **5.1.4** Search tools (Glob, Grep) (#27) - P1 - 6h
- **5.1.5** Result formatting and error handling (#28) - P2 - 4h
**Subtotal: ~1,800 lines, 32h**
---
## Summary
| Phase | Milestone | Lines | Hours | Issues |
|-------|-----------|-------|-------|--------|
| 1 | v0.2.0 TUI Foundation | 1,350 | 38h | #2, #3, #10-18 |
| 2 | v0.3.0 Chat Composer | 6,151 | - | #4, #5 |
| 3 | v0.4.0 Approval & Nav | 2,236 | - | #6, #7 |
| 4 | v1.0.0 Production | 3,400 | 64h | #8, #9, #19-28 |
**Total: ~13,137+ lines**
---
## Critical Path
```
#19#20#22#24#25#26#27#28
│ │
API Tools
```
**Critical Path Duration: ~42h**
---
## Dependencies Matrix
| Task | Depends On | Blocks |
|------|------------|--------|
| #10 | - | #11 |
| #11 | #10 | #12 |
| #12 | #11 | #13 |
| #13 | #12 | #14 |
| #14 | #13 | - |
| #15 | - | #16 |
| #16 | #15 | #17 |
| #17 | #16 | #18 |
| #18 | #17 | - |
| #19 | - | #20, #23 |
| #20 | #19 | #21, #22 |
| #21 | #20 | - |
| #22 | #20 | - |
| #23 | #19 | - |
| #24 | - | #25, #26, #27 |
| #25 | #24 | #26 |
| #26 | #25 | #27 |
| #27 | #26 | #28 |
| #28 | #27 | - |
---
## Resource Allocation
### Parallel Streams (Max 3)
**Stream A**: TUI (#10-14, #15-18)
**Stream B**: LLM (#19-23)
**Stream C**: Tools (#24-28)
### Sprint Allocation
| Sprint | Stream A | Stream B | Stream C |
|--------|----------|----------|----------|
| 1 | #10, #15 | #19 | #24 |
| 2 | #11, #16 | #20 | #25 |
| 3 | #12, #17 | #21, #22 | #26 |
| 4 | #13, #14, #18 | #23 | #27, #28 |
---
## Risk Register
| Risk | Impact | Mitigation |
|------|--------|------------|
| API rate limits | High | Implement caching, retry logic |
| Complex streaming | Medium | Incremental implementation |
| Tool security | High | Sandboxing, input validation |
| Performance | Medium | Benchmarking, profiling |
---
**Last Updated**: 2025-11-22

118
docs/gantt-chart.puml Normal file
View file

@ -0,0 +1,118 @@
@startgantt miyabi-cli-gantt
title miyabi-cli-standalone - Project Timeline
project starts 2025-11-25
' === Milestones ===
[v0.2.0 TUI Foundation] happens at 2025-12-06
[v1.0.0 Production Ready] happens at 2025-12-20
' === Sprint 1: Foundation ===
[Sprint 1] as [S1] lasts 5 days and is colored in LightBlue
[S1] starts 2025-11-25
-- Sprint 1: Foundation --
[#10 Core Structure] as [T10] lasts 1 day
[T10] starts at [S1]'s start
[T10] is colored in Coral
[#15 Diff Core] as [T15] lasts 1 day
[T15] starts at [S1]'s start
[T15] is colored in Orange
[#19 API Client] as [T19] lasts 2 days
[T19] starts at [S1]'s start
[T19] is colored in Coral
[#24 Tool Trait] as [T24] lasts 2 days
[T24] starts at [S1]'s start
[T24] is colored in Coral
' === Sprint 2: Parser & State ===
[Sprint 2] as [S2] lasts 5 days and is colored in LightGreen
[S2] starts at [S1]'s end
-- Sprint 2: Parser & State --
[#11 Incremental Parser] as [T11] lasts 2 days
[T11] starts at [T10]'s end
[T11] is colored in Coral
[#16 Diff Visualization] as [T16] lasts 2 days
[T16] starts at [T15]'s end
[T16] is colored in Orange
[#20 Conversation State] as [T20] lasts 2 days
[T20] starts at [T19]'s end
[T20] is colored in Coral
[#25 File Tools] as [T25] lasts 2 days
[T25] starts at [T24]'s end
[T25] is colored in Coral
' === Sprint 3: Integration ===
[Sprint 3] as [S3] lasts 5 days and is colored in LightYellow
[S3] starts at [S2]'s end
-- Sprint 3: Integration --
[#12 Code Blocks] as [T12] lasts 1 day
[T12] starts at [T11]'s end
[T12] is colored in Orange
[#17 Syntax in Diff] as [T17] lasts 1 day
[T17] starts at [T16]'s end
[T17] is colored in Yellow
[#21 Token Management] as [T21] lasts 2 days
[T21] starts at [T20]'s end
[T21] is colored in Orange
[#22 Tool Definitions] as [T22] lasts 2 days
[T22] starts at [T20]'s end
[T22] is colored in Coral
[#26 Bash Tool] as [T26] lasts 2 days
[T26] starts at [T25]'s end
[T26] is colored in Coral
' === Sprint 4: Polish ===
[Sprint 4] as [S4] lasts 5 days and is colored in LightCoral
[S4] starts at [S3]'s end
-- Sprint 4: Polish --
[#13 Cursor Tracking] as [T13] lasts 1 day
[T13] starts at [T12]'s end
[T13] is colored in Yellow
[#14 Tests] as [T14] lasts 1 day
[T14] starts at [T13]'s end
[T14] is colored in Yellow
[#18 Navigation] as [T18] lasts 1 day
[T18] starts at [T17]'s end
[T18] is colored in Yellow
[#23 Rate Limiting] as [T23] lasts 1 day
[T23] starts at [T22]'s end
[T23] is colored in Yellow
[#27 Search Tools] as [T27] lasts 2 days
[T27] starts at [T26]'s end
[T27] is colored in Orange
[#28 Result Formatting] as [T28] lasts 1 day
[T28] starts at [T27]'s end
[T28] is colored in Yellow
' Critical path highlighting
[T19] is colored in Red
[T20] is colored in Red
[T22] is colored in Red
[T24] is colored in Red
[T25] is colored in Red
[T26] is colored in Red
@endgantt

104
docs/wbs-diagram.puml Normal file
View file

@ -0,0 +1,104 @@
@startuml miyabi-cli-wbs
!theme plain
title miyabi-cli-standalone - Critical Path & WBS
' Define colors
!$critical = "#FF6B6B"
!$high = "#FFA94D"
!$medium = "#69DB7C"
!$low = "#74C0FC"
' Milestones
rectangle "v0.2.0\nTUI Foundation" as M1 #LightBlue
rectangle "v0.3.0\nChat Composer" as M2 #LightGreen
rectangle "v0.4.0\nApproval & Nav" as M3 #LightYellow
rectangle "v1.0.0\nProduction" as M4 #LightCoral
' === Stream A: TUI Rendering ===
package "Stream A: TUI Rendering" {
rectangle "#10\nCore Structure" as T10 $critical
rectangle "#11\nParser" as T11 $critical
rectangle "#12\nCode Blocks" as T12 $high
rectangle "#13\nCursor" as T13 $medium
rectangle "#14\nTests" as T14 $medium
rectangle "#15\nDiff Core" as T15 $high
rectangle "#16\nVisualization" as T16 $high
rectangle "#17\nSyntax" as T17 $medium
rectangle "#18\nNavigation" as T18 $medium
}
' === Stream B: LLM Integration ===
package "Stream B: LLM Integration" #FFE4E1 {
rectangle "#19\nAPI Client" as T19 $critical
rectangle "#20\nConversation" as T20 $critical
rectangle "#21\nTokens" as T21 $high
rectangle "#22\nTool Defs" as T22 $critical
rectangle "#23\nRate Limit" as T23 $medium
}
' === Stream C: Tool System ===
package "Stream C: Tool System" #E8F5E9 {
rectangle "#24\nTool Trait" as T24 $critical
rectangle "#25\nFile Tools" as T25 $critical
rectangle "#26\nBash Tool" as T26 $critical
rectangle "#27\nSearch" as T27 $high
rectangle "#28\nFormatting" as T28 $medium
}
' Dependencies - Stream A
T10 --> T11
T11 --> T12
T12 --> T13
T13 --> T14
T15 --> T16
T16 --> T17
T17 --> T18
' Dependencies - Stream B (CRITICAL PATH)
T19 --> T20 : **CRITICAL**
T20 --> T21
T20 --> T22 : **CRITICAL**
T19 --> T23
' Dependencies - Stream C
T24 --> T25 : **CRITICAL**
T25 --> T26 : **CRITICAL**
T26 --> T27
T27 --> T28
' Cross-stream dependencies
T22 ..> T24 : "requires"
' Milestone connections
T14 --> M1
T18 --> M1
M1 --> M2
M2 --> M3
T23 --> M4
T28 --> M4
' Legend
legend right
|= Color |= Priority |
| <$critical> | P0 Critical |
| <$high> | P1 High |
| <$medium> | P2 Medium |
| <$low> | P3 Low |
endlegend
note bottom of T19
**Critical Path Start**
API Client is the foundation
for all LLM functionality
end note
note bottom of T28
**Critical Path End**
Result formatting completes
the tool system
end note
@enduml