mcpField
D
domain-cli

domain-cli

github.com/actionbook開発1.6k3.2k 回インストール9 週間前に更新
リポジトリ

domain-cli について

domain-cli は、Rust のコマンドラインツール設計を扱うスキルです。出力、設定の優先順位、エラー処理、中断への対応と、関連するクレートや設計パターンを説明します。

主な機能

  1. 01clap 派生マクロによる引数解析
  2. 02設定ソースの優先順位付け
  3. 03データは stdout、エラーは stderr
  4. 04エラー時の非ゼロ終了コード
  5. 05Ctrl+C シグナルへの対応
  6. 06ターミナルのプロンプトと進捗表示

活用シーン

  1. 01型安全なコマンド階層の設計
  2. 02CLI・環境変数・ファイル間の設定上書き
  3. 03スクリプトでパイプ可能な出力の維持
  4. 04長時間処理の進捗表示

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/actionbook/rust-skills --skill domain-cli

インストール後、Claude Code で/domain-cliを入力して読み込まれたか確認します。

詳細

CLI ドメイン

レイヤー 3:ドメイン制約

ドメイン制約 → 設計への影響

ドメインルール設計上の制約Rust での実装
ユーザーの使いやすさ分かりやすいヘルプ、エラーclap の derive マクロ
設定の優先順位CLI > env > file階層化された設定の読み込み
終了コードエラー時は 0 以外適切な Result の処理
標準出力/標準エラーデータとエラーの分離エラーには eprintln!
割り込み可能Ctrl+C の処理シグナル処理

重要な制約

ユーザーへの伝達
RULE: Errors to stderr, data to stdout
WHY: Pipeable output, scriptability
RUST: eprintln! for errors, println! for data
設定の優先順位
RULE: CLI args > env vars > config file > defaults
WHY: User expectation, override capability
RUST: Layered config with clap + figment/config
終了コード
RULE: Return non-zero on any error
WHY: Script integration, automation
RUST: main() -> Result<(), Error> or explicit exit()

設計をたどる ↓

制約から設計へ(レイヤー 2):

"Need argument parsing"
    ↓ m05-type-driven: Derive structs for args
    ↓ clap: #[derive(Parser)]

"Need config layering"
    ↓ m09-domain: Config as domain object
    ↓ figment/config: Layer sources

"Need progress display"
    ↓ m12-lifecycle: Progress bar as RAII
    ↓ indicatif: ProgressBar

主なクレート

用途クレート
引数の解析clap
対話型プロンプトdialoguer
プログレスバーindicatif
色付き出力colored
ターミナル UIratatui
ターミナル制御crossterm
コンソールユーティリティconsole

設計パターン

パターン用途実装
Args 構造体型安全な引数#[derive(Parser)]
サブコマンドコマンド階層#[derive(Subcommand)]
設定レイヤー上書きの優先順位CLI > env > file
進捗表示ユーザーへのフィードバックProgressBar::new(len)

コードパターン:CLI の構造

use clap::{Parser, Subcommand};

#[derive(Parser)]
#[command(name = "myapp", about = "My CLI tool")]
struct Cli {
    /// Enable verbose output
    #[arg(short, long)]
    verbose: bool,

    #[command(subcommand)]
    command: Commands,
}

#[derive(Subcommand)]
enum Commands {
    /// Initialize a new project
    Init { name: String },
    /// Run the application
    Run {
        #[arg(short, long)]
        port: Option<u16>,
    },
}

fn main() -> anyhow::Result<()> {
    let cli = Cli::parse();
    match cli.command {
        Commands::Init { name } => init_project(&name)?,
        Commands::Run { port } => run_server(port.unwrap_or(8080))?,
    }
    Ok(())
}

よくある間違い

間違いドメイン制約違反修正方法
エラーを標準出力に出すパイプ処理を妨げるeprintln!
ヘルプテキストがないUX が悪い#[arg(help = "...")]
エラー時にパニックする不適切な終了コードResult と適切な処理
長時間の処理で進捗を表示しないユーザーが状況を把握できないindicatif

レイヤー 1 へたどる

制約レイヤー 2 のパターンレイヤー 1 の実装
型安全な引数Derive マクロclap Parser
エラー処理Result の伝播anyhow + 終了コード
ユーザーへのフィードバック進捗表示の RAIIindicatif ProgressBar
設定の優先順位Builder パターン階層化されたソース

関連スキル

場合参照先
エラー処理m06-error-handling
型駆動の引数m05-type-driven
進捗表示のライフサイクルm12-lifecycle
非同期 CLIm07-concurrency

コメント