@skill-toolbox/filesystem-source 0.0.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 +84 -0
- package/dist/index.d.mts +39 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.js +187 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +149 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +57 -0
package/README.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# @skill-toolbox/filesystem-source
|
|
2
|
+
|
|
3
|
+
Filesystem source adapter for skill-toolbox. Enables loading skills from local directories and files.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @skill-toolbox/filesystem-source
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### Basic Usage
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { FilesystemSource } from '@skill-toolbox/filesystem-source';
|
|
17
|
+
|
|
18
|
+
const source = new FilesystemSource();
|
|
19
|
+
|
|
20
|
+
// Check if source can handle a path
|
|
21
|
+
const canHandle = await source.canHandle('/path/to/skills');
|
|
22
|
+
|
|
23
|
+
// Resolve path to metadata
|
|
24
|
+
const meta = await source.resolve('/path/to/skills');
|
|
25
|
+
|
|
26
|
+
// Fetch (validates path exists)
|
|
27
|
+
const localPath = await source.fetch(meta);
|
|
28
|
+
|
|
29
|
+
// Discover skills
|
|
30
|
+
const skills = await source.discover(localPath, meta);
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### With Custom Working Directory
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
const source = new FilesystemSource({
|
|
37
|
+
cwd: '/base/directory'
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// Now relative paths are resolved from cwd
|
|
41
|
+
const meta = await source.resolve('./skills');
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Features
|
|
45
|
+
|
|
46
|
+
- **Single Skill Loading**: Load a skill from a directory containing a SKILL.md file
|
|
47
|
+
- **Multi-Skill Discovery**: Discover multiple skills in subdirectories
|
|
48
|
+
- **Direct File Loading**: Load a skill directly from a SKILL.md file
|
|
49
|
+
- **Relative Path Support**: Use relative paths with custom working directory
|
|
50
|
+
|
|
51
|
+
## API
|
|
52
|
+
|
|
53
|
+
### `FilesystemSource`
|
|
54
|
+
|
|
55
|
+
#### Constructor
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
constructor(options?: FilesystemSourceOptions)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**Options:**
|
|
62
|
+
- `cwd` - Base directory for relative paths (default: `process.cwd()`)
|
|
63
|
+
|
|
64
|
+
#### Methods
|
|
65
|
+
|
|
66
|
+
##### `canHandle(source: string): Promise<boolean>`
|
|
67
|
+
|
|
68
|
+
Check if the source string is a valid filesystem path.
|
|
69
|
+
|
|
70
|
+
##### `resolve(source: string): Promise<SkillSourceMeta>`
|
|
71
|
+
|
|
72
|
+
Resolve the source string to metadata.
|
|
73
|
+
|
|
74
|
+
##### `fetch(meta: SkillSourceMeta, options?: FetchOptions): Promise<string>`
|
|
75
|
+
|
|
76
|
+
Validate and return the path (no actual fetching needed for filesystem).
|
|
77
|
+
|
|
78
|
+
##### `discover(localPath: string, meta: SkillSourceMeta): Promise<DiscoveredSkill[]>`
|
|
79
|
+
|
|
80
|
+
Discover skills in the given path.
|
|
81
|
+
|
|
82
|
+
## License
|
|
83
|
+
|
|
84
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { SkillSource, SourceCategory, SourceInfo, SourceLoadResult } from '@skill-toolbox/utils';
|
|
2
|
+
|
|
3
|
+
interface FilesystemSourceOptions {
|
|
4
|
+
/** Path to the skills directory or file */
|
|
5
|
+
path: string;
|
|
6
|
+
/** Display name for this source (used in skill names) */
|
|
7
|
+
name?: string;
|
|
8
|
+
/** Category override (defaults to 'global' if name is 'global', else 'local') */
|
|
9
|
+
category?: SourceCategory;
|
|
10
|
+
}
|
|
11
|
+
declare class FilesystemSource implements SkillSource {
|
|
12
|
+
private targetPath;
|
|
13
|
+
private name;
|
|
14
|
+
private category;
|
|
15
|
+
constructor(options: FilesystemSourceOptions);
|
|
16
|
+
getSourceInfo(): SourceInfo;
|
|
17
|
+
load(): Promise<SourceLoadResult>;
|
|
18
|
+
cleanup(): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Load a single skill file
|
|
21
|
+
*/
|
|
22
|
+
private loadSingleFile;
|
|
23
|
+
/**
|
|
24
|
+
* Load all skills from a directory
|
|
25
|
+
*/
|
|
26
|
+
private loadDirectory;
|
|
27
|
+
/**
|
|
28
|
+
* Check if filename is a valid skill file name
|
|
29
|
+
*/
|
|
30
|
+
private isSkillFileName;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @skill-toolbox/filesystem-source
|
|
35
|
+
* Filesystem source adapter for skill-toolbox
|
|
36
|
+
*/
|
|
37
|
+
declare const VERSION = "1.0.0";
|
|
38
|
+
|
|
39
|
+
export { FilesystemSource, type FilesystemSourceOptions, VERSION };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { SkillSource, SourceCategory, SourceInfo, SourceLoadResult } from '@skill-toolbox/utils';
|
|
2
|
+
|
|
3
|
+
interface FilesystemSourceOptions {
|
|
4
|
+
/** Path to the skills directory or file */
|
|
5
|
+
path: string;
|
|
6
|
+
/** Display name for this source (used in skill names) */
|
|
7
|
+
name?: string;
|
|
8
|
+
/** Category override (defaults to 'global' if name is 'global', else 'local') */
|
|
9
|
+
category?: SourceCategory;
|
|
10
|
+
}
|
|
11
|
+
declare class FilesystemSource implements SkillSource {
|
|
12
|
+
private targetPath;
|
|
13
|
+
private name;
|
|
14
|
+
private category;
|
|
15
|
+
constructor(options: FilesystemSourceOptions);
|
|
16
|
+
getSourceInfo(): SourceInfo;
|
|
17
|
+
load(): Promise<SourceLoadResult>;
|
|
18
|
+
cleanup(): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Load a single skill file
|
|
21
|
+
*/
|
|
22
|
+
private loadSingleFile;
|
|
23
|
+
/**
|
|
24
|
+
* Load all skills from a directory
|
|
25
|
+
*/
|
|
26
|
+
private loadDirectory;
|
|
27
|
+
/**
|
|
28
|
+
* Check if filename is a valid skill file name
|
|
29
|
+
*/
|
|
30
|
+
private isSkillFileName;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @skill-toolbox/filesystem-source
|
|
35
|
+
* Filesystem source adapter for skill-toolbox
|
|
36
|
+
*/
|
|
37
|
+
declare const VERSION = "1.0.0";
|
|
38
|
+
|
|
39
|
+
export { FilesystemSource, type FilesystemSourceOptions, VERSION };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
FilesystemSource: () => FilesystemSource,
|
|
34
|
+
VERSION: () => VERSION
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(index_exports);
|
|
37
|
+
|
|
38
|
+
// src/FilesystemSource.ts
|
|
39
|
+
var import_path = __toESM(require("path"));
|
|
40
|
+
var import_fs_extra = __toESM(require("fs-extra"));
|
|
41
|
+
var import_utils = require("@skill-toolbox/utils");
|
|
42
|
+
var FilesystemSource = class {
|
|
43
|
+
targetPath;
|
|
44
|
+
name;
|
|
45
|
+
category;
|
|
46
|
+
constructor(options) {
|
|
47
|
+
this.targetPath = options.path;
|
|
48
|
+
if (options.name) {
|
|
49
|
+
this.name = options.name;
|
|
50
|
+
} else {
|
|
51
|
+
const resolved = import_path.default.resolve(options.path);
|
|
52
|
+
const dirName = import_path.default.basename(resolved);
|
|
53
|
+
this.name = dirName || "local";
|
|
54
|
+
}
|
|
55
|
+
if (options.category) {
|
|
56
|
+
this.category = options.category;
|
|
57
|
+
} else {
|
|
58
|
+
this.category = this.name === "global" ? "global" : "local";
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
getSourceInfo() {
|
|
62
|
+
return {
|
|
63
|
+
type: "filesystem",
|
|
64
|
+
category: this.category,
|
|
65
|
+
identifier: this.name
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
async load() {
|
|
69
|
+
const info = {
|
|
70
|
+
type: "filesystem",
|
|
71
|
+
category: this.category,
|
|
72
|
+
identifier: this.name,
|
|
73
|
+
path: ""
|
|
74
|
+
// Will be set below
|
|
75
|
+
};
|
|
76
|
+
const result = {
|
|
77
|
+
skills: [],
|
|
78
|
+
errors: [],
|
|
79
|
+
info
|
|
80
|
+
};
|
|
81
|
+
try {
|
|
82
|
+
const resolvedPath = import_path.default.resolve(this.targetPath);
|
|
83
|
+
result.info.path = resolvedPath;
|
|
84
|
+
if (!await import_fs_extra.default.pathExists(resolvedPath)) {
|
|
85
|
+
result.errors.push({
|
|
86
|
+
path: this.targetPath,
|
|
87
|
+
error: new Error(`Path does not exist: ${this.targetPath}`)
|
|
88
|
+
});
|
|
89
|
+
return result;
|
|
90
|
+
}
|
|
91
|
+
const stat = await import_fs_extra.default.stat(resolvedPath);
|
|
92
|
+
const isFile = stat.isFile();
|
|
93
|
+
if (isFile) {
|
|
94
|
+
await this.loadSingleFile(resolvedPath, result);
|
|
95
|
+
} else {
|
|
96
|
+
await this.loadDirectory(resolvedPath, result);
|
|
97
|
+
}
|
|
98
|
+
} catch (error) {
|
|
99
|
+
result.errors.push({
|
|
100
|
+
path: this.targetPath,
|
|
101
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
return result;
|
|
105
|
+
}
|
|
106
|
+
async cleanup() {
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Load a single skill file
|
|
110
|
+
*/
|
|
111
|
+
async loadSingleFile(filePath, result) {
|
|
112
|
+
try {
|
|
113
|
+
const content = await import_fs_extra.default.readFile(filePath, "utf-8");
|
|
114
|
+
const dir = import_path.default.dirname(filePath);
|
|
115
|
+
const baseName = import_path.default.basename(dir);
|
|
116
|
+
result.skills.push({
|
|
117
|
+
name: `${this.name}/${baseName}`,
|
|
118
|
+
baseName,
|
|
119
|
+
source: this.name,
|
|
120
|
+
path: filePath,
|
|
121
|
+
directory: dir,
|
|
122
|
+
content
|
|
123
|
+
});
|
|
124
|
+
} catch (error) {
|
|
125
|
+
result.errors.push({
|
|
126
|
+
path: filePath,
|
|
127
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Load all skills from a directory
|
|
133
|
+
*/
|
|
134
|
+
async loadDirectory(dirPath, result) {
|
|
135
|
+
try {
|
|
136
|
+
const entries = await import_fs_extra.default.readdir(dirPath, { withFileTypes: true });
|
|
137
|
+
for (const entry of entries) {
|
|
138
|
+
if (entry.name.startsWith(".")) continue;
|
|
139
|
+
const entryPath = import_path.default.join(dirPath, entry.name);
|
|
140
|
+
if (entry.isFile() && this.isSkillFileName(entry.name)) {
|
|
141
|
+
await this.loadSingleFile(entryPath, result);
|
|
142
|
+
} else if (entry.isDirectory()) {
|
|
143
|
+
const skillFile = await (0, import_utils.findSkillFile)(entryPath);
|
|
144
|
+
if (skillFile) {
|
|
145
|
+
try {
|
|
146
|
+
const content = await import_fs_extra.default.readFile(skillFile, "utf-8");
|
|
147
|
+
result.skills.push({
|
|
148
|
+
name: `${this.name}/${entry.name}`,
|
|
149
|
+
baseName: entry.name,
|
|
150
|
+
source: this.name,
|
|
151
|
+
path: skillFile,
|
|
152
|
+
directory: entryPath,
|
|
153
|
+
content
|
|
154
|
+
});
|
|
155
|
+
} catch (error) {
|
|
156
|
+
result.errors.push({
|
|
157
|
+
path: skillFile,
|
|
158
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
} catch (error) {
|
|
165
|
+
result.errors.push({
|
|
166
|
+
path: dirPath,
|
|
167
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Check if filename is a valid skill file name
|
|
173
|
+
*/
|
|
174
|
+
isSkillFileName(name) {
|
|
175
|
+
const lower = name.toLowerCase();
|
|
176
|
+
return lower === "skill.md";
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
// src/index.ts
|
|
181
|
+
var VERSION = "1.0.0";
|
|
182
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
183
|
+
0 && (module.exports = {
|
|
184
|
+
FilesystemSource,
|
|
185
|
+
VERSION
|
|
186
|
+
});
|
|
187
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/FilesystemSource.ts"],"sourcesContent":["/**\n * @skill-toolbox/filesystem-source\n * Filesystem source adapter for skill-toolbox\n */\n\nexport const VERSION = '1.0.0';\n\nexport { FilesystemSource } from './FilesystemSource';\nexport type { FilesystemSourceOptions } from './FilesystemSource';\n","import path from 'path';\nimport fs from 'fs-extra';\nimport type { SkillSource, SourceInfo, SourceLoadResult, SourceCategory, LoadedSourceInfo } from '@skill-toolbox/utils';\nimport { findSkillFile } from '@skill-toolbox/utils';\n\nexport interface FilesystemSourceOptions {\n /** Path to the skills directory or file */\n path: string;\n /** Display name for this source (used in skill names) */\n name?: string;\n /** Category override (defaults to 'global' if name is 'global', else 'local') */\n category?: SourceCategory;\n}\n\nexport class FilesystemSource implements SkillSource {\n private targetPath: string;\n private name: string;\n private category: SourceCategory;\n\n constructor(options: FilesystemSourceOptions) {\n this.targetPath = options.path;\n\n // Generate name for skill names\n if (options.name) {\n this.name = options.name;\n } else {\n // Use directory name or 'local' for absolute paths\n const resolved = path.resolve(options.path);\n const dirName = path.basename(resolved);\n this.name = dirName || 'local';\n }\n\n // Determine category\n if (options.category) {\n this.category = options.category;\n } else {\n this.category = this.name === 'global' ? 'global' : 'local';\n }\n }\n\n getSourceInfo(): SourceInfo {\n return {\n type: 'filesystem',\n category: this.category,\n identifier: this.name,\n };\n }\n\n async load(): Promise<SourceLoadResult> {\n // Initialize info with default path (will be updated after resolution)\n const info: LoadedSourceInfo = {\n type: 'filesystem',\n category: this.category,\n identifier: this.name,\n path: '', // Will be set below\n };\n\n const result: SourceLoadResult = {\n skills: [],\n errors: [],\n info,\n };\n\n try {\n // Resolve to absolute path\n const resolvedPath = path.resolve(this.targetPath);\n\n // Update info with resolved path\n result.info.path = resolvedPath;\n\n // Check if path exists\n if (!(await fs.pathExists(resolvedPath))) {\n result.errors.push({\n path: this.targetPath,\n error: new Error(`Path does not exist: ${this.targetPath}`),\n });\n return result;\n }\n\n const stat = await fs.stat(resolvedPath);\n const isFile = stat.isFile();\n\n if (isFile) {\n // Single skill file\n await this.loadSingleFile(resolvedPath, result);\n } else {\n // Directory with multiple skills\n await this.loadDirectory(resolvedPath, result);\n }\n } catch (error) {\n result.errors.push({\n path: this.targetPath,\n error: error instanceof Error ? error : new Error(String(error)),\n });\n }\n\n return result;\n }\n\n async cleanup(): Promise<void> {\n // Nothing to cleanup for filesystem sources\n }\n\n /**\n * Load a single skill file\n */\n private async loadSingleFile(filePath: string, result: SourceLoadResult): Promise<void> {\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n const dir = path.dirname(filePath);\n const baseName = path.basename(dir);\n\n result.skills.push({\n name: `${this.name}/${baseName}`,\n baseName,\n source: this.name,\n path: filePath,\n directory: dir,\n content,\n });\n } catch (error) {\n result.errors.push({\n path: filePath,\n error: error instanceof Error ? error : new Error(String(error)),\n });\n }\n }\n\n /**\n * Load all skills from a directory\n */\n private async loadDirectory(dirPath: string, result: SourceLoadResult): Promise<void> {\n try {\n const entries = await fs.readdir(dirPath, { withFileTypes: true });\n\n for (const entry of entries) {\n // Skip hidden files/directories\n if (entry.name.startsWith('.')) continue;\n\n const entryPath = path.join(dirPath, entry.name);\n\n if (entry.isFile() && this.isSkillFileName(entry.name)) {\n // Skill file in root directory\n await this.loadSingleFile(entryPath, result);\n } else if (entry.isDirectory()) {\n // Check if directory contains a skill file\n const skillFile = await findSkillFile(entryPath);\n if (skillFile) {\n try {\n const content = await fs.readFile(skillFile, 'utf-8');\n result.skills.push({\n name: `${this.name}/${entry.name}`,\n baseName: entry.name,\n source: this.name,\n path: skillFile,\n directory: entryPath,\n content,\n });\n } catch (error) {\n result.errors.push({\n path: skillFile,\n error: error instanceof Error ? error : new Error(String(error)),\n });\n }\n }\n }\n }\n } catch (error) {\n result.errors.push({\n path: dirPath,\n error: error instanceof Error ? error : new Error(String(error)),\n });\n }\n }\n\n /**\n * Check if filename is a valid skill file name\n */\n private isSkillFileName(name: string): boolean {\n const lower = name.toLowerCase();\n return lower === 'skill.md';\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,kBAAiB;AACjB,sBAAe;AAEf,mBAA8B;AAWvB,IAAM,mBAAN,MAA8C;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,SAAkC;AAC5C,SAAK,aAAa,QAAQ;AAG1B,QAAI,QAAQ,MAAM;AAChB,WAAK,OAAO,QAAQ;AAAA,IACtB,OAAO;AAEL,YAAM,WAAW,YAAAA,QAAK,QAAQ,QAAQ,IAAI;AAC1C,YAAM,UAAU,YAAAA,QAAK,SAAS,QAAQ;AACtC,WAAK,OAAO,WAAW;AAAA,IACzB;AAGA,QAAI,QAAQ,UAAU;AACpB,WAAK,WAAW,QAAQ;AAAA,IAC1B,OAAO;AACL,WAAK,WAAW,KAAK,SAAS,WAAW,WAAW;AAAA,IACtD;AAAA,EACF;AAAA,EAEA,gBAA4B;AAC1B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,UAAU,KAAK;AAAA,MACf,YAAY,KAAK;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,MAAM,OAAkC;AAEtC,UAAM,OAAyB;AAAA,MAC7B,MAAM;AAAA,MACN,UAAU,KAAK;AAAA,MACf,YAAY,KAAK;AAAA,MACjB,MAAM;AAAA;AAAA,IACR;AAEA,UAAM,SAA2B;AAAA,MAC/B,QAAQ,CAAC;AAAA,MACT,QAAQ,CAAC;AAAA,MACT;AAAA,IACF;AAEA,QAAI;AAEF,YAAM,eAAe,YAAAA,QAAK,QAAQ,KAAK,UAAU;AAGjD,aAAO,KAAK,OAAO;AAGnB,UAAI,CAAE,MAAM,gBAAAC,QAAG,WAAW,YAAY,GAAI;AACxC,eAAO,OAAO,KAAK;AAAA,UACjB,MAAM,KAAK;AAAA,UACX,OAAO,IAAI,MAAM,wBAAwB,KAAK,UAAU,EAAE;AAAA,QAC5D,CAAC;AACD,eAAO;AAAA,MACT;AAEA,YAAM,OAAO,MAAM,gBAAAA,QAAG,KAAK,YAAY;AACvC,YAAM,SAAS,KAAK,OAAO;AAE3B,UAAI,QAAQ;AAEV,cAAM,KAAK,eAAe,cAAc,MAAM;AAAA,MAChD,OAAO;AAEL,cAAM,KAAK,cAAc,cAAc,MAAM;AAAA,MAC/C;AAAA,IACF,SAAS,OAAO;AACd,aAAO,OAAO,KAAK;AAAA,QACjB,MAAM,KAAK;AAAA,QACX,OAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAAA,MACjE,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,UAAyB;AAAA,EAE/B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,eAAe,UAAkB,QAAyC;AACtF,QAAI;AACF,YAAM,UAAU,MAAM,gBAAAA,QAAG,SAAS,UAAU,OAAO;AACnD,YAAM,MAAM,YAAAD,QAAK,QAAQ,QAAQ;AACjC,YAAM,WAAW,YAAAA,QAAK,SAAS,GAAG;AAElC,aAAO,OAAO,KAAK;AAAA,QACjB,MAAM,GAAG,KAAK,IAAI,IAAI,QAAQ;AAAA,QAC9B;AAAA,QACA,QAAQ,KAAK;AAAA,QACb,MAAM;AAAA,QACN,WAAW;AAAA,QACX;AAAA,MACF,CAAC;AAAA,IACH,SAAS,OAAO;AACd,aAAO,OAAO,KAAK;AAAA,QACjB,MAAM;AAAA,QACN,OAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAAA,MACjE,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,cAAc,SAAiB,QAAyC;AACpF,QAAI;AACF,YAAM,UAAU,MAAM,gBAAAC,QAAG,QAAQ,SAAS,EAAE,eAAe,KAAK,CAAC;AAEjE,iBAAW,SAAS,SAAS;AAE3B,YAAI,MAAM,KAAK,WAAW,GAAG,EAAG;AAEhC,cAAM,YAAY,YAAAD,QAAK,KAAK,SAAS,MAAM,IAAI;AAE/C,YAAI,MAAM,OAAO,KAAK,KAAK,gBAAgB,MAAM,IAAI,GAAG;AAEtD,gBAAM,KAAK,eAAe,WAAW,MAAM;AAAA,QAC7C,WAAW,MAAM,YAAY,GAAG;AAE9B,gBAAM,YAAY,UAAM,4BAAc,SAAS;AAC/C,cAAI,WAAW;AACb,gBAAI;AACF,oBAAM,UAAU,MAAM,gBAAAC,QAAG,SAAS,WAAW,OAAO;AACpD,qBAAO,OAAO,KAAK;AAAA,gBACjB,MAAM,GAAG,KAAK,IAAI,IAAI,MAAM,IAAI;AAAA,gBAChC,UAAU,MAAM;AAAA,gBAChB,QAAQ,KAAK;AAAA,gBACb,MAAM;AAAA,gBACN,WAAW;AAAA,gBACX;AAAA,cACF,CAAC;AAAA,YACH,SAAS,OAAO;AACd,qBAAO,OAAO,KAAK;AAAA,gBACjB,MAAM;AAAA,gBACN,OAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAAA,cACjE,CAAC;AAAA,YACH;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,aAAO,OAAO,KAAK;AAAA,QACjB,MAAM;AAAA,QACN,OAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAAA,MACjE,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,gBAAgB,MAAuB;AAC7C,UAAM,QAAQ,KAAK,YAAY;AAC/B,WAAO,UAAU;AAAA,EACnB;AACF;;;ADjLO,IAAM,UAAU;","names":["path","fs"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
// src/FilesystemSource.ts
|
|
2
|
+
import path from "path";
|
|
3
|
+
import fs from "fs-extra";
|
|
4
|
+
import { findSkillFile } from "@skill-toolbox/utils";
|
|
5
|
+
var FilesystemSource = class {
|
|
6
|
+
targetPath;
|
|
7
|
+
name;
|
|
8
|
+
category;
|
|
9
|
+
constructor(options) {
|
|
10
|
+
this.targetPath = options.path;
|
|
11
|
+
if (options.name) {
|
|
12
|
+
this.name = options.name;
|
|
13
|
+
} else {
|
|
14
|
+
const resolved = path.resolve(options.path);
|
|
15
|
+
const dirName = path.basename(resolved);
|
|
16
|
+
this.name = dirName || "local";
|
|
17
|
+
}
|
|
18
|
+
if (options.category) {
|
|
19
|
+
this.category = options.category;
|
|
20
|
+
} else {
|
|
21
|
+
this.category = this.name === "global" ? "global" : "local";
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
getSourceInfo() {
|
|
25
|
+
return {
|
|
26
|
+
type: "filesystem",
|
|
27
|
+
category: this.category,
|
|
28
|
+
identifier: this.name
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
async load() {
|
|
32
|
+
const info = {
|
|
33
|
+
type: "filesystem",
|
|
34
|
+
category: this.category,
|
|
35
|
+
identifier: this.name,
|
|
36
|
+
path: ""
|
|
37
|
+
// Will be set below
|
|
38
|
+
};
|
|
39
|
+
const result = {
|
|
40
|
+
skills: [],
|
|
41
|
+
errors: [],
|
|
42
|
+
info
|
|
43
|
+
};
|
|
44
|
+
try {
|
|
45
|
+
const resolvedPath = path.resolve(this.targetPath);
|
|
46
|
+
result.info.path = resolvedPath;
|
|
47
|
+
if (!await fs.pathExists(resolvedPath)) {
|
|
48
|
+
result.errors.push({
|
|
49
|
+
path: this.targetPath,
|
|
50
|
+
error: new Error(`Path does not exist: ${this.targetPath}`)
|
|
51
|
+
});
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
const stat = await fs.stat(resolvedPath);
|
|
55
|
+
const isFile = stat.isFile();
|
|
56
|
+
if (isFile) {
|
|
57
|
+
await this.loadSingleFile(resolvedPath, result);
|
|
58
|
+
} else {
|
|
59
|
+
await this.loadDirectory(resolvedPath, result);
|
|
60
|
+
}
|
|
61
|
+
} catch (error) {
|
|
62
|
+
result.errors.push({
|
|
63
|
+
path: this.targetPath,
|
|
64
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
return result;
|
|
68
|
+
}
|
|
69
|
+
async cleanup() {
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Load a single skill file
|
|
73
|
+
*/
|
|
74
|
+
async loadSingleFile(filePath, result) {
|
|
75
|
+
try {
|
|
76
|
+
const content = await fs.readFile(filePath, "utf-8");
|
|
77
|
+
const dir = path.dirname(filePath);
|
|
78
|
+
const baseName = path.basename(dir);
|
|
79
|
+
result.skills.push({
|
|
80
|
+
name: `${this.name}/${baseName}`,
|
|
81
|
+
baseName,
|
|
82
|
+
source: this.name,
|
|
83
|
+
path: filePath,
|
|
84
|
+
directory: dir,
|
|
85
|
+
content
|
|
86
|
+
});
|
|
87
|
+
} catch (error) {
|
|
88
|
+
result.errors.push({
|
|
89
|
+
path: filePath,
|
|
90
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Load all skills from a directory
|
|
96
|
+
*/
|
|
97
|
+
async loadDirectory(dirPath, result) {
|
|
98
|
+
try {
|
|
99
|
+
const entries = await fs.readdir(dirPath, { withFileTypes: true });
|
|
100
|
+
for (const entry of entries) {
|
|
101
|
+
if (entry.name.startsWith(".")) continue;
|
|
102
|
+
const entryPath = path.join(dirPath, entry.name);
|
|
103
|
+
if (entry.isFile() && this.isSkillFileName(entry.name)) {
|
|
104
|
+
await this.loadSingleFile(entryPath, result);
|
|
105
|
+
} else if (entry.isDirectory()) {
|
|
106
|
+
const skillFile = await findSkillFile(entryPath);
|
|
107
|
+
if (skillFile) {
|
|
108
|
+
try {
|
|
109
|
+
const content = await fs.readFile(skillFile, "utf-8");
|
|
110
|
+
result.skills.push({
|
|
111
|
+
name: `${this.name}/${entry.name}`,
|
|
112
|
+
baseName: entry.name,
|
|
113
|
+
source: this.name,
|
|
114
|
+
path: skillFile,
|
|
115
|
+
directory: entryPath,
|
|
116
|
+
content
|
|
117
|
+
});
|
|
118
|
+
} catch (error) {
|
|
119
|
+
result.errors.push({
|
|
120
|
+
path: skillFile,
|
|
121
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
} catch (error) {
|
|
128
|
+
result.errors.push({
|
|
129
|
+
path: dirPath,
|
|
130
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Check if filename is a valid skill file name
|
|
136
|
+
*/
|
|
137
|
+
isSkillFileName(name) {
|
|
138
|
+
const lower = name.toLowerCase();
|
|
139
|
+
return lower === "skill.md";
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
// src/index.ts
|
|
144
|
+
var VERSION = "1.0.0";
|
|
145
|
+
export {
|
|
146
|
+
FilesystemSource,
|
|
147
|
+
VERSION
|
|
148
|
+
};
|
|
149
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/FilesystemSource.ts","../src/index.ts"],"sourcesContent":["import path from 'path';\nimport fs from 'fs-extra';\nimport type { SkillSource, SourceInfo, SourceLoadResult, SourceCategory, LoadedSourceInfo } from '@skill-toolbox/utils';\nimport { findSkillFile } from '@skill-toolbox/utils';\n\nexport interface FilesystemSourceOptions {\n /** Path to the skills directory or file */\n path: string;\n /** Display name for this source (used in skill names) */\n name?: string;\n /** Category override (defaults to 'global' if name is 'global', else 'local') */\n category?: SourceCategory;\n}\n\nexport class FilesystemSource implements SkillSource {\n private targetPath: string;\n private name: string;\n private category: SourceCategory;\n\n constructor(options: FilesystemSourceOptions) {\n this.targetPath = options.path;\n\n // Generate name for skill names\n if (options.name) {\n this.name = options.name;\n } else {\n // Use directory name or 'local' for absolute paths\n const resolved = path.resolve(options.path);\n const dirName = path.basename(resolved);\n this.name = dirName || 'local';\n }\n\n // Determine category\n if (options.category) {\n this.category = options.category;\n } else {\n this.category = this.name === 'global' ? 'global' : 'local';\n }\n }\n\n getSourceInfo(): SourceInfo {\n return {\n type: 'filesystem',\n category: this.category,\n identifier: this.name,\n };\n }\n\n async load(): Promise<SourceLoadResult> {\n // Initialize info with default path (will be updated after resolution)\n const info: LoadedSourceInfo = {\n type: 'filesystem',\n category: this.category,\n identifier: this.name,\n path: '', // Will be set below\n };\n\n const result: SourceLoadResult = {\n skills: [],\n errors: [],\n info,\n };\n\n try {\n // Resolve to absolute path\n const resolvedPath = path.resolve(this.targetPath);\n\n // Update info with resolved path\n result.info.path = resolvedPath;\n\n // Check if path exists\n if (!(await fs.pathExists(resolvedPath))) {\n result.errors.push({\n path: this.targetPath,\n error: new Error(`Path does not exist: ${this.targetPath}`),\n });\n return result;\n }\n\n const stat = await fs.stat(resolvedPath);\n const isFile = stat.isFile();\n\n if (isFile) {\n // Single skill file\n await this.loadSingleFile(resolvedPath, result);\n } else {\n // Directory with multiple skills\n await this.loadDirectory(resolvedPath, result);\n }\n } catch (error) {\n result.errors.push({\n path: this.targetPath,\n error: error instanceof Error ? error : new Error(String(error)),\n });\n }\n\n return result;\n }\n\n async cleanup(): Promise<void> {\n // Nothing to cleanup for filesystem sources\n }\n\n /**\n * Load a single skill file\n */\n private async loadSingleFile(filePath: string, result: SourceLoadResult): Promise<void> {\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n const dir = path.dirname(filePath);\n const baseName = path.basename(dir);\n\n result.skills.push({\n name: `${this.name}/${baseName}`,\n baseName,\n source: this.name,\n path: filePath,\n directory: dir,\n content,\n });\n } catch (error) {\n result.errors.push({\n path: filePath,\n error: error instanceof Error ? error : new Error(String(error)),\n });\n }\n }\n\n /**\n * Load all skills from a directory\n */\n private async loadDirectory(dirPath: string, result: SourceLoadResult): Promise<void> {\n try {\n const entries = await fs.readdir(dirPath, { withFileTypes: true });\n\n for (const entry of entries) {\n // Skip hidden files/directories\n if (entry.name.startsWith('.')) continue;\n\n const entryPath = path.join(dirPath, entry.name);\n\n if (entry.isFile() && this.isSkillFileName(entry.name)) {\n // Skill file in root directory\n await this.loadSingleFile(entryPath, result);\n } else if (entry.isDirectory()) {\n // Check if directory contains a skill file\n const skillFile = await findSkillFile(entryPath);\n if (skillFile) {\n try {\n const content = await fs.readFile(skillFile, 'utf-8');\n result.skills.push({\n name: `${this.name}/${entry.name}`,\n baseName: entry.name,\n source: this.name,\n path: skillFile,\n directory: entryPath,\n content,\n });\n } catch (error) {\n result.errors.push({\n path: skillFile,\n error: error instanceof Error ? error : new Error(String(error)),\n });\n }\n }\n }\n }\n } catch (error) {\n result.errors.push({\n path: dirPath,\n error: error instanceof Error ? error : new Error(String(error)),\n });\n }\n }\n\n /**\n * Check if filename is a valid skill file name\n */\n private isSkillFileName(name: string): boolean {\n const lower = name.toLowerCase();\n return lower === 'skill.md';\n }\n}\n","/**\n * @skill-toolbox/filesystem-source\n * Filesystem source adapter for skill-toolbox\n */\n\nexport const VERSION = '1.0.0';\n\nexport { FilesystemSource } from './FilesystemSource';\nexport type { FilesystemSourceOptions } from './FilesystemSource';\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@skill-toolbox/filesystem-source",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Filesystem source adapter for skill-toolbox",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
20
|
+
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
21
|
+
"test": "vitest run",
|
|
22
|
+
"test:watch": "vitest",
|
|
23
|
+
"clean": "rm -rf dist *.tsbuildinfo"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@skill-toolbox/utils": "workspace:*",
|
|
27
|
+
"fs-extra": "^11.2.0"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/fs-extra": "^11.0.4",
|
|
31
|
+
"tsup": "^8.0.0",
|
|
32
|
+
"vitest": "^1.2.0"
|
|
33
|
+
},
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public",
|
|
36
|
+
"registry": "https://registry.npmjs.org/"
|
|
37
|
+
},
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "git+https://github.com/Link-Reverie/skill-toolbox.git",
|
|
41
|
+
"directory": "packages/filesystem-source"
|
|
42
|
+
},
|
|
43
|
+
"bugs": {
|
|
44
|
+
"url": "https://github.com/Link-Reverie/skill-toolbox/issues"
|
|
45
|
+
},
|
|
46
|
+
"homepage": "https://github.com/Link-Reverie/skill-toolbox#readme",
|
|
47
|
+
"license": "MIT",
|
|
48
|
+
"keywords": [
|
|
49
|
+
"skill",
|
|
50
|
+
"ai-agent",
|
|
51
|
+
"claude",
|
|
52
|
+
"llm",
|
|
53
|
+
"typescript",
|
|
54
|
+
"filesystem",
|
|
55
|
+
"source"
|
|
56
|
+
]
|
|
57
|
+
}
|