πŸ“„ File detail

utils/computerUse/common.ts

🧩 .tsπŸ“ 62 linesπŸ’Ύ 2,617 bytesπŸ“ text
← Back to All Files

🎯 Use case

This file lives under β€œutils/”, which covers cross-cutting helpers (shell, tempfiles, settings, messages, process input, …). On the API surface it exposes COMPUTER_USE_MCP_SERVER_NAME, CLI_HOST_BUNDLE_ID, getTerminalBundleId, CLI_CU_CAPABILITIES, and isComputerUseMCPServer β€” mainly types, interfaces, or factory objects. It composes internal code from services and env (relative imports).

Generated from folder role, exports, dependency roots, and inline comments β€” not hand-reviewed for every path.

🧠 Inline summary

import { normalizeNameForMCP } from '../../services/mcp/normalization.js' import { env } from '../env.js' export const COMPUTER_USE_MCP_SERVER_NAME = 'computer-use'

πŸ“€ Exports (heuristic)

  • COMPUTER_USE_MCP_SERVER_NAME
  • CLI_HOST_BUNDLE_ID
  • getTerminalBundleId
  • CLI_CU_CAPABILITIES
  • isComputerUseMCPServer

πŸ–₯️ Source preview

import { normalizeNameForMCP } from '../../services/mcp/normalization.js'
import { env } from '../env.js'

export const COMPUTER_USE_MCP_SERVER_NAME = 'computer-use'

/**
 * Sentinel bundle ID for the frontmost gate. Claude Code is a terminal β€” it has
 * no window. This never matches a real `NSWorkspace.frontmostApplication`, so
 * the package's "host is frontmost" branch (mouse click-through exemption,
 * keyboard safety-net) is dead code for us. `prepareForAction`'s "exempt our
 * own window" is likewise a no-op β€” there is no window to exempt.
 */
export const CLI_HOST_BUNDLE_ID = 'com.anthropic.claude-code.cli-no-window'

/**
 * Fallback `env.terminal` β†’ bundleId map for when `__CFBundleIdentifier` is
 * unset. Covers the macOS terminals we can distinguish β€” Linux entries
 * (konsole, gnome-terminal, xterm) are deliberately absent since
 * `createCliExecutor` is darwin-guarded.
 */
const TERMINAL_BUNDLE_ID_FALLBACK: Readonly<Record<string, string>> = {
  'iTerm.app': 'com.googlecode.iterm2',
  Apple_Terminal: 'com.apple.Terminal',
  ghostty: 'com.mitchellh.ghostty',
  kitty: 'net.kovidgoyal.kitty',
  WarpTerminal: 'dev.warp.Warp-Stable',
  vscode: 'com.microsoft.VSCode',
}

/**
 * Bundle ID of the terminal emulator we're running inside, so `prepareDisplay`
 * can exempt it from hiding and `captureExcluding` can keep it out of
 * screenshots. Returns null when undetectable (ssh, cleared env, unknown
 * terminal) β€” caller must handle the null case.
 *
 * `__CFBundleIdentifier` is set by LaunchServices when a .app bundle spawns a
 * process and is inherited by children. It's the exact bundleId, no lookup
 * needed β€” handles terminals the fallback table doesn't know about. Under
 * tmux/screen it reflects the terminal that started the SERVER, which may
 * differ from the attached client. That's harmless here: we exempt A
 * terminal window, and the screenshots exclude it regardless.
 */
export function getTerminalBundleId(): string | null {
  const cfBundleId = process.env.__CFBundleIdentifier
  if (cfBundleId) return cfBundleId
  return TERMINAL_BUNDLE_ID_FALLBACK[env.terminal ?? ''] ?? null
}

/**
 * Static capabilities for macOS CLI. `hostBundleId` is not here β€” it's added
 * by `executor.ts` per `ComputerExecutor.capabilities`. `buildComputerUseTools`
 * takes this shape (no `hostBundleId`, no `teachMode`).
 */
export const CLI_CU_CAPABILITIES = {
  screenshotFiltering: 'native' as const,
  platform: 'darwin' as const,
}

export function isComputerUseMCPServer(name: string): boolean {
  return normalizeNameForMCP(name) === COMPUTER_USE_MCP_SERVER_NAME
}