load-skills 0.1.0 → 0.2.0

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.
package/README.md CHANGED
@@ -26,12 +26,11 @@ const { skills, report } = await loadSkills({
26
26
 
27
27
  `skills` includes loaded skill payloads:
28
28
 
29
- - `meta`: parsed frontmatter object
29
+ - shape: `Record<string, Skill>` (keyed by skill name)
30
+ - `meta`: typed frontmatter object with required `name` and `description`
30
31
  - `content`: `SKILL.md` content without frontmatter
31
32
  - `references`: absolute file paths from `references/`
32
33
  - `scripts`: script descriptors from `scripts/` as `{ path, type }`
33
- - `state`: `"valid"` or `"invalid"`
34
- - `warnings`: warning objects with machine-readable `code`
35
34
 
36
35
  `report` includes one entry per configured path:
37
36
 
@@ -42,6 +41,7 @@ const { skills, report } = await loadSkills({
42
41
  - `skillNames`: included skill names from that path
43
42
  - `error` (optional): `path_not_found` or `path_not_directory`
44
43
  - `ignoredDuplicates`: map of skipped duplicate skills (first-find-wins), keyed by kept skill name
44
+ - `invalidSkills`: invalid skill entries moved out of `skills`; each item includes `warnings`
45
45
 
46
46
  ## Path Priority
47
47
 
@@ -49,6 +49,8 @@ const { skills, report } = await loadSkills({
49
49
 
50
50
  ## Warning codes
51
51
 
52
+ These warnings appear on `report.invalidSkills[*].warnings`.
53
+
52
54
  - `missing_frontmatter`: `SKILL.md` is missing a valid `--- ... ---` frontmatter block.
53
55
  - `invalid_yaml_frontmatter`: Frontmatter exists but YAML parsing failed or did not produce an object.
54
56
  - `missing_required_meta_name`: Frontmatter is missing required `name`.
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export { loadSkills } from "./loadSkills.js";
2
- export type { LoadedSkill, LoadSkillsConfig, IgnoredDuplicateSkill, LoadSkillsPathError, LoadSkillsPathReport, LoadSkillsReport, LoadSkillsResult, SkillScript, SkillScriptType, SkillState, SkillWarning, SkillWarningCode, } from "./types.js";
2
+ export type { IgnoredDuplicateSkill, InvalidSkill, LoadSkillsConfig, LoadSkillsPathError, LoadSkillsPathReport, LoadSkillsReport, LoadSkillsResult, Skill, SkillMeta, SkillScript, SkillScriptType, SkillWarning, SkillWarningCode, } from "./types.js";
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,YAAY,EACV,WAAW,EACX,gBAAgB,EAChB,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,eAAe,EACf,UAAU,EACV,YAAY,EACZ,gBAAgB,GACjB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,YAAY,EACV,qBAAqB,EACrB,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,KAAK,EACL,SAAS,EACT,WAAW,EACX,eAAe,EACf,YAAY,EACZ,gBAAgB,GACjB,MAAM,YAAY,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"loadSkills.d.ts","sourceRoot":"","sources":["../src/loadSkills.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAGV,gBAAgB,EAChB,gBAAgB,EAIjB,MAAM,YAAY,CAAC;AAOpB,wBAAsB,UAAU,CAC9B,MAAM,CAAC,EAAE,gBAAgB,GACxB,OAAO,CAAC,gBAAgB,CAAC,CAoG3B"}
1
+ {"version":3,"file":"loadSkills.d.ts","sourceRoot":"","sources":["../src/loadSkills.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAGV,gBAAgB,EAChB,gBAAgB,EAKjB,MAAM,YAAY,CAAC;AAOpB,wBAAsB,UAAU,CAC9B,MAAM,CAAC,EAAE,gBAAgB,GACxB,OAAO,CAAC,gBAAgB,CAAC,CAgH3B"}
@@ -8,7 +8,8 @@ import { applyValidationRules, validateLargeReferences, } from "./validateSkill.
8
8
  export async function loadSkills(config) {
9
9
  const resolvedConfig = config ?? {};
10
10
  const discovery = await discoverSkillFiles(resolvedConfig);
11
- const results = [];
11
+ const skills = {};
12
+ const invalidSkills = [];
12
13
  const reportPaths = discovery.report.map((entry) => ({ ...entry }));
13
14
  const ignoredDuplicates = {};
14
15
  const includedByName = new Map();
@@ -23,63 +24,74 @@ export async function loadSkills(config) {
23
24
  skillWarnings.push(...resourceScan.warnings);
24
25
  const largeReferenceWarnings = validateLargeReferences(resourceScan.referenceContents);
25
26
  skillWarnings.push(...largeReferenceWarnings);
26
- const skill = applyValidationRules({
27
+ const validated = applyValidationRules({
27
28
  meta: parsed.meta,
28
29
  content: parsed.content,
29
- references: resourceScan.references,
30
- scripts: resourceScan.scripts,
31
- state: "valid",
32
30
  warnings: skillWarnings,
33
- skillPath,
34
- skillFilePath,
35
31
  });
36
32
  const reportItem = reportPaths[discovered.pathReportIndex];
37
33
  if (!reportItem) {
38
34
  continue;
39
35
  }
40
- const resolvedName = typeof skill.meta.name === "string" && skill.meta.name.trim() !== ""
41
- ? skill.meta.name.trim()
42
- : path.basename(skill.skillPath);
43
- if (typeof skill.meta.name === "string" && skill.meta.name.trim() !== "") {
44
- const normalizedName = skill.meta.name.trim().toLowerCase();
45
- const existing = includedByName.get(normalizedName);
46
- if (existing) {
47
- const ignoredEntry = {
48
- skillName: resolvedName,
49
- normalizedSkillName: normalizedName,
50
- ignoredSkillPath: skill.skillPath,
51
- ignoredSkillFilePath: skill.skillFilePath,
52
- ignoredFromInputPath: discovered.inputPath,
53
- keptSkillPath: existing.skillPath,
54
- keptSkillFilePath: existing.skillFilePath,
55
- keptFromInputPath: existing.inputPath,
56
- };
57
- const key = existing.skillName;
58
- ignoredDuplicates[key] = [
59
- ...(ignoredDuplicates[key] ?? []),
60
- ignoredEntry,
61
- ];
62
- continue;
63
- }
64
- includedByName.set(normalizedName, {
65
- skillName: resolvedName,
66
- skillPath: skill.skillPath,
67
- skillFilePath: skill.skillFilePath,
68
- inputPath: discovered.inputPath,
36
+ if (!validated.isValid || !validated.meta) {
37
+ invalidSkills.push({
38
+ meta: parsed.meta,
39
+ content: parsed.content,
40
+ references: resourceScan.references,
41
+ scripts: resourceScan.scripts,
42
+ warnings: validated.warnings,
43
+ skillPath,
44
+ skillFilePath,
69
45
  });
46
+ continue;
47
+ }
48
+ const skill = {
49
+ meta: validated.meta,
50
+ content: parsed.content,
51
+ references: resourceScan.references,
52
+ scripts: resourceScan.scripts,
53
+ skillPath,
54
+ skillFilePath,
55
+ };
56
+ const normalizedName = skill.meta.name.trim().toLowerCase();
57
+ const existing = includedByName.get(normalizedName);
58
+ if (existing) {
59
+ const ignoredEntry = {
60
+ skillName: skill.meta.name,
61
+ normalizedSkillName: normalizedName,
62
+ ignoredSkillPath: skill.skillPath,
63
+ ignoredSkillFilePath: skill.skillFilePath,
64
+ ignoredFromInputPath: discovered.inputPath,
65
+ keptSkillPath: existing.skillPath,
66
+ keptSkillFilePath: existing.skillFilePath,
67
+ keptFromInputPath: existing.inputPath,
68
+ };
69
+ const key = existing.skillName;
70
+ ignoredDuplicates[key] = [
71
+ ...(ignoredDuplicates[key] ?? []),
72
+ ignoredEntry,
73
+ ];
74
+ continue;
70
75
  }
71
- results.push(skill);
72
- reportItem.skillNames.push(resolvedName);
76
+ includedByName.set(normalizedName, {
77
+ skillName: skill.meta.name,
78
+ skillPath: skill.skillPath,
79
+ skillFilePath: skill.skillFilePath,
80
+ inputPath: discovered.inputPath,
81
+ });
82
+ skills[skill.meta.name] = skill;
83
+ reportItem.skillNames.push(skill.meta.name);
73
84
  reportItem.count += 1;
74
85
  }
75
86
  for (const reportItem of reportPaths) {
76
87
  reportItem.skillNames.sort((a, b) => a.localeCompare(b));
77
88
  }
78
89
  return {
79
- skills: results,
90
+ skills,
80
91
  report: {
81
92
  paths: reportPaths,
82
93
  ignoredDuplicates,
94
+ invalidSkills,
83
95
  },
84
96
  };
85
97
  }
package/dist/types.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- export type SkillState = "valid" | "invalid";
2
1
  export type SkillScriptType = "javascript" | "typescript" | "python" | "shell" | "ruby" | "other";
3
2
  export type SkillWarningCode = "missing_frontmatter" | "invalid_yaml_frontmatter" | "missing_required_meta_name" | "missing_required_meta_description" | "invalid_meta_name" | "invalid_meta_description" | "skill_md_content_size_limit_exceeded" | "reference_large_without_toc" | "resource_read_error";
4
3
  export interface SkillWarning {
@@ -9,12 +8,23 @@ export interface SkillScript {
9
8
  path: string;
10
9
  type: SkillScriptType;
11
10
  }
12
- export interface LoadedSkill {
11
+ export type SkillMeta = Record<string, unknown> & {
12
+ name: string;
13
+ description: string;
14
+ };
15
+ export interface Skill {
16
+ meta: SkillMeta;
17
+ content: string;
18
+ references: string[];
19
+ scripts: SkillScript[];
20
+ skillPath: string;
21
+ skillFilePath: string;
22
+ }
23
+ export interface InvalidSkill {
13
24
  meta: Record<string, unknown>;
14
25
  content: string;
15
26
  references: string[];
16
27
  scripts: SkillScript[];
17
- state: SkillState;
18
28
  warnings: SkillWarning[];
19
29
  skillPath: string;
20
30
  skillFilePath: string;
@@ -45,9 +55,10 @@ export interface IgnoredDuplicateSkill {
45
55
  export interface LoadSkillsReport {
46
56
  paths: LoadSkillsPathReport[];
47
57
  ignoredDuplicates: Record<string, IgnoredDuplicateSkill[]>;
58
+ invalidSkills: InvalidSkill[];
48
59
  }
49
60
  export interface LoadSkillsResult {
50
- skills: LoadedSkill[];
61
+ skills: Record<string, Skill>;
51
62
  report: LoadSkillsReport;
52
63
  }
53
64
  export interface ParseSkillResult {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,SAAS,CAAC;AAE7C,MAAM,MAAM,eAAe,GACvB,YAAY,GACZ,YAAY,GACZ,QAAQ,GACR,OAAO,GACP,MAAM,GACN,OAAO,CAAC;AAEZ,MAAM,MAAM,gBAAgB,GACxB,qBAAqB,GACrB,0BAA0B,GAC1B,4BAA4B,GAC5B,mCAAmC,GACnC,mBAAmB,GACnB,0BAA0B,GAC1B,sCAAsC,GACtC,6BAA6B,GAC7B,qBAAqB,CAAC;AAE1B,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,gBAAgB,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,eAAe,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,KAAK,EAAE,UAAU,CAAC;IAClB,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,mBAAmB,GAAG,gBAAgB,GAAG,oBAAoB,CAAC;AAE1E,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,mBAAmB,CAAC;CAC7B;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,gBAAgB,EAAE,MAAM,CAAC;IACzB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,oBAAoB,EAAE,CAAC;IAC9B,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,EAAE,CAAC,CAAC;CAC5D;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GACvB,YAAY,GACZ,YAAY,GACZ,QAAQ,GACR,OAAO,GACP,MAAM,GACN,OAAO,CAAC;AAEZ,MAAM,MAAM,gBAAgB,GACxB,qBAAqB,GACrB,0BAA0B,GAC1B,4BAA4B,GAC5B,mCAAmC,GACnC,mBAAmB,GACnB,0BAA0B,GAC1B,sCAAsC,GACtC,6BAA6B,GAC7B,qBAAqB,CAAC;AAE1B,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,gBAAgB,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,eAAe,CAAC;CACvB;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,mBAAmB,GAAG,gBAAgB,GAAG,oBAAoB,CAAC;AAE1E,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,mBAAmB,CAAC;CAC7B;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,gBAAgB,EAAE,MAAM,CAAC;IACzB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,oBAAoB,EAAE,CAAC;IAC9B,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,EAAE,CAAC,CAAC;IAC3D,aAAa,EAAE,YAAY,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC9B,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B"}
@@ -1,5 +1,13 @@
1
- import type { LoadedSkill, SkillWarning } from "./types.js";
2
- export declare function applyValidationRules(skill: LoadedSkill): LoadedSkill;
1
+ import type { SkillMeta, SkillWarning } from "./types.js";
2
+ export declare function applyValidationRules(input: {
3
+ meta: Record<string, unknown>;
4
+ content: string;
5
+ warnings: SkillWarning[];
6
+ }): {
7
+ warnings: SkillWarning[];
8
+ isValid: boolean;
9
+ meta?: SkillMeta;
10
+ };
3
11
  export declare function validateLargeReferences(references: Array<{
4
12
  path: string;
5
13
  content: string;
@@ -1 +1 @@
1
- {"version":3,"file":"validateSkill.d.ts","sourceRoot":"","sources":["../src/validateSkill.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAc5D,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,WAAW,GAAG,WAAW,CA8CpE;AAED,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,GACtE,YAAY,EAAE,CAqBhB"}
1
+ {"version":3,"file":"validateSkill.d.ts","sourceRoot":"","sources":["../src/validateSkill.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAc1D,wBAAgB,oBAAoB,CAAC,KAAK,EAAE;IAC1C,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B,GAAG;IACF,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB,CAoDA;AAED,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,GACtE,YAAY,EAAE,CAqBhB"}
@@ -9,10 +9,10 @@ const INVALID_WARNING_CODES = new Set([
9
9
  "reference_large_without_toc",
10
10
  "resource_read_error",
11
11
  ]);
12
- export function applyValidationRules(skill) {
13
- const warnings = [...skill.warnings];
14
- const metaName = skill.meta.name;
15
- const metaDescription = skill.meta.description;
12
+ export function applyValidationRules(input) {
13
+ const warnings = [...input.warnings];
14
+ const metaName = input.meta.name;
15
+ const metaDescription = input.meta.description;
16
16
  if (typeof metaName !== "string" || metaName.trim() === "") {
17
17
  warnings.push({
18
18
  code: typeof metaName === "undefined"
@@ -29,20 +29,25 @@ export function applyValidationRules(skill) {
29
29
  message: "Frontmatter field `description` is required and must be a non-empty string.",
30
30
  });
31
31
  }
32
- const contentLineCount = getLineCount(skill.content);
32
+ const contentLineCount = getLineCount(input.content);
33
33
  if (contentLineCount > 500) {
34
34
  warnings.push({
35
35
  code: "skill_md_content_size_limit_exceeded",
36
36
  message: `SKILL.md body exceeds the recommended 500-line limit (${contentLineCount} lines).`,
37
37
  });
38
38
  }
39
- const state = warnings.some((warning) => INVALID_WARNING_CODES.has(warning.code))
40
- ? "invalid"
41
- : "valid";
39
+ const dedupedWarnings = dedupeWarnings(warnings);
40
+ const isValid = !dedupedWarnings.some((warning) => INVALID_WARNING_CODES.has(warning.code));
41
+ if (isValid) {
42
+ return {
43
+ warnings: dedupedWarnings,
44
+ isValid: true,
45
+ meta: input.meta,
46
+ };
47
+ }
42
48
  return {
43
- ...skill,
44
- warnings: dedupeWarnings(warnings),
45
- state,
49
+ warnings: dedupedWarnings,
50
+ isValid: false,
46
51
  };
47
52
  }
48
53
  export function validateLargeReferences(references) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "load-skills",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Load and validate agent skills from configurable paths.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",