claude codeに使用トークン量とモデル名などを常時表示させる

引用: https://zenn.dev/little_hand_s/articles/dbd5fc27f5a2f0

・ statusline.jsを作成する

code ~/.claude/statusline.js

・ 以下の内容で保存する。

#!/usr/bin/env node

const fs = require('fs');
const path = require('path');
const readline = require('readline');
const { execSync } = require('child_process');

// Constants
const COMPACTION_THRESHOLD = 200000

// Read JSON from stdin
let input = '';
process.stdin.on('data', chunk => input += chunk);
process.stdin.on('end', async () => {
  try {
    const data = JSON.parse(input);

    // Extract values
    const model = data.model?.display_name || 'Unknown';
    const currentDir = data.workspace?.current_dir || data.cwd || '.';
    const dirName = path.basename(currentDir);
    const sessionId = data.session_id;

    // Get Git branch
    let branch = '';
    if (currentDir && fs.existsSync(path.join(currentDir, '.git'))) {
      try {
        const branchName = execSync('git --no-optional-locks branch --show-current 2>/dev/null', {
          cwd: currentDir,
          encoding: 'utf-8'
        }).trim();
        if (branchName) {
          branch = ` 🌿 ${branchName}`;
        }
      } catch (e) {
        // Gitコマンドエラーは無視
      }
    }

    // Calculate token usage for current session
    let totalTokens = 0;

    if (sessionId) {
      // Find all transcript files
      const projectsDir = path.join(process.env.HOME, '.claude', 'projects');

      if (fs.existsSync(projectsDir)) {
        // Get all project directories
        const projectDirs = fs.readdirSync(projectsDir)
          .map(dir => path.join(projectsDir, dir))
          .filter(dir => fs.statSync(dir).isDirectory());

        // Search for the current session's transcript file
        for (const projectDir of projectDirs) {
          const transcriptFile = path.join(projectDir, `${sessionId}.jsonl`);

          if (fs.existsSync(transcriptFile)) {
            totalTokens = await calculateTokensFromTranscript(transcriptFile);
            break;
          }
        }
      }
    }

    // Calculate percentage
    const percentage = Math.min(100, Math.round((totalTokens / COMPACTION_THRESHOLD) * 100));

    // Format token display
    const tokenDisplay = formatTokenCount(totalTokens);

    // Color coding for percentage (same ratio as original article with 160K base)
    let percentageColor = '\x1b[32m'; // Green
    if (percentage >= 56) percentageColor = '\x1b[33m'; // Yellow (112K/200K)
    if (percentage >= 72) percentageColor = '\x1b[91m'; // Bright Red (144K/200K)

    // Build status line
    const statusLine = `[${model}] 📁 ${dirName}${branch} | 🪙 ${tokenDisplay} | ${percentageColor}${percentage}%\x1b[0m \x1b[90m| ${sessionId}\x1b[0m`;

    console.log(statusLine);
  } catch (error) {
    // Fallback status line on error
    console.log('[Claude Code]');
  }
});

async function calculateTokensFromTranscript(filePath) {
  return new Promise((resolve, reject) => {
    let lastUsage = null;

    const fileStream = fs.createReadStream(filePath);
    const rl = readline.createInterface({
      input: fileStream,
      crlfDelay: Infinity
    });

    rl.on('line', (line) => {
      try {
        const entry = JSON.parse(line);

        // Check if this is an assistant message with usage data
        if (entry.type === 'assistant' && entry.message?.usage) {
          lastUsage = entry.message.usage;
        }
      } catch (e) {
        // Skip invalid JSON lines
      }
    });

    rl.on('close', () => {
      if (lastUsage) {
        // The last usage entry contains cumulative tokens
        const totalTokens = (lastUsage.input_tokens || 0) +
          (lastUsage.output_tokens || 0) +
          (lastUsage.cache_creation_input_tokens || 0) +
          (lastUsage.cache_read_input_tokens || 0);
        resolve(totalTokens);
      } else {
        resolve(0);
      }
    });

    rl.on('error', (err) => {
      reject(err);
    });
  });
}

function formatTokenCount(tokens) {
  if (tokens >= 1000000) {
    return `${(tokens / 1000000).toFixed(1)}M`;
  } else if (tokens >= 1000) {
    return `${(tokens / 1000).toFixed(1)}K`;
  }
  return tokens.toString();
}

・ 実行権限を与える

chmod +x ~/.claude/statusline.js

Settings.json を編集する

 code ~/.claude/settings.json

以下を追加する:

   "statusLine": {
      "type": "command",
       "command": "~/.claude/statusline.js"
    },
