Skip to content

Commit 162c2cd

Browse files
authored
fix(ai-config): add igniteui-webcomponents skills w/o framework config (#1634)
1 parent b161159 commit 162c2cd

3 files changed

Lines changed: 59 additions & 7 deletions

File tree

packages/core/update/package-resolve.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export const NPM_REACT_SPREADSHEET_CHART_ADAPTER = "igniteui-react-spreadsheet-c
4141
export const FEED_REACT_SPREADSHEET_CHART_ADAPTER = "@infragistics/igniteui-react-spreadsheet-chart-adapter";
4242

4343
// webcomponents
44+
export const NPM_WEBCOMPONENTS = "igniteui-webcomponents";
4445
export const NPM_WEBCOMPONENTS_CHARTS = "igniteui-webcomponents-charts";
4546
export const FEED_WEBCOMPONENTS_CHARTS = "@infragistics/igniteui-webcomponents-charts";
4647
export const NPM_WEBCOMPONENTS_CORE = "igniteui-webcomponents-core";

packages/core/util/ai-skills.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { App } from "./App";
33
import { IFileSystem, FS_TOKEN } from "../types/FileSystem";
44
import { ProjectConfig } from "./ProjectConfig";
55
import { Util } from "./Util";
6-
import { NPM_ANGULAR, NPM_REACT, resolvePackage, UPGRADEABLE_PACKAGES } from "../update/package-resolve";
6+
import { NPM_ANGULAR, NPM_REACT, NPM_WEBCOMPONENTS, resolvePackage, UPGRADEABLE_PACKAGES } from "../update/package-resolve";
77

88
const CLAUDE_SKILLS_DIR = ".claude/skills";
99

@@ -23,15 +23,16 @@ function resolveSkillsRoots(): string[] {
2323
} catch { /* config not readable – fall through to scan all */ }
2424

2525
const allPkgKeys = Object.keys(UPGRADEABLE_PACKAGES);
26-
let candidates: string[];
26+
let candidates = new Set<string>();
2727
if (framework === "angular") {
28-
candidates = [NPM_ANGULAR];
28+
candidates.add(NPM_ANGULAR);
2929
} else if (framework === "react") {
30-
candidates = [NPM_REACT];
30+
candidates.add(NPM_REACT);
3131
} else if (framework === "webcomponents") {
32-
candidates = allPkgKeys.filter(k => k.startsWith("igniteui-webcomponents"));
32+
candidates.add(NPM_WEBCOMPONENTS);
3333
} else {
34-
candidates = allPkgKeys;
34+
// NPM_REACT and NPM_WEBCOMPONENTS are OSS-only and not in UPGRADEABLE_PACKAGES, so add them explicitly
35+
candidates = new Set([...allPkgKeys, NPM_REACT, NPM_WEBCOMPONENTS]);
3536
}
3637

3738
for (const pkg of candidates) {

spec/unit/ai-skills-spec.ts

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ describe("Unit - copyAISkillsToProject", () => {
166166

167167
describe("WebComponents framework", () => {
168168
it("should copy skills from igniteui-webcomponents into .claude/skills/", async () => {
169-
const wcPkg = "igniteui-webcomponents-core";
169+
const wcPkg = "igniteui-webcomponents";
170170
const dir = skillsDir(wcPkg);
171171
const file = skillFile(wcPkg, "webcomponents.md");
172172
const content = "# Ignite UI WebComponents skills";
@@ -232,6 +232,56 @@ describe("Unit - copyAISkillsToProject", () => {
232232
// but since we scan ALL packages and only one directory exists, roots.length === 1 → no prefix
233233
expect(fs.writeFile).toHaveBeenCalledWith(".claude/skills/angular.md", "skill content");
234234
});
235+
236+
it("should also scan igniteui-react in the fallback", async () => {
237+
const reactPkg = "igniteui-react";
238+
const dir = skillsDir(reactPkg);
239+
const file = skillFile(reactPkg, "overview.md");
240+
241+
const fs = makeFs({
242+
fileExists: jasmine.createSpy("fileExists").and.returnValue(false),
243+
readFile: jasmine.createSpy("readFile").and.returnValue("react skill content"),
244+
directoryExists: jasmine.createSpy("directoryExists").and.callFake((p: string) =>
245+
p === dir
246+
),
247+
glob: jasmine.createSpy("glob").and.callFake((d: string) =>
248+
d === dir ? [file] : []
249+
),
250+
writeFile: jasmine.createSpy("writeFile")
251+
});
252+
253+
spyOn(App.container, "get").and.returnValue(fs);
254+
spyOn(ProjectConfig, "hasLocalConfig").and.returnValue(false);
255+
256+
await copyAISkillsToProject();
257+
258+
expect(fs.writeFile).toHaveBeenCalledWith(".claude/skills/overview.md", "react skill content");
259+
});
260+
261+
it("should also scan igniteui-webcomponents in the fallback", async () => {
262+
const wcPkg = "igniteui-webcomponents";
263+
const dir = skillsDir(wcPkg);
264+
const file = skillFile(wcPkg, "webcomponents.md");
265+
266+
const fs = makeFs({
267+
fileExists: jasmine.createSpy("fileExists").and.returnValue(false),
268+
readFile: jasmine.createSpy("readFile").and.returnValue("wc skill content"),
269+
directoryExists: jasmine.createSpy("directoryExists").and.callFake((p: string) =>
270+
p === dir
271+
),
272+
glob: jasmine.createSpy("glob").and.callFake((d: string) =>
273+
d === dir ? [file] : []
274+
),
275+
writeFile: jasmine.createSpy("writeFile")
276+
});
277+
278+
spyOn(App.container, "get").and.returnValue(fs);
279+
spyOn(ProjectConfig, "hasLocalConfig").and.returnValue(false);
280+
281+
await copyAISkillsToProject();
282+
283+
expect(fs.writeFile).toHaveBeenCalledWith(".claude/skills/webcomponents.md", "wc skill content");
284+
});
235285
});
236286

237287
describe("No skills available", () => {

0 commit comments

Comments
 (0)