-
Notifications
You must be signed in to change notification settings - Fork 36
feat(components/packages): add ai skills to workspace #4354
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
johnhwhite
wants to merge
16
commits into
main
Choose a base branch
from
add-skills-for-fixing-issues
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
bd737a7
feat(components/packages): add ai skills to workspace
johnhwhite e1c8d1c
Fix migration
johnhwhite 315fd16
Update file references
johnhwhite 6c2e24b
Merge remote-tracking branch 'origin/main' into add-skills-for-fixing…
johnhwhite b9ba7ba
Update file references
johnhwhite 46eb196
Merge remote-tracking branch 'origin/main' into add-skills-for-fixing…
johnhwhite fac217a
Fix api reference
johnhwhite c3249cc
Merge remote-tracking branch 'origin/main' into add-skills-for-fixing…
johnhwhite e5c5557
Update test, clarify example
johnhwhite 74f9d5d
Fix missing variable in example
johnhwhite cdc7948
Update standalone reference, update deprecation notes
johnhwhite 03c0c4e
Merge remote-tracking branch 'origin/main' into add-skills-for-fixing…
johnhwhite 5af9546
Merge remote-tracking branch 'origin/main' into add-skills-for-fixing…
johnhwhite a4bc72d
Add project modernization, rename to skyux-migration-debugger
johnhwhite 59e6501
Merge remote-tracking branch 'origin/main' into add-skills-for-fixing…
johnhwhite 997219c
Merge remote-tracking branch 'origin/main' into add-skills-for-fixing…
johnhwhite File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5 changes: 5 additions & 0 deletions
5
libs/components/packages/src/schematics/migrations/update-14/add-ai-skills/add-ai-skills.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| import { Rule, externalSchematic } from '@angular-devkit/schematics'; | ||
|
|
||
| export default function addAiSkills(): Rule { | ||
| return externalSchematic('@skyux/packages', 'add-ai-skills', {}); | ||
| } |
236 changes: 236 additions & 0 deletions
236
...ponents/packages/src/schematics/ng-generate/add-ai-skills/add-ai-skills.schematic.spec.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,236 @@ | ||
| import { SchematicTestRunner } from '@angular-devkit/schematics/testing'; | ||
|
|
||
| import { readFileSync, readdirSync, statSync } from 'fs'; | ||
| import { join, resolve } from 'path'; | ||
|
|
||
| import { createTestApp } from '../../testing/scaffold'; | ||
|
|
||
| describe('add-ai-skills', () => { | ||
| const runner = new SchematicTestRunner( | ||
| 'schematics', | ||
| require.resolve('../../../../collection.json'), | ||
| ); | ||
|
|
||
| it('should copy all skill files to .github/skills/', async () => { | ||
| const tree = await createTestApp(runner, { projectName: 'my-app' }); | ||
|
|
||
| const resultTree = await runner.runSchematic('add-ai-skills', {}, tree); | ||
|
|
||
| // Verify all SKILL.md files exist. | ||
| expect( | ||
| resultTree.exists('.github/skills/skyux-migration-debugger/SKILL.md'), | ||
| ).toBe(true); | ||
| expect( | ||
| resultTree.exists( | ||
| '.github/skills/skyux-test-driven-development/SKILL.md', | ||
| ), | ||
| ).toBe(true); | ||
| expect( | ||
| resultTree.exists( | ||
| '.github/skills/skyux-verification-before-completion/SKILL.md', | ||
| ), | ||
| ).toBe(true); | ||
| expect( | ||
| resultTree.exists('.github/skills/skyux-project-modernization/SKILL.md'), | ||
| ).toBe(true); | ||
|
|
||
| // Verify all skyux-migration-debugger reference files are included. | ||
| expect( | ||
| resultTree.exists( | ||
| '.github/skills/skyux-migration-debugger/references/angular-debugging.md', | ||
| ), | ||
| ).toBe(true); | ||
| expect( | ||
| resultTree.exists( | ||
| '.github/skills/skyux-migration-debugger/references/condition-based-waiting.md', | ||
| ), | ||
| ).toBe(true); | ||
| expect( | ||
| resultTree.exists( | ||
| '.github/skills/skyux-migration-debugger/references/defense-in-depth.md', | ||
| ), | ||
| ).toBe(true); | ||
| expect( | ||
| resultTree.exists( | ||
| '.github/skills/skyux-migration-debugger/references/root-cause-tracing.md', | ||
| ), | ||
| ).toBe(true); | ||
|
|
||
| // Verify all skyux-project-modernization reference files are included. | ||
| expect( | ||
| resultTree.exists( | ||
| '.github/skills/skyux-project-modernization/references/available-schematics.md', | ||
| ), | ||
| ).toBe(true); | ||
| expect( | ||
| resultTree.exists( | ||
| '.github/skills/skyux-project-modernization/references/deprecated-patterns.md', | ||
| ), | ||
| ).toBe(true); | ||
| expect( | ||
| resultTree.exists( | ||
| '.github/skills/skyux-project-modernization/references/available-harnesses.md', | ||
| ), | ||
| ).toBe(true); | ||
|
|
||
| // Verify all TDD reference files are included. | ||
| expect( | ||
| resultTree.exists( | ||
| '.github/skills/skyux-test-driven-development/references/angular-testing-patterns.md', | ||
| ), | ||
| ).toBe(true); | ||
| expect( | ||
| resultTree.exists( | ||
| '.github/skills/skyux-test-driven-development/references/testing-antipatterns.md', | ||
| ), | ||
| ).toBe(true); | ||
| }); | ||
|
|
||
| it('should preserve file content without template interpolation', async () => { | ||
| const tree = await createTestApp(runner, { projectName: 'my-app' }); | ||
|
|
||
| const resultTree = await runner.runSchematic('add-ai-skills', {}, tree); | ||
|
|
||
| const skillContent = resultTree.readContent( | ||
| '.github/skills/skyux-migration-debugger/SKILL.md', | ||
| ); | ||
| expect(skillContent).toContain( | ||
| 'ExpressionChangedAfterItHasBeenCheckedError', | ||
| ); | ||
| expect(skillContent).toContain( | ||
| '`TestbedHarnessEnvironment.documentRootLoader(fixture)`', | ||
| ); | ||
| }); | ||
|
|
||
| it('should preserve file content for TDD skill without template interpolation', async () => { | ||
| const tree = await createTestApp(runner, { projectName: 'my-app' }); | ||
|
|
||
| const resultTree = await runner.runSchematic('add-ai-skills', {}, tree); | ||
|
|
||
| const tddContent = resultTree.readContent( | ||
| '.github/skills/skyux-test-driven-development/SKILL.md', | ||
| ); | ||
| // Verify Mermaid diagram survives (contains brackets and special chars). | ||
| expect(tddContent).toContain('flowchart LR'); | ||
| // Verify backtick-heavy code blocks are preserved. | ||
| expect(tddContent).toContain('`Sky*Harness`'); | ||
| }); | ||
|
|
||
| it('should preserve user-owned files in .github/skills/', async () => { | ||
| const tree = await createTestApp(runner, { projectName: 'my-app' }); | ||
|
|
||
| // Simulate a user-owned skill file that exists before running the schematic. | ||
| tree.create('.github/skills/my-custom-skill/SKILL.md', '# My Custom Skill'); | ||
|
|
||
| const resultTree = await runner.runSchematic('add-ai-skills', {}, tree); | ||
|
|
||
| // User file should still exist. | ||
| expect(resultTree.exists('.github/skills/my-custom-skill/SKILL.md')).toBe( | ||
| true, | ||
| ); | ||
| expect( | ||
| resultTree.readContent('.github/skills/my-custom-skill/SKILL.md'), | ||
| ).toBe('# My Custom Skill'); | ||
| }); | ||
|
|
||
| it('should list all modernization schematics from collection.json', async () => { | ||
| const collectionPath = require.resolve('../../../../collection.json'); | ||
| const collection = JSON.parse(readFileSync(collectionPath, 'utf-8')); | ||
| const allSchematics = Object.keys(collection.schematics); | ||
|
|
||
| // These schematics are setup/infrastructure, not modernization. | ||
| const excluded = [ | ||
| 'ng-add', | ||
| 'add-skyux-to-project', | ||
| 'add-ag-grid-styles', | ||
| 'add-ai-skills', | ||
| ]; | ||
|
|
||
| const modernizationSchematics = allSchematics.filter( | ||
| (name) => !excluded.includes(name), | ||
| ); | ||
|
|
||
| const tree = await createTestApp(runner, { projectName: 'my-app' }); | ||
| const resultTree = await runner.runSchematic('add-ai-skills', {}, tree); | ||
| const content = resultTree.readContent( | ||
| '.github/skills/skyux-project-modernization/references/available-schematics.md', | ||
| ); | ||
|
|
||
| const missing = modernizationSchematics.filter( | ||
| (name) => !content.includes(name), | ||
| ); | ||
|
|
||
| if (missing.length > 0) { | ||
| fail( | ||
| `These schematics exist in collection.json but are missing from available-schematics.md:\n${missing.join('\n')}`, | ||
| ); | ||
| } | ||
| }); | ||
|
|
||
| it('should list all exported harnesses from the monorepo', async () => { | ||
| // Scan all testing public-api.ts files for exported harness classes. | ||
| const componentsRoot = resolve(__dirname, '../../../../../../'); | ||
| const harnessesByPackage: Record<string, string[]> = {}; | ||
|
|
||
| for (const pkg of readdirSync(componentsRoot)) { | ||
| const testingApi = join( | ||
| componentsRoot, | ||
| pkg, | ||
| 'testing', | ||
| 'src', | ||
| 'public-api.ts', | ||
| ); | ||
| try { | ||
| if (!statSync(testingApi).isFile()) continue; | ||
| } catch { | ||
| continue; | ||
| } | ||
|
|
||
| const apiContent = readFileSync(testingApi, 'utf-8'); | ||
| const harnessExports = apiContent | ||
| .match(/export\s*\{[^}]*\}/gs) | ||
| ?.flatMap((block) => { | ||
| const names = block.match(/\b(Sky\w+Harness)\b/g) || []; | ||
| return names.filter( | ||
| (n) => !n.endsWith('HarnessFilters') && !n.endsWith('Harnesses'), | ||
| ); | ||
| }); | ||
|
|
||
| if (harnessExports?.length) { | ||
| harnessesByPackage[pkg] = [...new Set(harnessExports)]; | ||
| } | ||
| } | ||
|
|
||
| const allHarnesses = Object.values(harnessesByPackage).flat(); | ||
|
|
||
| const tree = await createTestApp(runner, { projectName: 'my-app' }); | ||
| const resultTree = await runner.runSchematic('add-ai-skills', {}, tree); | ||
| const content = resultTree.readContent( | ||
| '.github/skills/skyux-project-modernization/references/available-harnesses.md', | ||
| ); | ||
|
|
||
| const missing = allHarnesses.filter((name) => !content.includes(name)); | ||
|
|
||
| if (missing.length > 0) { | ||
| fail( | ||
| `These harnesses are exported from the monorepo but missing from available-harnesses.md:\n${missing.join('\n')}`, | ||
| ); | ||
| } | ||
| }); | ||
|
|
||
| it('should overwrite existing files on re-run', async () => { | ||
| const tree = await createTestApp(runner, { projectName: 'my-app' }); | ||
|
|
||
| const firstTree = await runner.runSchematic('add-ai-skills', {}, tree); | ||
|
|
||
| const secondTree = await runner.runSchematic( | ||
| 'add-ai-skills', | ||
| {}, | ||
| firstTree, | ||
| ); | ||
|
|
||
| expect( | ||
| secondTree.exists('.github/skills/skyux-migration-debugger/SKILL.md'), | ||
| ).toBe(true); | ||
| }); | ||
| }); |
17 changes: 17 additions & 0 deletions
17
libs/components/packages/src/schematics/ng-generate/add-ai-skills/add-ai-skills.schematic.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| import { normalize } from '@angular-devkit/core'; | ||
| import { | ||
| MergeStrategy, | ||
| Rule, | ||
| apply, | ||
| mergeWith, | ||
| move, | ||
| url, | ||
| } from '@angular-devkit/schematics'; | ||
|
|
||
| export function addAiSkills(): Rule { | ||
| return mergeWith( | ||
| apply(url('./files'), [move(normalize('.github'))]), | ||
| MergeStrategy.Overwrite, | ||
| ); | ||
| } | ||
| export default addAiSkills; |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.