MCPcopy Create free account
hub / github.com/Zoo-Code-Org/Zoo-Code / countFileLinesAndTokens

Function countFileLinesAndTokens

src/integrations/misc/line-counter.ts:71–167  ·  view source on GitHub ↗
(
	filePath: string,
	options: LineAndTokenCountOptions = {},
)

Source from the content-addressed store, hash-verified

69 * @returns A promise that resolves to line count, token estimate, and completion status
70 */
71export async function countFileLinesAndTokens(
72 filePath: string,
73 options: LineAndTokenCountOptions = {},
74): Promise<LineAndTokenCountResult> {
75 const { budgetTokens, chunkLines = 256 } = options
76
77 // Check if file exists
78 try {
79 await fs.promises.access(filePath, fs.constants.F_OK)
80 } catch (error) {
81 throw new Error(`File not found: ${filePath}`)
82 }
83
84 return new Promise((resolve, reject) => {
85 let lineCount = 0
86 let tokenEstimate = 0
87 let lineBuffer: string[] = []
88 let complete = true
89 let isProcessing = false
90 let shouldClose = false
91
92 const readStream = createReadStream(filePath)
93 const rl = createInterface({
94 input: readStream,
95 crlfDelay: Infinity,
96 })
97
98 const processBuffer = async () => {
99 if (lineBuffer.length === 0) return
100
101 const bufferText = lineBuffer.join("\n")
102 lineBuffer = [] // Clear buffer before processing
103
104 try {
105 const contentBlocks: Anthropic.Messages.ContentBlockParam[] = [{ type: "text", text: bufferText }]
106 const chunkTokens = await countTokens(contentBlocks)
107 tokenEstimate += chunkTokens
108 } catch (error) {
109 // On tokenizer error, use conservative estimate: 2 char ≈ 1 token
110 tokenEstimate += Math.ceil(bufferText.length / 2)
111 }
112
113 // Check if we've exceeded budget
114 if (budgetTokens !== undefined && tokenEstimate > budgetTokens) {
115 complete = false
116 shouldClose = true
117 rl.close()
118 readStream.destroy()
119 }
120 }
121
122 rl.on("line", (line) => {
123 lineCount++
124 lineBuffer.push(line)
125
126 // Process buffer when it reaches chunk size
127 if (lineBuffer.length >= chunkLines && !isProcessing) {
128 isProcessing = true

Callers 1

Calls 4

pauseMethod · 0.80
resumeMethod · 0.80
processBufferFunction · 0.70
onMethod · 0.65

Tested by

no test coverage detected