# All files / src/components/tools classifyTool.ts

94.44% Statements 17/18
87.5% Branches 7/8
100% Functions 2/2
94.44% Lines 17/18

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136

    65x

    277x

    277x
    150x
    150x
    150x
    150x
    150x

    127x
    127x
    6x
    6x
    6x

    121x

    65x

    147x
    147x

     /**
     * Classifies a tool name into a rendering category.
     *
     * Maps tool names from all supported runtimes (Claude Code, Copilot, Codex)
     * to a UI category that determines which card component renders the event.
     */

    /** Tool rendering categories corresponding to specialized card components. */
    export type ToolCategory =
      | "file-read"
      | "file-edit"
      | "file-write"
      | "shell"
      | "search"
      | "todo"
      | "metadata"
      | "task"
      | "workpad"
      | "knowledge"
      | "ipc"
      | "tool-search"
      | "agent"
      | "generic";

    /** Known MCP server names for bare-name extraction from Copilot dash format. */
    const KNOWN_MCP_SERVERS: Set<string> = new Set(["grackle"]);

    /**
     * Extracts the bare tool name from runtime-specific naming conventions.
     *
     * - Claude Code / Codex: `mcp__grackle__task_create` -> `task_create`
     * - Copilot: `grackle-task_create` -> `task_create`
     * - Built-in: `Read` -> `read` (unchanged, lowered later)
     */
    export function extractBareName(toolName: string): string {
      // Defensive: callers may pass undefined for legacy events that never carried
      // a tool name (e.g. stub fixtures, runtimes that emit tool_use with only
      // tool_name / display_name in `content`). Treat as empty string.
      Iif (!toolName) {
        return "";
      }
      // MCP double-underscore format: mcp__<server>__<tool> (only for known servers)
      if (toolName.startsWith("mcp__")) {
        const serverSep = toolName.indexOf("__", 5);
        if (serverSep > 5) {
          const server = toolName.slice(5, serverSep);
          if (KNOWN_MCP_SERVERS.has(server)) {
            return toolName.slice(serverSep + 2);
          }
        }
      }
      // Copilot dash format: <server>-<tool> (only for known servers)
      const dashIndex = toolName.indexOf("-");
      if (dashIndex > 0) {
        const server = toolName.slice(0, dashIndex);
        if (KNOWN_MCP_SERVERS.has(server)) {
          return toolName.slice(dashIndex + 1);
        }
      }
      return toolName;
    }

    const TOOL_MAP: Record<string, ToolCategory> = {
      // File read — Claude Code: Read, Copilot: view
      read: "file-read",
      view: "file-read",

      // File edit — Claude Code: Edit, Copilot: edit, Codex: file_change
      edit: "file-edit",
      file_change: "file-edit",

      // File write — Claude Code: Write
      write: "file-write",

      // Shell — Claude Code: Bash, Copilot: powershell, Codex: command_execution
      bash: "shell",
      powershell: "shell",
      command_execution: "shell",

      // Search — Claude Code: Grep, Glob
      grep: "search",
      glob: "search",

      // Todo — Claude Code: TodoWrite, Codex: update_plan, Goose: todo_write
      todowrite: "todo",
      update_plan: "todo",
      todo_write: "todo",

      // Metadata — Copilot: report_intent
      report_intent: "metadata",

      // Task — Grackle MCP
      task_list: "task",
      task_create: "task",
      task_show: "task",
      task_update: "task",
      task_start: "task",
      task_complete: "task",
      task_resume: "task",
      task_delete: "task",

      // Workpad — Grackle MCP
      workpad_write: "workpad",
      workpad_read: "workpad",

      // Knowledge — Grackle MCP
      knowledge_search: "knowledge",
      knowledge_get_node: "knowledge",
      knowledge_create_node: "knowledge",

      // IPC — Grackle MCP
      ipc_spawn: "ipc",
      ipc_write: "ipc",
      ipc_close: "ipc",
      ipc_list_fds: "ipc",
      ipc_terminate: "ipc",
      ipc_create_stream: "ipc",
      ipc_attach: "ipc",
      ipc_share_stream: "ipc",
      ipc_list_streams: "ipc",

      // ToolSearch — Claude Code built-in
      toolsearch: "tool-search",

      // Agent — Claude Code: Agent (formerly Task), Copilot: task, read_agent
      agent: "agent",
      task: "agent",
      read_agent: "agent",
    };

    /** Classifies a tool name to determine which card component should render it. */
    export function classifyTool(toolName: string): ToolCategory {
      const bare = extractBareName(toolName);
      return TOOL_MAP[bare.toLowerCase()] ?? "generic";
    }