No.2721
02/17 16:39

edit

Cursor CLI で コマンドラインでCursorを使う

cursor CLI にログインする

cursor agent login

cursor CLIで使用可能なモデル一覧を表示させる。

cursor agent --list-models

● cursor CLI を起動する

cursor agent

(以降、Cursor CLI Agent内での操作です)

モデルを選択する

/model

モードを(ノーマル → Auto run → Plan → Ask と変更する。)

「Shift」+「Tab」

あとは Claude Code ほとんど同じです。

No.2718
02/10 13:20

edit

Claude Code で、エージェントチームを自動的に作らせるように設定する。

● Claude Code で、エージェントチームを自動的に作らせるように設定する。

1 . Cloud Code の設定を変更する。

~/.claude/settings.json に次の設定値を追加する。

  "env": {
    "CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1"
  },

2 . tmuxをインストールして起動する。

# tmuxをインストールする
brew install tmux

# tmuxを起動する
tmux

3 . Claude Code を起動して、チームが作れるかどうか聞いてみる。

claude 

❯ チームを作れるような設定になっていますか??

以下のように返ってくれば、チームが作れる状態になっています。

⏺ はい、チーム機能は利用可能です。以下のツールが使えます:

  - TeamCreate - チームの作成
  - TaskCreate / TaskList / TaskUpdate - タスクの作成・管理
  - SendMessage - チームメイト間のメッセージ送受信
  - Task (サブエージェント) - 専門エージェントの起動

  チームを作成すると、複数のエージェントが並行してタスクに取り組めます。例えば:

  - Explore エージェント - コード調査専門
  - general-purpose エージェント - コード編集・実装
  - Bash エージェント - コマンド実行
  - Plan エージェント - 設計・計画

  何かチームで取り組みたいタスクはありますか?
No.2717
02/09 09:58

edit

Claude Codeで「Shift + Enter」で改行コードを入力する。

Karabiner-Elements で、以下のように設定します。

{
    "description": "【Claude Code】Shift+Enterを'バックスラッシュ+enter'に変換",
    "manipulators": [
        {
            "conditions": [
                {
                    "bundle_identifiers": [
                        "com.apple.Terminal"
                    ],
                    "type": "frontmost_application_if"
                },
                {
                    "input_sources": [{ "language": "^ja$" }],
                    "type": "input_source_if"
                }
            ],
            "from": {
                "key_code": "return_or_enter",
                "modifiers": { "mandatory": ["shift"] }
            },
            "to": [
                { "select_input_source": { "language": "^en$" } },
                { "key_code": "backslash" },
                { "key_code": "return_or_enter" },
                {
                    "key_code": "spacebar",
                    "modifiers": ["left_control"]
                }
            ],
            "type": "basic"
        },
        {
            "conditions": [
                {
                    "bundle_identifiers": [
                        "com.apple.Terminal"
                    ],
                    "type": "frontmost_application_if"
                },
                {
                    "input_sources": [{ "language": "^en$" }],
                    "type": "input_source_if"
                }
            ],
            "from": {
                "key_code": "return_or_enter",
                "modifiers": { "mandatory": ["shift"] }
            },
            "to": [
                { "key_code": "backslash" },
                { "key_code": "return_or_enter" }
            ],
            "type": "basic"
        }
    ]
}
No.2713
02/02 12:46

edit

Claude Code の skills

skill-creator

→ anthropic公式のスキル

引数付き起動

/create-skill pdf-converter PDFファイルを画像に変換するスキル

引数なし起動(対話的)

/create-skill

UI UX Pro Max

→ フロントエンドのUIを書くのにすごく便利

https://github.com/nextlevelbuilder/ui-ux-pro-max-skill

seo-review

→ AIで作ったサイトのSEO審査に使います

https://github.com/leonardomso/33-js-concepts/tree/master/.opencode/skill/seo-review

skills 使い方

・初級編「体験」
  まずは公式のskill-creatorスキルを使って、最初のスキルを作成する。
  目標は、「AIに仕事を教える」という感覚を掴むこと。

・中級編「実践」
  自分のための便利スキル(デバッグ、リファクタリング等)をゼロから設計する。
  目標は、descriptionを磨き込み、トリガー精度を90%以上に高めること。

・上級編「スケール」
  作成したスキルをHooksやSub-agentと連携させ、開発ワークフローに組み込む。
  目標はスキルをチームで共有し、組織の「手続き的知識」をコード化する。

https://x.com/_nogu66/status/2000133200689897578?s=20

No.2707
01/21 21:38

edit