Skip to content

Commit 2a09900

Browse files
committed
fix(mobile): the slash menu hides disabled skills and stops listing duplicates
#8009 put the slash-menu rules into client-runtime, but only web called them. Mobile built its `/` menu straight from the raw skills and command lists, so a skill the provider also exposes as a native slash command rendered twice, and disabled skills appeared even though mobile's own `$` menu already filters them. Routes mobile through getProviderSkillsForSlashMenu and getProviderSlashCommandsForSlashMenu so both clients share one definition of what the menu contains. `showSkillsInSlashMenu` is passed as its contract default rather than read: UnifiedSettings is reachable only from apps/web today, so honoring it on mobile needs a settings read path that does not exist yet. The enabled filter and the dedupe do not depend on it, so they land now. Covers the disabled-skill case in the shared helper's tests, which previously only exercised enabled skills.
1 parent 3fd9e00 commit 2a09900

2 files changed

Lines changed: 33 additions & 2 deletions

File tree

apps/mobile/src/features/threads/ThreadComposer.tsx

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,10 @@ import {
129129
import { resolveProviderOptionDescriptors } from "../../lib/providerOptions";
130130
import { useComposerPathSearch } from "../../state/use-composer-path-search";
131131
import { ComposerCommandPopover, type ComposerCommandItem } from "./ComposerCommandPopover";
132+
import {
133+
getProviderSkillsForSlashMenu,
134+
getProviderSlashCommandsForSlashMenu,
135+
} from "@t3tools/client-runtime/providerSkills";
132136
import { matchesSlashSkillQuery } from "./composerSlashSkillSearch";
133137
import {
134138
type ExistingThreadSettingsRouteSession,
@@ -1297,8 +1301,20 @@ export const ThreadComposer = memo(function ThreadComposer(props: ThreadComposer
12971301
];
12981302
const builtIn = allBuiltIn.filter((item) => item.command.includes(q));
12991303

1304+
// Shared with web so both clients agree on what the `/` menu contains.
1305+
// `showSkillsInSlashMenu` is passed as its contract default because the
1306+
// synced settings blob is web-only today; the enabled filter and the
1307+
// native-command dedupe do not depend on it.
1308+
const slashMenuSkills = getProviderSkillsForSlashMenu(
1309+
selectedProviderStatus?.skills ?? [],
1310+
true,
1311+
);
1312+
13001313
const providerCommands: ComposerCommandItem[] = [];
1301-
for (const cmd of providerSlashCommands) {
1314+
for (const cmd of getProviderSlashCommandsForSlashMenu(
1315+
providerSlashCommands,
1316+
slashMenuSkills,
1317+
)) {
13021318
if (!cmd.name.toLowerCase().includes(q)) continue;
13031319
providerCommands.push({
13041320
id: `pcmd:${cmd.name}`,
@@ -1309,7 +1325,7 @@ export const ThreadComposer = memo(function ThreadComposer(props: ThreadComposer
13091325
});
13101326
}
13111327

1312-
const skillItems = (selectedProviderStatus?.skills ?? [])
1328+
const skillItems = slashMenuSkills
13131329
.filter((skill) => matchesSlashSkillQuery(skill, q))
13141330
.map((skill) => ({
13151331
id: `skill:${skill.name}`,

packages/client-runtime/src/providerSkills.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,21 @@ describe("getProviderSkillsForSlashMenu", () => {
3737
"ask-matt",
3838
]);
3939
});
40+
41+
it("drops disabled skills so they cannot leak into the slash menu", () => {
42+
const skills = [
43+
{ name: "ask-matt", path: "/skills/ask-matt/SKILL.md", enabled: true },
44+
{ name: "retired", path: "/skills/retired/SKILL.md", enabled: false },
45+
];
46+
expect(getProviderSkillsForSlashMenu(skills, true).map((skill) => skill.name)).toEqual([
47+
"ask-matt",
48+
]);
49+
});
50+
51+
it("hides every skill when the slash menu is set to commands only", () => {
52+
const skills = [{ name: "ask-matt", path: "/skills/ask-matt/SKILL.md", enabled: true }];
53+
expect(getProviderSkillsForSlashMenu(skills, false)).toEqual([]);
54+
});
4055
});
4156

4257
describe("getProviderSlashCommandsForSlashMenu", () => {

0 commit comments

Comments
 (0)