@elizaos/skills 2.0.0-beta.1 → 2.0.3-beta.2

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 (36) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +36 -11
  3. package/dist/formatter.d.ts +0 -18
  4. package/dist/formatter.d.ts.map +1 -1
  5. package/dist/formatter.js +4 -50
  6. package/dist/frontmatter.d.ts +0 -29
  7. package/dist/frontmatter.d.ts.map +1 -1
  8. package/dist/frontmatter.js +25 -56
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +0 -4
  11. package/dist/loader.d.ts +1 -1
  12. package/dist/loader.d.ts.map +1 -1
  13. package/dist/loader.js +6 -82
  14. package/dist/resolver.d.ts +0 -4
  15. package/dist/resolver.d.ts.map +1 -1
  16. package/dist/resolver.js +4 -26
  17. package/dist/types.d.ts +0 -121
  18. package/dist/types.d.ts.map +1 -1
  19. package/package.json +27 -9
  20. package/skills/build-monetized-app/SKILL.md +7 -7
  21. package/skills/build-monetized-app/references/sdk-flow.md +23 -25
  22. package/skills/build-monetized-app/references/survival-economics.md +1 -1
  23. package/skills/canvas/SKILL.md +2 -2
  24. package/skills/coding-agent/SKILL.md +10 -10
  25. package/skills/eliza-cloud/SKILL.md +15 -4
  26. package/skills/eliza-cloud/references/cloud-backend-and-monetization.md +27 -10
  27. package/skills/eliza-cloud/references/payments-and-promotion.md +72 -9
  28. package/skills/elizaos/SKILL.md +2 -2
  29. package/skills/elizaos/references/plugin-development.md +2 -2
  30. package/skills/ordercli/SKILL.md +2 -8
  31. package/skills/skill-creator/SKILL.md +4 -4
  32. package/skills/skill-creator/scripts/init_skill.py +11 -11
  33. package/skills/skill-creator/scripts/package_skill.py +1 -8
  34. package/skills/skill-creator/scripts/quick_validate.py +1 -3
  35. package/skills/spotify-player/SKILL.md +2 -2
  36. package/skills/weather/SKILL.md +2 -2
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Shaw Walters and elizaOS Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -49,7 +49,7 @@ const result = loadSkillsFromDir({
49
49
  import { formatSkillsForPrompt } from "@elizaos/skills";
50
50
 
51
51
  const prompt = formatSkillsForPrompt(skills);
52
- // Returns XML-formatted skills section for system prompt
52
+ // Returns a compact structured skills section for system prompt
53
53
  ```
54
54
 
55
55
  ### Build Command Specs
@@ -71,9 +71,10 @@ Alongside community-oriented skills, this package ships **`elizaos`**, **`eliza-
71
71
  Skills are loaded from multiple locations in precedence order (later overrides earlier):
72
72
 
73
73
  1. **Bundled skills** - Included in this package (`skills/`)
74
- 2. **Managed skills** - User-installed skills (`~/.elizaos/skills/`)
75
- 3. **Project skills** - Project-local skills (`<cwd>/.elizaos/skills/`)
76
- 4. **Explicit paths** - Via `skillPaths` option
74
+ 2. **Managed skills** - User-installed skills (`<stateDir>/skills/`)
75
+ 3. **Curated/active** - Human- or agent-promoted skills (`<stateDir>/skills/curated/active/`)
76
+ 4. **Project skills** - Project-local skills (`<cwd>/.elizaos/skills/`)
77
+ 5. **Explicit paths** - Via `skillPaths` option
77
78
 
78
79
  ## Skill Format
79
80
 
@@ -98,7 +99,7 @@ Detailed instructions for the AI agent...
98
99
 
99
100
  | Field | Type | Description |
100
101
  |-------|------|-------------|
101
- | `name` | string | Skill name (should match directory name) |
102
+ | `name` | string | Skill name (must match directory name) |
102
103
  | `description` | string | Human-readable description (required) |
103
104
  | `disable-model-invocation` | boolean | If true, skill won't appear in prompts |
104
105
  | `user-invocable` | boolean | If false, can't be invoked via commands |
@@ -106,6 +107,8 @@ Detailed instructions for the AI agent...
106
107
  | `required-os` | string[] | Required operating systems |
107
108
  | `required-bins` | string[] | Required binaries in PATH |
108
109
  | `required-env` | string[] | Required environment variables |
110
+ | `command-dispatch` | string | Set to `tool` to enable tool-dispatch in `buildSkillCommandSpecs` |
111
+ | `command-tool` | string | Tool name used when `command-dispatch: tool` |
109
112
 
110
113
  ## API Reference
111
114
 
@@ -114,17 +117,39 @@ Detailed instructions for the AI agent...
114
117
  - `Skill` - Loaded skill with metadata
115
118
  - `SkillFrontmatter` - Parsed frontmatter
116
119
  - `SkillEntry` - Full skill entry with all metadata
120
+ - `SkillMetadata` - Resolved metadata (env, bins, os)
121
+ - `SkillInvocationPolicy` - Resolved invocation flags
122
+ - `SkillCommandSpec` - Command spec for chat interfaces
123
+ - `SkillProvenance` - Provenance tracking for the learning loop
117
124
  - `LoadSkillsResult` - Result from loading skills
118
125
 
119
- ### Functions
126
+ ### Discovery / Resolution
120
127
 
121
128
  - `getSkillsDir()` - Get bundled skills path
129
+ - `clearSkillsDirCache()` - Reset bundled-dir resolution cache
130
+ - `getCuratedActiveDir()` - `<stateDir>/skills/curated/active/`
131
+ - `getProposedSkillsDir()` - `<stateDir>/skills/curated/proposed/`
132
+ - `promoteSkill(name)` - Move a proposed skill to active atomically
133
+
134
+ ### Loading
135
+
122
136
  - `loadSkills(options?)` - Load from all locations
123
137
  - `loadSkillsFromDir(options)` - Load from single directory
124
- - `loadSkillEntries(options?)` - Load with full metadata
125
- - `formatSkillsForPrompt(skills)` - Format for LLM prompt
126
- - `buildSkillCommandSpecs(entries)` - Build command specs
138
+ - `loadSkillEntries(options?)` - Load with full metadata parsed into `SkillEntry[]`
139
+
140
+ ### Formatting
141
+
142
+ - `formatSkillsForPrompt(skills)` - Format `Skill[]` for system prompt
143
+ - `formatSkillEntriesForPrompt(entries)` - Same but from `SkillEntry[]` (respects invocation policy)
144
+ - `formatSkillSummary(skill)` - Single `"name: description"` string
145
+ - `formatSkillsList(skills)` - Newline-joined list
146
+ - `buildSkillCommandSpecs(entries, reservedNames?)` - Build command specs
127
147
 
128
- ## License
148
+ ### Frontmatter
129
149
 
130
- MIT
150
+ - `parseFrontmatter(content)` - Parse YAML frontmatter from markdown string
151
+ - `stripFrontmatter(content)` - Return body without frontmatter
152
+ - `serializeSkillFile(frontmatter, body)` - Re-serialize frontmatter + body (learning loop)
153
+ - `resolveSkillMetadata(frontmatter)` - Resolve `SkillMetadata` from frontmatter
154
+ - `resolveSkillInvocationPolicy(frontmatter)` - Resolve `SkillInvocationPolicy`
155
+ - `resolveSkillProvenance(frontmatter)` - Resolve `SkillProvenance` (returns `undefined` if missing/malformed)
@@ -10,12 +10,6 @@ import type { Skill, SkillCommandSpec, SkillEntry } from "./types.js";
10
10
  * @returns Formatted skills prompt section
11
11
  */
12
12
  export declare function formatSkillsForPrompt(skills: Skill[]): string;
13
- /**
14
- * Format skill entries for prompt (filters by invocation policy)
15
- *
16
- * @param entries - Skill entries to format
17
- * @returns Formatted skills prompt section
18
- */
19
13
  export declare function formatSkillEntriesForPrompt(entries: SkillEntry[]): string;
20
14
  /**
21
15
  * Build command specifications from skill entries.
@@ -26,18 +20,6 @@ export declare function formatSkillEntriesForPrompt(entries: SkillEntry[]): stri
26
20
  * @returns Array of skill command specifications
27
21
  */
28
22
  export declare function buildSkillCommandSpecs(entries: SkillEntry[], reservedNames?: Set<string>): SkillCommandSpec[];
29
- /**
30
- * Format a single skill for display (minimal format)
31
- *
32
- * @param skill - Skill to format
33
- * @returns Formatted skill string
34
- */
35
23
  export declare function formatSkillSummary(skill: Skill): string;
36
- /**
37
- * Format skills as a simple list
38
- *
39
- * @param skills - Skills to format
40
- * @returns Newline-separated list of skills
41
- */
42
24
  export declare function formatSkillsList(skills: Skill[]): string;
43
25
  //# sourceMappingURL=formatter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"formatter.d.ts","sourceRoot":"","sources":["../src/formatter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAYtE;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAwB7D;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,MAAM,CAMzE;AA0DD;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,UAAU,EAAE,EACrB,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAC1B,gBAAgB,EAAE,CAgEpB;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAEvD;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAExD"}
1
+ {"version":3,"file":"formatter.d.ts","sourceRoot":"","sources":["../src/formatter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAMtE;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAwB7D;AAED,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,MAAM,CAMzE;AAsCD;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,UAAU,EAAE,EACrB,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAC1B,gBAAgB,EAAE,CA8DpB;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAEvD;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAExD"}
package/dist/formatter.js CHANGED
@@ -1,9 +1,3 @@
1
- /**
2
- * Compact a skill field for prompt-friendly structured text.
3
- *
4
- * @param str - String to compact
5
- * @returns Single-line prompt field
6
- */
7
1
  function compactPromptField(str) {
8
2
  return str.replace(/\s+/g, " ").trim();
9
3
  }
@@ -38,31 +32,15 @@ export function formatSkillsForPrompt(skills) {
38
32
  }
39
33
  return lines.join("\n");
40
34
  }
41
- /**
42
- * Format skill entries for prompt (filters by invocation policy)
43
- *
44
- * @param entries - Skill entries to format
45
- * @returns Formatted skills prompt section
46
- */
47
35
  export function formatSkillEntriesForPrompt(entries) {
48
36
  const visibleSkills = entries
49
37
  .filter((entry) => entry.invocation?.disableModelInvocation !== true)
50
38
  .map((entry) => entry.skill);
51
39
  return formatSkillsForPrompt(visibleSkills);
52
40
  }
53
- /** Maximum length for skill command names */
54
41
  const SKILL_COMMAND_MAX_LENGTH = 32;
55
- /** Fallback command name if sanitization produces empty string */
56
42
  const SKILL_COMMAND_FALLBACK = "skill";
57
- /** Maximum length for command descriptions (Discord limit) */
58
43
  const SKILL_COMMAND_DESCRIPTION_MAX_LENGTH = 100;
59
- /**
60
- * Sanitize a skill name for use as a command name.
61
- * Converts to lowercase, replaces invalid characters with underscores.
62
- *
63
- * @param raw - Raw skill name
64
- * @returns Sanitized command name
65
- */
66
44
  function sanitizeSkillCommandName(raw) {
67
45
  const clamped = raw.length > 1024 ? raw.slice(0, 1024) : raw;
68
46
  const normalized = clamped
@@ -73,19 +51,11 @@ function sanitizeSkillCommandName(raw) {
73
51
  const trimmed = normalized.slice(0, SKILL_COMMAND_MAX_LENGTH);
74
52
  return trimmed || SKILL_COMMAND_FALLBACK;
75
53
  }
76
- /**
77
- * Resolve a unique command name by appending a numeric suffix if needed.
78
- *
79
- * @param base - Base command name
80
- * @param used - Set of already-used command names (lowercase)
81
- * @returns Unique command name
82
- */
83
54
  function resolveUniqueSkillCommandName(base, used) {
84
- const normalizedBase = base.toLowerCase();
85
- if (!used.has(normalizedBase)) {
86
- return base;
87
- }
88
- for (let index = 2; index < 1000; index += 1) {
55
+ for (let index = 1;; index += 1) {
56
+ if (index === 1 && !used.has(base.toLowerCase())) {
57
+ return base;
58
+ }
89
59
  const suffix = `_${index}`;
90
60
  const maxBaseLength = Math.max(1, SKILL_COMMAND_MAX_LENGTH - suffix.length);
91
61
  const trimmedBase = base.slice(0, maxBaseLength);
@@ -95,8 +65,6 @@ function resolveUniqueSkillCommandName(base, used) {
95
65
  return candidate;
96
66
  }
97
67
  }
98
- const fallback = `${base.slice(0, Math.max(1, SKILL_COMMAND_MAX_LENGTH - 2))}_x`;
99
- return fallback;
100
68
  }
101
69
  /**
102
70
  * Build command specifications from skill entries.
@@ -107,7 +75,6 @@ function resolveUniqueSkillCommandName(base, used) {
107
75
  * @returns Array of skill command specifications
108
76
  */
109
77
  export function buildSkillCommandSpecs(entries, reservedNames) {
110
- // Filter to user-invocable skills
111
78
  const userInvocable = entries.filter((entry) => entry.invocation?.userInvocable !== false);
112
79
  const used = new Set();
113
80
  for (const reserved of reservedNames ?? []) {
@@ -123,7 +90,6 @@ export function buildSkillCommandSpecs(entries, reservedNames) {
123
90
  const description = rawDescription.length > SKILL_COMMAND_DESCRIPTION_MAX_LENGTH
124
91
  ? `${rawDescription.slice(0, SKILL_COMMAND_DESCRIPTION_MAX_LENGTH - 1)}…`
125
92
  : rawDescription;
126
- // Parse dispatch configuration from frontmatter
127
93
  const dispatch = (() => {
128
94
  const kindRaw = (entry.frontmatter?.["command-dispatch"] ??
129
95
  entry.frontmatter?.command_dispatch ??
@@ -153,21 +119,9 @@ export function buildSkillCommandSpecs(entries, reservedNames) {
153
119
  }
154
120
  return specs;
155
121
  }
156
- /**
157
- * Format a single skill for display (minimal format)
158
- *
159
- * @param skill - Skill to format
160
- * @returns Formatted skill string
161
- */
162
122
  export function formatSkillSummary(skill) {
163
123
  return `${skill.name}: ${skill.description}`;
164
124
  }
165
- /**
166
- * Format skills as a simple list
167
- *
168
- * @param skills - Skills to format
169
- * @returns Newline-separated list of skills
170
- */
171
125
  export function formatSkillsList(skills) {
172
126
  return skills.map(formatSkillSummary).join("\n");
173
127
  }
@@ -1,40 +1,11 @@
1
1
  import type { SkillFrontmatter, SkillInvocationPolicy, SkillMetadata, SkillProvenance } from "./types.js";
2
- /**
3
- * Result of parsing frontmatter from a file
4
- */
5
2
  export interface ParsedFrontmatter<T extends Record<string, unknown>> {
6
- /** Parsed frontmatter object */
7
3
  frontmatter: T;
8
- /** Remaining body content after frontmatter */
9
4
  body: string;
10
5
  }
11
- /**
12
- * Parse YAML frontmatter from markdown content
13
- *
14
- * @param content - Raw file content with optional YAML frontmatter
15
- * @returns Parsed frontmatter object and remaining body
16
- */
17
6
  export declare function parseFrontmatter<T extends Record<string, unknown> = Record<string, unknown>>(content: string): ParsedFrontmatter<T>;
18
- /**
19
- * Strip frontmatter from content and return only the body
20
- *
21
- * @param content - Raw file content with optional YAML frontmatter
22
- * @returns Content without frontmatter
23
- */
24
7
  export declare function stripFrontmatter(content: string): string;
25
- /**
26
- * Resolve skill metadata from skill frontmatter
27
- *
28
- * @param frontmatter - Parsed skill frontmatter
29
- * @returns Normalized metadata object
30
- */
31
8
  export declare function resolveSkillMetadata(frontmatter: SkillFrontmatter): SkillMetadata;
32
- /**
33
- * Resolve skill invocation policy from frontmatter
34
- *
35
- * @param frontmatter - Parsed skill frontmatter
36
- * @returns Invocation policy
37
- */
38
9
  export declare function resolveSkillInvocationPolicy(frontmatter: SkillFrontmatter): SkillInvocationPolicy;
39
10
  /**
40
11
  * Best-effort provenance parsing from a frontmatter block. Returns `undefined`
@@ -1 +1 @@
1
- {"version":3,"file":"frontmatter.d.ts","sourceRoot":"","sources":["../src/frontmatter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,gBAAgB,EAChB,qBAAqB,EACrB,aAAa,EACb,eAAe,EAChB,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,MAAM,WAAW,iBAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAClE,gCAAgC;IAChC,WAAW,EAAE,CAAC,CAAC;IACf,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;CACd;AAsCD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3D,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAOvC;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,gBAAgB,GAC5B,aAAa,CAmCf;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,WAAW,EAAE,gBAAgB,GAC5B,qBAAqB,CAmBvB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,gBAAgB,GAC5B,eAAe,GAAG,SAAS,CAuC7B;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,gBAAgB,EAC7B,IAAI,EAAE,MAAM,GACX,MAAM,CAIR"}
1
+ {"version":3,"file":"frontmatter.d.ts","sourceRoot":"","sources":["../src/frontmatter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,gBAAgB,EAChB,qBAAqB,EACrB,aAAa,EACb,eAAe,EAChB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,iBAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAClE,WAAW,EAAE,CAAC,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAkDD,wBAAgB,gBAAgB,CAC9B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3D,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAOvC;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,gBAAgB,GAC5B,aAAa,CAqCf;AAED,wBAAgB,4BAA4B,CAC1C,WAAW,EAAE,gBAAgB,GAC5B,qBAAqB,CAsBvB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,gBAAgB,GAC5B,eAAe,GAAG,SAAS,CAuC7B;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,gBAAgB,EAC7B,IAAI,EAAE,MAAM,GACX,MAAM,CAIR"}
@@ -1,17 +1,23 @@
1
1
  import { parse, stringify } from "yaml";
2
- /**
3
- * Normalize line endings to Unix-style LF
4
- */
5
2
  function normalizeNewlines(value) {
6
3
  return value.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
7
4
  }
8
5
  function isRecord(value) {
9
6
  return typeof value === "object" && value !== null && !Array.isArray(value);
10
7
  }
11
- /**
12
- * Extract YAML frontmatter block from content
13
- * Frontmatter must start with --- on the first line and end with --- on its own line
14
- */
8
+ function frontmatterValue(frontmatter, kebabKey, snakeKey) {
9
+ return frontmatter[kebabKey] ?? frontmatter[snakeKey];
10
+ }
11
+ function stringList(value, transform) {
12
+ if (!Array.isArray(value)) {
13
+ return undefined;
14
+ }
15
+ const out = value
16
+ .filter((item) => typeof item === "string")
17
+ .map(transform)
18
+ .filter((item) => item.length > 0);
19
+ return out.length > 0 ? out : undefined;
20
+ }
15
21
  function extractFrontmatter(content) {
16
22
  const normalized = normalizeNewlines(content);
17
23
  if (!normalized.startsWith("---")) {
@@ -26,12 +32,6 @@ function extractFrontmatter(content) {
26
32
  body: normalized.slice(endIndex + 4).trim(),
27
33
  };
28
34
  }
29
- /**
30
- * Parse YAML frontmatter from markdown content
31
- *
32
- * @param content - Raw file content with optional YAML frontmatter
33
- * @returns Parsed frontmatter object and remaining body
34
- */
35
35
  export function parseFrontmatter(content) {
36
36
  const { yamlString, body } = extractFrontmatter(content);
37
37
  if (!yamlString) {
@@ -40,67 +40,36 @@ export function parseFrontmatter(content) {
40
40
  const parsed = parse(yamlString);
41
41
  return { frontmatter: (parsed ?? {}), body };
42
42
  }
43
- /**
44
- * Strip frontmatter from content and return only the body
45
- *
46
- * @param content - Raw file content with optional YAML frontmatter
47
- * @returns Content without frontmatter
48
- */
49
43
  export function stripFrontmatter(content) {
50
44
  return parseFrontmatter(content).body;
51
45
  }
52
- /**
53
- * Resolve skill metadata from skill frontmatter
54
- *
55
- * @param frontmatter - Parsed skill frontmatter
56
- * @returns Normalized metadata object
57
- */
58
46
  export function resolveSkillMetadata(frontmatter) {
59
47
  const metadata = {};
60
- // Primary environment
61
- const primaryEnv = frontmatter["primary-env"] ?? frontmatter.primary_env;
48
+ const primaryEnv = frontmatterValue(frontmatter, "primary-env", "primary_env");
62
49
  if (typeof primaryEnv === "string" && primaryEnv.trim()) {
63
50
  metadata.primaryEnv = primaryEnv.trim();
64
51
  }
65
- // Required operating systems
66
- const requiredOs = frontmatter["required-os"] ?? frontmatter.required_os;
67
- if (Array.isArray(requiredOs)) {
68
- metadata.requiredOs = requiredOs
69
- .filter((os) => typeof os === "string")
70
- .map((os) => os.trim().toLowerCase());
52
+ const requiredOs = stringList(frontmatterValue(frontmatter, "required-os", "required_os"), (os) => os.trim().toLowerCase());
53
+ if (requiredOs) {
54
+ metadata.requiredOs = requiredOs;
71
55
  }
72
- // Required binaries
73
- const requiredBins = frontmatter["required-bins"] ?? frontmatter.required_bins;
74
- if (Array.isArray(requiredBins)) {
75
- metadata.requiredBins = requiredBins
76
- .filter((bin) => typeof bin === "string")
77
- .map((bin) => bin.trim());
56
+ const requiredBins = stringList(frontmatterValue(frontmatter, "required-bins", "required_bins"), (bin) => bin.trim());
57
+ if (requiredBins) {
58
+ metadata.requiredBins = requiredBins;
78
59
  }
79
- // Required environment variables
80
- const requiredEnv = frontmatter["required-env"] ?? frontmatter.required_env;
81
- if (Array.isArray(requiredEnv)) {
82
- metadata.requiredEnv = requiredEnv
83
- .filter((env) => typeof env === "string")
84
- .map((env) => env.trim());
60
+ const requiredEnv = stringList(frontmatterValue(frontmatter, "required-env", "required_env"), (env) => env.trim());
61
+ if (requiredEnv) {
62
+ metadata.requiredEnv = requiredEnv;
85
63
  }
86
64
  return metadata;
87
65
  }
88
- /**
89
- * Resolve skill invocation policy from frontmatter
90
- *
91
- * @param frontmatter - Parsed skill frontmatter
92
- * @returns Invocation policy
93
- */
94
66
  export function resolveSkillInvocationPolicy(frontmatter) {
95
67
  const policy = {};
96
- // Disable model invocation (snake_case and kebab-case)
97
- const disableModelInvocation = frontmatter["disable-model-invocation"] ??
98
- frontmatter.disable_model_invocation;
68
+ const disableModelInvocation = frontmatterValue(frontmatter, "disable-model-invocation", "disable_model_invocation");
99
69
  if (disableModelInvocation === true) {
100
70
  policy.disableModelInvocation = true;
101
71
  }
102
- // User invocable (snake_case and kebab-case)
103
- const userInvocable = frontmatter["user-invocable"] ?? frontmatter.user_invocable;
72
+ const userInvocable = frontmatterValue(frontmatter, "user-invocable", "user_invocable");
104
73
  if (userInvocable === false) {
105
74
  policy.userInvocable = false;
106
75
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,EACL,sBAAsB,EACtB,2BAA2B,EAC3B,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,KAAK,iBAAiB,EACtB,gBAAgB,EAChB,4BAA4B,EAC5B,oBAAoB,EACpB,sBAAsB,EACtB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAE9E,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,YAAY,GACb,MAAM,eAAe,CAAC;AAEvB,YAAY,EACV,wBAAwB,EACxB,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,EACL,qBAAqB,EACrB,gBAAgB,EAChB,eAAe,EACf,UAAU,EACV,gBAAgB,EAChB,qBAAqB,EACrB,aAAa,EACb,eAAe,EACf,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EACL,sBAAsB,EACtB,2BAA2B,EAC3B,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,KAAK,iBAAiB,EACtB,gBAAgB,EAChB,4BAA4B,EAC5B,oBAAoB,EACpB,sBAAsB,EACtB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,YAAY,GACb,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,wBAAwB,EACxB,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,EACL,qBAAqB,EACrB,gBAAgB,EAChB,eAAe,EACf,UAAU,EACV,gBAAgB,EAChB,qBAAqB,EACrB,aAAa,EACb,eAAe,EACf,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -21,11 +21,7 @@
21
21
  * const prompt = formatSkillsForPrompt(skills);
22
22
  * ```
23
23
  */
24
- // Prompt formatting
25
24
  export { buildSkillCommandSpecs, formatSkillEntriesForPrompt, formatSkillSummary, formatSkillsForPrompt, formatSkillsList, } from "./formatter.js";
26
- // Frontmatter parsing
27
25
  export { parseFrontmatter, resolveSkillInvocationPolicy, resolveSkillMetadata, resolveSkillProvenance, serializeSkillFile, stripFrontmatter, } from "./frontmatter.js";
28
- // Skill loading
29
26
  export { loadSkillEntries, loadSkills, loadSkillsFromDir } from "./loader.js";
30
- // Path resolution
31
27
  export { clearSkillsDirCache, getCuratedActiveDir, getProposedSkillsDir, getSkillsDir, promoteSkill, } from "./resolver.js";
package/dist/loader.d.ts CHANGED
@@ -15,7 +15,7 @@ export declare function loadSkillsFromDir(options: LoadSkillsFromDirOptions): Lo
15
15
  *
16
16
  * Sources are loaded in precedence order (later sources override earlier):
17
17
  * 1. Bundled skills (from this package)
18
- * 2. User/managed skills (~/.elizaos/skills)
18
+ * 2. User/managed skills (<stateDir>/skills)
19
19
  * 3. Project skills (<cwd>/.elizaos/skills)
20
20
  * 4. Explicit skill paths
21
21
  *
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EACV,wBAAwB,EACxB,iBAAiB,EACjB,gBAAgB,EAGhB,UAAU,EAEX,MAAM,YAAY,CAAC;AAqMpB;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,wBAAwB,GAChC,gBAAgB,CAGlB;AA8CD;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,OAAO,GAAE,iBAAsB,GAAG,gBAAgB,CA6H5E;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,GAAE,iBAAsB,GAC9B,UAAU,EAAE,CAuBd"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EACV,wBAAwB,EACxB,iBAAiB,EACjB,gBAAgB,EAGhB,UAAU,EAEX,MAAM,YAAY,CAAC;AA0JpB;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,wBAAwB,GAChC,gBAAgB,CAGlB;AA0BD;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,OAAO,GAAE,iBAAsB,GAAG,gBAAgB,CAkH5E;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,GAAE,iBAAsB,GAC9B,UAAU,EAAE,CAkBd"}