fix(extensions): reset stale codex skill filters
This commit is contained in:
parent
b0c4319ba3
commit
14ee2fc550
2 changed files with 118 additions and 0 deletions
|
|
@ -173,6 +173,12 @@ export const SkillsPanel = ({
|
||||||
? (selectedDetail?.item ?? mergedSkills.find((skill) => skill.id === selectedSkillId) ?? null)
|
? (selectedDetail?.item ?? mergedSkills.find((skill) => skill.id === selectedSkillId) ?? null)
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (quickFilter === 'codex-only' && !showCodexOnlyUi) {
|
||||||
|
setQuickFilter('all');
|
||||||
|
}
|
||||||
|
}, [quickFilter, showCodexOnlyUi]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!selectedSkillId) return;
|
if (!selectedSkillId) return;
|
||||||
if (mergedSkills.some((skill) => skill.id === selectedSkillId)) return;
|
if (mergedSkills.some((skill) => skill.id === selectedSkillId)) return;
|
||||||
|
|
|
||||||
|
|
@ -168,6 +168,20 @@ function makeUserSkill(): SkillCatalogItem {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function makeCodexSkill(): SkillCatalogItem {
|
||||||
|
return {
|
||||||
|
...makeUserSkill(),
|
||||||
|
id: '/Users/me/.codex/skills/codex-helper',
|
||||||
|
name: 'Codex Helper',
|
||||||
|
description: 'Helps only Codex sessions',
|
||||||
|
folderName: 'codex-helper',
|
||||||
|
rootKind: 'codex',
|
||||||
|
discoveryRoot: '/Users/me/.codex/skills',
|
||||||
|
skillDir: '/Users/me/.codex/skills/codex-helper',
|
||||||
|
skillFile: '/Users/me/.codex/skills/codex-helper/SKILL.md',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function makeMultimodelStatus(
|
function makeMultimodelStatus(
|
||||||
overrides?: Partial<CliInstallationStatus>
|
overrides?: Partial<CliInstallationStatus>
|
||||||
): CliInstallationStatus {
|
): CliInstallationStatus {
|
||||||
|
|
@ -373,4 +387,102 @@ describe('SkillsPanel', () => {
|
||||||
await Promise.resolve();
|
await Promise.resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('resets the codex-only quick filter when codex entries disappear', async () => {
|
||||||
|
storeState.cliStatus = makeMultimodelStatus({
|
||||||
|
providers: [
|
||||||
|
...makeMultimodelStatus().providers,
|
||||||
|
{
|
||||||
|
providerId: 'codex',
|
||||||
|
displayName: 'Codex',
|
||||||
|
supported: true,
|
||||||
|
authenticated: true,
|
||||||
|
authMethod: 'api_key',
|
||||||
|
verificationState: 'verified',
|
||||||
|
statusMessage: 'Connected',
|
||||||
|
models: [],
|
||||||
|
canLoginFromUi: true,
|
||||||
|
capabilities: {
|
||||||
|
teamLaunch: true,
|
||||||
|
oneShot: true,
|
||||||
|
extensions: {
|
||||||
|
plugins: { status: 'unsupported', ownership: 'provider', reason: null },
|
||||||
|
mcp: { status: 'supported', ownership: 'shared', reason: null },
|
||||||
|
skills: { status: 'supported', ownership: 'shared', reason: null },
|
||||||
|
apiKeys: { status: 'supported', ownership: 'shared', reason: null },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
connection: null,
|
||||||
|
backend: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
storeState.skillsUserCatalog = [makeUserSkill(), makeCodexSkill()];
|
||||||
|
|
||||||
|
const host = document.createElement('div');
|
||||||
|
document.body.appendChild(host);
|
||||||
|
const root = createRoot(host);
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
root.render(
|
||||||
|
React.createElement(SkillsPanel, {
|
||||||
|
projectPath: '/tmp/project-a',
|
||||||
|
projectLabel: 'Project A',
|
||||||
|
skillsSearchQuery: '',
|
||||||
|
setSkillsSearchQuery: vi.fn(),
|
||||||
|
skillsSort: 'name-asc',
|
||||||
|
setSkillsSort: vi.fn(),
|
||||||
|
selectedSkillId: null,
|
||||||
|
setSelectedSkillId: vi.fn(),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
await Promise.resolve();
|
||||||
|
await Promise.resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
const codexOnlyButton = Array.from(host.querySelectorAll('button')).find((button) =>
|
||||||
|
button.textContent?.includes('Codex only')
|
||||||
|
);
|
||||||
|
expect(codexOnlyButton).toBeDefined();
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
(codexOnlyButton as HTMLButtonElement).click();
|
||||||
|
await Promise.resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(host.textContent).toContain('Codex Helper');
|
||||||
|
expect(host.textContent).not.toContain('Review Helper');
|
||||||
|
|
||||||
|
storeState.cliStatus = {
|
||||||
|
...storeState.cliStatus,
|
||||||
|
providers: storeState.cliStatus.providers.filter((provider) => provider.providerId !== 'codex'),
|
||||||
|
};
|
||||||
|
storeState.skillsUserCatalog = [makeUserSkill()];
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
root.render(
|
||||||
|
React.createElement(SkillsPanel, {
|
||||||
|
projectPath: '/tmp/project-a',
|
||||||
|
projectLabel: 'Project A',
|
||||||
|
skillsSearchQuery: '',
|
||||||
|
setSkillsSearchQuery: vi.fn(),
|
||||||
|
skillsSort: 'name-asc',
|
||||||
|
setSkillsSort: vi.fn(),
|
||||||
|
selectedSkillId: null,
|
||||||
|
setSelectedSkillId: vi.fn(),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
await Promise.resolve();
|
||||||
|
await Promise.resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(host.textContent).toContain('Review Helper');
|
||||||
|
expect(host.textContent).not.toContain('Codex Helper');
|
||||||
|
expect(host.textContent).not.toContain('No skills yet');
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
root.unmount();
|
||||||
|
await Promise.resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue