@skillbase/compiler 0.2.5 → 0.2.8

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/dist/index.cjs CHANGED
@@ -30,8 +30,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
+ SECTION_ORDER: () => SECTION_ORDER,
34
+ SECTION_TYPE_LABELS: () => SECTION_TYPE_LABELS,
33
35
  SkillParseError: () => SkillParseError,
34
36
  SoulParseError: () => SoulParseError,
37
+ autoFixSections: () => autoFixSections,
35
38
  buildLegacyBody: () => buildLegacyBody,
36
39
  canonicalToParsedSkill: () => canonicalToParsedSkill,
37
40
  canonicalToParsedSoul: () => canonicalToParsedSoul,
@@ -42,6 +45,7 @@ __export(index_exports, {
42
45
  getCompiler: () => getCompiler,
43
46
  getImporter: () => getImporter,
44
47
  importFromFormat: () => importFromFormat,
48
+ inferSectionType: () => inferSectionType,
45
49
  inferTags: () => inferTags,
46
50
  isVercelFormat: () => isVercelFormat,
47
51
  legacyPersonaToSoul: () => legacyPersonaToSoul,
@@ -49,12 +53,17 @@ __export(index_exports, {
49
53
  listTargets: () => listTargets,
50
54
  normalizeCanonical: () => normalizeCanonical,
51
55
  parseSkill: () => parseSkill,
56
+ parseSkillLenient: () => parseSkillLenient,
52
57
  parseSoul: () => parseSoul,
58
+ parseSoulLenient: () => parseSoulLenient,
53
59
  parsedSkillToCanonical: () => parsedSkillToCanonical,
54
60
  parsedSoulToCanonical: () => parsedSoulToCanonical,
61
+ reorderSections: () => reorderSections,
55
62
  resolveContextSlots: () => resolveContextSlots,
56
63
  serializeSkill: () => serializeSkill,
57
64
  serializeSoul: () => serializeSoul,
65
+ validateCanonicalOrder: () => validateCanonicalOrder,
66
+ validateSectionOrder: () => validateSectionOrder,
58
67
  validateSkillFrontmatter: () => validateSkillFrontmatter,
59
68
  validateSoulFrontmatter: () => validateSoulFrontmatter
60
69
  });
@@ -86,6 +95,91 @@ ${yamlStr}
86
95
  ${content}`;
87
96
  }
88
97
 
98
+ // src/section-order.ts
99
+ var SECTION_ORDER = {
100
+ context: 0,
101
+ instructions: 1,
102
+ guidelines: 2,
103
+ verification: 3,
104
+ examples: 4,
105
+ custom: 5
106
+ };
107
+ var SECTION_TYPE_LABELS = {
108
+ context: "Context",
109
+ instructions: "Instructions",
110
+ guidelines: "Guidelines",
111
+ verification: "Verification",
112
+ examples: "Examples",
113
+ custom: "Custom"
114
+ };
115
+ var TYPE_PATTERNS = [
116
+ {
117
+ type: "context",
118
+ keywords: /\b(context|background|overview|about|introduction|who you are|role|persona)\b/i
119
+ },
120
+ {
121
+ type: "examples",
122
+ keywords: /\b(example|sample|demo|few.?shot|illustration|showcase)\b/i
123
+ },
124
+ {
125
+ type: "guidelines",
126
+ keywords: /\b(guideline|style|convention|best.?practice|approach|principle|standard|rule|format|tone)\b/i
127
+ },
128
+ {
129
+ type: "verification",
130
+ keywords: /\b(verif|check|valid|review|self.?check|quality|assert|ensure|confirm|output.?requirement)\b/i
131
+ },
132
+ {
133
+ type: "instructions",
134
+ keywords: /\b(instruct|task|step|procedure|workflow|process|how to|implement|action|do)\b/i
135
+ }
136
+ ];
137
+ function inferSectionType(label) {
138
+ if (!label) return "instructions";
139
+ for (const { type, keywords } of TYPE_PATTERNS) {
140
+ if (keywords.test(label)) return type;
141
+ }
142
+ return "custom";
143
+ }
144
+ function validateSectionOrder(sections) {
145
+ if (sections.length <= 1) return [];
146
+ const reordered = reorderSections(sections);
147
+ const issues = [];
148
+ for (let i = 0; i < sections.length; i++) {
149
+ const current = sections[i];
150
+ const expectedIdx = reordered.indexOf(current);
151
+ if (expectedIdx !== i) {
152
+ const typeLabel = SECTION_TYPE_LABELS[current.type] ?? current.type;
153
+ issues.push({
154
+ index: i,
155
+ section: current,
156
+ expectedIndex: expectedIdx,
157
+ message: `"${current.label || typeLabel}" is at position ${i + 1}, expected ${expectedIdx + 1}`
158
+ });
159
+ }
160
+ }
161
+ return issues;
162
+ }
163
+ function reorderSections(sections) {
164
+ return [...sections].sort((a, b) => {
165
+ const orderA = SECTION_ORDER[a.type] ?? SECTION_ORDER.custom;
166
+ const orderB = SECTION_ORDER[b.type] ?? SECTION_ORDER.custom;
167
+ return orderA - orderB;
168
+ });
169
+ }
170
+ function autoFixSections(sections) {
171
+ const typed = sections.map((s) => {
172
+ if (s.type !== "custom") return s;
173
+ return { ...s, type: inferSectionType(s.label ?? "") };
174
+ });
175
+ return reorderSections(typed);
176
+ }
177
+ function validateCanonicalOrder(canonical) {
178
+ const sections = canonical.instructions.sections;
179
+ if (!sections || sections.length <= 1) return [];
180
+ return validateSectionOrder(sections);
181
+ }
182
+
89
183
  // src/parse/skill-parser.ts
90
184
  var REQUIRED_FIELDS = [
91
185
  "schema_version",
@@ -131,6 +225,38 @@ function parseSkill(content) {
131
225
  body: body.trim()
132
226
  };
133
227
  }
228
+ function parseSkillLenient(content, options) {
229
+ const { data, content: body } = parseFrontmatter(content);
230
+ const filledDefaults = [];
231
+ if (data.schema_version === void 0 || data.schema_version === "") {
232
+ data.schema_version = 3;
233
+ filledDefaults.push("schema_version");
234
+ }
235
+ if (!data.name) {
236
+ data.name = options?.dirName ? options.dirName.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "") || "imported-skill" : "imported-skill";
237
+ filledDefaults.push("name");
238
+ }
239
+ if (!data.version) {
240
+ data.version = "1.0.0";
241
+ filledDefaults.push("version");
242
+ }
243
+ if (!data.author) {
244
+ data.author = options?.defaultAuthor ?? "unknown";
245
+ filledDefaults.push("author");
246
+ }
247
+ if (!data.license) {
248
+ data.license = options?.defaultLicense ?? "MIT";
249
+ filledDefaults.push("license");
250
+ }
251
+ if (!data.description) {
252
+ data.description = "";
253
+ filledDefaults.push("description");
254
+ }
255
+ return {
256
+ parsed: { frontmatter: data, body: body.trim() },
257
+ filledDefaults
258
+ };
259
+ }
134
260
  function serializeSkill(skill) {
135
261
  return stringifyFrontmatter(skill.body, skill.frontmatter);
136
262
  }
@@ -159,16 +285,17 @@ function splitBodyIntoSections(body) {
159
285
  return { sections };
160
286
  }
161
287
  function normalizeCanonical(canonical) {
162
- const { content } = canonical.instructions;
163
- if (!content) return canonical;
164
- const { sections } = splitBodyIntoSections(content);
288
+ const flat = denormalizeCanonical(canonical);
289
+ const fullContent = flat.instructions.content;
290
+ if (!fullContent) return canonical;
291
+ const { sections } = splitBodyIntoSections(fullContent);
165
292
  if (sections.length === 0) return canonical;
166
293
  return {
167
294
  ...canonical,
168
295
  instructions: {
169
296
  content: "",
170
297
  sections: sections.map((s) => ({
171
- type: "custom",
298
+ type: inferSectionType(s.label),
172
299
  label: s.label,
173
300
  content: s.content
174
301
  }))
@@ -179,6 +306,9 @@ function denormalizeCanonical(canonical) {
179
306
  const sections = canonical.instructions.sections ?? [];
180
307
  if (sections.length === 0) return canonical;
181
308
  const parts = [];
309
+ if (canonical.instructions.content) {
310
+ parts.push(canonical.instructions.content);
311
+ }
182
312
  for (const s of sections) {
183
313
  if (s.label) {
184
314
  parts.push(`## ${s.label}
@@ -363,6 +493,34 @@ function parseSoul(content) {
363
493
  body: body.trim()
364
494
  };
365
495
  }
496
+ function parseSoulLenient(content, options) {
497
+ const { data, content: body } = parseFrontmatter(content);
498
+ const filledDefaults = [];
499
+ if (!data.name) {
500
+ data.name = options?.dirName ? options.dirName.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "") || "imported-persona" : "imported-persona";
501
+ filledDefaults.push("name");
502
+ }
503
+ if (!data.version) {
504
+ data.version = "1.0.0";
505
+ filledDefaults.push("version");
506
+ }
507
+ if (!data.author) {
508
+ data.author = options?.defaultAuthor ?? "unknown";
509
+ filledDefaults.push("author");
510
+ }
511
+ if (!data.license) {
512
+ data.license = options?.defaultLicense ?? "MIT";
513
+ filledDefaults.push("license");
514
+ }
515
+ if (!data.description) {
516
+ data.description = "";
517
+ filledDefaults.push("description");
518
+ }
519
+ return {
520
+ parsed: { frontmatter: data, body: body.trim() },
521
+ filledDefaults
522
+ };
523
+ }
366
524
  function serializeSoul(soul) {
367
525
  return stringifyFrontmatter(soul.body, soul.frontmatter);
368
526
  }
