@framers/agentos-skills 0.1.0 → 0.2.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.
- package/README.md +58 -46
- package/dist/SkillLoader.d.ts +50 -0
- package/dist/SkillLoader.d.ts.map +1 -0
- package/dist/SkillLoader.js +291 -0
- package/dist/SkillLoader.js.map +1 -0
- package/dist/SkillRegistry.d.ts +135 -0
- package/dist/SkillRegistry.d.ts.map +1 -0
- package/dist/SkillRegistry.js +455 -0
- package/dist/SkillRegistry.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/paths.d.ts +35 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +71 -0
- package/dist/paths.js.map +1 -0
- package/dist/types.d.ts +231 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +21 -0
- package/dist/types.js.map +1 -0
- package/package.json +34 -13
- package/registry/curated/1password/SKILL.md +0 -53
- package/registry/curated/apple-notes/SKILL.md +0 -45
- package/registry/curated/apple-reminders/SKILL.md +0 -46
- package/registry/curated/coding-agent/SKILL.md +0 -40
- package/registry/curated/discord-helper/SKILL.md +0 -43
- package/registry/curated/git/SKILL.md +0 -32
- package/registry/curated/github/SKILL.md +0 -54
- package/registry/curated/healthcheck/SKILL.md +0 -43
- package/registry/curated/image-gen/SKILL.md +0 -44
- package/registry/curated/notion/SKILL.md +0 -43
- package/registry/curated/obsidian/SKILL.md +0 -42
- package/registry/curated/slack-helper/SKILL.md +0 -42
- package/registry/curated/spotify-player/SKILL.md +0 -44
- package/registry/curated/summarize/SKILL.md +0 -40
- package/registry/curated/trello/SKILL.md +0 -43
- package/registry/curated/weather/SKILL.md +0 -37
- package/registry/curated/whisper-transcribe/SKILL.md +0 -58
- package/registry.json +0 -363
- package/types.d.ts +0 -76
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @framers/agentos-skills
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Skills runtime for the [AgentOS](https://github.com/framersai/agentos) ecosystem -- loads, parses, and manages SKILL.md prompt modules.
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@framers/agentos-skills)
|
|
6
6
|
|
|
@@ -10,69 +10,81 @@ npm install @framers/agentos-skills
|
|
|
10
10
|
|
|
11
11
|
## What's Inside
|
|
12
12
|
|
|
13
|
-
This package is
|
|
13
|
+
This package is the **runtime** for the AgentOS skills system. It provides:
|
|
14
14
|
|
|
15
|
-
|
|
|
16
|
-
|
|
|
17
|
-
| `
|
|
18
|
-
| `
|
|
19
|
-
| `
|
|
15
|
+
| Module | Description |
|
|
16
|
+
| ------------------- | ------------------------------------------------------------------------ |
|
|
17
|
+
| `SkillLoader` | Loads and parses SKILL.md files with YAML frontmatter |
|
|
18
|
+
| `SkillRegistry` | Runtime registry for managing, querying, and filtering loaded skills |
|
|
19
|
+
| `paths` | Path resolution utilities for discovering default skill directories |
|
|
20
|
+
| `types` | Full TypeScript type definitions for skills, metadata, and configuration |
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
## Usage
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
```typescript
|
|
25
|
+
import {
|
|
26
|
+
SkillRegistry,
|
|
27
|
+
loadSkillFromDir,
|
|
28
|
+
loadSkillsFromDir,
|
|
29
|
+
resolveDefaultSkillsDirs,
|
|
30
|
+
} from '@framers/agentos-skills';
|
|
24
31
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
| **Information** | weather, summarize |
|
|
28
|
-
| **Developer Tools** | github, coding-agent |
|
|
29
|
-
| **Communication** | slack-helper, discord-helper |
|
|
30
|
-
| **Productivity** | notion, obsidian, trello, apple-notes, apple-reminders |
|
|
31
|
-
| **DevOps** | healthcheck |
|
|
32
|
-
| **Media** | spotify-player, whisper-transcribe |
|
|
33
|
-
| **Security** | 1password |
|
|
34
|
-
| **Creative** | image-gen |
|
|
32
|
+
// Discover default skill directories
|
|
33
|
+
const dirs = resolveDefaultSkillsDirs();
|
|
35
34
|
|
|
36
|
-
|
|
35
|
+
// Create a registry and load skills
|
|
36
|
+
const registry = new SkillRegistry();
|
|
37
|
+
await registry.loadFromDirs(dirs);
|
|
37
38
|
|
|
38
|
-
|
|
39
|
+
console.log(`Loaded ${registry.size} skills`);
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
// Build a snapshot for LLM context
|
|
42
|
+
const snapshot = registry.buildSnapshot({ platform: 'darwin', strict: true });
|
|
43
|
+
console.log(snapshot.prompt);
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Relationship to Other Packages
|
|
42
47
|
|
|
43
|
-
|
|
44
|
-
|
|
48
|
+
```
|
|
49
|
+
@framers/agentos-skills <-- You are here (runtime: SkillLoader, SkillRegistry, types)
|
|
50
|
+
@framers/agentos-skills-registry (catalog: 40+ curated SKILL.md files + JSON index)
|
|
51
|
+
@framers/agentos (full cognitive runtime, re-exports skills from here)
|
|
45
52
|
```
|
|
46
53
|
|
|
47
|
-
|
|
54
|
+
| Package | What | Runtime Code | Dependencies |
|
|
55
|
+
| ------------------------------------ | ----------------------------------------- | :----------: | --------------- |
|
|
56
|
+
| **@framers/agentos-skills** | SkillLoader, SkillRegistry, path utils | Yes | `yaml` |
|
|
57
|
+
| **@framers/agentos-skills-registry** | 40+ SKILL.md files + JSON index + catalog | No | `yaml` |
|
|
58
|
+
| **@framers/agentos** | Full cognitive runtime | Yes | Many |
|
|
48
59
|
|
|
49
|
-
|
|
60
|
+
## API
|
|
50
61
|
|
|
51
|
-
|
|
52
|
-
npm install @framers/agentos-skills-registry
|
|
53
|
-
```
|
|
62
|
+
### SkillLoader
|
|
54
63
|
|
|
55
|
-
|
|
56
|
-
|
|
64
|
+
- `parseSkillFrontmatter(content)` -- Parse YAML frontmatter from SKILL.md content
|
|
65
|
+
- `extractMetadata(frontmatter)` -- Extract typed SkillMetadata from parsed frontmatter
|
|
66
|
+
- `loadSkillFromDir(dir)` -- Load a single skill from a directory containing SKILL.md
|
|
67
|
+
- `loadSkillsFromDir(dir)` -- Load all skills from a parent directory
|
|
68
|
+
- `filterByPlatform(entries, platform)` -- Filter skill entries by OS platform
|
|
69
|
+
- `filterByEligibility(entries, context)` -- Filter by full eligibility context
|
|
70
|
+
- `checkBinaryRequirements(entry, hasBin)` -- Check if binary requirements are met
|
|
57
71
|
|
|
58
|
-
|
|
59
|
-
const matches = searchSkills('github');
|
|
60
|
-
```
|
|
72
|
+
### SkillRegistry
|
|
61
73
|
|
|
62
|
-
|
|
74
|
+
- `register(entry)` / `unregister(name)` -- Add/remove skills
|
|
75
|
+
- `loadFromDir(dir)` / `loadFromDirs(dirs)` / `reload(options)` -- Bulk loading
|
|
76
|
+
- `getByName(name)` / `listAll()` / `has(name)` / `size` -- Queries
|
|
77
|
+
- `filterByPlatform(platform)` / `filterByEligibility(context)` -- Filtering
|
|
78
|
+
- `getUserInvocableSkills()` / `getModelInvocableSkills()` -- Invocation filtering
|
|
79
|
+
- `buildSnapshot(options)` -- Build LLM context snapshot
|
|
80
|
+
- `buildPrompt(entries)` -- Format skills into prompt text
|
|
81
|
+
- `buildCommandSpecs(options)` -- Generate CLI command specs
|
|
63
82
|
|
|
64
|
-
|
|
65
|
-
@framers/agentos-skills ← You are here (data: SKILL.md files + JSON index)
|
|
66
|
-
└── @framers/agentos-skills-registry (SDK: typed catalog, query helpers, registry factories)
|
|
67
|
-
└── @framers/agentos (optional peer: live SkillRegistry + snapshots)
|
|
68
|
-
```
|
|
83
|
+
### Path Utilities
|
|
69
84
|
|
|
70
|
-
|
|
71
|
-
| ------------------------------------ | ----------------------------------------- | :----------: | -------------------------------------- |
|
|
72
|
-
| **@framers/agentos-skills** | Raw SKILL.md files + JSON index | No | Zero |
|
|
73
|
-
| **@framers/agentos-skills-registry** | Typed catalog + query helpers + factories | Yes | `agentos-skills`, optionally `agentos` |
|
|
74
|
-
| **@framers/agentos** | Full cognitive runtime with SkillRegistry | Yes | Many |
|
|
85
|
+
- `resolveDefaultSkillsDirs(options)` -- Resolve default skill directories to scan
|
|
75
86
|
|
|
76
87
|
## License
|
|
77
88
|
|
|
78
89
|
MIT
|
|
90
|
+
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Skill Loader for AgentOS
|
|
3
|
+
* @module @framers/agentos-skills/SkillLoader
|
|
4
|
+
*
|
|
5
|
+
* Loads skills from directories by parsing SKILL.md files with YAML frontmatter.
|
|
6
|
+
* Skills are modular capabilities that extend agent functionality.
|
|
7
|
+
*/
|
|
8
|
+
import type { SkillEntry, SkillMetadata, SkillEligibilityContext, ParsedSkillFrontmatter } from './types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Parse YAML frontmatter from SKILL.md content.
|
|
11
|
+
* Supports the standard `---` delimited format.
|
|
12
|
+
*/
|
|
13
|
+
export declare function parseSkillFrontmatter(content: string): {
|
|
14
|
+
frontmatter: ParsedSkillFrontmatter;
|
|
15
|
+
body: string;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Extract SkillMetadata from parsed frontmatter.
|
|
19
|
+
*/
|
|
20
|
+
export declare function extractMetadata(frontmatter: ParsedSkillFrontmatter): SkillMetadata | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* Load a single skill from a directory.
|
|
23
|
+
*
|
|
24
|
+
* @param skillDir - Path to skill directory (should contain SKILL.md)
|
|
25
|
+
* @returns SkillEntry or null if invalid
|
|
26
|
+
*/
|
|
27
|
+
export declare function loadSkillFromDir(skillDir: string): Promise<SkillEntry | null>;
|
|
28
|
+
/**
|
|
29
|
+
* Load all skills from a directory.
|
|
30
|
+
*
|
|
31
|
+
* @param dir - Parent directory containing skill subdirectories
|
|
32
|
+
* @returns Array of SkillEntry objects
|
|
33
|
+
*/
|
|
34
|
+
export declare function loadSkillsFromDir(dir: string): Promise<SkillEntry[]>;
|
|
35
|
+
/**
|
|
36
|
+
* Filter skill entries by platform.
|
|
37
|
+
*/
|
|
38
|
+
export declare function filterByPlatform(entries: SkillEntry[], platform: string): SkillEntry[];
|
|
39
|
+
/**
|
|
40
|
+
* Filter skill entries by eligibility context.
|
|
41
|
+
*/
|
|
42
|
+
export declare function filterByEligibility(entries: SkillEntry[], context: SkillEligibilityContext): SkillEntry[];
|
|
43
|
+
/**
|
|
44
|
+
* Check if all binary requirements for a skill are met.
|
|
45
|
+
*/
|
|
46
|
+
export declare function checkBinaryRequirements(entry: SkillEntry, hasBin: (bin: string) => boolean): {
|
|
47
|
+
met: boolean;
|
|
48
|
+
missing: string[];
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=SkillLoader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SkillLoader.d.ts","sourceRoot":"","sources":["../src/SkillLoader.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,KAAK,EAEV,UAAU,EACV,aAAa,EACb,uBAAuB,EACvB,sBAAsB,EAEvB,MAAM,YAAY,CAAC;AAQpB;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG;IACtD,WAAW,EAAE,sBAAsB,CAAC;IACpC,IAAI,EAAE,MAAM,CAAC;CACd,CAkCA;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,sBAAsB,GAAG,aAAa,GAAG,SAAS,CAoC9F;AAiED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAyCnF;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAuB1E;AAMD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,EAAE,CAStF;AAaD;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,UAAU,EAAE,EACrB,OAAO,EAAE,uBAAuB,GAC/B,UAAU,EAAE,CA+Bd;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,GAC/B;IAAE,GAAG,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAgBrC"}
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Skill Loader for AgentOS
|
|
3
|
+
* @module @framers/agentos-skills/SkillLoader
|
|
4
|
+
*
|
|
5
|
+
* Loads skills from directories by parsing SKILL.md files with YAML frontmatter.
|
|
6
|
+
* Skills are modular capabilities that extend agent functionality.
|
|
7
|
+
*/
|
|
8
|
+
import * as fs from 'fs';
|
|
9
|
+
import * as path from 'path';
|
|
10
|
+
import YAML from 'yaml';
|
|
11
|
+
const fsp = fs.promises;
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// FRONTMATTER PARSING
|
|
14
|
+
// ============================================================================
|
|
15
|
+
/**
|
|
16
|
+
* Parse YAML frontmatter from SKILL.md content.
|
|
17
|
+
* Supports the standard `---` delimited format.
|
|
18
|
+
*/
|
|
19
|
+
export function parseSkillFrontmatter(content) {
|
|
20
|
+
const normalized = content.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
21
|
+
const lines = normalized.split('\n');
|
|
22
|
+
// Check for frontmatter start
|
|
23
|
+
if (lines[0]?.trim() !== '---') {
|
|
24
|
+
return { frontmatter: {}, body: normalized.trim() };
|
|
25
|
+
}
|
|
26
|
+
// Find frontmatter end
|
|
27
|
+
let endIndex = -1;
|
|
28
|
+
for (let i = 1; i < lines.length; i++) {
|
|
29
|
+
if (lines[i]?.trim() === '---') {
|
|
30
|
+
endIndex = i;
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (endIndex === -1) {
|
|
35
|
+
return { frontmatter: {}, body: normalized.trim() };
|
|
36
|
+
}
|
|
37
|
+
const frontmatterBlock = lines.slice(1, endIndex).join('\n');
|
|
38
|
+
const body = lines.slice(endIndex + 1).join('\n').trim();
|
|
39
|
+
try {
|
|
40
|
+
const parsed = YAML.parse(frontmatterBlock);
|
|
41
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
42
|
+
return { frontmatter: {}, body };
|
|
43
|
+
}
|
|
44
|
+
return { frontmatter: parsed, body };
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return { frontmatter: {}, body };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Extract SkillMetadata from parsed frontmatter.
|
|
52
|
+
*/
|
|
53
|
+
export function extractMetadata(frontmatter) {
|
|
54
|
+
const metadataValue = frontmatter.metadata;
|
|
55
|
+
let meta = undefined;
|
|
56
|
+
if (metadataValue && typeof metadataValue === 'object') {
|
|
57
|
+
const mObj = metadataValue;
|
|
58
|
+
meta = mObj.openclaw ?? mObj.wunderland ?? mObj.agentos ?? mObj;
|
|
59
|
+
}
|
|
60
|
+
else if (typeof metadataValue === 'string' && metadataValue.trim()) {
|
|
61
|
+
// Support OpenClaw-style metadata serialization (JSON-ish string in YAML).
|
|
62
|
+
try {
|
|
63
|
+
meta = JSON.parse(metadataValue);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
meta = undefined;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (!meta) {
|
|
70
|
+
meta = frontmatter;
|
|
71
|
+
}
|
|
72
|
+
if (!meta || typeof meta !== 'object') {
|
|
73
|
+
return undefined;
|
|
74
|
+
}
|
|
75
|
+
const m = meta;
|
|
76
|
+
return {
|
|
77
|
+
always: m.always === true,
|
|
78
|
+
skillKey: typeof m.skillKey === 'string' ? m.skillKey : undefined,
|
|
79
|
+
primaryEnv: typeof m.primaryEnv === 'string' ? m.primaryEnv : undefined,
|
|
80
|
+
emoji: typeof m.emoji === 'string' ? m.emoji : undefined,
|
|
81
|
+
homepage: typeof m.homepage === 'string' ? m.homepage : undefined,
|
|
82
|
+
os: Array.isArray(m.os) ? m.os : undefined,
|
|
83
|
+
requires: m.requires,
|
|
84
|
+
install: Array.isArray(m.install) ? m.install : undefined,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Extract skill description from body content.
|
|
89
|
+
*/
|
|
90
|
+
function extractDescription(body) {
|
|
91
|
+
// Skip markdown title and get first paragraph
|
|
92
|
+
const lines = body.split('\n');
|
|
93
|
+
let inParagraph = false;
|
|
94
|
+
const paragraphLines = [];
|
|
95
|
+
for (const line of lines) {
|
|
96
|
+
const trimmed = line.trim();
|
|
97
|
+
// Skip headings
|
|
98
|
+
if (trimmed.startsWith('#')) {
|
|
99
|
+
if (inParagraph)
|
|
100
|
+
break;
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
// Skip empty lines before paragraph
|
|
104
|
+
if (!trimmed && !inParagraph) {
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
// Empty line ends paragraph
|
|
108
|
+
if (!trimmed && inParagraph) {
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
inParagraph = true;
|
|
112
|
+
paragraphLines.push(trimmed);
|
|
113
|
+
}
|
|
114
|
+
return paragraphLines.join(' ').slice(0, 200);
|
|
115
|
+
}
|
|
116
|
+
function coerceBoolean(value) {
|
|
117
|
+
if (typeof value === 'boolean')
|
|
118
|
+
return value;
|
|
119
|
+
if (typeof value === 'string') {
|
|
120
|
+
const lowered = value.trim().toLowerCase();
|
|
121
|
+
if (lowered === 'true')
|
|
122
|
+
return true;
|
|
123
|
+
if (lowered === 'false')
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
return undefined;
|
|
127
|
+
}
|
|
128
|
+
function resolveSkillInvocationPolicy(frontmatter) {
|
|
129
|
+
const userInvocable = coerceBoolean(frontmatter['user-invocable']) ??
|
|
130
|
+
coerceBoolean(frontmatter.userInvocable) ??
|
|
131
|
+
true;
|
|
132
|
+
const disableModelInvocation = coerceBoolean(frontmatter['disable-model-invocation']) ??
|
|
133
|
+
coerceBoolean(frontmatter.disableModelInvocation) ??
|
|
134
|
+
false;
|
|
135
|
+
return { userInvocable, disableModelInvocation };
|
|
136
|
+
}
|
|
137
|
+
// ============================================================================
|
|
138
|
+
// SKILL LOADING
|
|
139
|
+
// ============================================================================
|
|
140
|
+
/**
|
|
141
|
+
* Load a single skill from a directory.
|
|
142
|
+
*
|
|
143
|
+
* @param skillDir - Path to skill directory (should contain SKILL.md)
|
|
144
|
+
* @returns SkillEntry or null if invalid
|
|
145
|
+
*/
|
|
146
|
+
export async function loadSkillFromDir(skillDir) {
|
|
147
|
+
const skillPath = path.join(skillDir, 'SKILL.md');
|
|
148
|
+
try {
|
|
149
|
+
const stat = await fsp.stat(skillPath);
|
|
150
|
+
if (!stat.isFile()) {
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
const content = await fsp.readFile(skillPath, 'utf-8');
|
|
154
|
+
const { frontmatter, body } = parseSkillFrontmatter(content);
|
|
155
|
+
const name = (typeof frontmatter.name === 'string' && frontmatter.name.trim())
|
|
156
|
+
? frontmatter.name.trim()
|
|
157
|
+
: path.basename(skillDir);
|
|
158
|
+
const description = (typeof frontmatter.description === 'string' && frontmatter.description.trim())
|
|
159
|
+
? frontmatter.description.trim()
|
|
160
|
+
: extractDescription(body);
|
|
161
|
+
const skill = {
|
|
162
|
+
name,
|
|
163
|
+
description,
|
|
164
|
+
content: body,
|
|
165
|
+
};
|
|
166
|
+
const metadata = extractMetadata(frontmatter);
|
|
167
|
+
const invocation = resolveSkillInvocationPolicy(frontmatter);
|
|
168
|
+
return {
|
|
169
|
+
skill,
|
|
170
|
+
frontmatter,
|
|
171
|
+
metadata,
|
|
172
|
+
invocation,
|
|
173
|
+
sourcePath: skillDir,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
// Skill doesn't exist or is invalid
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Load all skills from a directory.
|
|
183
|
+
*
|
|
184
|
+
* @param dir - Parent directory containing skill subdirectories
|
|
185
|
+
* @returns Array of SkillEntry objects
|
|
186
|
+
*/
|
|
187
|
+
export async function loadSkillsFromDir(dir) {
|
|
188
|
+
const entries = [];
|
|
189
|
+
try {
|
|
190
|
+
const items = await fsp.readdir(dir, { withFileTypes: true });
|
|
191
|
+
for (const item of items) {
|
|
192
|
+
if (!item.isDirectory())
|
|
193
|
+
continue;
|
|
194
|
+
if (item.name.startsWith('.'))
|
|
195
|
+
continue;
|
|
196
|
+
const skillDir = path.join(dir, item.name);
|
|
197
|
+
const entry = await loadSkillFromDir(skillDir);
|
|
198
|
+
if (entry) {
|
|
199
|
+
entries.push(entry);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
catch (err) {
|
|
204
|
+
// Directory doesn't exist or is inaccessible
|
|
205
|
+
console.warn(`[SkillLoader] Failed to load skills from ${dir}:`, err);
|
|
206
|
+
}
|
|
207
|
+
return entries;
|
|
208
|
+
}
|
|
209
|
+
// ============================================================================
|
|
210
|
+
// FILTERING
|
|
211
|
+
// ============================================================================
|
|
212
|
+
/**
|
|
213
|
+
* Filter skill entries by platform.
|
|
214
|
+
*/
|
|
215
|
+
export function filterByPlatform(entries, platform) {
|
|
216
|
+
return entries.filter((entry) => {
|
|
217
|
+
const os = entry.metadata?.os;
|
|
218
|
+
if (!os || os.length === 0)
|
|
219
|
+
return true;
|
|
220
|
+
// Normalize platform names
|
|
221
|
+
const normalizedPlatform = normalizeOSName(platform);
|
|
222
|
+
return os.some((p) => normalizeOSName(p) === normalizedPlatform);
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Normalize OS name for comparison.
|
|
227
|
+
*/
|
|
228
|
+
function normalizeOSName(name) {
|
|
229
|
+
const lower = name.toLowerCase();
|
|
230
|
+
if (lower === 'darwin' || lower === 'macos' || lower === 'mac')
|
|
231
|
+
return 'darwin';
|
|
232
|
+
if (lower === 'win32' || lower === 'windows')
|
|
233
|
+
return 'win32';
|
|
234
|
+
if (lower === 'linux')
|
|
235
|
+
return 'linux';
|
|
236
|
+
return lower;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Filter skill entries by eligibility context.
|
|
240
|
+
*/
|
|
241
|
+
export function filterByEligibility(entries, context) {
|
|
242
|
+
return entries.filter((entry) => {
|
|
243
|
+
const requires = entry.metadata?.requires;
|
|
244
|
+
if (!requires)
|
|
245
|
+
return true;
|
|
246
|
+
// Check required binaries
|
|
247
|
+
if (requires.bins && requires.bins.length > 0) {
|
|
248
|
+
const allBins = requires.bins.every((bin) => context.hasBin(bin));
|
|
249
|
+
if (!allBins)
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
// Check any-of binaries
|
|
253
|
+
if (requires.anyBins && requires.anyBins.length > 0) {
|
|
254
|
+
const anyBin = context.hasAnyBin(requires.anyBins);
|
|
255
|
+
if (!anyBin)
|
|
256
|
+
return false;
|
|
257
|
+
}
|
|
258
|
+
// Check environment variables
|
|
259
|
+
if (requires.env && requires.env.length > 0 && context.hasEnv) {
|
|
260
|
+
const allEnv = requires.env.every((env) => context.hasEnv(env));
|
|
261
|
+
if (!allEnv)
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
// Platform check
|
|
265
|
+
for (const platform of context.platforms) {
|
|
266
|
+
const filtered = filterByPlatform([entry], platform);
|
|
267
|
+
if (filtered.length === 0)
|
|
268
|
+
return false;
|
|
269
|
+
}
|
|
270
|
+
return true;
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Check if all binary requirements for a skill are met.
|
|
275
|
+
*/
|
|
276
|
+
export function checkBinaryRequirements(entry, hasBin) {
|
|
277
|
+
const requires = entry.metadata?.requires;
|
|
278
|
+
const missing = [];
|
|
279
|
+
if (requires?.bins) {
|
|
280
|
+
for (const bin of requires.bins) {
|
|
281
|
+
if (!hasBin(bin)) {
|
|
282
|
+
missing.push(bin);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return {
|
|
287
|
+
met: missing.length === 0,
|
|
288
|
+
missing,
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
//# sourceMappingURL=SkillLoader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SkillLoader.js","sourceRoot":"","sources":["../src/SkillLoader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Skill Registry for AgentOS
|
|
3
|
+
* @module @framers/agentos-skills/SkillRegistry
|
|
4
|
+
*
|
|
5
|
+
* Runtime registry for managing and querying loaded skills.
|
|
6
|
+
* Provides methods for registration, filtering, and building
|
|
7
|
+
* skill snapshots for agent context.
|
|
8
|
+
*/
|
|
9
|
+
import type { SkillEntry, SkillSnapshot, SkillEligibilityContext, SkillCommandSpec, SkillsConfig } from './types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Registry options for initialization.
|
|
12
|
+
*/
|
|
13
|
+
export interface SkillRegistryOptions {
|
|
14
|
+
/** Workspace directory containing skills */
|
|
15
|
+
workspaceDir?: string;
|
|
16
|
+
/** Managed/global skills directory (e.g., ~/.codex/skills). */
|
|
17
|
+
managedSkillsDir?: string;
|
|
18
|
+
/** Additional skill directories to scan */
|
|
19
|
+
extraDirs?: string[];
|
|
20
|
+
/** Bundled skills directory */
|
|
21
|
+
bundledSkillsDir?: string;
|
|
22
|
+
/** Skills configuration */
|
|
23
|
+
config?: SkillsConfig;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Skill Registry for managing loaded skills at runtime.
|
|
27
|
+
*/
|
|
28
|
+
export declare class SkillRegistry {
|
|
29
|
+
private readonly entries;
|
|
30
|
+
private config?;
|
|
31
|
+
private snapshotVersion;
|
|
32
|
+
constructor(config?: SkillsConfig);
|
|
33
|
+
/**
|
|
34
|
+
* Register a skill entry.
|
|
35
|
+
*
|
|
36
|
+
* @returns Whether the skill was registered (false if already exists)
|
|
37
|
+
*/
|
|
38
|
+
register(entry: SkillEntry): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Unregister a skill by name.
|
|
41
|
+
*/
|
|
42
|
+
unregister(name: string): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Clear all registered skills.
|
|
45
|
+
*/
|
|
46
|
+
clear(): void;
|
|
47
|
+
/**
|
|
48
|
+
* Get a skill by name.
|
|
49
|
+
*/
|
|
50
|
+
getByName(name: string): SkillEntry | undefined;
|
|
51
|
+
/**
|
|
52
|
+
* List all registered skills.
|
|
53
|
+
*/
|
|
54
|
+
listAll(): SkillEntry[];
|
|
55
|
+
/**
|
|
56
|
+
* Get the count of registered skills.
|
|
57
|
+
*/
|
|
58
|
+
get size(): number;
|
|
59
|
+
/**
|
|
60
|
+
* Check if a skill is registered.
|
|
61
|
+
*/
|
|
62
|
+
has(name: string): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Load skills from one or more directories.
|
|
65
|
+
*/
|
|
66
|
+
loadFromDirs(dirs: string[]): Promise<number>;
|
|
67
|
+
/**
|
|
68
|
+
* Load skills from a single directory, optionally tagging the source.
|
|
69
|
+
*/
|
|
70
|
+
loadFromDir(dir: string, options?: {
|
|
71
|
+
source?: string;
|
|
72
|
+
}): Promise<number>;
|
|
73
|
+
/**
|
|
74
|
+
* Reload all skills from configured directories.
|
|
75
|
+
*/
|
|
76
|
+
reload(options: SkillRegistryOptions): Promise<number>;
|
|
77
|
+
/**
|
|
78
|
+
* Get skills filtered by platform.
|
|
79
|
+
*/
|
|
80
|
+
filterByPlatform(platform: string): SkillEntry[];
|
|
81
|
+
/**
|
|
82
|
+
* Get skills filtered by eligibility context.
|
|
83
|
+
*/
|
|
84
|
+
filterByEligibility(context: SkillEligibilityContext): SkillEntry[];
|
|
85
|
+
/**
|
|
86
|
+
* Get skills that can be invoked by users.
|
|
87
|
+
*/
|
|
88
|
+
getUserInvocableSkills(): SkillEntry[];
|
|
89
|
+
/**
|
|
90
|
+
* Get skills that can be invoked by the model.
|
|
91
|
+
*/
|
|
92
|
+
getModelInvocableSkills(): SkillEntry[];
|
|
93
|
+
/**
|
|
94
|
+
* Build a skill snapshot for agent context.
|
|
95
|
+
*/
|
|
96
|
+
buildSnapshot(options?: {
|
|
97
|
+
platform?: string;
|
|
98
|
+
eligibility?: SkillEligibilityContext;
|
|
99
|
+
filter?: string[];
|
|
100
|
+
/**
|
|
101
|
+
* If true, apply OpenClaw-style eligibility gating (OS/bins/anyBins/env/config).
|
|
102
|
+
* This is useful for "only show runnable skills" behavior.
|
|
103
|
+
*/
|
|
104
|
+
strict?: boolean;
|
|
105
|
+
/** Optional config object used to evaluate `requires.config` paths. */
|
|
106
|
+
runtimeConfig?: Record<string, unknown>;
|
|
107
|
+
}): SkillSnapshot;
|
|
108
|
+
/**
|
|
109
|
+
* Format skills into a prompt for LLM context.
|
|
110
|
+
*/
|
|
111
|
+
buildPrompt(entries: SkillEntry[]): string;
|
|
112
|
+
/**
|
|
113
|
+
* Build command specifications for all skills.
|
|
114
|
+
*/
|
|
115
|
+
buildCommandSpecs(options?: {
|
|
116
|
+
platform?: string;
|
|
117
|
+
eligibility?: SkillEligibilityContext;
|
|
118
|
+
reservedNames?: Set<string>;
|
|
119
|
+
}): SkillCommandSpec[];
|
|
120
|
+
/**
|
|
121
|
+
* Check requirements for all registered skills.
|
|
122
|
+
*/
|
|
123
|
+
checkAllRequirements(hasBin: (bin: string) => boolean): Map<string, {
|
|
124
|
+
met: boolean;
|
|
125
|
+
missing: string[];
|
|
126
|
+
}>;
|
|
127
|
+
/**
|
|
128
|
+
* Get skills with unmet requirements.
|
|
129
|
+
*/
|
|
130
|
+
getSkillsWithMissingRequirements(hasBin: (bin: string) => boolean): Array<{
|
|
131
|
+
skill: string;
|
|
132
|
+
missing: string[];
|
|
133
|
+
}>;
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=SkillRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SkillRegistry.d.ts","sourceRoot":"","sources":["../src/SkillRegistry.ts"],"names":[],"mappings":"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"}
|