fix(commands): search skills by keyword in slash autocomplete
This commit is contained in:
1 parent
3c7fbe3809
commit
eea4f03db8
3 files changed
+55
-3
No files matched your search
+5
-2
@@ -187,6 +187,7 @@ function getMatchingCommands(prefix){
|
||||
const matches=COMMANDS.filter(c=>c.name.startsWith(q)).map(c=>({...c,source:'builtin'}));
|
||||
const seen=new Set(matches.map(c=>c.name));
|
||||
const reserved=_getReservedSlashCommandSlugs();
|
||||
const bundleSlugs=new Set(_bundleCommandCache.map(bundle=>bundle.name));
|
||||
for(const [name, spec] of Object.entries(SLASH_SUBARG_SOURCES)){
|
||||
if(!name.startsWith(q)||seen.has(name))continue;
|
||||
matches.push({
|
||||
@@ -228,9 +229,11 @@ function getMatchingCommands(prefix){
|
||||
}
|
||||
}
|
||||
for(const skill of _skillCommandCache){
|
||||
if(!skill.name.startsWith(q)||seen.has(skill.name)||reserved.has(skill.name))continue;
|
||||
const name=String(skill&&skill.name||'').toLowerCase();
|
||||
const description=String(skill&&skill.desc||'').toLowerCase();
|
||||
if((!name.includes(q)&&!description.includes(q))||seen.has(name)||reserved.has(name)||bundleSlugs.has(name))continue;
|
||||
matches.push(skill);
|
||||
seen.add(skill.name);
|
||||
seen.add(name);
|
||||
}
|
||||
return matches;
|
||||
}
|
||||
|
||||
@@ -215,6 +215,18 @@ def _run_commands_js(script_body: str) -> dict:
|
||||
{{
|
||||
name: 'plugin review',
|
||||
description: 'Plugin collisions should stay hidden from slash autocomplete'
|
||||
}},
|
||||
{{
|
||||
name: 'hermes-upgrade',
|
||||
description: 'Safely upgrade and verify a Hermes installation'
|
||||
}},
|
||||
{{
|
||||
name: 'maintenance-guide',
|
||||
description: 'Plan a safe upgrade and rollback path'
|
||||
}},
|
||||
{{
|
||||
name: 'reinstall-helper',
|
||||
description: 'Recover from a failed reinstall'
|
||||
}}
|
||||
]
|
||||
}};
|
||||
@@ -352,6 +364,41 @@ def test_cli_only_slugs_reserve_skill_autocomplete_namespace():
|
||||
assert "use" in result["use_names"]
|
||||
|
||||
|
||||
def test_skill_autocomplete_matches_keyword_in_name_or_description():
|
||||
result = _run_commands_js(
|
||||
"""
|
||||
await loadSkillCommands(true);
|
||||
const upgrade = await getSlashAutocompleteMatches('/upgrade');
|
||||
const reinstall = await getSlashAutocompleteMatches('/reinstall');
|
||||
return {
|
||||
upgrade_names: upgrade.map(item => item.name),
|
||||
upgrade_sources: upgrade.map(item => item.source),
|
||||
reinstall_names: reinstall.map(item => item.name),
|
||||
reinstall_sources: reinstall.map(item => item.source)
|
||||
};
|
||||
"""
|
||||
)
|
||||
|
||||
assert result["upgrade_names"] == ["hermes-upgrade", "maintenance-guide"]
|
||||
assert result["upgrade_sources"] == ["skill", "skill"]
|
||||
assert result["reinstall_names"] == ["reinstall-helper"]
|
||||
assert result["reinstall_sources"] == ["skill"]
|
||||
|
||||
|
||||
def test_skill_autocomplete_hides_keyword_match_shadowed_by_bundle():
|
||||
result = _run_commands_js(
|
||||
"""
|
||||
await loadAgentCommandMetadata(true);
|
||||
await loadBundleCommands(true);
|
||||
await loadSkillCommands(true);
|
||||
const matches = await getSlashAutocompleteMatches('/non-colliding');
|
||||
return matches.map(item => ({ name: item.name, source: item.source }));
|
||||
"""
|
||||
)
|
||||
|
||||
assert result == []
|
||||
|
||||
|
||||
def test_bundle_collisions_stay_hidden_until_agent_metadata_is_ready():
|
||||
script = textwrap.dedent(
|
||||
f"""
|
||||
|
||||
@@ -63,7 +63,9 @@ def test_skill_mutations_invalidate_slash_skill_caches():
|
||||
def test_builtin_commands_take_precedence_over_skill_slug_collisions():
|
||||
assert "_getReservedSlashCommandSlugs" in COMMANDS_JS
|
||||
assert "if(_getReservedSlashCommandSlugs().has(slug)) return null;" in COMMANDS_JS
|
||||
assert "if(!skill.name.startsWith(q)||seen.has(skill.name)||reserved.has(skill.name))continue;" in COMMANDS_JS
|
||||
command_matching = _function_body(COMMANDS_JS, "getMatchingCommands")
|
||||
assert "reserved.has(name)" in command_matching
|
||||
assert "!name.includes(q)&&!description.includes(q)" in command_matching
|
||||
|
||||
|
||||
def test_bundle_entries_merge_before_plain_skill_entries():
|
||||
|
||||
Reference in new issue
Block a user