• 作成:

Claude Codeに`nix run '.#generate-hlint'`みたいなシェルと干渉する記号を含むコマンドを自動実行してもらう

背景

nix flakesにワークフローで以下のようなappを追加することがあります。

generate-hlint = {
  type = "app";
  program = pkgs.lib.getExe (
    pkgs.writeShellApplication {
      name = "generate-hlint";
      runtimeInputs = [
        pkgs.dhall-yaml
        pkgs.git
        pkgs.prettier
      ];
      text = ''
        cd "$(git rev-parse --show-toplevel)"
        {
          cat <<'HEADER'
        # himari hlint configuration
        #
        # このファイルはDhallによって自動生成されています。
        # 直接編集しないでください。
        #
        # himariが推奨するスタイルを機械的にチェックするためのhlint設定ファイルです。
        # 部分関数や危険な関数の使用を警告したり、
        # より可読性の高いパターンを提案します。
        #
        # 使い方:
        #   * このファイルをプロジェクトルートに .hlint.yaml としてコピー
        #   * または .hlint.yaml から参照: - arguments: [--hint=path/to/this/.hlint.yaml]
        HEADER
          dhall-to-yaml-ng --file hlint/hlint.dhall
        } > .hlint.yaml
        prettier --write .hlint.yaml
      '';
    }
  );
};

ワークフローの一部としてちょくちょく実行するわけですね。依存関係がほぼ完全に管理されたタスクランナーと言えるでしょう。

こういうアプリは、

nix run '.#generate-hlint'

のように実行します。

本当はシングルクオートは不要なのですが、 zshの構文とかと衝突することがあるみたいです。

問題

Claude Codeはこのコマンドを許可無しで実行することをなかなか覚えられません。

settings.jsonを直接編集したり、 Claude Code自身から編集してもらっても全然成功しませんでした。

解決

Claude CodeのTUIの/permissions (allowed-tools)コマンドから、許可したいコマンドを追加したら以下のような形式になっていました。

"Bash(nix run '.#generate-hlint')"

何も複雑なことはなく普段シェルで実行するのと同じように記述してやれば良かったということですね。

ともかくClaude CodeのTUIを通すことでエスケープとかが解決されるようなので、迷ったときは使うと良さそうです。