beth-copilot 1.0.12 → 1.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/README.md +173 -32
  3. package/bin/cli.js +111 -193
  4. package/dist/cli/commands/doctor.d.ts +25 -0
  5. package/dist/cli/commands/doctor.d.ts.map +1 -0
  6. package/dist/cli/commands/doctor.js +238 -0
  7. package/dist/cli/commands/doctor.js.map +1 -0
  8. package/dist/cli/commands/doctor.test.d.ts +6 -0
  9. package/dist/cli/commands/doctor.test.d.ts.map +1 -0
  10. package/dist/cli/commands/doctor.test.js +137 -0
  11. package/dist/cli/commands/doctor.test.js.map +1 -0
  12. package/dist/cli/commands/index.d.ts +7 -0
  13. package/dist/cli/commands/index.d.ts.map +1 -0
  14. package/dist/cli/commands/index.js +10 -0
  15. package/dist/cli/commands/index.js.map +1 -0
  16. package/dist/cli/commands/quickstart.d.ts +18 -0
  17. package/dist/cli/commands/quickstart.d.ts.map +1 -0
  18. package/dist/cli/commands/quickstart.js +141 -0
  19. package/dist/cli/commands/quickstart.js.map +1 -0
  20. package/dist/core/agents/index.d.ts +6 -0
  21. package/dist/core/agents/index.d.ts.map +1 -0
  22. package/dist/core/agents/index.js +6 -0
  23. package/dist/core/agents/index.js.map +1 -0
  24. package/dist/core/agents/loader.d.ts +49 -0
  25. package/dist/core/agents/loader.d.ts.map +1 -0
  26. package/dist/core/agents/loader.js +217 -0
  27. package/dist/core/agents/loader.js.map +1 -0
  28. package/dist/core/agents/loader.test.d.ts +7 -0
  29. package/dist/core/agents/loader.test.d.ts.map +1 -0
  30. package/dist/core/agents/loader.test.js +144 -0
  31. package/dist/core/agents/loader.test.js.map +1 -0
  32. package/dist/core/agents/types.d.ts +77 -0
  33. package/dist/core/agents/types.d.ts.map +1 -0
  34. package/dist/core/agents/types.js +8 -0
  35. package/dist/core/agents/types.js.map +1 -0
  36. package/dist/core/agents/types.test.d.ts +6 -0
  37. package/dist/core/agents/types.test.d.ts.map +1 -0
  38. package/dist/core/agents/types.test.js +254 -0
  39. package/dist/core/agents/types.test.js.map +1 -0
  40. package/dist/core/skills/index.d.ts +6 -0
  41. package/dist/core/skills/index.d.ts.map +1 -0
  42. package/dist/core/skills/index.js +6 -0
  43. package/dist/core/skills/index.js.map +1 -0
  44. package/dist/core/skills/loader.d.ts +69 -0
  45. package/dist/core/skills/loader.d.ts.map +1 -0
  46. package/dist/core/skills/loader.js +243 -0
  47. package/dist/core/skills/loader.js.map +1 -0
  48. package/dist/core/skills/loader.test.d.ts +7 -0
  49. package/dist/core/skills/loader.test.d.ts.map +1 -0
  50. package/dist/core/skills/loader.test.js +184 -0
  51. package/dist/core/skills/loader.test.js.map +1 -0
  52. package/dist/core/skills/types.d.ts +58 -0
  53. package/dist/core/skills/types.d.ts.map +1 -0
  54. package/dist/core/skills/types.js +8 -0
  55. package/dist/core/skills/types.js.map +1 -0
  56. package/dist/index.d.ts +10 -0
  57. package/dist/index.d.ts.map +1 -0
  58. package/dist/index.js +14 -0
  59. package/dist/index.js.map +1 -0
  60. package/dist/lib/index.d.ts +7 -0
  61. package/dist/lib/index.d.ts.map +1 -0
  62. package/dist/lib/index.js +7 -0
  63. package/dist/lib/index.js.map +1 -0
  64. package/dist/lib/pathValidation.d.ts +69 -0
  65. package/dist/lib/pathValidation.d.ts.map +1 -0
  66. package/dist/lib/pathValidation.js +185 -0
  67. package/dist/lib/pathValidation.js.map +1 -0
  68. package/dist/lib/pathValidation.test.d.ts +9 -0
  69. package/dist/lib/pathValidation.test.d.ts.map +1 -0
  70. package/dist/lib/pathValidation.test.js +195 -0
  71. package/dist/lib/pathValidation.test.js.map +1 -0
  72. package/package.json +15 -3
  73. package/templates/.github/agents/developer.agent.md +9 -0
  74. package/templates/.github/agents/product-manager.agent.md +9 -0
  75. package/templates/.github/agents/researcher.agent.md +9 -0
  76. package/templates/.github/agents/security-reviewer.agent.md +9 -2
  77. package/templates/.github/agents/tester.agent.md +9 -0
  78. package/templates/.github/agents/ux-designer.agent.md +9 -0
  79. package/templates/.github/copilot-instructions.md +3 -3
