mirror of
https://wget.la/https://github.com/leookun/cursor-byok
synced 2026-10-06 13:44:21 +08:00
refactor: align project directory architecture
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
// Persistent-process adapter for measuring CodeGraph library search without CLI startup noise.
|
||||
|
||||
'use strict'
|
||||
|
||||
const fs = require('node:fs')
|
||||
const path = require('node:path')
|
||||
|
||||
async function main() {
|
||||
const [libraryRoot, projectRoot, repetitionsText, limitText] = process.argv.slice(2)
|
||||
const repetitions = Number(repetitionsText)
|
||||
const limit = Number(limitText)
|
||||
const input = JSON.parse(fs.readFileSync(0, 'utf8'))
|
||||
const loadStarted = process.hrtime.bigint()
|
||||
const codegraphModule = require(path.join(libraryRoot, 'dist/index.js'))
|
||||
const generatedModule = require(path.join(
|
||||
libraryRoot,
|
||||
'dist/extraction/generated-detection.js',
|
||||
))
|
||||
const { ToolHandler } = require(path.join(libraryRoot, 'dist/mcp/tools.js'))
|
||||
const CodeGraph = codegraphModule.CodeGraph || codegraphModule.default
|
||||
const graph = await CodeGraph.open(projectRoot, { sync: false, readOnly: true })
|
||||
const loadMs = millisecondsSince(loadStarted)
|
||||
const stats = graph.getStats()
|
||||
const handler = new ToolHandler(graph)
|
||||
const tracks = []
|
||||
for (const track of input.tracks) {
|
||||
const queries = []
|
||||
for (const query of track.queries) {
|
||||
queries.push(
|
||||
track.name !== 'symbol'
|
||||
? await runExplore(handler, query, repetitions, limit)
|
||||
: runSearch(graph, generatedModule, query, repetitions, limit),
|
||||
)
|
||||
}
|
||||
tracks.push({ name: track.name, queries })
|
||||
}
|
||||
graph.close()
|
||||
process.stdout.write(JSON.stringify({ loadMs, stats, tracks }))
|
||||
}
|
||||
|
||||
async function runExplore(handler, query, repetitions, limit) {
|
||||
const first = await explore(handler, query.query, limit)
|
||||
const durationsMs = []
|
||||
for (let index = 0; index < repetitions; index += 1) {
|
||||
const started = process.hrtime.bigint()
|
||||
await explore(handler, query.query, limit)
|
||||
durationsMs.push(millisecondsSince(started))
|
||||
}
|
||||
return { id: query.id, query: query.query, durationsMs, results: first }
|
||||
}
|
||||
|
||||
async function explore(handler, query, limit) {
|
||||
const response = await handler.execute('codegraph_explore', { query, maxFiles: limit })
|
||||
if (response.isError) throw new Error(response.content?.[0]?.text || 'CodeGraph explore failed')
|
||||
return parseExplore(response.content?.[0]?.text || '')
|
||||
}
|
||||
|
||||
function parseExplore(text) {
|
||||
const results = []
|
||||
let current = null
|
||||
let inCode = false
|
||||
for (const line of text.split('\n')) {
|
||||
const heading = line.match(/^####\s+(.+?)(?:\s+—|$)/)
|
||||
if (heading) {
|
||||
current = { path: heading[1].trim(), startLine: 0, endLine: 0, score: 0, lines: [] }
|
||||
results.push(current)
|
||||
inCode = false
|
||||
continue
|
||||
}
|
||||
if (line.startsWith('```')) {
|
||||
inCode = !inCode
|
||||
continue
|
||||
}
|
||||
if (!inCode || !current) continue
|
||||
const numbered = line.match(/^(\d+)\t/)
|
||||
if (!numbered) continue
|
||||
const number = Number(numbered[1])
|
||||
current.lines.push(number)
|
||||
if (current.startLine === 0) current.startLine = number
|
||||
current.endLine = number
|
||||
}
|
||||
return results
|
||||
.filter((result) => result.lines.length > 0)
|
||||
.map((result, index) => ({ ...result, score: 1 / (index + 1) }))
|
||||
}
|
||||
|
||||
function runSearch(graph, generatedModule, query, repetitions, limit) {
|
||||
const durationsMs = []
|
||||
const first = sortedResults(graph, generatedModule, query.query, limit)
|
||||
for (let index = 0; index < repetitions; index += 1) {
|
||||
const started = process.hrtime.bigint()
|
||||
sortedResults(graph, generatedModule, query.query, limit)
|
||||
durationsMs.push(millisecondsSince(started))
|
||||
}
|
||||
return {
|
||||
id: query.id,
|
||||
query: query.query,
|
||||
durationsMs,
|
||||
results: first.map(({ node, score }) => ({
|
||||
path: node.filePath,
|
||||
startLine: node.startLine,
|
||||
endLine: node.endLine,
|
||||
score,
|
||||
lines: null,
|
||||
})),
|
||||
}
|
||||
}
|
||||
|
||||
function sortedResults(graph, generatedModule, query, limit) {
|
||||
const raw = graph.searchNodes(query, { limit })
|
||||
return [...raw].sort((left, right) => {
|
||||
const leftGenerated = generatedModule.isGeneratedFile(left.node.filePath) ? 1 : 0
|
||||
const rightGenerated = generatedModule.isGeneratedFile(right.node.filePath) ? 1 : 0
|
||||
return leftGenerated - rightGenerated
|
||||
})
|
||||
}
|
||||
|
||||
function millisecondsSince(started) {
|
||||
return Number(process.hrtime.bigint() - started) / 1_000_000
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
process.stderr.write(`${error.stack || error}\n`)
|
||||
process.exitCode = 1
|
||||
})
|
||||
Reference in New Issue
Block a user