@magnolia/skill-loader 0.1.0-preview.1

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 (43) hide show
  1. package/LICENSE.txt +27 -0
  2. package/README.md +354 -0
  3. package/dist/filter.d.ts +26 -0
  4. package/dist/filter.d.ts.map +1 -0
  5. package/dist/filter.js +160 -0
  6. package/dist/filter.js.map +1 -0
  7. package/dist/index.d.ts +35 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +38 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/loader.d.ts +81 -0
  12. package/dist/loader.d.ts.map +1 -0
  13. package/dist/loader.js +192 -0
  14. package/dist/loader.js.map +1 -0
  15. package/dist/manager.d.ts +131 -0
  16. package/dist/manager.d.ts.map +1 -0
  17. package/dist/manager.js +236 -0
  18. package/dist/manager.js.map +1 -0
  19. package/dist/parser.d.ts +25 -0
  20. package/dist/parser.d.ts.map +1 -0
  21. package/dist/parser.js +110 -0
  22. package/dist/parser.js.map +1 -0
  23. package/dist/sources/directory.d.ts +18 -0
  24. package/dist/sources/directory.d.ts.map +1 -0
  25. package/dist/sources/directory.js +57 -0
  26. package/dist/sources/directory.js.map +1 -0
  27. package/dist/sources/file.d.ts +15 -0
  28. package/dist/sources/file.d.ts.map +1 -0
  29. package/dist/sources/file.js +30 -0
  30. package/dist/sources/file.js.map +1 -0
  31. package/dist/sources/inline.d.ts +15 -0
  32. package/dist/sources/inline.d.ts.map +1 -0
  33. package/dist/sources/inline.js +21 -0
  34. package/dist/sources/inline.js.map +1 -0
  35. package/dist/sources/url.d.ts +20 -0
  36. package/dist/sources/url.d.ts.map +1 -0
  37. package/dist/sources/url.js +65 -0
  38. package/dist/sources/url.js.map +1 -0
  39. package/dist/types.d.ts +111 -0
  40. package/dist/types.d.ts.map +1 -0
  41. package/dist/types.js +21 -0
  42. package/dist/types.js.map +1 -0
  43. package/package.json +60 -0
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @magnolia/skill-loader - Frontmatter Parser
3
+ *
4
+ * Parses skill files with YAML frontmatter into Skill objects.
5
+ */
6
+ import { Skill, SkillMetadata } from './types.js';
7
+ /**
8
+ * Parse a skill file content into a Skill object.
9
+ *
10
+ * @param content - The raw file content (with frontmatter)
11
+ * @param filename - Optional filename for deriving the skill name
12
+ * @returns Parsed Skill object
13
+ * @throws SkillLoaderError if parsing fails
14
+ */
15
+ export declare function parseSkillFile(content: string, filename?: string): Skill;
16
+ /**
17
+ * Create a skill programmatically.
18
+ *
19
+ * @param name - Unique identifier for the skill
20
+ * @param content - The prompt content
21
+ * @param metadata - Optional metadata for filtering
22
+ * @returns A Skill object
23
+ */
24
+ export declare function createSkill(name: string, content: string, metadata?: Partial<SkillMetadata>): Skill;
25
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,KAAK,EAAE,aAAa,EAAoB,MAAM,YAAY,CAAC;AAQpE;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,KAAK,CAoCxE;AA2DD;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAChC,KAAK,CAOP"}
package/dist/parser.js ADDED
@@ -0,0 +1,110 @@
1
+ /**
2
+ * @magnolia/skill-loader - Frontmatter Parser
3
+ *
4
+ * Parses skill files with YAML frontmatter into Skill objects.
5
+ */
6
+ import { parse as parseYaml } from 'yaml';
7
+ import { SkillLoaderError } from './types.js';
8
+ /**
9
+ * Regex to match YAML frontmatter at the start of a file.
10
+ * Matches content between --- delimiters.
11
+ */
12
+ const FRONTMATTER_REGEX = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
13
+ /**
14
+ * Parse a skill file content into a Skill object.
15
+ *
16
+ * @param content - The raw file content (with frontmatter)
17
+ * @param filename - Optional filename for deriving the skill name
18
+ * @returns Parsed Skill object
19
+ * @throws SkillLoaderError if parsing fails
20
+ */
21
+ export function parseSkillFile(content, filename) {
22
+ try {
23
+ const frontmatterMatch = content.match(FRONTMATTER_REGEX);
24
+ let metadata = {};
25
+ let skillContent;
26
+ if (frontmatterMatch) {
27
+ const frontmatterYaml = frontmatterMatch[1];
28
+ metadata = parseYaml(frontmatterYaml) || {};
29
+ skillContent = content.slice(frontmatterMatch[0].length).trim();
30
+ }
31
+ else {
32
+ // No frontmatter, entire content is the skill content
33
+ skillContent = content.trim();
34
+ }
35
+ // Normalize metadata
36
+ const normalizedMetadata = normalizeMetadata(metadata);
37
+ // Derive name from metadata or filename
38
+ const name = deriveName(normalizedMetadata, filename);
39
+ return {
40
+ name,
41
+ description: normalizedMetadata.description,
42
+ content: skillContent,
43
+ metadata: normalizedMetadata,
44
+ };
45
+ }
46
+ catch (error) {
47
+ throw new SkillLoaderError(`Failed to parse skill file${filename ? `: ${filename}` : ''}`, 'PARSE_ERROR', filename, error instanceof Error ? error : undefined);
48
+ }
49
+ }
50
+ /**
51
+ * Normalize metadata, handling legacy field names.
52
+ */
53
+ function normalizeMetadata(raw) {
54
+ const metadata = { ...raw };
55
+ // Support 'magnolia' as legacy field name for 'version'
56
+ if (metadata.magnolia && !metadata.version) {
57
+ metadata.version = String(metadata.magnolia);
58
+ }
59
+ // Ensure arrays are properly typed
60
+ if (metadata.targets && !Array.isArray(metadata.targets)) {
61
+ metadata.targets = [String(metadata.targets)];
62
+ }
63
+ if (metadata.tags && !Array.isArray(metadata.tags)) {
64
+ metadata.tags = [String(metadata.tags)];
65
+ }
66
+ if (metadata.requires && !Array.isArray(metadata.requires)) {
67
+ metadata.requires = [String(metadata.requires)];
68
+ }
69
+ // Ensure priority is a number
70
+ if (metadata.priority !== undefined) {
71
+ metadata.priority = Number(metadata.priority) || 0;
72
+ }
73
+ return metadata;
74
+ }
75
+ /**
76
+ * Derive the skill name from metadata or filename.
77
+ */
78
+ function deriveName(metadata, filename) {
79
+ // Use explicit name from metadata if provided
80
+ if (metadata.name && typeof metadata.name === 'string') {
81
+ return metadata.name;
82
+ }
83
+ // Derive from filename
84
+ if (filename) {
85
+ // Remove extension(s) like .prompt.md
86
+ return filename
87
+ .replace(/\.prompt\.md$/i, '')
88
+ .replace(/\.md$/i, '')
89
+ .replace(/\.[^.]+$/, '');
90
+ }
91
+ // Fallback to 'unnamed'
92
+ return 'unnamed';
93
+ }
94
+ /**
95
+ * Create a skill programmatically.
96
+ *
97
+ * @param name - Unique identifier for the skill
98
+ * @param content - The prompt content
99
+ * @param metadata - Optional metadata for filtering
100
+ * @returns A Skill object
101
+ */
102
+ export function createSkill(name, content, metadata) {
103
+ return {
104
+ name,
105
+ description: metadata?.description,
106
+ content: content.trim(),
107
+ metadata: normalizeMetadata(metadata || {}),
108
+ };
109
+ }
110
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @magnolia/skill-loader - Directory Source Loader
3
+ *
4
+ * Loads skills from a directory using glob patterns.
5
+ */
6
+ import { Skill } from '../types.js';
7
+ /** Default pattern for skill files (recursive to support subdirectories) */
8
+ export declare const DEFAULT_PATTERN = "**/*.prompt.md";
9
+ /**
10
+ * Load skills from a directory.
11
+ *
12
+ * @param dirPath - Path to the directory
13
+ * @param pattern - Glob pattern for matching files (default: '*.prompt.md')
14
+ * @returns Array of parsed Skills
15
+ * @throws SkillLoaderError if directory cannot be read
16
+ */
17
+ export declare function loadSkillsFromDirectory(dirPath: string, pattern?: string): Promise<Skill[]>;
18
+ //# sourceMappingURL=directory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directory.d.ts","sourceRoot":"","sources":["../../src/sources/directory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,KAAK,EAAoB,MAAM,aAAa,CAAC;AAGtD,4EAA4E;AAC5E,eAAO,MAAM,eAAe,mBAAmB,CAAC;AAEhD;;;;;;;GAOG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,MAAwB,GAChC,OAAO,CAAC,KAAK,EAAE,CAAC,CAkDlB"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * @magnolia/skill-loader - Directory Source Loader
3
+ *
4
+ * Loads skills from a directory using glob patterns.
5
+ */
6
+ import { glob } from 'glob';
7
+ import { join, isAbsolute } from 'node:path';
8
+ import { SkillLoaderError } from '../types.js';
9
+ import { loadSkillFromFile } from './file.js';
10
+ /** Default pattern for skill files (recursive to support subdirectories) */
11
+ export const DEFAULT_PATTERN = '**/*.prompt.md';
12
+ /**
13
+ * Load skills from a directory.
14
+ *
15
+ * @param dirPath - Path to the directory
16
+ * @param pattern - Glob pattern for matching files (default: '*.prompt.md')
17
+ * @returns Array of parsed Skills
18
+ * @throws SkillLoaderError if directory cannot be read
19
+ */
20
+ export async function loadSkillsFromDirectory(dirPath, pattern = DEFAULT_PATTERN) {
21
+ try {
22
+ // Construct the full glob pattern
23
+ const fullPattern = isAbsolute(pattern)
24
+ ? pattern
25
+ : join(dirPath, pattern);
26
+ // Find matching files
27
+ const files = await glob(fullPattern, {
28
+ nodir: true,
29
+ absolute: true,
30
+ });
31
+ // Load each file
32
+ const skills = [];
33
+ const errors = [];
34
+ for (const file of files) {
35
+ try {
36
+ const skill = await loadSkillFromFile(file);
37
+ skills.push(skill);
38
+ }
39
+ catch (error) {
40
+ // Collect errors but continue loading other files
41
+ errors.push(error instanceof Error ? error : new Error(String(error)));
42
+ }
43
+ }
44
+ // If all files failed to load, throw an error
45
+ if (errors.length > 0 && skills.length === 0) {
46
+ throw new SkillLoaderError(`Failed to load any skills from directory: ${dirPath}`, 'SOURCE_ERROR', dirPath, errors[0]);
47
+ }
48
+ return skills;
49
+ }
50
+ catch (error) {
51
+ if (error instanceof SkillLoaderError) {
52
+ throw error;
53
+ }
54
+ throw new SkillLoaderError(`Failed to read directory: ${dirPath}`, 'SOURCE_ERROR', dirPath, error instanceof Error ? error : undefined);
55
+ }
56
+ }
57
+ //# sourceMappingURL=directory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directory.js","sourceRoot":"","sources":["../../src/sources/directory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAS,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAE9C,4EAA4E;AAC5E,MAAM,CAAC,MAAM,eAAe,GAAG,gBAAgB,CAAC;AAEhD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,OAAe,EACf,UAAkB,eAAe;IAEjC,IAAI,CAAC;QACH,kCAAkC;QAClC,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,CAAC;YACrC,CAAC,CAAC,OAAO;YACT,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAE3B,sBAAsB;QACtB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE;YACpC,KAAK,EAAE,IAAI;YACX,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC;QAEH,iBAAiB;QACjB,MAAM,MAAM,GAAY,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAY,EAAE,CAAC;QAE3B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC;gBAC5C,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,kDAAkD;gBAClD,MAAM,CAAC,IAAI,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACzE,CAAC;QACH,CAAC;QAED,8CAA8C;QAC9C,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7C,MAAM,IAAI,gBAAgB,CACxB,6CAA6C,OAAO,EAAE,EACtD,cAAc,EACd,OAAO,EACP,MAAM,CAAC,CAAC,CAAC,CACV,CAAC;QACJ,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,gBAAgB,EAAE,CAAC;YACtC,MAAM,KAAK,CAAC;QACd,CAAC;QAED,MAAM,IAAI,gBAAgB,CACxB,6BAA6B,OAAO,EAAE,EACtC,cAAc,EACd,OAAO,EACP,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAC3C,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @magnolia/skill-loader - File Source Loader
3
+ *
4
+ * Loads a single skill from a file.
5
+ */
6
+ import { Skill } from '../types.js';
7
+ /**
8
+ * Load a single skill from a file.
9
+ *
10
+ * @param filePath - Path to the skill file
11
+ * @returns The parsed Skill
12
+ * @throws SkillLoaderError if file cannot be read or parsed
13
+ */
14
+ export declare function loadSkillFromFile(filePath: string): Promise<Skill>;
15
+ //# sourceMappingURL=file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../src/sources/file.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,KAAK,EAAoB,MAAM,aAAa,CAAC;AAGtD;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAiBxE"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @magnolia/skill-loader - File Source Loader
3
+ *
4
+ * Loads a single skill from a file.
5
+ */
6
+ import { readFile } from 'node:fs/promises';
7
+ import { basename } from 'node:path';
8
+ import { SkillLoaderError } from '../types.js';
9
+ import { parseSkillFile } from '../parser.js';
10
+ /**
11
+ * Load a single skill from a file.
12
+ *
13
+ * @param filePath - Path to the skill file
14
+ * @returns The parsed Skill
15
+ * @throws SkillLoaderError if file cannot be read or parsed
16
+ */
17
+ export async function loadSkillFromFile(filePath) {
18
+ try {
19
+ const content = await readFile(filePath, 'utf-8');
20
+ const filename = basename(filePath);
21
+ return parseSkillFile(content, filename);
22
+ }
23
+ catch (error) {
24
+ if (error instanceof SkillLoaderError) {
25
+ throw error;
26
+ }
27
+ throw new SkillLoaderError(`Failed to load skill file: ${filePath}`, 'SOURCE_ERROR', filePath, error instanceof Error ? error : undefined);
28
+ }
29
+ }
30
+ //# sourceMappingURL=file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.js","sourceRoot":"","sources":["../../src/sources/file.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAS,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,QAAgB;IACtD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAClD,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACpC,OAAO,cAAc,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC3C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,gBAAgB,EAAE,CAAC;YACtC,MAAM,KAAK,CAAC;QACd,CAAC;QAED,MAAM,IAAI,gBAAgB,CACxB,8BAA8B,QAAQ,EAAE,EACxC,cAAc,EACd,QAAQ,EACR,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAC3C,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @magnolia/skill-loader - Inline Source Handler
3
+ *
4
+ * Handles inline skill arrays (passthrough).
5
+ */
6
+ import { Skill } from '../types.js';
7
+ /**
8
+ * Process inline skills.
9
+ * This is essentially a passthrough but validates the skills array.
10
+ *
11
+ * @param skills - Array of skills
12
+ * @returns The same array of skills
13
+ */
14
+ export declare function processInlineSkills(skills: Skill[]): Skill[];
15
+ //# sourceMappingURL=inline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inline.d.ts","sourceRoot":"","sources":["../../src/sources/inline.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,CAS5D"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @magnolia/skill-loader - Inline Source Handler
3
+ *
4
+ * Handles inline skill arrays (passthrough).
5
+ */
6
+ /**
7
+ * Process inline skills.
8
+ * This is essentially a passthrough but validates the skills array.
9
+ *
10
+ * @param skills - Array of skills
11
+ * @returns The same array of skills
12
+ */
13
+ export function processInlineSkills(skills) {
14
+ // Validate that each item has required fields
15
+ return skills.filter((skill) => {
16
+ return (typeof skill.name === 'string' &&
17
+ skill.name.length > 0 &&
18
+ typeof skill.content === 'string');
19
+ });
20
+ }
21
+ //# sourceMappingURL=inline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inline.js","sourceRoot":"","sources":["../../src/sources/inline.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAe;IACjD,8CAA8C;IAC9C,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;QAC7B,OAAO,CACL,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;YAC9B,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;YACrB,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,CAClC,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @magnolia/skill-loader - URL Source Loader
3
+ *
4
+ * Loads skills from a remote URL (Phase 2 feature).
5
+ */
6
+ import { Skill } from '../types.js';
7
+ /**
8
+ * Load skills from a remote URL.
9
+ *
10
+ * The URL should return either:
11
+ * - A single skill file (markdown with frontmatter)
12
+ * - A JSON array of Skill objects
13
+ *
14
+ * @param url - URL to fetch skills from
15
+ * @param headers - Optional headers for the request
16
+ * @returns Array of parsed Skills
17
+ * @throws SkillLoaderError if fetch fails or response is invalid
18
+ */
19
+ export declare function loadSkillsFromUrl(url: string, headers?: Record<string, string>): Promise<Skill[]>;
20
+ //# sourceMappingURL=url.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url.d.ts","sourceRoot":"","sources":["../../src/sources/url.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,EAAoB,MAAM,aAAa,CAAC;AAGtD;;;;;;;;;;;GAWG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,OAAO,CAAC,KAAK,EAAE,CAAC,CAoElB"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * @magnolia/skill-loader - URL Source Loader
3
+ *
4
+ * Loads skills from a remote URL (Phase 2 feature).
5
+ */
6
+ import { SkillLoaderError } from '../types.js';
7
+ import { parseSkillFile } from '../parser.js';
8
+ /**
9
+ * Load skills from a remote URL.
10
+ *
11
+ * The URL should return either:
12
+ * - A single skill file (markdown with frontmatter)
13
+ * - A JSON array of Skill objects
14
+ *
15
+ * @param url - URL to fetch skills from
16
+ * @param headers - Optional headers for the request
17
+ * @returns Array of parsed Skills
18
+ * @throws SkillLoaderError if fetch fails or response is invalid
19
+ */
20
+ export async function loadSkillsFromUrl(url, headers) {
21
+ try {
22
+ const response = await fetch(url, {
23
+ headers: {
24
+ Accept: 'application/json, text/markdown, text/plain',
25
+ ...headers,
26
+ },
27
+ });
28
+ if (!response.ok) {
29
+ throw new SkillLoaderError(`Failed to fetch skills from URL: ${url} (${response.status})`, 'SOURCE_ERROR', url);
30
+ }
31
+ const contentType = response.headers.get('content-type') || '';
32
+ const text = await response.text();
33
+ // Try to parse as JSON first
34
+ if (contentType.includes('application/json')) {
35
+ try {
36
+ const data = JSON.parse(text);
37
+ // Could be an array of skills or a single skill
38
+ if (Array.isArray(data)) {
39
+ return data;
40
+ }
41
+ // Single skill object
42
+ if (data.name && data.content) {
43
+ return [data];
44
+ }
45
+ throw new SkillLoaderError(`Invalid JSON response from URL: ${url}`, 'PARSE_ERROR', url);
46
+ }
47
+ catch (error) {
48
+ if (error instanceof SkillLoaderError) {
49
+ throw error;
50
+ }
51
+ throw new SkillLoaderError(`Failed to parse JSON from URL: ${url}`, 'PARSE_ERROR', url, error instanceof Error ? error : undefined);
52
+ }
53
+ }
54
+ // Parse as markdown with frontmatter
55
+ const skill = parseSkillFile(text, url);
56
+ return [skill];
57
+ }
58
+ catch (error) {
59
+ if (error instanceof SkillLoaderError) {
60
+ throw error;
61
+ }
62
+ throw new SkillLoaderError(`Failed to load skills from URL: ${url}`, 'SOURCE_ERROR', url, error instanceof Error ? error : undefined);
63
+ }
64
+ }
65
+ //# sourceMappingURL=url.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url.js","sourceRoot":"","sources":["../../src/sources/url.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAS,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,GAAW,EACX,OAAgC;IAEhC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,OAAO,EAAE;gBACP,MAAM,EAAE,6CAA6C;gBACrD,GAAG,OAAO;aACX;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,gBAAgB,CACxB,oCAAoC,GAAG,KAAK,QAAQ,CAAC,MAAM,GAAG,EAC9D,cAAc,EACd,GAAG,CACJ,CAAC;QACJ,CAAC;QAED,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;QAC/D,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAEnC,6BAA6B;QAC7B,IAAI,WAAW,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;YAC7C,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAE9B,gDAAgD;gBAChD,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;oBACxB,OAAO,IAAe,CAAC;gBACzB,CAAC;gBAED,sBAAsB;gBACtB,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;oBAC9B,OAAO,CAAC,IAAa,CAAC,CAAC;gBACzB,CAAC;gBAED,MAAM,IAAI,gBAAgB,CACxB,mCAAmC,GAAG,EAAE,EACxC,aAAa,EACb,GAAG,CACJ,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,KAAK,YAAY,gBAAgB,EAAE,CAAC;oBACtC,MAAM,KAAK,CAAC;gBACd,CAAC;gBACD,MAAM,IAAI,gBAAgB,CACxB,kCAAkC,GAAG,EAAE,EACvC,aAAa,EACb,GAAG,EACH,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAC3C,CAAC;YACJ,CAAC;QACH,CAAC;QAED,qCAAqC;QACrC,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACxC,OAAO,CAAC,KAAK,CAAC,CAAC;IACjB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,gBAAgB,EAAE,CAAC;YACtC,MAAM,KAAK,CAAC;QACd,CAAC;QAED,MAAM,IAAI,gBAAgB,CACxB,mCAAmC,GAAG,EAAE,EACxC,cAAc,EACd,GAAG,EACH,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAC3C,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * @magnolia/skill-loader - Type Definitions
3
+ *
4
+ * This module defines all the core types for the skill-loader library.
5
+ */
6
+ /**
7
+ * Metadata for filtering and selecting skills.
8
+ */
9
+ export interface SkillMetadata {
10
+ /** Target platforms/frameworks this skill applies to */
11
+ targets?: string[];
12
+ /** Version constraint (semver range) */
13
+ version?: string;
14
+ /** Legacy field name for version (supports 'magnolia' during transition) */
15
+ magnolia?: string;
16
+ /** Tags for categorization and filtering */
17
+ tags?: string[];
18
+ /** Required field types - skill only included when these are detected */
19
+ requires?: string[];
20
+ /** Priority for ordering (higher = earlier in output) */
21
+ priority?: number;
22
+ /** Custom metadata (extensible) */
23
+ [key: string]: unknown;
24
+ }
25
+ /**
26
+ * A skill is a structured prompt with metadata for conditional inclusion.
27
+ */
28
+ export interface Skill {
29
+ /** Unique identifier for the skill */
30
+ name: string;
31
+ /** Human-readable description */
32
+ description?: string;
33
+ /** The prompt content (markdown, text, or structured) */
34
+ content: string;
35
+ /** Metadata for filtering and selection */
36
+ metadata: SkillMetadata;
37
+ }
38
+ /**
39
+ * The context provided when loading skills, used for filtering.
40
+ */
41
+ export interface SkillContext {
42
+ /** Target platform: 'freemarker', 'spa', 'react', 'vue', 'angular', etc. */
43
+ target?: string;
44
+ /** Product/platform version (e.g., '6.3.0') */
45
+ version?: string;
46
+ /** Detected field types in the current context */
47
+ detectedFieldTypes?: string[];
48
+ /** Tags to require (skills must have at least one) */
49
+ requiredTags?: string[];
50
+ /** Tags to exclude (skills with these tags are filtered out) */
51
+ excludedTags?: string[];
52
+ /** Custom context properties (matched against skill metadata) */
53
+ [key: string]: unknown;
54
+ }
55
+ /**
56
+ * Skill sources - where skills can be loaded from.
57
+ */
58
+ export type SkillSource = {
59
+ type: 'directory';
60
+ path: string;
61
+ pattern?: string;
62
+ } | {
63
+ type: 'file';
64
+ path: string;
65
+ } | {
66
+ type: 'inline';
67
+ skills: Skill[];
68
+ } | {
69
+ type: 'url';
70
+ url: string;
71
+ headers?: Record<string, string>;
72
+ } | {
73
+ type: 'custom';
74
+ loader: () => Promise<Skill[]>;
75
+ };
76
+ /**
77
+ * Options for the SkillLoader constructor.
78
+ */
79
+ export interface SkillLoaderOptions {
80
+ /** Custom filter function applied after standard filtering */
81
+ customFilter?: (skill: Skill, context: SkillContext) => boolean;
82
+ /** Custom sort function for ordering skills */
83
+ customSort?: (a: Skill, b: Skill) => number;
84
+ /** Cache TTL in milliseconds (default: 0 = no expiry) */
85
+ cacheTtl?: number;
86
+ /** File pattern for directory sources (default: '*.prompt.md') */
87
+ defaultPattern?: string;
88
+ }
89
+ /**
90
+ * Options for generating combined prompts from skills.
91
+ */
92
+ export interface PromptOptions {
93
+ /** Separator between skill contents (default: '\n\n---\n\n') */
94
+ separator?: string;
95
+ /** Include skill name as header (default: true) */
96
+ includeHeaders?: boolean;
97
+ /** Header format (default: '## {name}') */
98
+ headerFormat?: string;
99
+ /** Maximum total length (truncates if exceeded) */
100
+ maxLength?: number;
101
+ }
102
+ /**
103
+ * Error class for skill loader errors.
104
+ */
105
+ export declare class SkillLoaderError extends Error {
106
+ code: 'PARSE_ERROR' | 'SOURCE_ERROR' | 'FILTER_ERROR';
107
+ source?: string;
108
+ cause?: Error;
109
+ constructor(message: string, code: 'PARSE_ERROR' | 'SOURCE_ERROR' | 'FILTER_ERROR', source?: string, cause?: Error);
110
+ }
111
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @magnolia/skill-loader - Type Definitions
3
+ *
4
+ * This module defines all the core types for the skill-loader library.
5
+ */
6
+ /**
7
+ * Error class for skill loader errors.
8
+ */
9
+ export class SkillLoaderError extends Error {
10
+ code;
11
+ source;
12
+ cause;
13
+ constructor(message, code, source, cause) {
14
+ super(message);
15
+ this.name = 'SkillLoaderError';
16
+ this.code = code;
17
+ this.source = source;
18
+ this.cause = cause;
19
+ }
20
+ }
21
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAgHH;;GAEG;AACH,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACzC,IAAI,CAAkD;IACtD,MAAM,CAAU;IACP,KAAK,CAAS;IAEvB,YACE,OAAe,EACf,IAAqD,EACrD,MAAe,EACf,KAAa;QAEb,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;QAC/B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;CACF"}
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@magnolia/skill-loader",
3
+ "version": "0.1.0-preview.1",
4
+ "description": "A Node.js library for loading, filtering, and managing AI prompt skills",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "README.md",
17
+ "LICENSE.txt"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsc",
21
+ "dev": "tsc --watch",
22
+ "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
23
+ "test:watch": "node --experimental-vm-modules node_modules/jest/bin/jest.js --watch",
24
+ "lint": "eslint src tests",
25
+ "format": "prettier --check .",
26
+ "format:write": "prettier --write .",
27
+ "prepublishOnly": "npm run build && npm test"
28
+ },
29
+ "keywords": [
30
+ "magnolia",
31
+ "skills",
32
+ "prompts",
33
+ "ai",
34
+ "llm",
35
+ "mcp"
36
+ ],
37
+ "author": "Magnolia International Ltd.",
38
+ "license": "SEE LICENSE IN LICENSE.txt",
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "https://github.com/magnolia-cms/magnolia-mcp"
42
+ },
43
+ "engines": {
44
+ "node": ">=18"
45
+ },
46
+ "dependencies": {
47
+ "glob": "^11.0.0",
48
+ "semver": "^7.6.0",
49
+ "yaml": "^2.4.0"
50
+ },
51
+ "devDependencies": {
52
+ "@types/jest": "^29.5.12",
53
+ "@types/node": "^20.14.0",
54
+ "@types/semver": "^7.5.8",
55
+ "jest": "^29.7.0",
56
+ "prettier": "^3.3.0",
57
+ "ts-jest": "^29.1.4",
58
+ "typescript": "^5.4.5"
59
+ }
60
+ }