skills-sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +104 -0
- package/dist/client.d.ts +44 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +93 -0
- package/dist/client.js.map +1 -0
- package/dist/errors.d.ts +20 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +30 -0
- package/dist/errors.js.map +1 -0
- package/dist/github.d.ts +19 -0
- package/dist/github.d.ts.map +1 -0
- package/dist/github.js +67 -0
- package/dist/github.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/parser.d.ts +9 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +39 -0
- package/dist/parser.js.map +1 -0
- package/dist/store/fs.d.ts +9 -0
- package/dist/store/fs.d.ts.map +1 -0
- package/dist/store/fs.js +28 -0
- package/dist/store/fs.js.map +1 -0
- package/dist/store/gcs.d.ts +13 -0
- package/dist/store/gcs.d.ts.map +1 -0
- package/dist/store/gcs.js +48 -0
- package/dist/store/gcs.js.map +1 -0
- package/dist/store/index.d.ts +18 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/index.js +3 -0
- package/dist/store/index.js.map +1 -0
- package/dist/store/memory.d.ts +10 -0
- package/dist/store/memory.d.ts.map +1 -0
- package/dist/store/memory.js +48 -0
- package/dist/store/memory.js.map +1 -0
- package/dist/store/s3.d.ts +13 -0
- package/dist/store/s3.d.ts.map +1 -0
- package/dist/store/s3.js +104 -0
- package/dist/store/s3.js.map +1 -0
- package/dist/store.d.ts +26 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +31 -0
- package/dist/store.js.map +1 -0
- package/dist/tarball.d.ts +2 -0
- package/dist/tarball.d.ts.map +1 -0
- package/dist/tarball.js +68 -0
- package/dist/tarball.js.map +1 -0
- package/dist/types.d.ts +12 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +38 -0
package/README.md
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# skills-sdk
|
|
2
|
+
|
|
3
|
+
TypeScript SDK for fetching and managing [agent skills](https://agentskills.io) from GitHub repositories.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
npm install skills-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { Client, FS } from "skills-sdk";
|
|
15
|
+
|
|
16
|
+
const client = new Client(new FS(), "/tmp/skills");
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The client takes a storage backend and a base path. `FS` writes to disk, `Memory` keeps everything in-memory (useful for tests).
|
|
20
|
+
|
|
21
|
+
### Authentication
|
|
22
|
+
|
|
23
|
+
Pass a GitHub token directly or set it as an environment variable:
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
// explicit
|
|
27
|
+
const client = new Client(new FS(), "/tmp/skills", {
|
|
28
|
+
token: "ghp_...",
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// or via environment
|
|
32
|
+
// SKILLS_GITHUB_TOKEN=ghp_...
|
|
33
|
+
// SKILLS_GITHUB_URL=https://github.example.com/api/v3 (optional, for GHE)
|
|
34
|
+
const client = new Client(new FS(), "/tmp/skills");
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Fetch skills from GitHub
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
// fetch all skills from a repo
|
|
41
|
+
await client.store("owner", "repo");
|
|
42
|
+
|
|
43
|
+
// fetch a specific skill
|
|
44
|
+
await client.store("owner", "repo", { name: "my-skill" });
|
|
45
|
+
|
|
46
|
+
// fetch from a specific branch or tag
|
|
47
|
+
await client.store("owner", "repo", { ref: "v2" });
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### List skills
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
// remote — reads from GitHub without storing anything
|
|
54
|
+
const remote = await client.listRemote("owner", "repo");
|
|
55
|
+
|
|
56
|
+
// local — reads from whatever you've already stored
|
|
57
|
+
const local = await client.listLocal();
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Both return `Metadata[]` with `name`, `description`, and optional fields like `license`, `compatibility`, `allowedTools`.
|
|
61
|
+
|
|
62
|
+
### Read stored skills
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
const meta = await client.getMetadata("my-skill");
|
|
66
|
+
const raw = await client.getSkillMd("my-skill");
|
|
67
|
+
const file = await client.getFile("my-skill", "prompt.txt");
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Custom storage backends
|
|
71
|
+
|
|
72
|
+
The SDK ships with `FS` and `Memory`, but you can plug in any backend by implementing the `Store` interface:
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
import type { Store } from "skills-sdk";
|
|
76
|
+
|
|
77
|
+
class S3Store implements Store {
|
|
78
|
+
async write(path: string, content: Buffer): Promise<void> {
|
|
79
|
+
/* ... */
|
|
80
|
+
}
|
|
81
|
+
async read(path: string): Promise<Buffer> {
|
|
82
|
+
/* ... */
|
|
83
|
+
}
|
|
84
|
+
async list(prefix: string): Promise<string[]> {
|
|
85
|
+
/* ... */
|
|
86
|
+
}
|
|
87
|
+
async exists(path: string): Promise<boolean> {
|
|
88
|
+
/* ... */
|
|
89
|
+
}
|
|
90
|
+
async delete(path: string): Promise<void> {
|
|
91
|
+
/* ... */
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const client = new Client(new S3Store(), "skills/");
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
A few things to keep in mind when writing a backend:
|
|
99
|
+
|
|
100
|
+
- **`write`** should create any intermediate directories/prefixes as needed.
|
|
101
|
+
- **`list`** returns immediate child _directory_ names under the given prefix, not files. Think `ls`, not `find`.
|
|
102
|
+
- **`exists`** should return `true` for both files and directories.
|
|
103
|
+
- **`delete`** is recursive -- it removes the path and everything under it.
|
|
104
|
+
- Paths use `/` as the separator. The client never sends backslashes.
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { Store } from "./store/index.js";
|
|
2
|
+
import type { Metadata } from "./types.js";
|
|
3
|
+
export interface ClientOptions {
|
|
4
|
+
token?: string;
|
|
5
|
+
baseUrl?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Options for the {@link Client.store} method.
|
|
9
|
+
*/
|
|
10
|
+
export interface StoreOptions {
|
|
11
|
+
/** Fetch only the skill with this name. Fetches all skills if omitted. */
|
|
12
|
+
name?: string;
|
|
13
|
+
/** Git ref (branch, tag, or SHA) to fetch from. Uses the default branch if omitted. */
|
|
14
|
+
ref?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Main entry point for fetching skills from GitHub and reading them from local storage.
|
|
18
|
+
*
|
|
19
|
+
* Falls back to `SKILLS_GITHUB_TOKEN` and `SKILLS_GITHUB_URL` environment
|
|
20
|
+
* variables when `ClientOptions` are not provided.
|
|
21
|
+
*/
|
|
22
|
+
export declare class Client {
|
|
23
|
+
private fileStore;
|
|
24
|
+
private basePath;
|
|
25
|
+
private fetcher;
|
|
26
|
+
constructor(store: Store, basePath: string, options?: ClientOptions);
|
|
27
|
+
/** List metadata for all skills in a remote GitHub repository. */
|
|
28
|
+
listRemote(owner: string, repo: string, ref?: string): Promise<Metadata[]>;
|
|
29
|
+
/**
|
|
30
|
+
* Fetch skills from a GitHub repository and write them to local storage.
|
|
31
|
+
* Downloads the entire repo as a tarball (1 API request) even when storing
|
|
32
|
+
* a single skill -- at typical repo sizes this is faster than per-file fetching.
|
|
33
|
+
*/
|
|
34
|
+
store(owner: string, repo: string, options?: StoreOptions): Promise<void>;
|
|
35
|
+
/** List metadata for all skills stored locally under the base path. */
|
|
36
|
+
listLocal(): Promise<Metadata[]>;
|
|
37
|
+
/** Get the parsed frontmatter metadata for a stored skill. */
|
|
38
|
+
getMetadata(name: string): Promise<Metadata>;
|
|
39
|
+
/** Get the raw SKILL.md content for a stored skill. */
|
|
40
|
+
getSkillMd(name: string): Promise<string>;
|
|
41
|
+
/** Get a single file from a stored skill by its relative path. */
|
|
42
|
+
getFile(name: string, path: string): Promise<Buffer>;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAO3C,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,0EAA0E;IAC1E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uFAAuF;IACvF,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;GAKG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAe;gBAElB,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa;IAWnE,kEAAkE;IAC5D,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAShF;;;;OAIG;IACG,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAuB/E,uEAAuE;IACjE,SAAS,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IAoBtC,8DAA8D;IACxD,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAMlD,uDAAuD;IACjD,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK/C,kEAAkE;IAC5D,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAG3D"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { join } from "node:path/posix";
|
|
2
|
+
import { GitHubClient, discoverSkills } from "./github.js";
|
|
3
|
+
import { parseSkillMd } from "./parser.js";
|
|
4
|
+
import { SkillsError } from "./errors.js";
|
|
5
|
+
const SKILL_MD = "SKILL.md";
|
|
6
|
+
/**
|
|
7
|
+
* Main entry point for fetching skills from GitHub and reading them from local storage.
|
|
8
|
+
*
|
|
9
|
+
* Falls back to `SKILLS_GITHUB_TOKEN` and `SKILLS_GITHUB_URL` environment
|
|
10
|
+
* variables when `ClientOptions` are not provided.
|
|
11
|
+
*/
|
|
12
|
+
export class Client {
|
|
13
|
+
fileStore;
|
|
14
|
+
basePath;
|
|
15
|
+
fetcher;
|
|
16
|
+
constructor(store, basePath, options) {
|
|
17
|
+
this.fileStore = store;
|
|
18
|
+
this.basePath = basePath;
|
|
19
|
+
const token = options?.token ?? process.env.SKILLS_GITHUB_TOKEN;
|
|
20
|
+
const baseUrl = options?.baseUrl ?? process.env.SKILLS_GITHUB_URL;
|
|
21
|
+
this.fetcher = new GitHubClient({
|
|
22
|
+
...(token ? { token } : {}),
|
|
23
|
+
...(baseUrl ? { baseUrl } : {}),
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
/** List metadata for all skills in a remote GitHub repository. */
|
|
27
|
+
async listRemote(owner, repo, ref) {
|
|
28
|
+
const repoFiles = await this.fetcher.fetchRepo(owner, repo, ref);
|
|
29
|
+
const discovered = discoverSkills(repoFiles);
|
|
30
|
+
return discovered.map((skill) => {
|
|
31
|
+
const { metadata } = parseSkillMd(skill.skillMdContent.toString("utf-8"));
|
|
32
|
+
return metadata;
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Fetch skills from a GitHub repository and write them to local storage.
|
|
37
|
+
* Downloads the entire repo as a tarball (1 API request) even when storing
|
|
38
|
+
* a single skill -- at typical repo sizes this is faster than per-file fetching.
|
|
39
|
+
*/
|
|
40
|
+
async store(owner, repo, options) {
|
|
41
|
+
const repoFiles = await this.fetcher.fetchRepo(owner, repo, options?.ref);
|
|
42
|
+
let discovered = discoverSkills(repoFiles);
|
|
43
|
+
if (options?.name) {
|
|
44
|
+
discovered = discovered.filter((s) => s.directoryName === options.name);
|
|
45
|
+
if (discovered.length === 0) {
|
|
46
|
+
throw new SkillsError(`Skill "${options.name}" not found`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
for (const skill of discovered) {
|
|
50
|
+
const { metadata } = parseSkillMd(skill.skillMdContent.toString("utf-8"));
|
|
51
|
+
const skillDir = join(this.basePath, metadata.name);
|
|
52
|
+
await this.fileStore.write(join(skillDir, SKILL_MD), skill.skillMdContent);
|
|
53
|
+
for (const [relPath, content] of skill.files) {
|
|
54
|
+
await this.fileStore.write(join(skillDir, relPath), content);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/** List metadata for all skills stored locally under the base path. */
|
|
59
|
+
async listLocal() {
|
|
60
|
+
const dirs = await this.fileStore.list(this.basePath);
|
|
61
|
+
const results = [];
|
|
62
|
+
for (const dir of dirs) {
|
|
63
|
+
const skillMdPath = join(this.basePath, dir, SKILL_MD);
|
|
64
|
+
if (!(await this.fileStore.exists(skillMdPath)))
|
|
65
|
+
continue;
|
|
66
|
+
try {
|
|
67
|
+
const content = await this.fileStore.read(skillMdPath);
|
|
68
|
+
const { metadata } = parseSkillMd(content.toString("utf-8"));
|
|
69
|
+
results.push(metadata);
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// skip directories with invalid SKILL.md
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return results;
|
|
76
|
+
}
|
|
77
|
+
/** Get the parsed frontmatter metadata for a stored skill. */
|
|
78
|
+
async getMetadata(name) {
|
|
79
|
+
const content = await this.fileStore.read(join(this.basePath, name, SKILL_MD));
|
|
80
|
+
const { metadata } = parseSkillMd(content.toString("utf-8"));
|
|
81
|
+
return metadata;
|
|
82
|
+
}
|
|
83
|
+
/** Get the raw SKILL.md content for a stored skill. */
|
|
84
|
+
async getSkillMd(name) {
|
|
85
|
+
const content = await this.fileStore.read(join(this.basePath, name, SKILL_MD));
|
|
86
|
+
return content.toString("utf-8");
|
|
87
|
+
}
|
|
88
|
+
/** Get a single file from a stored skill by its relative path. */
|
|
89
|
+
async getFile(name, path) {
|
|
90
|
+
return this.fileStore.read(join(this.basePath, name, path));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base error class for all skills-related errors.
|
|
3
|
+
*/
|
|
4
|
+
export declare class SkillsError extends Error {
|
|
5
|
+
constructor(message: string);
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Error thrown when a SKILL.md file cannot be parsed.
|
|
9
|
+
*/
|
|
10
|
+
export declare class ParseError extends SkillsError {
|
|
11
|
+
constructor(message: string);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Error thrown when a GitHub API request fails.
|
|
15
|
+
*/
|
|
16
|
+
export declare class GitHubFetchError extends SkillsError {
|
|
17
|
+
status: number;
|
|
18
|
+
constructor(status: number, message: string);
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,WAAY,SAAQ,KAAK;gBACxB,OAAO,EAAE,MAAM;CAI5B;AAED;;GAEG;AACH,qBAAa,UAAW,SAAQ,WAAW;gBAC7B,OAAO,EAAE,MAAM;CAI5B;AAED;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,WAAW;IAC/C,MAAM,EAAE,MAAM,CAAC;gBAEH,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAK5C"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base error class for all skills-related errors.
|
|
3
|
+
*/
|
|
4
|
+
export class SkillsError extends Error {
|
|
5
|
+
constructor(message) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = "SkillsError";
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Error thrown when a SKILL.md file cannot be parsed.
|
|
12
|
+
*/
|
|
13
|
+
export class ParseError extends SkillsError {
|
|
14
|
+
constructor(message) {
|
|
15
|
+
super(message);
|
|
16
|
+
this.name = "ParseError";
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Error thrown when a GitHub API request fails.
|
|
21
|
+
*/
|
|
22
|
+
export class GitHubFetchError extends SkillsError {
|
|
23
|
+
status;
|
|
24
|
+
constructor(status, message) {
|
|
25
|
+
super(message);
|
|
26
|
+
this.name = "GitHubFetchError";
|
|
27
|
+
this.status = status;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,OAAO,WAAY,SAAQ,KAAK;IACpC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,UAAW,SAAQ,WAAW;IACzC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;IAC3B,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,gBAAiB,SAAQ,WAAW;IAC/C,MAAM,CAAS;IAEf,YAAY,MAAc,EAAE,OAAe;QACzC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;QAC/B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF"}
|
package/dist/github.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface DiscoveredSkill {
|
|
2
|
+
path: string;
|
|
3
|
+
directoryName: string;
|
|
4
|
+
skillMdContent: Buffer;
|
|
5
|
+
files: Map<string, Buffer>;
|
|
6
|
+
}
|
|
7
|
+
interface GitHubClientOptions {
|
|
8
|
+
token?: string;
|
|
9
|
+
baseUrl?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare class GitHubClient {
|
|
12
|
+
private baseUrl;
|
|
13
|
+
private token;
|
|
14
|
+
constructor(options?: GitHubClientOptions);
|
|
15
|
+
fetchRepo(owner: string, repo: string, ref?: string): Promise<Map<string, Buffer>>;
|
|
16
|
+
}
|
|
17
|
+
export declare function discoverSkills(files: Map<string, Buffer>): DiscoveredSkill[];
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=github.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../src/github.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC5B;AAED,UAAU,mBAAmB;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAqB;gBAEtB,OAAO,CAAC,EAAE,mBAAmB;IAKnC,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAmBzF;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,eAAe,EAAE,CAoC5E"}
|
package/dist/github.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { GitHubFetchError } from "./errors.js";
|
|
2
|
+
import { parseTarGz } from "./tarball.js";
|
|
3
|
+
const DEFAULT_BASE_URL = "https://api.github.com";
|
|
4
|
+
export class GitHubClient {
|
|
5
|
+
baseUrl;
|
|
6
|
+
token;
|
|
7
|
+
constructor(options) {
|
|
8
|
+
this.baseUrl = options?.baseUrl ?? DEFAULT_BASE_URL;
|
|
9
|
+
this.token = options?.token;
|
|
10
|
+
}
|
|
11
|
+
async fetchRepo(owner, repo, ref) {
|
|
12
|
+
const path = ref ? `/repos/${owner}/${repo}/tarball/${ref}` : `/repos/${owner}/${repo}/tarball`;
|
|
13
|
+
const url = `${this.baseUrl}${path}`;
|
|
14
|
+
const headers = {};
|
|
15
|
+
if (this.token) {
|
|
16
|
+
headers.Authorization = `Bearer ${this.token}`;
|
|
17
|
+
}
|
|
18
|
+
const response = await fetch(url, { headers, redirect: "follow" });
|
|
19
|
+
if (!response.ok) {
|
|
20
|
+
throw new GitHubFetchError(response.status, `GitHub API error: ${response.status} ${response.statusText} for ${path}`);
|
|
21
|
+
}
|
|
22
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
23
|
+
return parseTarGz(Buffer.from(arrayBuffer));
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export function discoverSkills(files) {
|
|
27
|
+
// Pass 1: find all SKILL.md locations
|
|
28
|
+
const skillMdEntries = [];
|
|
29
|
+
for (const [path, content] of files) {
|
|
30
|
+
if (path === "SKILL.md" || path.endsWith("/SKILL.md")) {
|
|
31
|
+
const skillDir = path === "SKILL.md" ? "" : path.slice(0, path.lastIndexOf("/"));
|
|
32
|
+
skillMdEntries.push({ skillDir, content });
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// Pass 2: bucket each non-SKILL.md file into its owning skill directory
|
|
36
|
+
const buckets = new Map();
|
|
37
|
+
for (const { skillDir } of skillMdEntries) {
|
|
38
|
+
buckets.set(skillDir, new Map());
|
|
39
|
+
}
|
|
40
|
+
for (const [filePath, fileContent] of files) {
|
|
41
|
+
if (filePath === "SKILL.md" || filePath.endsWith("/SKILL.md"))
|
|
42
|
+
continue;
|
|
43
|
+
for (const skillDir of buckets.keys()) {
|
|
44
|
+
if (skillDir === "") {
|
|
45
|
+
if (!filePath.includes("/")) {
|
|
46
|
+
buckets.get(skillDir).set(filePath, fileContent);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
else if (filePath.startsWith(skillDir + "/")) {
|
|
50
|
+
buckets.get(skillDir).set(filePath.slice(skillDir.length + 1), fileContent);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return skillMdEntries.map(({ skillDir, content }) => ({
|
|
55
|
+
path: skillDir || ".",
|
|
56
|
+
directoryName: getDirectoryName(skillDir),
|
|
57
|
+
skillMdContent: content,
|
|
58
|
+
files: buckets.get(skillDir),
|
|
59
|
+
}));
|
|
60
|
+
}
|
|
61
|
+
function getDirectoryName(skillDir) {
|
|
62
|
+
if (!skillDir)
|
|
63
|
+
return "root";
|
|
64
|
+
const lastSlash = skillDir.lastIndexOf("/");
|
|
65
|
+
return lastSlash === -1 ? skillDir : skillDir.slice(lastSlash + 1);
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=github.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.js","sourceRoot":"","sources":["../src/github.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { Client } from "./client.js";
|
|
2
|
+
export type { ClientOptions, StoreOptions } from "./client.js";
|
|
3
|
+
export { FS, Memory } from "./store/index.js";
|
|
4
|
+
export type { Store } from "./store/index.js";
|
|
5
|
+
export { SkillsError, ParseError, GitHubFetchError } from "./errors.js";
|
|
6
|
+
export type { Metadata } from "./types.js";
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACxE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/parser.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG3C;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG;IAC7C,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd,CAuCA"}
|
package/dist/parser.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import matter from "gray-matter";
|
|
2
|
+
import { ParseError } from "./errors.js";
|
|
3
|
+
/**
|
|
4
|
+
* Parse a SKILL.md file into its metadata and body.
|
|
5
|
+
*/
|
|
6
|
+
export function parseSkillMd(content) {
|
|
7
|
+
const { data, content: body } = matter(content);
|
|
8
|
+
if (!data.name || typeof data.name !== "string") {
|
|
9
|
+
throw new ParseError('SKILL.md frontmatter must include a "name" field');
|
|
10
|
+
}
|
|
11
|
+
if (!data.description || typeof data.description !== "string") {
|
|
12
|
+
throw new ParseError('SKILL.md frontmatter must include a "description" field');
|
|
13
|
+
}
|
|
14
|
+
const metadata = {
|
|
15
|
+
name: data.name,
|
|
16
|
+
description: data.description,
|
|
17
|
+
};
|
|
18
|
+
if (data.license != null) {
|
|
19
|
+
metadata.license = String(data.license);
|
|
20
|
+
}
|
|
21
|
+
if (data.compatibility != null) {
|
|
22
|
+
metadata.compatibility = String(data.compatibility);
|
|
23
|
+
}
|
|
24
|
+
const tools = data["allowed-tools"] ?? data.allowedTools;
|
|
25
|
+
if (tools != null) {
|
|
26
|
+
if (!Array.isArray(tools)) {
|
|
27
|
+
throw new ParseError('"allowed-tools" must be an array');
|
|
28
|
+
}
|
|
29
|
+
metadata.allowedTools = tools.map(String);
|
|
30
|
+
}
|
|
31
|
+
if (data.metadata != null) {
|
|
32
|
+
if (typeof data.metadata !== "object" || Array.isArray(data.metadata)) {
|
|
33
|
+
throw new ParseError('"metadata" must be an object');
|
|
34
|
+
}
|
|
35
|
+
metadata.metadata = data.metadata;
|
|
36
|
+
}
|
|
37
|
+
return { metadata, body: body.trim() };
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,OAAe;IAI1C,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAEhD,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAChD,MAAM,IAAI,UAAU,CAAC,kDAAkD,CAAC,CAAC;IAC3E,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,OAAO,IAAI,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;QAC9D,MAAM,IAAI,UAAU,CAAC,yDAAyD,CAAC,CAAC;IAClF,CAAC;IAED,MAAM,QAAQ,GAAa;QACzB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,WAAW,EAAE,IAAI,CAAC,WAAW;KAC9B,CAAC;IAEF,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,EAAE,CAAC;QACzB,QAAQ,CAAC,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC1C,CAAC;IAED,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,EAAE,CAAC;QAC/B,QAAQ,CAAC,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC;IACzD,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;QAClB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,UAAU,CAAC,kCAAkC,CAAC,CAAC;QAC3D,CAAC;QACD,QAAQ,CAAC,YAAY,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5C,CAAC;IAED,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,EAAE,CAAC;QAC1B,IAAI,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YACtE,MAAM,IAAI,UAAU,CAAC,8BAA8B,CAAC,CAAC;QACvD,CAAC;QACD,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAmC,CAAC;IAC/D,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Store } from "./index.js";
|
|
2
|
+
export declare class FS implements Store {
|
|
3
|
+
write(path: string, content: Buffer): Promise<void>;
|
|
4
|
+
read(path: string): Promise<Buffer>;
|
|
5
|
+
list(prefix: string): Promise<string[]>;
|
|
6
|
+
exists(path: string): Promise<boolean>;
|
|
7
|
+
delete(path: string): Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=fs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/store/fs.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,qBAAa,EAAG,YAAW,KAAK;IACxB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKnD,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAInC,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAKvC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAStC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAG1C"}
|
package/dist/store/fs.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { readFile, writeFile, readdir, stat, rm, mkdir } from "node:fs/promises";
|
|
2
|
+
import { dirname } from "node:path";
|
|
3
|
+
export class FS {
|
|
4
|
+
async write(path, content) {
|
|
5
|
+
await mkdir(dirname(path), { recursive: true });
|
|
6
|
+
await writeFile(path, content);
|
|
7
|
+
}
|
|
8
|
+
async read(path) {
|
|
9
|
+
return readFile(path);
|
|
10
|
+
}
|
|
11
|
+
async list(prefix) {
|
|
12
|
+
const entries = await readdir(prefix, { withFileTypes: true });
|
|
13
|
+
return entries.filter((e) => e.isDirectory()).map((e) => e.name);
|
|
14
|
+
}
|
|
15
|
+
async exists(path) {
|
|
16
|
+
try {
|
|
17
|
+
await stat(path);
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
async delete(path) {
|
|
25
|
+
await rm(path, { recursive: true, force: true });
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=fs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs.js","sourceRoot":"","sources":["../../src/store/fs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACjF,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,MAAM,OAAO,EAAE;IACb,KAAK,CAAC,KAAK,CAAC,IAAY,EAAE,OAAe;QACvC,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,MAAM,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAY;QACrB,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,MAAc;QACvB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,MAAM,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/D,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACnE,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;YACjB,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,CAAC;CACF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Storage } from "@google-cloud/storage";
|
|
2
|
+
import type { Store } from "./index.js";
|
|
3
|
+
export declare class GCS implements Store {
|
|
4
|
+
private storage;
|
|
5
|
+
private bucketName;
|
|
6
|
+
constructor(storage: Storage, bucketName: string);
|
|
7
|
+
write(path: string, content: Buffer): Promise<void>;
|
|
8
|
+
read(path: string): Promise<Buffer>;
|
|
9
|
+
list(prefix: string): Promise<string[]>;
|
|
10
|
+
exists(path: string): Promise<boolean>;
|
|
11
|
+
delete(path: string): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=gcs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gcs.d.ts","sourceRoot":"","sources":["../../src/store/gcs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,qBAAa,GAAI,YAAW,KAAK;IAC/B,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,UAAU,CAAS;gBAEf,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM;IAK1C,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKnD,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAMnC,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAevC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAMtC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAa1C"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export class GCS {
|
|
2
|
+
storage;
|
|
3
|
+
bucketName;
|
|
4
|
+
constructor(storage, bucketName) {
|
|
5
|
+
this.storage = storage;
|
|
6
|
+
this.bucketName = bucketName;
|
|
7
|
+
}
|
|
8
|
+
async write(path, content) {
|
|
9
|
+
const bucket = this.storage.bucket(this.bucketName);
|
|
10
|
+
await bucket.file(path).save(content);
|
|
11
|
+
}
|
|
12
|
+
async read(path) {
|
|
13
|
+
const bucket = this.storage.bucket(this.bucketName);
|
|
14
|
+
const [contents] = await bucket.file(path).download();
|
|
15
|
+
return Buffer.from(contents);
|
|
16
|
+
}
|
|
17
|
+
async list(prefix) {
|
|
18
|
+
const normalizedPrefix = prefix.endsWith("/") ? prefix : prefix + "/";
|
|
19
|
+
const bucket = this.storage.bucket(this.bucketName);
|
|
20
|
+
const [, , apiResponse] = await bucket.getFiles({
|
|
21
|
+
prefix: normalizedPrefix,
|
|
22
|
+
delimiter: "/",
|
|
23
|
+
autoPaginate: false,
|
|
24
|
+
});
|
|
25
|
+
const prefixes = apiResponse?.prefixes ?? [];
|
|
26
|
+
return prefixes.map((p) => {
|
|
27
|
+
const rest = p.slice(normalizedPrefix.length);
|
|
28
|
+
return rest.endsWith("/") ? rest.slice(0, -1) : rest;
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
async exists(path) {
|
|
32
|
+
const bucket = this.storage.bucket(this.bucketName);
|
|
33
|
+
const [exists] = await bucket.file(path).exists();
|
|
34
|
+
return exists;
|
|
35
|
+
}
|
|
36
|
+
async delete(path) {
|
|
37
|
+
const bucket = this.storage.bucket(this.bucketName);
|
|
38
|
+
// Delete the exact key itself
|
|
39
|
+
await bucket.file(path).delete({ ignoreNotFound: true });
|
|
40
|
+
// Delete all children under path/
|
|
41
|
+
const normalizedPrefix = path.endsWith("/") ? path : path + "/";
|
|
42
|
+
const [files] = await bucket.getFiles({ prefix: normalizedPrefix });
|
|
43
|
+
for (const file of files) {
|
|
44
|
+
await file.delete();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=gcs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gcs.js","sourceRoot":"","sources":["../../src/store/gcs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Low-level storage backend for reading and writing raw files.
|
|
3
|
+
*/
|
|
4
|
+
export interface Store {
|
|
5
|
+
/** Write content to the given path, creating parent directories as needed. */
|
|
6
|
+
write(path: string, content: Buffer): Promise<void>;
|
|
7
|
+
/** Read raw content from the given path. */
|
|
8
|
+
read(path: string): Promise<Buffer>;
|
|
9
|
+
/** List immediate child directory names under the given prefix. */
|
|
10
|
+
list(prefix: string): Promise<string[]>;
|
|
11
|
+
/** Check whether a file or directory exists at the given path. */
|
|
12
|
+
exists(path: string): Promise<boolean>;
|
|
13
|
+
/** Recursively delete the file or directory at the given path. */
|
|
14
|
+
delete(path: string): Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
export { Memory } from "./memory.js";
|
|
17
|
+
export { FS } from "./fs.js";
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/store/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,KAAK;IACpB,8EAA8E;IAC9E,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,4CAA4C;IAC5C,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACpC,mEAAmE;IACnE,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACxC,kEAAkE;IAClE,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,kEAAkE;IAClE,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAED,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/store/index.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Store } from "./index.js";
|
|
2
|
+
export declare class Memory implements Store {
|
|
3
|
+
private files;
|
|
4
|
+
write(path: string, content: Buffer): Promise<void>;
|
|
5
|
+
read(path: string): Promise<Buffer>;
|
|
6
|
+
list(prefix: string): Promise<string[]>;
|
|
7
|
+
exists(path: string): Promise<boolean>;
|
|
8
|
+
delete(path: string): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=memory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/store/memory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,qBAAa,MAAO,YAAW,KAAK;IAClC,OAAO,CAAC,KAAK,CAA6B;IAEpC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAInD,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQnC,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAgBvC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAStC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAQ1C"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export class Memory {
|
|
2
|
+
files = new Map();
|
|
3
|
+
async write(path, content) {
|
|
4
|
+
this.files.set(path, content);
|
|
5
|
+
}
|
|
6
|
+
async read(path) {
|
|
7
|
+
const content = this.files.get(path);
|
|
8
|
+
if (!content) {
|
|
9
|
+
throw new Error(`ENOENT: no such file: ${path}`);
|
|
10
|
+
}
|
|
11
|
+
return content;
|
|
12
|
+
}
|
|
13
|
+
async list(prefix) {
|
|
14
|
+
const normalizedPrefix = prefix.endsWith("/") ? prefix : prefix + "/";
|
|
15
|
+
const dirs = new Set();
|
|
16
|
+
for (const key of this.files.keys()) {
|
|
17
|
+
if (!key.startsWith(normalizedPrefix))
|
|
18
|
+
continue;
|
|
19
|
+
const rest = key.slice(normalizedPrefix.length);
|
|
20
|
+
const slashIndex = rest.indexOf("/");
|
|
21
|
+
if (slashIndex !== -1) {
|
|
22
|
+
dirs.add(rest.slice(0, slashIndex));
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return [...dirs];
|
|
26
|
+
}
|
|
27
|
+
async exists(path) {
|
|
28
|
+
if (this.files.has(path))
|
|
29
|
+
return true;
|
|
30
|
+
const dirPrefix = path.endsWith("/") ? path : path + "/";
|
|
31
|
+
for (const key of this.files.keys()) {
|
|
32
|
+
if (key.startsWith(dirPrefix))
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
async delete(path) {
|
|
38
|
+
const dirPrefix = path.endsWith("/") ? path : path + "/";
|
|
39
|
+
const toDelete = [path];
|
|
40
|
+
for (const key of this.files.keys()) {
|
|
41
|
+
if (key.startsWith(dirPrefix))
|
|
42
|
+
toDelete.push(key);
|
|
43
|
+
}
|
|
44
|
+
for (const key of toDelete)
|
|
45
|
+
this.files.delete(key);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/store/memory.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,MAAM;IACT,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE1C,KAAK,CAAC,KAAK,CAAC,IAAY,EAAE,OAAe;QACvC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAY;QACrB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,EAAE,CAAC,CAAC;QACnD,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,MAAc;QACvB,MAAM,gBAAgB,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC;QACtE,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAE/B,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;YACpC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,gBAAgB,CAAC;gBAAE,SAAS;YAChD,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;YAChD,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACrC,IAAI,UAAU,KAAK,CAAC,CAAC,EAAE,CAAC;gBACtB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC;YACtC,CAAC;QACH,CAAC;QAED,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QACtC,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC;QACzD,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;YACpC,IAAI,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC;gBAAE,OAAO,IAAI,CAAC;QAC7C,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC;QACzD,MAAM,QAAQ,GAAG,CAAC,IAAI,CAAC,CAAC;QACxB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;YACpC,IAAI,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC;gBAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpD,CAAC;QACD,KAAK,MAAM,GAAG,IAAI,QAAQ;YAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACrD,CAAC;CACF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { S3Client } from "@aws-sdk/client-s3";
|
|
2
|
+
import type { Store } from "./index.js";
|
|
3
|
+
export declare class S3 implements Store {
|
|
4
|
+
private client;
|
|
5
|
+
private bucket;
|
|
6
|
+
constructor(client: S3Client, bucket: string);
|
|
7
|
+
write(path: string, content: Buffer): Promise<void>;
|
|
8
|
+
read(path: string): Promise<Buffer>;
|
|
9
|
+
list(prefix: string): Promise<string[]>;
|
|
10
|
+
exists(path: string): Promise<boolean>;
|
|
11
|
+
delete(path: string): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=s3.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s3.d.ts","sourceRoot":"","sources":["../../src/store/s3.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EAIT,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,qBAAa,EAAG,YAAW,KAAK;IAC9B,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM;IAKtC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUnD,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAenC,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IA8BvC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAoBtC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CA4C1C"}
|
package/dist/store/s3.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
export class S3 {
|
|
2
|
+
client;
|
|
3
|
+
bucket;
|
|
4
|
+
constructor(client, bucket) {
|
|
5
|
+
this.client = client;
|
|
6
|
+
this.bucket = bucket;
|
|
7
|
+
}
|
|
8
|
+
async write(path, content) {
|
|
9
|
+
const { PutObjectCommand } = await import("@aws-sdk/client-s3");
|
|
10
|
+
const params = {
|
|
11
|
+
Bucket: this.bucket,
|
|
12
|
+
Key: path,
|
|
13
|
+
Body: content,
|
|
14
|
+
};
|
|
15
|
+
await this.client.send(new PutObjectCommand(params));
|
|
16
|
+
}
|
|
17
|
+
async read(path) {
|
|
18
|
+
const { GetObjectCommand } = await import("@aws-sdk/client-s3");
|
|
19
|
+
const params = {
|
|
20
|
+
Bucket: this.bucket,
|
|
21
|
+
Key: path,
|
|
22
|
+
};
|
|
23
|
+
const response = await this.client.send(new GetObjectCommand(params));
|
|
24
|
+
const stream = response.Body;
|
|
25
|
+
if (!stream) {
|
|
26
|
+
throw new Error(`Empty response body for key: ${path}`);
|
|
27
|
+
}
|
|
28
|
+
const bytes = await stream.transformToByteArray();
|
|
29
|
+
return Buffer.from(bytes);
|
|
30
|
+
}
|
|
31
|
+
async list(prefix) {
|
|
32
|
+
const { ListObjectsV2Command } = await import("@aws-sdk/client-s3");
|
|
33
|
+
const normalizedPrefix = prefix.endsWith("/") ? prefix : prefix + "/";
|
|
34
|
+
const dirs = [];
|
|
35
|
+
let continuationToken;
|
|
36
|
+
do {
|
|
37
|
+
const response = await this.client.send(new ListObjectsV2Command({
|
|
38
|
+
Bucket: this.bucket,
|
|
39
|
+
Prefix: normalizedPrefix,
|
|
40
|
+
Delimiter: "/",
|
|
41
|
+
ContinuationToken: continuationToken,
|
|
42
|
+
}));
|
|
43
|
+
for (const cp of response.CommonPrefixes ?? []) {
|
|
44
|
+
if (!cp.Prefix)
|
|
45
|
+
continue;
|
|
46
|
+
const rest = cp.Prefix.slice(normalizedPrefix.length);
|
|
47
|
+
dirs.push(rest.endsWith("/") ? rest.slice(0, -1) : rest);
|
|
48
|
+
}
|
|
49
|
+
continuationToken = response.IsTruncated
|
|
50
|
+
? response.NextContinuationToken
|
|
51
|
+
: undefined;
|
|
52
|
+
} while (continuationToken);
|
|
53
|
+
return dirs;
|
|
54
|
+
}
|
|
55
|
+
async exists(path) {
|
|
56
|
+
const { HeadObjectCommand } = await import("@aws-sdk/client-s3");
|
|
57
|
+
try {
|
|
58
|
+
const params = {
|
|
59
|
+
Bucket: this.bucket,
|
|
60
|
+
Key: path,
|
|
61
|
+
};
|
|
62
|
+
await this.client.send(new HeadObjectCommand(params));
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
if (err instanceof Error &&
|
|
67
|
+
(err.name === "NotFound" || err.name === "NoSuchKey")) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
throw err;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
async delete(path) {
|
|
74
|
+
const { ListObjectsV2Command, DeleteObjectsCommand } = await import("@aws-sdk/client-s3");
|
|
75
|
+
// Delete the exact key itself
|
|
76
|
+
await this.client.send(new DeleteObjectsCommand({
|
|
77
|
+
Bucket: this.bucket,
|
|
78
|
+
Delete: { Objects: [{ Key: path }] },
|
|
79
|
+
}));
|
|
80
|
+
// Delete all children under path/
|
|
81
|
+
const normalizedPrefix = path.endsWith("/") ? path : path + "/";
|
|
82
|
+
let continuationToken;
|
|
83
|
+
do {
|
|
84
|
+
const response = await this.client.send(new ListObjectsV2Command({
|
|
85
|
+
Bucket: this.bucket,
|
|
86
|
+
Prefix: normalizedPrefix,
|
|
87
|
+
ContinuationToken: continuationToken,
|
|
88
|
+
}));
|
|
89
|
+
const objects = (response.Contents ?? [])
|
|
90
|
+
.filter((obj) => obj.Key)
|
|
91
|
+
.map((obj) => ({ Key: obj.Key }));
|
|
92
|
+
if (objects.length > 0) {
|
|
93
|
+
await this.client.send(new DeleteObjectsCommand({
|
|
94
|
+
Bucket: this.bucket,
|
|
95
|
+
Delete: { Objects: objects },
|
|
96
|
+
}));
|
|
97
|
+
}
|
|
98
|
+
continuationToken = response.IsTruncated
|
|
99
|
+
? response.NextContinuationToken
|
|
100
|
+
: undefined;
|
|
101
|
+
} while (continuationToken);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=s3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s3.js","sourceRoot":"","sources":["../../src/store/s3.ts"],"names":[],"mappings":"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"}
|
package/dist/store.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Low-level storage backend for reading and writing raw files.
|
|
3
|
+
*/
|
|
4
|
+
export interface Store {
|
|
5
|
+
/** Write content to the given path, creating parent directories as needed. */
|
|
6
|
+
write(path: string, content: Buffer): Promise<void>;
|
|
7
|
+
/** Read raw content from the given path. */
|
|
8
|
+
read(path: string): Promise<Buffer>;
|
|
9
|
+
/** List immediate child directory names under the given prefix. */
|
|
10
|
+
list(prefix: string): Promise<string[]>;
|
|
11
|
+
/** Check whether a file or directory exists at the given path. */
|
|
12
|
+
exists(path: string): Promise<boolean>;
|
|
13
|
+
/** Recursively delete the file or directory at the given path. */
|
|
14
|
+
delete(path: string): Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Store implementation backed by the local filesystem.
|
|
18
|
+
*/
|
|
19
|
+
export declare class FileSystemStore implements Store {
|
|
20
|
+
write(path: string, content: Buffer): Promise<void>;
|
|
21
|
+
read(path: string): Promise<Buffer>;
|
|
22
|
+
list(prefix: string): Promise<string[]>;
|
|
23
|
+
exists(path: string): Promise<boolean>;
|
|
24
|
+
delete(path: string): Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,WAAW,KAAK;IACpB,8EAA8E;IAC9E,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,4CAA4C;IAC5C,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACpC,mEAAmE;IACnE,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACxC,kEAAkE;IAClE,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,kEAAkE;IAClE,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAED;;GAEG;AACH,qBAAa,eAAgB,YAAW,KAAK;IACrC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKnD,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAInC,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAKvC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAStC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAG1C"}
|
package/dist/store.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { readFile, writeFile, readdir, stat, rm, mkdir } from "node:fs/promises";
|
|
2
|
+
import { dirname } from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* Store implementation backed by the local filesystem.
|
|
5
|
+
*/
|
|
6
|
+
export class FileSystemStore {
|
|
7
|
+
async write(path, content) {
|
|
8
|
+
await mkdir(dirname(path), { recursive: true });
|
|
9
|
+
await writeFile(path, content);
|
|
10
|
+
}
|
|
11
|
+
async read(path) {
|
|
12
|
+
return readFile(path);
|
|
13
|
+
}
|
|
14
|
+
async list(prefix) {
|
|
15
|
+
const entries = await readdir(prefix, { withFileTypes: true });
|
|
16
|
+
return entries.filter((e) => e.isDirectory()).map((e) => e.name);
|
|
17
|
+
}
|
|
18
|
+
async exists(path) {
|
|
19
|
+
try {
|
|
20
|
+
await stat(path);
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
async delete(path) {
|
|
28
|
+
await rm(path, { recursive: true, force: true });
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACjF,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkBpC;;GAEG;AACH,MAAM,OAAO,eAAe;IAC1B,KAAK,CAAC,KAAK,CAAC,IAAY,EAAE,OAAe;QACvC,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,MAAM,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAY;QACrB,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,MAAc;QACvB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,MAAM,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/D,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACnE,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;YACjB,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tarball.d.ts","sourceRoot":"","sources":["../src/tarball.ts"],"names":[],"mappings":"AAYA,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAmDlE"}
|
package/dist/tarball.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { gunzipSync } from "node:zlib";
|
|
2
|
+
// POSIX tar header field offsets and sizes (bytes)
|
|
3
|
+
const BLOCK_SIZE = 512;
|
|
4
|
+
const NAME_OFFSET = 0;
|
|
5
|
+
const NAME_LENGTH = 100;
|
|
6
|
+
const SIZE_OFFSET = 124;
|
|
7
|
+
const SIZE_LENGTH = 12;
|
|
8
|
+
const TYPEFLAG_OFFSET = 156;
|
|
9
|
+
const PREFIX_OFFSET = 345;
|
|
10
|
+
const PREFIX_LENGTH = 155;
|
|
11
|
+
export function parseTarGz(compressed) {
|
|
12
|
+
const tar = gunzipSync(compressed);
|
|
13
|
+
const files = new Map();
|
|
14
|
+
let offset = 0;
|
|
15
|
+
let paxPath;
|
|
16
|
+
// GitHub tarballs nest all files under a single prefix directory (e.g. "owner-repo-sha/").
|
|
17
|
+
// We detect this from the first path containing "/" and strip it from all entries.
|
|
18
|
+
let stripPrefix = "";
|
|
19
|
+
while (offset + BLOCK_SIZE <= tar.length) {
|
|
20
|
+
const header = tar.subarray(offset, offset + BLOCK_SIZE);
|
|
21
|
+
if (header.every((b) => b === 0))
|
|
22
|
+
break;
|
|
23
|
+
const name = readString(header, NAME_OFFSET, NAME_LENGTH);
|
|
24
|
+
const size = readOctal(header, SIZE_OFFSET, SIZE_LENGTH);
|
|
25
|
+
const typeflag = String.fromCharCode(header[TYPEFLAG_OFFSET]);
|
|
26
|
+
const prefix = readString(header, PREFIX_OFFSET, PREFIX_LENGTH);
|
|
27
|
+
const fullName = prefix ? `${prefix}/${name}` : name;
|
|
28
|
+
const dataBlocks = size > 0 ? Math.ceil(size / BLOCK_SIZE) * BLOCK_SIZE : 0;
|
|
29
|
+
offset += BLOCK_SIZE;
|
|
30
|
+
if (typeflag === "x") {
|
|
31
|
+
const paxData = tar.subarray(offset, offset + size).toString("utf-8");
|
|
32
|
+
paxPath = extractPaxPath(paxData);
|
|
33
|
+
offset += dataBlocks;
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
let path = paxPath ?? fullName;
|
|
37
|
+
paxPath = undefined;
|
|
38
|
+
if (!stripPrefix && path.includes("/")) {
|
|
39
|
+
stripPrefix = path.slice(0, path.indexOf("/") + 1);
|
|
40
|
+
}
|
|
41
|
+
if (stripPrefix && path.startsWith(stripPrefix)) {
|
|
42
|
+
path = path.slice(stripPrefix.length);
|
|
43
|
+
}
|
|
44
|
+
if ((typeflag === "0" || typeflag === "\0") && path) {
|
|
45
|
+
files.set(path, Buffer.from(tar.subarray(offset, offset + size)));
|
|
46
|
+
}
|
|
47
|
+
offset += dataBlocks;
|
|
48
|
+
}
|
|
49
|
+
return files;
|
|
50
|
+
}
|
|
51
|
+
function readString(buf, offset, length) {
|
|
52
|
+
const slice = buf.subarray(offset, offset + length);
|
|
53
|
+
const nullIdx = slice.indexOf(0);
|
|
54
|
+
return slice.subarray(0, nullIdx === -1 ? length : nullIdx).toString("utf-8");
|
|
55
|
+
}
|
|
56
|
+
function readOctal(buf, offset, length) {
|
|
57
|
+
const str = readString(buf, offset, length).trim();
|
|
58
|
+
return str ? parseInt(str, 8) : 0;
|
|
59
|
+
}
|
|
60
|
+
function extractPaxPath(data) {
|
|
61
|
+
for (const line of data.split("\n")) {
|
|
62
|
+
const match = line.match(/^\d+ path=(.+)/);
|
|
63
|
+
if (match?.[1])
|
|
64
|
+
return match[1];
|
|
65
|
+
}
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=tarball.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tarball.js","sourceRoot":"","sources":["../src/tarball.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The frontmatter of a SKILL.md.
|
|
3
|
+
*/
|
|
4
|
+
export interface Metadata {
|
|
5
|
+
name: string;
|
|
6
|
+
description: string;
|
|
7
|
+
license?: string;
|
|
8
|
+
compatibility?: string;
|
|
9
|
+
allowedTools?: string[];
|
|
10
|
+
metadata?: Record<string, unknown>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "skills-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Skills SDK for JavaScript",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"agent skills",
|
|
8
|
+
"skills"
|
|
9
|
+
],
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://github.com/a4s-lab/skills.git",
|
|
14
|
+
"directory": "js"
|
|
15
|
+
},
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"import": "./dist/index.js",
|
|
19
|
+
"types": "./dist/index.d.ts"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist"
|
|
24
|
+
],
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"gray-matter": "^4"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@types/node": "^25",
|
|
30
|
+
"prettier": "^3.8.1",
|
|
31
|
+
"typescript": "^5",
|
|
32
|
+
"vitest": "^3"
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "tsc",
|
|
36
|
+
"test": "vitest run"
|
|
37
|
+
}
|
|
38
|
+
}
|