Files
orcs-code/src/components/shell/OutputLine.tsx
Anandan 462a985d7e Remove embedded source map directives from tracked sources (#329)
Inline base64 source maps had been checked into tracked src files. This strips those comments from the repository without changing runtime behavior or adding ongoing guardrails, per the requested one-time cleanup scope.

Constraint: Keep this change limited to tracked source cleanup only
Rejected: Add CI/source verification guard | user requested one-time cleanup only
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: If these directives reappear, fix the producing transform instead of reintroducing repo-side cleanup code
Tested: rg -n "sourceMappingURL" ., bun run smoke, bun run verify:privacy, bun run test:provider, npm run test:provider-recommendation
Not-tested: bun run typecheck (repository has many pre-existing unrelated failures)

Co-authored-by: anandh8x <test@example.com>
2026-04-04 21:19:27 +08:00

118 lines
4.0 KiB
TypeScript

import { c as _c } from "react-compiler-runtime";
import * as React from 'react';
import { useMemo } from 'react';
import { useTerminalSize } from '../../hooks/useTerminalSize.js';
import { Ansi, Text } from '../../ink.js';
import { createHyperlink } from '../../utils/hyperlink.js';
import { jsonParse, jsonStringify } from '../../utils/slowOperations.js';
import { renderTruncatedContent } from '../../utils/terminal.js';
import { MessageResponse } from '../MessageResponse.js';
import { InVirtualListContext } from '../messageActions.js';
import { useExpandShellOutput } from './ExpandShellOutputContext.js';
export function tryFormatJson(line: string): string {
try {
const parsed = jsonParse(line);
const stringified = jsonStringify(parsed);
// Check if precision was lost during JSON round-trip
// This happens when large integers exceed Number.MAX_SAFE_INTEGER
// We normalize both strings by removing whitespace and unnecessary
// escapes (\/ is valid but optional in JSON) for comparison
const normalizedOriginal = line.replace(/\\\//g, '/').replace(/\s+/g, '');
const normalizedStringified = stringified.replace(/\s+/g, '');
if (normalizedOriginal !== normalizedStringified) {
// Precision loss detected - return original line unformatted
return line;
}
return jsonStringify(parsed, null, 2);
} catch {
return line;
}
}
const MAX_JSON_FORMAT_LENGTH = 10_000;
export function tryJsonFormatContent(content: string): string {
if (content.length > MAX_JSON_FORMAT_LENGTH) {
return content;
}
const allLines = content.split('\n');
return allLines.map(tryFormatJson).join('\n');
}
// Match http(s) URLs inside JSON string values. Conservative: no quotes,
// no whitespace, no trailing comma/brace that'd be JSON structure.
const URL_IN_JSON = /https?:\/\/[^\s"'<>\\]+/g;
export function linkifyUrlsInText(content: string): string {
return content.replace(URL_IN_JSON, url => createHyperlink(url));
}
export function OutputLine(t0) {
const $ = _c(11);
const {
content,
verbose,
isError,
isWarning,
linkifyUrls
} = t0;
const {
columns
} = useTerminalSize();
const expandShellOutput = useExpandShellOutput();
const inVirtualList = React.useContext(InVirtualListContext);
const shouldShowFull = verbose || expandShellOutput;
let t1;
if ($[0] !== columns || $[1] !== content || $[2] !== inVirtualList || $[3] !== linkifyUrls || $[4] !== shouldShowFull) {
bb0: {
let formatted = tryJsonFormatContent(content);
if (linkifyUrls) {
formatted = linkifyUrlsInText(formatted);
}
if (shouldShowFull) {
t1 = stripUnderlineAnsi(formatted);
break bb0;
}
t1 = stripUnderlineAnsi(renderTruncatedContent(formatted, columns, inVirtualList));
}
$[0] = columns;
$[1] = content;
$[2] = inVirtualList;
$[3] = linkifyUrls;
$[4] = shouldShowFull;
$[5] = t1;
} else {
t1 = $[5];
}
const formattedContent = t1;
const color = isError ? "error" : isWarning ? "warning" : undefined;
let t2;
if ($[6] !== formattedContent) {
t2 = <Ansi>{formattedContent}</Ansi>;
$[6] = formattedContent;
$[7] = t2;
} else {
t2 = $[7];
}
let t3;
if ($[8] !== color || $[9] !== t2) {
t3 = <MessageResponse><Text color={color}>{t2}</Text></MessageResponse>;
$[8] = color;
$[9] = t2;
$[10] = t3;
} else {
t3 = $[10];
}
return t3;
}
/**
* Underline ANSI codes in particular tend to leak out for some reason. I wasn't
* able to figure out why, or why emitting a reset ANSI code wasn't enough to
* prevent them from leaking. I also didn't want to strip all ANSI codes with
* stripAnsi(), because we used to do that and people complained about losing
* all formatting. So we just strip the underline ANSI codes specifically.
*/
export function stripUnderlineAnsi(content: string): string {
return content.replace(
// eslint-disable-next-line no-control-regex
/\u001b\[([0-9]+;)*4(;[0-9]+)*m|\u001b\[4(;[0-9]+)*m|\u001b\[([0-9]+;)*4m/g, '');
}