viewMarkdown
tcm view's output as Markdown, for clients that render it: what it said first (the names it didn't find), then
for each definition a line with its names, hash and where it runs, and its code (or a file's content) as a
highlighted block.
import { fence, LANG } from "#codebase/tcmts/cli/mcp"; export function viewMarkdown(out: string): string { const header = /^\/\/ (\S+(?:, \S+)*) (#[a-z2-7]{8,}) ?(.*)$/; const before: string[] = []; const blocks: { names: string; hash: string; rest: string; lines: string[] }[] = []; // (said on stderr, so it may come in among the code) const said = /^'[^']+' (not found|is a namespace, not a definition)/; for (const line of out.split("\n")) { const m = header.exec(line); if (m) blocks.push({ names: m[1]!, hash: m[2]!, rest: m[3]!, lines: [] }); else if (said.test(line) || (!blocks.length && line.trim())) before.push(line); else if (blocks.length) blocks.at(-1)!.lines.push(line); } if (!blocks.length) return out; return [ ...(before.length ? [before.join("\n")] : []), ...blocks.map((b) => { while (b.lines.length && !b.lines.at(-1)!.trim()) b.lines.pop(); // code says its type after a colon; a file, its format const file = !b.rest.startsWith(":"); const runs = !file && b.lines[0]?.startsWith("// runs ") ? b.lines.shift()!.slice(3) : undefined; const about = file ? `${b.rest || "text"} file` : runs; return `**${b.names}** \`${b.hash}\`${about ? ` · ${about}` : ""}\n\n${fence(b.lines.join("\n"), file ? (LANG[b.rest] ?? "") : "ts")}`; }), ].join("\n\n"); }