(raw: string)
| 55 | * duplicated the line-only logic). |
| 56 | */ |
| 57 | export function truncateEntrypointContent(raw: string): EntrypointTruncation { |
| 58 | const trimmed = raw.trim() |
| 59 | const contentLines = trimmed.split('\n') |
| 60 | const lineCount = contentLines.length |
| 61 | const byteCount = trimmed.length |
| 62 | |
| 63 | const wasLineTruncated = lineCount > MAX_ENTRYPOINT_LINES |
| 64 | // Check original byte count — long lines are the failure mode the byte cap |
| 65 | // targets, so post-line-truncation size would understate the warning. |
| 66 | const wasByteTruncated = byteCount > MAX_ENTRYPOINT_BYTES |
| 67 | |
| 68 | if (!wasLineTruncated && !wasByteTruncated) { |
| 69 | return { |
| 70 | content: trimmed, |
| 71 | lineCount, |
| 72 | byteCount, |
| 73 | wasLineTruncated, |
| 74 | wasByteTruncated, |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | let truncated = wasLineTruncated |
| 79 | ? contentLines.slice(0, MAX_ENTRYPOINT_LINES).join('\n') |
| 80 | : trimmed |
| 81 | |
| 82 | if (truncated.length > MAX_ENTRYPOINT_BYTES) { |
| 83 | const cutAt = truncated.lastIndexOf('\n', MAX_ENTRYPOINT_BYTES) |
| 84 | truncated = truncated.slice(0, cutAt > 0 ? cutAt : MAX_ENTRYPOINT_BYTES) |
| 85 | } |
| 86 | |
| 87 | const reason = |
| 88 | wasByteTruncated && !wasLineTruncated |
| 89 | ? `${formatFileSize(byteCount)} (limit: ${formatFileSize(MAX_ENTRYPOINT_BYTES)}) — index entries are too long` |
| 90 | : wasLineTruncated && !wasByteTruncated |
| 91 | ? `${lineCount} lines (limit: ${MAX_ENTRYPOINT_LINES})` |
| 92 | : `${lineCount} lines and ${formatFileSize(byteCount)}` |
| 93 | |
| 94 | return { |
| 95 | content: |
| 96 | truncated + |
| 97 | `\n\n> WARNING: ${ENTRYPOINT_NAME} is ${reason}. Only part of it was loaded. Keep index entries to one line under ~200 chars; move detail into topic files.`, |
| 98 | lineCount, |
| 99 | byteCount, |
| 100 | wasLineTruncated, |
| 101 | wasByteTruncated, |
| 102 | } |
| 103 | } |
| 104 | |
| 105 | /* eslint-disable @typescript-eslint/no-require-imports */ |
| 106 | const teamMemPrompts = feature('TEAMMEM') |
no test coverage detected