@@ -0,0 +1,254 @@
1
+ /**
2
+ * Unit tests for agent schema types and parsing.
3
+ * Run with: node --test dist/core/agents/types.test.js
4
+ */
5
+ import { describe, it } from 'node:test';
6
+ import assert from 'node:assert';
7
+ describe('AgentFrontmatter type validation', () => {
8
+ it('should accept valid minimal frontmatter', () => {
9
+ const frontmatter = {
10
+ name: 'test-agent',
11
+ };
12
+ assert.strictEqual(frontmatter.name, 'test-agent');
13
+ assert.strictEqual(frontmatter.description, undefined);
14
+ assert.strictEqual(frontmatter.model, undefined);
15
+ assert.strictEqual(frontmatter.tools, undefined);
16
+ assert.strictEqual(frontmatter.handoffs, undefined);
17
+ assert.strictEqual(frontmatter.infer, undefined);
18
+ });
19
+ it('should accept valid full frontmatter', () => {
20
+ const frontmatter = {
21
+ name: 'developer',
22
+ description: 'Expert React developer',
23
+ model: 'Claude Opus 4.5',
24
+ tools: ['readFile', 'editFiles', 'runInTerminal'],
25
+ handoffs: [
26
+ {
27
+ label: 'Quality Assurance',
28
+ agent: 'tester',
29
+ prompt: 'Test the feature',
30
+ send: false,
31
+ },
32
+ ],
33
+ infer: true,
34
+ };
35
+ assert.strictEqual(frontmatter.name, 'developer');
36
+ assert.strictEqual(frontmatter.description, 'Expert React developer');
37
+ assert.strictEqual(frontmatter.model, 'Claude Opus 4.5');
38
+ assert.strictEqual(frontmatter.tools?.length, 3);
39
+ assert.strictEqual(frontmatter.handoffs?.length, 1);
40
+ assert.strictEqual(frontmatter.infer, true);
41
+ });
42
+ });
43
+ describe('AgentHandoff type validation', () => {
44
+ it('should accept valid handoff with all fields', () => {
45
+ const handoff = {
46
+ label: 'Design Review',
47
+ agent: 'ux-designer',
48
+ prompt: 'Review the UI implementation',
49
+ send: true,
50
+ };
51
+ assert.strictEqual(handoff.label, 'Design Review');
52
+ assert.strictEqual(handoff.agent, 'ux-designer');
53
+ assert.strictEqual(handoff.prompt, 'Review the UI implementation');
54
+ assert.strictEqual(handoff.send, true);
55
+ });
56
+ it('should accept handoff without optional send field', () => {
57
+ const handoff = {
58
+ label: 'Security Audit',
59
+ agent: 'security-reviewer',
60
+ prompt: 'Check for vulnerabilities',
61
+ };
62
+ assert.strictEqual(handoff.label, 'Security Audit');
63
+ assert.strictEqual(handoff.agent, 'security-reviewer');
64
+ assert.strictEqual(handoff.send, undefined);
65
+ });
66
+ });
67
+ describe('AgentTool type validation', () => {
68
+ it('should accept known tool names', () => {
69
+ const tools = [
70
+ 'codebase',
71
+ 'readFile',
72
+ 'editFiles',
73
+ 'createFile',
74
+ 'listDirectory',
75
+ 'fileSearch',
76
+ 'textSearch',
77
+ 'runInTerminal',
78
+ 'getTerminalOutput',
79
+ 'problems',
80
+ 'usages',
81
+ 'runSubagent',
82
+ ];
83
+ assert.strictEqual(tools.length, 12);
84
+ assert.ok(tools.includes('readFile'));
85
+ assert.ok(tools.includes('runSubagent'));
86
+ });
87
+ it('should accept custom/MCP tool names as strings', () => {
88
+ const tools = [
89
+ 'readFile',
90
+ 'mcp_brave_search', // Custom MCP tool
91
+ 'mcp_azure_deploy', // Custom MCP tool
92
+ ];
93
+ assert.strictEqual(tools.length, 3);
94
+ assert.ok(tools.includes('mcp_brave_search'));
95
+ });
96
+ });
97
+ describe('AgentDefinition type validation', () => {
98
+ it('should accept valid agent definition', () => {
99
+ const agent = {
100
+ id: 'developer',
101
+ frontmatter: {
102
+ name: 'developer',
103
+ description: 'Expert developer',
104
+ model: 'Claude Opus 4.5',
105
+ tools: ['readFile', 'editFiles'],
106
+ infer: true,
107
+ },
108
+ body: '# Developer Agent\n\nYou are an expert developer.',
109
+ sourcePath: '/project/.github/agents/developer.agent.md',
110
+ };
111
+ assert.strictEqual(agent.id, 'developer');
112
+ assert.strictEqual(agent.frontmatter.name, 'developer');
113
+ assert.ok(agent.body.includes('expert developer'));
114
+ assert.ok(agent.sourcePath.endsWith('.agent.md'));
115
+ });
116
+ });
117
+ describe('AgentLoadResult type validation', () => {
118
+ it('should represent successful load with no errors', () => {
119
+ const result = {
120
+ agents: [
121
+ {
122
+ id: 'beth',
123
+ frontmatter: { name: 'Beth' },
124
+ body: '# Beth\n\nOrchestrator',
125
+ sourcePath: '.github/agents/beth.agent.md',
126
+ },
127
+ ],
128
+ errors: [],
129
+ };
130
+ assert.strictEqual(result.agents.length, 1);
131
+ assert.strictEqual(result.errors.length, 0);
132
+ });
133
+ it('should represent partial load with some errors', () => {
134
+ const result = {
135
+ agents: [
136
+ {
137
+ id: 'developer',
138
+ frontmatter: { name: 'developer' },
139
+ body: '# Developer',
140
+ sourcePath: '.github/agents/developer.agent.md',
141
+ },
142
+ ],
143
+ errors: [
144
+ {
145
+ filePath: '.github/agents/broken.agent.md',
146
+ message: 'Invalid YAML frontmatter',
147
+ },
148
+ ],
149
+ };
150
+ assert.strictEqual(result.agents.length, 1);
151
+ assert.strictEqual(result.errors.length, 1);
152
+ assert.ok(result.errors[0].message.includes('YAML'));
153
+ });
154
+ });
155
+ describe('AgentLoadError type validation', () => {
156
+ it('should represent error without cause', () => {
157
+ const error = {
158
+ filePath: '.github/agents/invalid.agent.md',
159
+ message: 'Missing name field in frontmatter',
160
+ };
161
+ assert.strictEqual(error.filePath, '.github/agents/invalid.agent.md');
162
+ assert.ok(error.message.includes('name'));
163
+ assert.strictEqual(error.cause, undefined);
164
+ });
165
+ it('should represent error with cause', () => {
166
+ const originalError = new Error('YAML parse error at line 5');
167
+ const error = {
168
+ filePath: '.github/agents/malformed.agent.md',
169
+ message: 'Failed to parse YAML frontmatter',
170
+ cause: originalError,
171
+ };
172
+ assert.ok(error.cause instanceof Error);
173
+ assert.ok(error.cause?.message.includes('line 5'));
174
+ });
175
+ });
176
+ describe('Type compatibility with actual agent files', () => {
177
+ it('should represent Beth agent structure', () => {
178
+ // This mirrors the actual beth.agent.md structure
179
+ const beth = {
180
+ id: 'beth',
181
+ frontmatter: {
182
+ name: 'Beth',
183
+ description: 'Ruthless, hyper-competent orchestrator for multi-agent workflows',
184
+ model: 'Claude Opus 4.5',
185
+ tools: [
186
+ 'codebase',
187
+ 'readFile',
188
+ 'editFiles',
189
+ 'createFile',
190
+ 'listDirectory',
191
+ 'fileSearch',
192
+ 'textSearch',
193
+ 'runInTerminal',
194
+ 'getTerminalOutput',
195
+ 'runSubagent',
196
+ ],
197
+ handoffs: [
198
+ { label: 'Development', agent: 'developer', prompt: 'Implement this feature' },
199
+ { label: 'Testing', agent: 'tester', prompt: 'Test this feature' },
200
+ { label: 'Design', agent: 'ux-designer', prompt: 'Design this feature' },
201
+ { label: 'Requirements', agent: 'product-manager', prompt: 'Define requirements' },
202
+ { label: 'Research', agent: 'researcher', prompt: 'Research this topic' },
203
+ { label: 'Security', agent: 'security-reviewer', prompt: 'Review security' },
204
+ ],
205
+ infer: true,
206
+ },
207
+ body: '# Beth\n\n> "I don\'t speak dipshit. I speak in consequences."',
208
+ sourcePath: '.github/agents/beth.agent.md',
209
+ };
210
+ assert.strictEqual(beth.frontmatter.name, 'Beth');
211
+ assert.strictEqual(beth.frontmatter.tools?.length, 10);
212
+ assert.strictEqual(beth.frontmatter.handoffs?.length, 6);
213
+ assert.strictEqual(beth.frontmatter.infer, true);
214
+ });
215
+ it('should represent developer agent structure', () => {
216
+ // This mirrors the actual developer.agent.md structure
217
+ const developer = {
218
+ id: 'developer',
219
+ frontmatter: {
220
+ name: 'developer',
221
+ description: 'Expert React/TypeScript/Next.js developer',
222
+ model: 'Claude Opus 4.5',
223
+ tools: [
224
+ 'codebase',
225
+ 'readFile',
226
+ 'editFiles',
227
+ 'createFile',
228
+ 'listDirectory',
229
+ 'fileSearch',
230
+ 'textSearch',
231
+ 'runInTerminal',
232
+ 'getTerminalOutput',
233
+ 'problems',
234
+ 'usages',
235
+ 'runSubagent',
236
+ ],
237
+ handoffs: [
238
+ { label: 'Quality Assurance', agent: 'tester', prompt: 'Test the implemented feature', send: false },
239
+ { label: 'Design Review', agent: 'ux-designer', prompt: 'Review implementation against design specs', send: false },
240
+ { label: 'Technical Feasibility', agent: 'product-manager', prompt: 'Provide technical feasibility assessment', send: false },
241
+ ],
242
+ infer: true,
243
+ },
244
+ body: '# IDEO Developer Agent',
245
+ sourcePath: '.github/agents/developer.agent.md',
246
+ };
247
+ assert.strictEqual(developer.frontmatter.name, 'developer');
248
+ assert.strictEqual(developer.frontmatter.tools?.length, 12);
249
+ assert.strictEqual(developer.frontmatter.handoffs?.length, 3);
250
+ // Check handoff has send: false
251
+ assert.strictEqual(developer.frontmatter.handoffs?.[0].send, false);
252
+ });
253
+ });
254
+ //# sourceMappingURL=types.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.test.js","sourceRoot":"","sources":["../../../src/core/agents/types.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Skills module exports
3
+ */
4
+ export * from './types.js';
5
+ export * from './loader.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/skills/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Skills module exports
3
+ */
4
+ export * from './types.js';
5
+ export * from './loader.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/skills/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Skill Loader
3
+ *
4
+ * Parses SKILL.md files from the skills directory into typed SkillDefinition objects.
5
+ * Extracts trigger phrases from the description field for on-demand loading.
6
+ */
7
+ import type { SkillDefinition, SkillLoadResult, SkillLoadError, TriggerMap } from './types.js';
8
+ /**
9
+ * Default skills directory relative to workspace root.
10
+ */
11
+ export declare const DEFAULT_SKILLS_DIR = ".github/skills";
12
+ /**
13
+ * File name for skill definition files.
14
+ */
15
+ export declare const SKILL_FILE_NAME = "SKILL.md";
16
+ /**
17
+ * Load all skills from a directory.
18
+ * Skills are expected to be in subdirectories: skills/<name>/SKILL.md
19
+ *
20
+ * @param skillsDir - Path to skills directory (default: .github/skills)
21
+ * @returns Object containing loaded skills and any errors
22
+ */
23
+ export declare function loadSkills(skillsDir?: string): SkillLoadResult;
24
+ /**
25
+ * Load a single skill from a file.
26
+ *
27
+ * @param filePath - Path to the SKILL.md file
28
+ * @param id - Skill ID (directory name)
29
+ * @returns Either a skill definition or an error
30
+ */
31
+ export declare function loadSkill(filePath: string, id?: string): {
32
+ skill: SkillDefinition;
33
+ } | {
34
+ error: SkillLoadError;
35
+ };
36
+ /**
37
+ * Extract trigger phrases from a skill description.
38
+ *
39
+ * Looks for patterns like:
40
+ * - "Triggers on: phrase1, phrase2, phrase3"
41
+ * - "Use when: phrase1, phrase2"
42
+ *
43
+ * Also extracts quoted phrases as potential triggers.
44
+ */
45
+ export declare function extractTriggers(description?: string): string[];
46
+ /**
47
+ * Build a trigger map for quick lookups.
48
+ *
49
+ * @param result - The result from loadSkills()
50
+ * @returns Map of lowercase trigger phrase -> skill definition
51
+ */
52
+ export declare function buildTriggerMap(result: SkillLoadResult): TriggerMap;
53
+ /**
54
+ * Find skills that match a user query.
55
+ *
56
+ * @param query - User input to check for triggers
57
+ * @param triggerMap - Map from buildTriggerMap()
58
+ * @returns Array of matching skills (ordered by trigger length, longest first)
59
+ */
60
+ export declare function findMatchingSkills(query: string, triggerMap: TriggerMap): SkillDefinition[];
61
+ /**
62
+ * Get a skill by ID from a load result.
63
+ *
64
+ * @param result - The result from loadSkills()
65
+ * @param id - Skill ID to find (e.g., 'prd', 'shadcn-ui')
66
+ * @returns The skill definition or undefined if not found
67
+ */
68
+ export declare function getSkillById(result: SkillLoadResult, id: string): SkillDefinition | undefined;
69
+ //# sourceMappingURL=loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/core/skills/loader.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EACV,eAAe,EAEf,eAAe,EACf,cAAc,EACd,UAAU,EACX,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,eAAO,MAAM,kBAAkB,mBAAmB,CAAC;AAEnD;;GAEG;AACH,eAAO,MAAM,eAAe,aAAa,CAAC;AAE1C;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,SAAS,GAAE,MAA2B,GAAG,eAAe,CAgDlF;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CACvB,QAAQ,EAAE,MAAM,EAChB,EAAE,CAAC,EAAE,MAAM,GACV;IAAE,KAAK,EAAE,eAAe,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,cAAc,CAAA;CAAE,CA2CxD;AA+DD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAqB9D;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,UAAU,CAWnE;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,UAAU,GACrB,eAAe,EAAE,CAyBnB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,eAAe,EACvB,EAAE,EAAE,MAAM,GACT,eAAe,GAAG,SAAS,CAE7B"}
@@ -0,0 +1,243 @@
1
+ /**
2
+ * Skill Loader
3
+ *
4
+ * Parses SKILL.md files from the skills directory into typed SkillDefinition objects.
5
+ * Extracts trigger phrases from the description field for on-demand loading.
6
+ */
7
+ import { readFileSync, readdirSync, existsSync, statSync } from 'node:fs';
8
+ import { join, basename } from 'node:path';
9
+ import matter from 'gray-matter';
10
+ /**
11
+ * Default skills directory relative to workspace root.
12
+ */
13
+ export const DEFAULT_SKILLS_DIR = '.github/skills';
14
+ /**
15
+ * File name for skill definition files.
16
+ */
17
+ export const SKILL_FILE_NAME = 'SKILL.md';
18
+ /**
19
+ * Load all skills from a directory.
20
+ * Skills are expected to be in subdirectories: skills/<name>/SKILL.md
21
+ *
22
+ * @param skillsDir - Path to skills directory (default: .github/skills)
23
+ * @returns Object containing loaded skills and any errors
24
+ */
25
+ export function loadSkills(skillsDir = DEFAULT_SKILLS_DIR) {
26
+ const skills = [];
27
+ const errors = [];
28
+ if (!existsSync(skillsDir)) {
29
+ errors.push({
30
+ filePath: skillsDir,
31
+ message: `Skills directory not found: ${skillsDir}`,
32
+ });
33
+ return { skills, errors };
34
+ }
35
+ // Get subdirectories (each skill is in its own folder)
36
+ const entries = readdirSync(skillsDir);
37
+ const skillDirs = entries.filter((entry) => {
38
+ const entryPath = join(skillsDir, entry);
39
+ return existsSync(entryPath) && statSync(entryPath).isDirectory();
40
+ });
41
+ if (skillDirs.length === 0) {
42
+ errors.push({
43
+ filePath: skillsDir,
44
+ message: `No skill directories found in ${skillsDir}`,
45
+ });
46
+ return { skills, errors };
47
+ }
48
+ for (const dir of skillDirs) {
49
+ const skillPath = join(skillsDir, dir, SKILL_FILE_NAME);
50
+ if (!existsSync(skillPath)) {
51
+ errors.push({
52
+ filePath: join(skillsDir, dir),
53
+ message: `Missing ${SKILL_FILE_NAME} in skill directory: ${dir}`,
54
+ });
55
+ continue;
56
+ }
57
+ const result = loadSkill(skillPath, dir);
58
+ if ('error' in result) {
59
+ errors.push(result.error);
60
+ }
61
+ else {
62
+ skills.push(result.skill);
63
+ }
64
+ }
65
+ return { skills, errors };
66
+ }
67
+ /**
68
+ * Load a single skill from a file.
69
+ *
70
+ * @param filePath - Path to the SKILL.md file
71
+ * @param id - Skill ID (directory name)
72
+ * @returns Either a skill definition or an error
73
+ */
74
+ export function loadSkill(filePath, id) {
75
+ try {
76
+ let content = readFileSync(filePath, 'utf-8');
77
+ // Handle GitHub Copilot skill file format: ```skill\n---\n...\n---\n...\n```
78
+ // Strip the code fence wrapper if present
79
+ content = stripCodeFence(content);
80
+ const { data, content: body } = matter(content);
81
+ // Validate required fields
82
+ const validation = validateFrontmatter(data, filePath);
83
+ if (validation.error) {
84
+ return { error: validation.error };
85
+ }
86
+ // Use provided ID or extract from path
87
+ const skillId = id || basename(join(filePath, '..'));
88
+ // Normalize frontmatter
89
+ const frontmatter = normalizeFrontmatter(data);
90
+ // Extract trigger phrases from description
91
+ const triggers = extractTriggers(frontmatter.description);
92
+ return {
93
+ skill: {
94
+ id: skillId,
95
+ frontmatter,
96
+ body: body.trim(),
97
+ sourcePath: filePath,
98
+ triggers,
99
+ },
100
+ };
101
+ }
102
+ catch (err) {
103
+ return {
104
+ error: {
105
+ filePath,
106
+ message: `Failed to parse skill file: ${err instanceof Error ? err.message : String(err)}`,
107
+ cause: err instanceof Error ? err : undefined,
108
+ },
109
+ };
110
+ }
111
+ }
112
+ /**
113
+ * Strip GitHub Copilot code fence wrapper from skill/agent files.
114
+ *
115
+ * Files may be wrapped in ```skill or ```chatagent code fences.
116
+ * This extracts the content inside the fence.
117
+ */
118
+ function stripCodeFence(content) {
119
+ // Match opening fence: ```skill, ```chatagent, ````skill, etc.
120
+ const fenceMatch = content.match(/^(`{3,})(skill|chatagent)\s*[\r\n]/);
121
+ if (!fenceMatch) {
122
+ return content;
123
+ }
124
+ const fenceLength = fenceMatch[1].length;
125
+ const closingFence = '`'.repeat(fenceLength);
126
+ // Find the closing fence
127
+ const closingIndex = content.lastIndexOf(closingFence);
128
+ if (closingIndex === -1 || closingIndex === 0) {
129
+ return content;
130
+ }
131
+ // Extract content between fences
132
+ const startIndex = fenceMatch[0].length;
133
+ return content.slice(startIndex, closingIndex).trim();
134
+ }
135
+ /**
136
+ * Validate that frontmatter has required fields.
137
+ */
138
+ function validateFrontmatter(data, filePath) {
139
+ if (!data.name || typeof data.name !== 'string') {
140
+ return {
141
+ error: {
142
+ filePath,
143
+ message: `Missing or invalid 'name' in frontmatter`,
144
+ },
145
+ };
146
+ }
147
+ return {};
148
+ }
149
+ /**
150
+ * Normalize frontmatter data to typed SkillFrontmatter.
151
+ */
152
+ function normalizeFrontmatter(data) {
153
+ const frontmatter = {
154
+ name: data.name,
155
+ };
156
+ if (data.description) {
157
+ frontmatter.description = String(data.description);
158
+ }
159
+ return frontmatter;
160
+ }
161
+ /**
162
+ * Extract trigger phrases from a skill description.
163
+ *
164
+ * Looks for patterns like:
165
+ * - "Triggers on: phrase1, phrase2, phrase3"
166
+ * - "Use when: phrase1, phrase2"
167
+ *
168
+ * Also extracts quoted phrases as potential triggers.
169
+ */
170
+ export function extractTriggers(description) {
171
+ if (!description)
172
+ return [];
173
+ const triggers = [];
174
+ // Pattern 1: "Triggers on: x, y, z" or "Use when: x, y, z"
175
+ const triggersMatch = description.match(/(?:Triggers on|Use when)[:\s]+([^.]+)/i);
176
+ if (triggersMatch) {
177
+ const phrases = triggersMatch[1].split(',').map((s) => s.trim().toLowerCase());
178
+ triggers.push(...phrases.filter((p) => p.length > 0));
179
+ }
180
+ // Pattern 2: Quoted phrases like "create a prd"
181
+ const quotedMatches = description.match(/"([^"]+)"/g);
182
+ if (quotedMatches) {
183
+ const quoted = quotedMatches.map((q) => q.replace(/"/g, '').toLowerCase());
184
+ triggers.push(...quoted.filter((q) => !triggers.includes(q)));
185
+ }
186
+ // Deduplicate
187
+ return [...new Set(triggers)];
188
+ }
189
+ /**
190
+ * Build a trigger map for quick lookups.
191
+ *
192
+ * @param result - The result from loadSkills()
193
+ * @returns Map of lowercase trigger phrase -> skill definition
194
+ */
195
+ export function buildTriggerMap(result) {
196
+ const map = new Map();
197
+ for (const skill of result.skills) {
198
+ for (const trigger of skill.triggers) {
199
+ // Store with lowercase key for case-insensitive matching
200
+ map.set(trigger.toLowerCase(), skill);
201
+ }
202
+ }
203
+ return map;
204
+ }
205
+ /**
206
+ * Find skills that match a user query.
207
+ *
208
+ * @param query - User input to check for triggers
209
+ * @param triggerMap - Map from buildTriggerMap()
210
+ * @returns Array of matching skills (ordered by trigger length, longest first)
211
+ */
212
+ export function findMatchingSkills(query, triggerMap) {
213
+ const queryLower = query.toLowerCase();
214
+ const matches = [];
215
+ for (const [trigger, skill] of triggerMap) {
216
+ if (queryLower.includes(trigger)) {
217
+ matches.push({ skill, triggerLength: trigger.length });
218
+ }
219
+ }
220
+ // Sort by trigger length (prefer more specific matches)
221
+ matches.sort((a, b) => b.triggerLength - a.triggerLength);
222
+ // Deduplicate skills (a skill might match multiple triggers)
223
+ const seen = new Set();
224
+ const result = [];
225
+ for (const { skill } of matches) {
226
+ if (!seen.has(skill.id)) {
227
+ seen.add(skill.id);
228
+ result.push(skill);
229
+ }
230
+ }
231
+ return result;
232
+ }
233
+ /**
234
+ * Get a skill by ID from a load result.
235
+ *
236
+ * @param result - The result from loadSkills()
237
+ * @param id - Skill ID to find (e.g., 'prd', 'shadcn-ui')
238
+ * @returns The skill definition or undefined if not found
239
+ */
240
+ export function getSkillById(result, id) {
241
+ return result.skills.find((skill) => skill.id.toLowerCase() === id.toLowerCase());
242
+ }
243
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/core/skills/loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Skill Loader Tests
3
+ *
4
+ * Tests for parsing SKILL.md files into typed SkillDefinition objects.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=loader.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.test.d.ts","sourceRoot":"","sources":["../../../src/core/skills/loader.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}