Skip to content

Commit 2e8fb9c

Browse files
thdxrishaksebsib
authored andcommitted
Simplify directory tree output for prompts (anomalyco#11731)
1 parent 65b16eb commit 2e8fb9c

2 files changed

Lines changed: 36 additions & 80 deletions

File tree

packages/opencode/src/file/ripgrep.ts

Lines changed: 33 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -275,100 +275,56 @@ export namespace Ripgrep {
275275
log.info("tree", input)
276276
const files = await Array.fromAsync(Ripgrep.files({ cwd: input.cwd, signal: input.signal }))
277277
interface Node {
278-
path: string[]
279-
children: Node[]
278+
name: string
279+
children: Map<string, Node>
280280
}
281281

282-
function getPath(node: Node, parts: string[], create: boolean) {
283-
if (parts.length === 0) return node
284-
let current = node
285-
for (const part of parts) {
286-
let existing = current.children.find((x) => x.path.at(-1) === part)
287-
if (!existing) {
288-
if (!create) return
289-
existing = {
290-
path: current.path.concat(part),
291-
children: [],
292-
}
293-
current.children.push(existing)
294-
}
295-
current = existing
296-
}
297-
return current
282+
function dir(node: Node, name: string) {
283+
const existing = node.children.get(name)
284+
if (existing) return existing
285+
const next = { name, children: new Map() }
286+
node.children.set(name, next)
287+
return next
298288
}
299289

300-
const root: Node = {
301-
path: [],
302-
children: [],
303-
}
290+
const root: Node = { name: "", children: new Map() }
304291
for (const file of files) {
305292
if (file.includes(".opencode")) continue
306293
const parts = file.split(path.sep)
307-
getPath(root, parts, true)
308-
}
309-
310-
function sort(node: Node) {
311-
node.children.sort((a, b) => {
312-
if (!a.children.length && b.children.length) return 1
313-
if (!b.children.length && a.children.length) return -1
314-
return a.path.at(-1)!.localeCompare(b.path.at(-1)!)
315-
})
316-
for (const child of node.children) {
317-
sort(child)
294+
if (parts.length < 2) continue
295+
let node = root
296+
for (const part of parts.slice(0, -1)) {
297+
node = dir(node, part)
318298
}
319299
}
320-
sort(root)
321-
322-
let current = [root]
323-
const result: Node = {
324-
path: [],
325-
children: [],
326-
}
327300

328-
let processed = 0
329-
const limit = input.limit ?? 50
330-
while (current.length > 0) {
331-
const next = []
332-
for (const node of current) {
333-
if (node.children.length) next.push(...node.children)
334-
}
335-
const max = Math.max(...current.map((x) => x.children.length))
336-
for (let i = 0; i < max && processed < limit; i++) {
337-
for (const node of current) {
338-
const child = node.children[i]
339-
if (!child) continue
340-
getPath(result, child.path, true)
341-
processed++
342-
if (processed >= limit) break
343-
}
344-
}
345-
if (processed >= limit) {
346-
for (const node of [...current, ...next]) {
347-
const compare = getPath(result, node.path, false)
348-
if (!compare) continue
349-
if (compare?.children.length !== node.children.length) {
350-
const diff = node.children.length - compare.children.length
351-
compare.children.push({
352-
path: compare.path.concat(`[${diff} truncated]`),
353-
children: [],
354-
})
355-
}
356-
}
357-
break
301+
function count(node: Node): number {
302+
let total = 0
303+
for (const child of node.children.values()) {
304+
total += 1 + count(child)
358305
}
359-
current = next
306+
return total
360307
}
361308

309+
const total = count(root)
310+
const limit = input.limit ?? total
362311
const lines: string[] = []
312+
const queue: { node: Node; path: string }[] = []
313+
for (const child of Array.from(root.children.values()).sort((a, b) => a.name.localeCompare(b.name))) {
314+
queue.push({ node: child, path: child.name })
315+
}
363316

364-
function render(node: Node, depth: number) {
365-
const indent = "\t".repeat(depth)
366-
lines.push(indent + node.path.at(-1) + (node.children.length ? "/" : ""))
367-
for (const child of node.children) {
368-
render(child, depth + 1)
317+
let used = 0
318+
for (let i = 0; i < queue.length && used < limit; i++) {
319+
const { node, path } = queue[i]
320+
lines.push(path)
321+
used++
322+
for (const child of Array.from(node.children.values()).sort((a, b) => a.name.localeCompare(b.name))) {
323+
queue.push({ node: child, path: `${path}/${child.name}` })
369324
}
370325
}
371-
result.children.map((x) => render(x, 0))
326+
327+
if (total > used) lines.push(`[${total - used} truncated]`)
372328

373329
return lines.join("\n")
374330
}

packages/opencode/src/session/system.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,16 @@ export namespace SystemPrompt {
3636
` Platform: ${process.platform}`,
3737
` Today's date: ${new Date().toDateString()}`,
3838
`</env>`,
39-
`<files>`,
39+
`<directories>`,
4040
` ${
4141
project.vcs === "git" && false
4242
? await Ripgrep.tree({
4343
cwd: Instance.directory,
44-
limit: 200,
44+
limit: 50,
4545
})
4646
: ""
4747
}`,
48-
`</files>`,
48+
`</directories>`,
4949
].join("\n"),
5050
]
5151
}

0 commit comments

Comments
 (0)