πŸ“„ File detail

utils/cliHighlight.ts

🧩 .tsπŸ“ 55 linesπŸ’Ύ 2,140 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 CliHighlight, getCliHighlightPromise, and getLanguageName β€” mainly functions, hooks, or classes. Dependencies touch Node path helpers. What the file header says: highlight.js's type defs carry `/// <reference lib="dom" />`. SSETransport, mcp/client, ssh, dumpPrompts use DOM types (TextDecodeOptions, RequestInfo) that only typecheck because this file's `typeof import('highlight.js')` pulls lib.dom in. tsconfig has lib: ["ESNext"] only β€” fi.

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

🧠 Inline summary

highlight.js's type defs carry `/// <reference lib="dom" />`. SSETransport, mcp/client, ssh, dumpPrompts use DOM types (TextDecodeOptions, RequestInfo) that only typecheck because this file's `typeof import('highlight.js')` pulls lib.dom in. tsconfig has lib: ["ESNext"] only β€” fixing the actual DOM-type deps is a separate sweep; this ref preserves the status quo. / <reference lib="dom" />

πŸ“€ Exports (heuristic)

  • CliHighlight
  • getCliHighlightPromise
  • getLanguageName

πŸ“š External import roots

Package roots from from "…" (relative paths omitted).

  • path

πŸ–₯️ Source preview

// highlight.js's type defs carry `/// <reference lib="dom" />`. SSETransport,
// mcp/client, ssh, dumpPrompts use DOM types (TextDecodeOptions, RequestInfo)
// that only typecheck because this file's `typeof import('highlight.js')` pulls
// lib.dom in. tsconfig has lib: ["ESNext"] only β€” fixing the actual DOM-type
// deps is a separate sweep; this ref preserves the status quo.
/// <reference lib="dom" />

import { extname } from 'path'

export type CliHighlight = {
  highlight: typeof import('cli-highlight').highlight
  supportsLanguage: typeof import('cli-highlight').supportsLanguage
}

// One promise shared by Fallback.tsx, markdown.ts, events.ts, getLanguageName.
// The highlight.js import piggybacks: cli-highlight has already pulled it into
// the module cache, so the second import() is a cache hit β€” no extra bytes
// faulted in.
let cliHighlightPromise: Promise<CliHighlight | null> | undefined

let loadedGetLanguage: typeof import('highlight.js').getLanguage | undefined

async function loadCliHighlight(): Promise<CliHighlight | null> {
  try {
    const cliHighlight = await import('cli-highlight')
    // cache hit β€” cli-highlight already loaded highlight.js
    const highlightJs = await import('highlight.js')
    loadedGetLanguage = highlightJs.getLanguage
    return {
      highlight: cliHighlight.highlight,
      supportsLanguage: cliHighlight.supportsLanguage,
    }
  } catch {
    return null
  }
}

export function getCliHighlightPromise(): Promise<CliHighlight | null> {
  cliHighlightPromise ??= loadCliHighlight()
  return cliHighlightPromise
}

/**
 * eg. "foo/bar.ts" β†’ "TypeScript". Awaits the shared cli-highlight load,
 * then reads highlight.js's language registry. All callers are telemetry
 * (OTel counter attributes, permission-dialog unary events) β€” none block
 * on this, they fire-and-forget or the consumer already handles Promise<string>.
 */
export async function getLanguageName(file_path: string): Promise<string> {
  await getCliHighlightPromise()
  const ext = extname(file_path).slice(1)
  if (!ext) return 'unknown'
  return loadedGetLanguage?.(ext)?.name ?? 'unknown'
}