Something went wrong. Try again.
source dump of claude code forked from oppi.li/claude-code
Something went wrong. Try again.
5.0 kB · 170 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171import figures from 'figures'import { color } from '../components/design-system/color.js'import type { Theme, ThemeName } from './theme.js'
export type TreeNode = { [key: string]: TreeNode | string | undefined}
export type TreeifyOptions = { showValues?: boolean hideFunctions?: boolean useColors?: boolean themeName?: ThemeName treeCharColors?: { treeChar?: keyof Theme // Color for tree characters (├ └ │) key?: keyof Theme // Color for property names value?: keyof Theme // Color for values }}
type TreeCharacters = { branch: string lastBranch: string line: string empty: string}
const DEFAULT_TREE_CHARS: TreeCharacters = { branch: figures.lineUpDownRight, // '├' lastBranch: figures.lineUpRight, // '└' line: figures.lineVertical, // '│' empty: ' ',}
/** * Custom treeify implementation with Ink theme color support * Based on https://github.com/notatestuser/treeify */export function treeify(obj: TreeNode, options: TreeifyOptions = {}): string { const { showValues = true, hideFunctions = false, themeName = 'dark', treeCharColors = {}, } = options
const lines: string[] = [] const visited = new WeakSet<object>()
function colorize(text: string, colorKey?: keyof Theme): string { if (!colorKey) return text return color(colorKey, themeName)(text) }
function growBranch( node: TreeNode | string, prefix: string, _isLast: boolean, depth: number = 0, ): void { if (typeof node === 'string') { lines.push(prefix + colorize(node, treeCharColors.value)) return }
if (typeof node !== 'object' || node === null) { if (showValues) { const valueStr = String(node) lines.push(prefix + colorize(valueStr, treeCharColors.value)) } return }
// Check for circular references if (visited.has(node)) { lines.push(prefix + colorize('[Circular]', treeCharColors.value)) return } visited.add(node)
const keys = Object.keys(node).filter(key => { const value = node[key] if (hideFunctions && typeof value === 'function') return false return true })
keys.forEach((key, index) => { const value = node[key] const isLastKey = index === keys.length - 1 const nodePrefix = depth === 0 && index === 0 ? '' : prefix
// Determine which tree character to use const treeChar = isLastKey ? DEFAULT_TREE_CHARS.lastBranch : DEFAULT_TREE_CHARS.branch const coloredTreeChar = colorize(treeChar, treeCharColors.treeChar) const coloredKey = key.trim() === '' ? '' : colorize(key, treeCharColors.key)
let line = nodePrefix + coloredTreeChar + (coloredKey ? ' ' + coloredKey : '')
// Check if we should add a colon (not for empty/whitespace keys) const shouldAddColon = key.trim() !== ''
// Check for circular reference before recursing if (value && typeof value === 'object' && visited.has(value)) { const coloredValue = colorize('[Circular]', treeCharColors.value) lines.push( line + (shouldAddColon ? ': ' : line ? ' ' : '') + coloredValue, ) } else if (value && typeof value === 'object' && !Array.isArray(value)) { lines.push(line) // Calculate the continuation prefix for nested items const continuationChar = isLastKey ? DEFAULT_TREE_CHARS.empty : DEFAULT_TREE_CHARS.line const coloredContinuation = colorize( continuationChar, treeCharColors.treeChar, ) const nextPrefix = nodePrefix + coloredContinuation + ' ' growBranch(value, nextPrefix, isLastKey, depth + 1) } else if (Array.isArray(value)) { // Handle arrays lines.push( line + (shouldAddColon ? ': ' : line ? ' ' : '') + '[Array(' + value.length + ')]', ) } else if (showValues) { // Add value if showValues is true const valueStr = typeof value === 'function' ? '[Function]' : String(value) const coloredValue = colorize(valueStr, treeCharColors.value) line += (shouldAddColon ? ': ' : line ? ' ' : '') + coloredValue lines.push(line) } else { lines.push(line) } }) }
// Start growing the tree const keys = Object.keys(obj) if (keys.length === 0) { return colorize('(empty)', treeCharColors.value) }
// Special case for single empty/whitespace string key if ( keys.length === 1 && keys[0] !== undefined && keys[0].trim() === '' && typeof obj[keys[0]] === 'string' ) { const firstKey = keys[0] const coloredTreeChar = colorize( DEFAULT_TREE_CHARS.lastBranch, treeCharColors.treeChar, ) const coloredValue = colorize(obj[firstKey] as string, treeCharColors.value) return coloredTreeChar + ' ' + coloredValue }
growBranch(obj, '', true) return lines.join('\n')}