@@ -1279,7 +1437,21 @@ function buildFlatBody(canonical, options) {
1279
1437
  parts.push(`Tone: ${canonical.identity.tone}`, "");
1280
1438
  }
1281
1439
  }
1282
- parts.push(canonical.rawBody ?? canonical.instructions.content);
1440
+ const sections = canonical.instructions.sections;
1441
+ if (sections && sections.length > 0) {
1442
+ const sorted = reorderSections(sections);
1443
+ for (const s of sorted) {
1444
+ if (s.label) {
1445
+ parts.push(`## ${s.label}
1446
+
1447
+ ${s.content}`);
1448
+ } else if (s.content) {
1449
+ parts.push(s.content);
1450
+ }
1451
+ }
1452
+ } else {
1453
+ parts.push(canonical.rawBody ?? canonical.instructions.content);
1454
+ }
1283
1455
  if (canonical.constraints) {
1284
1456
  if (canonical.constraints.always && canonical.constraints.always.length > 0) {
1285
1457
  parts.push(
@@ -1319,7 +1491,7 @@ function buildBody(canonical) {
1319
1491
  if (canonical.instructions.content) {
1320
1492
  parts.push(canonical.instructions.content);
1321
1493
  }
1322
- const sections = canonical.instructions.sections ?? [];
1494
+ const sections = reorderSections(canonical.instructions.sections ?? []);
1323
1495
  for (const s of sections) {
1324
1496
  if (s.label || s.content) {
1325
1497
  if (s.label) {
@@ -1779,8 +1951,11 @@ function getCompiler(target) {
1779
1951
  }
1780
1952
  // Annotate the CommonJS export names for ESM import in node:
1781
1953
  0 && (module.exports = {
1954
+ SECTION_ORDER,
1955
+ SECTION_TYPE_LABELS,
1782
1956
  SkillParseError,
1783
1957
  SoulParseError,
1958
+ autoFixSections,
1784
1959
  buildLegacyBody,
1785
1960
  canonicalToParsedSkill,
1786
1961
  canonicalToParsedSoul,
@@ -1791,6 +1966,7 @@ function getCompiler(target) {
1791
1966
  getCompiler,
1792
1967
  getImporter,
1793
1968
  importFromFormat,
1969
+ inferSectionType,
1794
1970
  inferTags,
1795
1971
  isVercelFormat,
1796
1972
  legacyPersonaToSoul,
@@ -1798,12 +1974,17 @@ function getCompiler(target) {
1798
1974
  listTargets,
1799
1975
  normalizeCanonical,
1800
1976
  parseSkill,
1977
+ parseSkillLenient,
1801
1978
  parseSoul,
1979
+ parseSoulLenient,
1802
1980
  parsedSkillToCanonical,
1803
1981
  parsedSoulToCanonical,
1982
+ reorderSections,
1804
1983
  resolveContextSlots,
1805
1984
  serializeSkill,
1806
1985
  serializeSoul,
1986
+ validateCanonicalOrder,
1987
+ validateSectionOrder,
1807
1988
  validateSkillFrontmatter,
1808
1989
  validateSoulFrontmatter
1809
1990
  });