mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-30 19:09:28 +00:00
fix(desktop): keep the @ popover open while typing a path
`AT_TRIGGER_RE` excluded `/` from the query, so the trigger died on the first separator: `@/desk`, `@./www`, `@~/Desktop` and even `@file:src/foo` all stopped matching the moment a path appeared. The gateway already answered those queries correctly — the composer just never asked. A `/` inside an `@` token is navigation, not a delimiter. The token stays whitespace-bounded, which is what actually ends it.
This commit is contained in:
parent
b378cc0a72
commit
de0b376cc9
2 changed files with 39 additions and 2 deletions
|
|
@ -51,6 +51,39 @@ describe('detectTrigger', () => {
|
|||
expect(detectTrigger('and/or')).toBeNull()
|
||||
})
|
||||
|
||||
it('keeps the at-mention live while walking into subfolders', () => {
|
||||
// A `/` inside the query is path navigation, not the end of the token —
|
||||
// the popover has to stay open so the next directory level can load.
|
||||
expect(detectTrigger('@./')).toEqual({ kind: '@', query: './', tokenLength: 3 })
|
||||
expect(detectTrigger('@./src')).toEqual({ kind: '@', query: './src', tokenLength: 6 })
|
||||
expect(detectTrigger('@~/Desktop/')).toEqual({ kind: '@', query: '~/Desktop/', tokenLength: 11 })
|
||||
expect(detectTrigger('@/usr/local')).toEqual({ kind: '@', query: '/usr/local', tokenLength: 11 })
|
||||
expect(detectTrigger('@apps/desktop/src')).toEqual({
|
||||
kind: '@',
|
||||
query: 'apps/desktop/src',
|
||||
tokenLength: 17
|
||||
})
|
||||
})
|
||||
|
||||
it('keeps the at-mention live for a typed ref kind with a path', () => {
|
||||
expect(detectTrigger('@file:src/main.tsx')).toEqual({
|
||||
kind: '@',
|
||||
query: 'file:src/main.tsx',
|
||||
tokenLength: 18
|
||||
})
|
||||
expect(detectTrigger('@folder:apps/')).toEqual({ kind: '@', query: 'folder:apps/', tokenLength: 13 })
|
||||
})
|
||||
|
||||
it('still ends the at-mention token at whitespace', () => {
|
||||
// The token is whitespace-delimited; a path doesn't change that.
|
||||
expect(detectTrigger('@./src and more')).toBeNull()
|
||||
expect(detectTrigger('look at @apps/desktop')).toEqual({
|
||||
kind: '@',
|
||||
query: 'apps/desktop',
|
||||
tokenLength: 13
|
||||
})
|
||||
})
|
||||
|
||||
it('treats a mid-message slash as an inline reference', () => {
|
||||
// Skills have to be reachable anywhere in a prompt, not just at position 0.
|
||||
expect(detectTrigger('hello /')).toEqual({ kind: '/', inline: true, query: '', tokenLength: 1 })
|
||||
|
|
|
|||
|
|
@ -10,7 +10,11 @@ export interface TriggerState {
|
|||
}
|
||||
|
||||
// `@` triggers stop at the first whitespace — `@file:path` and `@diff` are
|
||||
// single tokens. Restricting the slash command name to `[a-zA-Z][\w-]*` avoids
|
||||
// single tokens, and a path is part of that token: `@./src/`, `@~/Desktop/`,
|
||||
// and `@file:src/foo` all have to keep the popover live while the user walks
|
||||
// into subdirectories. Excluding `/` from the query class would end the token
|
||||
// at the first separator, which is exactly the "can't browse into a folder"
|
||||
// bug. Restricting the slash command name to `[a-zA-Z][\w-]*` avoids
|
||||
// matching file paths like `src/foo/bar`.
|
||||
//
|
||||
// `/` triggers fire in two shapes, because a slash means two different things
|
||||
|
|
@ -27,7 +31,7 @@ export interface TriggerState {
|
|||
// The inline shape is what makes skills reachable anywhere in a prompt. Both
|
||||
// shapes need the trailing `$`: detection runs against the text BEFORE the
|
||||
// caret, so the match must end where the user is typing.
|
||||
const AT_TRIGGER_RE = /(?:^|[\s])(@)([^\s@/]*)$/
|
||||
const AT_TRIGGER_RE = /(?:^|[\s])(@)([^\s@]*)$/
|
||||
const SLASH_COMMAND_TRIGGER_RE = /^(\/)((?:[a-zA-Z][\w-]*(?:\s+\S*)*)?)$/
|
||||
const SLASH_INLINE_TRIGGER_RE = /[\s](\/)([a-zA-Z][\w-]*)?$/
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue