Skip to content

Commit 51843df

Browse files
committed
add back file to @ autocomplete
1 parent fc5fd9e commit 51843df

File tree

1 file changed

+92
-28
lines changed

1 file changed

+92
-28
lines changed

npm-app/src/cli.ts

Lines changed: 92 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
} from '@codebuff/common/util/agent-name-resolver'
1616
import { isDir } from '@codebuff/common/util/file'
1717
import { pluralize } from '@codebuff/common/util/string'
18+
import { uniq } from 'lodash'
1819
import {
1920
blueBright,
2021
bold,
@@ -458,6 +459,84 @@ export class CLI {
458459
process.stdin.on('keypress', (str, key) => this.handleKeyPress(str, key))
459460
}
460461

462+
private calculateAgentNameCompletions(
463+
line: string,
464+
): [string[], string] | null {
465+
if (!line.includes('@')) {
466+
return null
467+
}
468+
469+
const $split = line.split('@')
470+
const atAgentPrefix = `@${$split[$split.length - 1]}`
471+
const searchTerm = atAgentPrefix.substring(1).toLowerCase() // Remove @ prefix
472+
473+
// Get all agent names using functional API
474+
const localAgentInfo = getCachedLocalAgentInfo()
475+
const allAgentNames = [
476+
...new Set(
477+
getAllAgents(localAgentInfo).map((agent) => agent.displayName),
478+
),
479+
]
480+
481+
// Filter agent names that match the search term
482+
const matchingAgents = allAgentNames.filter((name) =>
483+
name.toLowerCase().startsWith(searchTerm),
484+
)
485+
486+
if (matchingAgents.length > 0) {
487+
// Return completions with @ prefix
488+
const completions = matchingAgents.map((name) => `@${name}`)
489+
return [completions, atAgentPrefix]
490+
}
491+
492+
return null
493+
}
494+
495+
private calculateAtFilenameCompletions(
496+
line: string,
497+
): [string[], string] | null {
498+
if (!line.includes('@')) {
499+
return null
500+
}
501+
502+
const $split = line.split('@')
503+
const atFilePrefix = `@${$split[$split.length - 1]}`
504+
const searchTerm = atFilePrefix.substring(1).toLowerCase() // Remove @ prefix
505+
506+
const client = Client.getInstance()
507+
if (!client.fileContext) {
508+
return null
509+
}
510+
const allFiles = this.getAllFilePaths(client.fileContext.fileTree)
511+
// high priority first
512+
function priority(filePath: string): number {
513+
if (!filePath.endsWith('/')) {
514+
return 0
515+
}
516+
return 1
517+
}
518+
const matchingPaths = uniq(
519+
allFiles
520+
.map((filePath) => {
521+
let candidate = null
522+
while (filePath.includes(searchTerm)) {
523+
candidate = filePath
524+
filePath = path.dirname(filePath) + '/'
525+
}
526+
return candidate
527+
})
528+
.filter((filePath): filePath is string => !!filePath),
529+
).sort((a, b) => priority(a) - priority(b))
530+
531+
if (matchingPaths.length > 0) {
532+
// Return completions with @ prefix
533+
const completions = matchingPaths.map((path) => `@${path}`)
534+
return [completions, atFilePrefix]
535+
}
536+
537+
return null
538+
}
539+
461540
private inputCompleter(line: string): [string[], string] {
462541
const lastWord = line.split(' ').pop() || ''
463542

@@ -483,34 +562,19 @@ export class CLI {
483562
return [[], line] // No slash command matches
484563
}
485564

486-
// Handle @ prefix for agent name completion
487-
if (line.includes('@')) {
488-
const $split = line.split('@')
489-
const atAgentPrefix = `@${$split[$split.length - 1]}`
490-
const searchTerm = atAgentPrefix.substring(1).toLowerCase() // Remove @ prefix
491-
492-
// Get all agent names using functional API
493-
const localAgentInfo = getCachedLocalAgentInfo()
494-
const allAgentNames = [
495-
...new Set(
496-
getAllAgents(localAgentInfo).map((agent) => agent.displayName),
497-
),
498-
]
499-
500-
// Filter agent names that match the search term
501-
const matchingAgents = allAgentNames.filter((name) =>
502-
name.toLowerCase().startsWith(searchTerm),
503-
)
504-
505-
if (matchingAgents.length > 0) {
506-
// Return completions with @ prefix
507-
const completions = matchingAgents.map((name) => `@${name}`)
508-
return [completions, atAgentPrefix]
509-
}
510-
511-
// If no agent matches, return empty completions for better UX
512-
// Users typing @ likely intend to mention an agent
513-
return [[], atAgentPrefix]
565+
const agentCompletions = this.calculateAgentNameCompletions(line)
566+
const atFilenameCompletions = this.calculateAtFilenameCompletions(line)
567+
const atCompletion: [string[], string] = [[], '']
568+
if (agentCompletions) {
569+
atCompletion[0].push(...agentCompletions[0])
570+
atCompletion[1] = agentCompletions[1]
571+
}
572+
if (atFilenameCompletions) {
573+
atCompletion[0].push(...atFilenameCompletions[0])
574+
atCompletion[1] = atFilenameCompletions[1]
575+
}
576+
if (atCompletion[1]) {
577+
return atCompletion
514578
}
515579

516580
// Original file path completion logic (unchanged)

0 commit comments

Comments
 (0)