overskill 1.0.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/LICENSE +21 -0
- package/README.md +261 -0
- package/dist/commands/add.d.ts +3 -0
- package/dist/commands/add.d.ts.map +1 -0
- package/dist/commands/add.js +121 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/bundle.d.ts +3 -0
- package/dist/commands/bundle.d.ts.map +1 -0
- package/dist/commands/bundle.js +58 -0
- package/dist/commands/bundle.js.map +1 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +109 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/delete.d.ts +3 -0
- package/dist/commands/delete.d.ts.map +1 -0
- package/dist/commands/delete.js +64 -0
- package/dist/commands/delete.js.map +1 -0
- package/dist/commands/diff.d.ts +3 -0
- package/dist/commands/diff.d.ts.map +1 -0
- package/dist/commands/diff.js +93 -0
- package/dist/commands/diff.js.map +1 -0
- package/dist/commands/edit.d.ts +3 -0
- package/dist/commands/edit.d.ts.map +1 -0
- package/dist/commands/edit.js +69 -0
- package/dist/commands/edit.js.map +1 -0
- package/dist/commands/import.d.ts +3 -0
- package/dist/commands/import.d.ts.map +1 -0
- package/dist/commands/import.js +514 -0
- package/dist/commands/import.js.map +1 -0
- package/dist/commands/info.d.ts +3 -0
- package/dist/commands/info.d.ts.map +1 -0
- package/dist/commands/info.js +89 -0
- package/dist/commands/info.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +88 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/list.d.ts +3 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +84 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/login.d.ts +3 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +143 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/new.d.ts +3 -0
- package/dist/commands/new.d.ts.map +1 -0
- package/dist/commands/new.js +262 -0
- package/dist/commands/new.js.map +1 -0
- package/dist/commands/publish.d.ts +3 -0
- package/dist/commands/publish.d.ts.map +1 -0
- package/dist/commands/publish.js +215 -0
- package/dist/commands/publish.js.map +1 -0
- package/dist/commands/push.d.ts +3 -0
- package/dist/commands/push.d.ts.map +1 -0
- package/dist/commands/push.js +151 -0
- package/dist/commands/push.js.map +1 -0
- package/dist/commands/registry.d.ts +3 -0
- package/dist/commands/registry.d.ts.map +1 -0
- package/dist/commands/registry.js +169 -0
- package/dist/commands/registry.js.map +1 -0
- package/dist/commands/remove.d.ts +3 -0
- package/dist/commands/remove.d.ts.map +1 -0
- package/dist/commands/remove.js +48 -0
- package/dist/commands/remove.js.map +1 -0
- package/dist/commands/search.d.ts +3 -0
- package/dist/commands/search.d.ts.map +1 -0
- package/dist/commands/search.js +48 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/sync.d.ts +3 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +160 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/update.d.ts +3 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +130 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/validate.d.ts +3 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +94 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api.d.ts +60 -0
- package/dist/lib/api.d.ts.map +1 -0
- package/dist/lib/api.js +340 -0
- package/dist/lib/api.js.map +1 -0
- package/dist/lib/auth.d.ts +78 -0
- package/dist/lib/auth.d.ts.map +1 -0
- package/dist/lib/auth.js +241 -0
- package/dist/lib/auth.js.map +1 -0
- package/dist/lib/config.d.ts +94 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +294 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/editor.d.ts +6 -0
- package/dist/lib/editor.d.ts.map +1 -0
- package/dist/lib/editor.js +60 -0
- package/dist/lib/editor.js.map +1 -0
- package/dist/lib/fs.d.ts +74 -0
- package/dist/lib/fs.d.ts.map +1 -0
- package/dist/lib/fs.js +235 -0
- package/dist/lib/fs.js.map +1 -0
- package/dist/lib/index-gen.d.ts +18 -0
- package/dist/lib/index-gen.d.ts.map +1 -0
- package/dist/lib/index-gen.js +75 -0
- package/dist/lib/index-gen.js.map +1 -0
- package/dist/lib/local-registry/index.d.ts +15 -0
- package/dist/lib/local-registry/index.d.ts.map +1 -0
- package/dist/lib/local-registry/index.js +18 -0
- package/dist/lib/local-registry/index.js.map +1 -0
- package/dist/lib/local-registry/objects.d.ts +51 -0
- package/dist/lib/local-registry/objects.d.ts.map +1 -0
- package/dist/lib/local-registry/objects.js +148 -0
- package/dist/lib/local-registry/objects.js.map +1 -0
- package/dist/lib/local-registry/paths.d.ts +53 -0
- package/dist/lib/local-registry/paths.d.ts.map +1 -0
- package/dist/lib/local-registry/paths.js +85 -0
- package/dist/lib/local-registry/paths.js.map +1 -0
- package/dist/lib/local-registry/skills.d.ts +83 -0
- package/dist/lib/local-registry/skills.d.ts.map +1 -0
- package/dist/lib/local-registry/skills.js +261 -0
- package/dist/lib/local-registry/skills.js.map +1 -0
- package/dist/lib/local-registry/types.d.ts +79 -0
- package/dist/lib/local-registry/types.d.ts.map +1 -0
- package/dist/lib/local-registry/types.js +5 -0
- package/dist/lib/local-registry/types.js.map +1 -0
- package/dist/lib/local-registry/versions.d.ts +61 -0
- package/dist/lib/local-registry/versions.d.ts.map +1 -0
- package/dist/lib/local-registry/versions.js +163 -0
- package/dist/lib/local-registry/versions.js.map +1 -0
- package/dist/lib/lockfile.d.ts +38 -0
- package/dist/lib/lockfile.d.ts.map +1 -0
- package/dist/lib/lockfile.js +102 -0
- package/dist/lib/lockfile.js.map +1 -0
- package/dist/lib/meta-skill.d.ts +6 -0
- package/dist/lib/meta-skill.d.ts.map +1 -0
- package/dist/lib/meta-skill.js +72 -0
- package/dist/lib/meta-skill.js.map +1 -0
- package/dist/lib/semver.d.ts +63 -0
- package/dist/lib/semver.d.ts.map +1 -0
- package/dist/lib/semver.js +107 -0
- package/dist/lib/semver.js.map +1 -0
- package/dist/types.d.ts +147 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content-addressed object storage for skill content
|
|
3
|
+
*
|
|
4
|
+
* Objects are stored by their SHA256 hash, providing:
|
|
5
|
+
* - Deduplication across versions
|
|
6
|
+
* - Integrity verification on read
|
|
7
|
+
* - Atomic writes using temp file + rename
|
|
8
|
+
*/
|
|
9
|
+
import * as fs from 'fs';
|
|
10
|
+
import * as path from 'path';
|
|
11
|
+
import * as crypto from 'crypto';
|
|
12
|
+
import { getObjectsDir, getObjectPath, ensureDir } from './paths.js';
|
|
13
|
+
/**
|
|
14
|
+
* Compute SHA256 hash of content
|
|
15
|
+
*/
|
|
16
|
+
export function computeHash(content) {
|
|
17
|
+
return crypto.createHash('sha256').update(content, 'utf8').digest('hex');
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Write content to the object store.
|
|
21
|
+
* Uses atomic write (temp file + rename) to prevent corruption.
|
|
22
|
+
*
|
|
23
|
+
* @returns The SHA256 hash of the content
|
|
24
|
+
*/
|
|
25
|
+
export function writeObject(content) {
|
|
26
|
+
const sha256 = computeHash(content);
|
|
27
|
+
const objectPath = getObjectPath(sha256);
|
|
28
|
+
// If object already exists (same content), no need to write
|
|
29
|
+
if (fs.existsSync(objectPath)) {
|
|
30
|
+
return sha256;
|
|
31
|
+
}
|
|
32
|
+
// Ensure objects directory exists
|
|
33
|
+
ensureDir(getObjectsDir());
|
|
34
|
+
// Atomic write: write to temp file, then rename
|
|
35
|
+
const tempPath = `${objectPath}.tmp.${process.pid}.${Date.now()}`;
|
|
36
|
+
try {
|
|
37
|
+
fs.writeFileSync(tempPath, content, 'utf-8');
|
|
38
|
+
fs.renameSync(tempPath, objectPath);
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
// Clean up temp file on error
|
|
42
|
+
try {
|
|
43
|
+
if (fs.existsSync(tempPath)) {
|
|
44
|
+
fs.unlinkSync(tempPath);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// Ignore cleanup errors
|
|
49
|
+
}
|
|
50
|
+
throw error;
|
|
51
|
+
}
|
|
52
|
+
return sha256;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Read content from the object store.
|
|
56
|
+
* Verifies integrity by checking the hash matches the filename.
|
|
57
|
+
*
|
|
58
|
+
* @returns The content, or null if object doesn't exist or is corrupted
|
|
59
|
+
*/
|
|
60
|
+
export function readObject(sha256) {
|
|
61
|
+
const objectPath = getObjectPath(sha256);
|
|
62
|
+
if (!fs.existsSync(objectPath)) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
const content = fs.readFileSync(objectPath, 'utf-8');
|
|
66
|
+
// Verify integrity
|
|
67
|
+
const actualHash = computeHash(content);
|
|
68
|
+
if (actualHash !== sha256) {
|
|
69
|
+
console.error(`Cache integrity error: object ${sha256} corrupted (actual hash: ${actualHash}). ` +
|
|
70
|
+
`Run 'skills cache verify' for details.`);
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
return content;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Check if an object exists in the store
|
|
77
|
+
*/
|
|
78
|
+
export function objectExists(sha256) {
|
|
79
|
+
return fs.existsSync(getObjectPath(sha256));
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Delete an object from the store
|
|
83
|
+
*
|
|
84
|
+
* @returns true if deleted, false if didn't exist
|
|
85
|
+
*/
|
|
86
|
+
export function deleteObject(sha256) {
|
|
87
|
+
const objectPath = getObjectPath(sha256);
|
|
88
|
+
if (!fs.existsSync(objectPath)) {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
fs.unlinkSync(objectPath);
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* List all objects in the store
|
|
96
|
+
*/
|
|
97
|
+
export function listObjects() {
|
|
98
|
+
const objectsDir = getObjectsDir();
|
|
99
|
+
if (!fs.existsSync(objectsDir)) {
|
|
100
|
+
return [];
|
|
101
|
+
}
|
|
102
|
+
return fs.readdirSync(objectsDir).filter((name) => {
|
|
103
|
+
// Filter out temp files
|
|
104
|
+
return !name.includes('.tmp.');
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Verify integrity of all objects
|
|
109
|
+
*
|
|
110
|
+
* @returns Array of corrupted object hashes
|
|
111
|
+
*/
|
|
112
|
+
export function verifyAllObjects() {
|
|
113
|
+
const corrupted = [];
|
|
114
|
+
for (const sha256 of listObjects()) {
|
|
115
|
+
const objectPath = getObjectPath(sha256);
|
|
116
|
+
const content = fs.readFileSync(objectPath, 'utf-8');
|
|
117
|
+
const actualHash = computeHash(content);
|
|
118
|
+
if (actualHash !== sha256) {
|
|
119
|
+
corrupted.push(sha256);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return corrupted;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Clean up orphaned temp files
|
|
126
|
+
*/
|
|
127
|
+
export function cleanupTempFiles() {
|
|
128
|
+
const objectsDir = getObjectsDir();
|
|
129
|
+
if (!fs.existsSync(objectsDir)) {
|
|
130
|
+
return 0;
|
|
131
|
+
}
|
|
132
|
+
let cleaned = 0;
|
|
133
|
+
const files = fs.readdirSync(objectsDir);
|
|
134
|
+
for (const name of files) {
|
|
135
|
+
if (name.includes('.tmp.')) {
|
|
136
|
+
const filePath = path.join(objectsDir, name);
|
|
137
|
+
// Only delete temp files older than 1 hour
|
|
138
|
+
const stats = fs.statSync(filePath);
|
|
139
|
+
const age = Date.now() - stats.mtimeMs;
|
|
140
|
+
if (age > 60 * 60 * 1000) {
|
|
141
|
+
fs.unlinkSync(filePath);
|
|
142
|
+
cleaned++;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return cleaned;
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=objects.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"objects.js","sourceRoot":"","sources":["../../../src/lib/local-registry/objects.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Path utilities for the local registry
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Get the root directory of the local registry.
|
|
6
|
+
* Located alongside the CLI config file (e.g., ~/.overskill/registry/)
|
|
7
|
+
*/
|
|
8
|
+
export declare function getRoot(): string;
|
|
9
|
+
/**
|
|
10
|
+
* Get the objects directory (content-addressed storage)
|
|
11
|
+
*/
|
|
12
|
+
export declare function getObjectsDir(): string;
|
|
13
|
+
/**
|
|
14
|
+
* Get the path to a specific object by its sha256 hash
|
|
15
|
+
*/
|
|
16
|
+
export declare function getObjectPath(sha256: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Get the skills directory
|
|
19
|
+
*/
|
|
20
|
+
export declare function getSkillsDir(): string;
|
|
21
|
+
/**
|
|
22
|
+
* Get the directory for a specific skill
|
|
23
|
+
*/
|
|
24
|
+
export declare function getSkillDir(slug: string): string;
|
|
25
|
+
/**
|
|
26
|
+
* Get the path to a skill's meta.yaml
|
|
27
|
+
*/
|
|
28
|
+
export declare function getMetaPath(slug: string): string;
|
|
29
|
+
/**
|
|
30
|
+
* Get the path to a skill's versions.yaml
|
|
31
|
+
*/
|
|
32
|
+
export declare function getVersionsPath(slug: string): string;
|
|
33
|
+
/**
|
|
34
|
+
* Ensure a directory exists, creating it recursively if needed
|
|
35
|
+
*/
|
|
36
|
+
export declare function ensureDir(dirPath: string): void;
|
|
37
|
+
/**
|
|
38
|
+
* Ensure the registry structure exists
|
|
39
|
+
*/
|
|
40
|
+
export declare function ensureRegistryStructure(): void;
|
|
41
|
+
/**
|
|
42
|
+
* Check if the registry exists
|
|
43
|
+
*/
|
|
44
|
+
export declare function registryExists(): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Check if a skill exists in the registry
|
|
47
|
+
*/
|
|
48
|
+
export declare function skillExists(slug: string): boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Check if an object exists
|
|
51
|
+
*/
|
|
52
|
+
export declare function objectExists(sha256: string): boolean;
|
|
53
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../src/lib/local-registry/paths.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH;;;GAGG;AACH,wBAAgB,OAAO,IAAI,MAAM,CAIhC;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAI/C;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,IAAI,CAG9C;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,OAAO,CAExC;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEpD"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Path utilities for the local registry
|
|
3
|
+
*/
|
|
4
|
+
import * as path from 'path';
|
|
5
|
+
import * as fs from 'fs';
|
|
6
|
+
import { getConfigPath } from '../auth.js';
|
|
7
|
+
/**
|
|
8
|
+
* Get the root directory of the local registry.
|
|
9
|
+
* Located alongside the CLI config file (e.g., ~/.overskill/registry/)
|
|
10
|
+
*/
|
|
11
|
+
export function getRoot() {
|
|
12
|
+
const configPath = getConfigPath();
|
|
13
|
+
const configDir = path.dirname(configPath);
|
|
14
|
+
return path.join(configDir, 'registry');
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Get the objects directory (content-addressed storage)
|
|
18
|
+
*/
|
|
19
|
+
export function getObjectsDir() {
|
|
20
|
+
return path.join(getRoot(), 'objects');
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Get the path to a specific object by its sha256 hash
|
|
24
|
+
*/
|
|
25
|
+
export function getObjectPath(sha256) {
|
|
26
|
+
return path.join(getObjectsDir(), sha256);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Get the skills directory
|
|
30
|
+
*/
|
|
31
|
+
export function getSkillsDir() {
|
|
32
|
+
return path.join(getRoot(), 'skills');
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Get the directory for a specific skill
|
|
36
|
+
*/
|
|
37
|
+
export function getSkillDir(slug) {
|
|
38
|
+
return path.join(getSkillsDir(), slug);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Get the path to a skill's meta.yaml
|
|
42
|
+
*/
|
|
43
|
+
export function getMetaPath(slug) {
|
|
44
|
+
return path.join(getSkillDir(slug), 'meta.yaml');
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Get the path to a skill's versions.yaml
|
|
48
|
+
*/
|
|
49
|
+
export function getVersionsPath(slug) {
|
|
50
|
+
return path.join(getSkillDir(slug), 'versions.yaml');
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Ensure a directory exists, creating it recursively if needed
|
|
54
|
+
*/
|
|
55
|
+
export function ensureDir(dirPath) {
|
|
56
|
+
if (!fs.existsSync(dirPath)) {
|
|
57
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Ensure the registry structure exists
|
|
62
|
+
*/
|
|
63
|
+
export function ensureRegistryStructure() {
|
|
64
|
+
ensureDir(getObjectsDir());
|
|
65
|
+
ensureDir(getSkillsDir());
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Check if the registry exists
|
|
69
|
+
*/
|
|
70
|
+
export function registryExists() {
|
|
71
|
+
return fs.existsSync(getRoot());
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Check if a skill exists in the registry
|
|
75
|
+
*/
|
|
76
|
+
export function skillExists(slug) {
|
|
77
|
+
return fs.existsSync(getMetaPath(slug)) && fs.existsSync(getVersionsPath(slug));
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Check if an object exists
|
|
81
|
+
*/
|
|
82
|
+
export function objectExists(sha256) {
|
|
83
|
+
return fs.existsSync(getObjectPath(sha256));
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../src/lib/local-registry/paths.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C;;;GAGG;AACH,MAAM,UAAU,OAAO;IACrB,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IACnC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3C,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;AAC1C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;AACzC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,MAAM,CAAC,CAAC;AAC5C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;AACxC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,CAAC;AACzC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC,CAAC;AACnD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,eAAe,CAAC,CAAC;AACvD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,OAAe;IACvC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB;IACrC,SAAS,CAAC,aAAa,EAAE,CAAC,CAAC;IAC3B,SAAS,CAAC,YAAY,EAAE,CAAC,CAAC;AAC5B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;AAClF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc;IACzC,OAAO,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;AAC9C,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill CRUD operations for the local registry
|
|
3
|
+
*/
|
|
4
|
+
import type { LocalSkillMeta, PutVersionParams, GetVersionResult, SkillSummary, SearchResult, Provenance } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Read meta.yaml for a skill
|
|
7
|
+
*/
|
|
8
|
+
export declare function readMeta(slug: string): LocalSkillMeta | null;
|
|
9
|
+
/**
|
|
10
|
+
* Write meta.yaml for a skill (atomic)
|
|
11
|
+
*/
|
|
12
|
+
export declare function writeMeta(slug: string, meta: LocalSkillMeta): void;
|
|
13
|
+
/**
|
|
14
|
+
* Put a new skill version into the registry
|
|
15
|
+
*
|
|
16
|
+
* @returns The sha256 hash of the content
|
|
17
|
+
*/
|
|
18
|
+
export declare function putVersion(params: PutVersionParams): {
|
|
19
|
+
sha256: string;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Get a specific version of a skill
|
|
23
|
+
*
|
|
24
|
+
* @returns The skill content and metadata, or null if not found
|
|
25
|
+
*/
|
|
26
|
+
export declare function getVersion(slug: string, version: string): GetVersionResult | null;
|
|
27
|
+
/**
|
|
28
|
+
* Get the latest version of a skill
|
|
29
|
+
*/
|
|
30
|
+
export declare function getLatest(slug: string): GetVersionResult | null;
|
|
31
|
+
/**
|
|
32
|
+
* Resolve and get a skill version based on constraint
|
|
33
|
+
*
|
|
34
|
+
* @param slug - Skill slug
|
|
35
|
+
* @param constraint - Optional semver constraint
|
|
36
|
+
* @returns The resolved skill, or null if no match
|
|
37
|
+
*/
|
|
38
|
+
export declare function resolveAndGet(slug: string, constraint?: string): GetVersionResult | null;
|
|
39
|
+
/**
|
|
40
|
+
* Check if a skill exists in the registry
|
|
41
|
+
*/
|
|
42
|
+
export declare function skillExists(slug: string): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* List all skills in the registry
|
|
45
|
+
*/
|
|
46
|
+
export declare function listSkills(): SkillSummary[];
|
|
47
|
+
/**
|
|
48
|
+
* Search skills by query
|
|
49
|
+
*
|
|
50
|
+
* Searches in: slug, name, tags, description
|
|
51
|
+
*/
|
|
52
|
+
export declare function searchSkills(query: string): SearchResult[];
|
|
53
|
+
/**
|
|
54
|
+
* Search skills by tags
|
|
55
|
+
*/
|
|
56
|
+
export declare function searchByTags(tags: string[]): SkillSummary[];
|
|
57
|
+
/**
|
|
58
|
+
* Search skills by compatibility
|
|
59
|
+
*/
|
|
60
|
+
export declare function searchByCompat(compat: string[]): SkillSummary[];
|
|
61
|
+
/**
|
|
62
|
+
* Delete a skill entirely from the registry
|
|
63
|
+
* Note: This does not delete the objects (they may be shared)
|
|
64
|
+
*/
|
|
65
|
+
export declare function deleteSkill(slug: string): boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Get skill info including all versions
|
|
68
|
+
*/
|
|
69
|
+
export declare function getSkillInfo(slug: string): {
|
|
70
|
+
meta: LocalSkillMeta;
|
|
71
|
+
versions: Array<{
|
|
72
|
+
version: string;
|
|
73
|
+
sha256: string;
|
|
74
|
+
createdAt: string;
|
|
75
|
+
provenance: Provenance;
|
|
76
|
+
changelog?: string;
|
|
77
|
+
}>;
|
|
78
|
+
} | null;
|
|
79
|
+
export { resolveVersion } from './versions.js';
|
|
80
|
+
export { getLatestVersion, getAllVersions, getVersionCount, versionExists } from './versions.js';
|
|
81
|
+
export { objectExists, readObject } from './objects.js';
|
|
82
|
+
export { ensureRegistryStructure, getRoot } from './paths.js';
|
|
83
|
+
//# sourceMappingURL=skills.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../../src/lib/local-registry/skills.ts"],"names":[],"mappings":"AAAA;;GAEG;AAsBH,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,UAAU,EACX,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAS5D;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,IAAI,CAqBlE;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAoCvE;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAwBjF;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAM/D;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,GAClB,gBAAgB,GAAG,IAAI,CAMzB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,YAAY,EAAE,CAgC3C;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,EAAE,CAwC1D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,YAAY,EAAE,CAO3D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,YAAY,EAAE,CAO/D;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CASjD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG;IAC1C,IAAI,EAAE,cAAc,CAAC;IACrB,QAAQ,EAAE,KAAK,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,UAAU,CAAC;QACvB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;CACJ,GAAG,IAAI,CAkBP;AAGD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACjG,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,uBAAuB,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill CRUD operations for the local registry
|
|
3
|
+
*/
|
|
4
|
+
import * as fs from 'fs';
|
|
5
|
+
import * as yaml from 'yaml';
|
|
6
|
+
import { getSkillDir, getSkillsDir, getMetaPath, ensureDir, skillExists as pathSkillExists, ensureRegistryStructure, } from './paths.js';
|
|
7
|
+
import { writeObject, readObject } from './objects.js';
|
|
8
|
+
import { addVersionEntry, getVersionEntry, getLatestVersion, getAllVersions, getVersionCount, resolveVersion as resolveVersionInternal, } from './versions.js';
|
|
9
|
+
/**
|
|
10
|
+
* Read meta.yaml for a skill
|
|
11
|
+
*/
|
|
12
|
+
export function readMeta(slug) {
|
|
13
|
+
const metaPath = getMetaPath(slug);
|
|
14
|
+
if (!fs.existsSync(metaPath)) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
const content = fs.readFileSync(metaPath, 'utf-8');
|
|
18
|
+
return yaml.parse(content);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Write meta.yaml for a skill (atomic)
|
|
22
|
+
*/
|
|
23
|
+
export function writeMeta(slug, meta) {
|
|
24
|
+
const metaPath = getMetaPath(slug);
|
|
25
|
+
ensureDir(getSkillDir(slug));
|
|
26
|
+
const content = yaml.stringify(meta, { lineWidth: 0 });
|
|
27
|
+
// Atomic write
|
|
28
|
+
const tempPath = `${metaPath}.tmp.${process.pid}.${Date.now()}`;
|
|
29
|
+
try {
|
|
30
|
+
fs.writeFileSync(tempPath, content, 'utf-8');
|
|
31
|
+
fs.renameSync(tempPath, metaPath);
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
try {
|
|
35
|
+
if (fs.existsSync(tempPath)) {
|
|
36
|
+
fs.unlinkSync(tempPath);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
// Ignore cleanup errors
|
|
41
|
+
}
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Put a new skill version into the registry
|
|
47
|
+
*
|
|
48
|
+
* @returns The sha256 hash of the content
|
|
49
|
+
*/
|
|
50
|
+
export function putVersion(params) {
|
|
51
|
+
const { slug, version, content, meta, provenance, changelog } = params;
|
|
52
|
+
// Ensure registry structure exists
|
|
53
|
+
ensureRegistryStructure();
|
|
54
|
+
// Write content to object store
|
|
55
|
+
const sha256 = writeObject(content);
|
|
56
|
+
// Create or update meta.yaml
|
|
57
|
+
const fullMeta = {
|
|
58
|
+
slug,
|
|
59
|
+
name: meta.name,
|
|
60
|
+
description: meta.description,
|
|
61
|
+
tags: meta.tags || [],
|
|
62
|
+
compat: meta.compat || [],
|
|
63
|
+
updatedAt: new Date().toISOString(),
|
|
64
|
+
};
|
|
65
|
+
writeMeta(slug, fullMeta);
|
|
66
|
+
// Add version entry
|
|
67
|
+
const fullProvenance = {
|
|
68
|
+
kind: provenance?.kind || 'local',
|
|
69
|
+
source: provenance?.source || 'created',
|
|
70
|
+
fetchedAt: provenance?.fetchedAt,
|
|
71
|
+
publishedBy: provenance?.publishedBy,
|
|
72
|
+
};
|
|
73
|
+
addVersionEntry(slug, {
|
|
74
|
+
version,
|
|
75
|
+
sha256,
|
|
76
|
+
provenance: fullProvenance,
|
|
77
|
+
changelog,
|
|
78
|
+
});
|
|
79
|
+
return { sha256 };
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Get a specific version of a skill
|
|
83
|
+
*
|
|
84
|
+
* @returns The skill content and metadata, or null if not found
|
|
85
|
+
*/
|
|
86
|
+
export function getVersion(slug, version) {
|
|
87
|
+
const meta = readMeta(slug);
|
|
88
|
+
if (!meta) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
const versionEntry = getVersionEntry(slug, version);
|
|
92
|
+
if (!versionEntry) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
const content = readObject(versionEntry.sha256);
|
|
96
|
+
if (!content) {
|
|
97
|
+
// Object is missing or corrupted
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
content,
|
|
102
|
+
meta,
|
|
103
|
+
sha256: versionEntry.sha256,
|
|
104
|
+
version: versionEntry.version,
|
|
105
|
+
provenance: versionEntry.provenance,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Get the latest version of a skill
|
|
110
|
+
*/
|
|
111
|
+
export function getLatest(slug) {
|
|
112
|
+
const latestVersion = getLatestVersion(slug);
|
|
113
|
+
if (!latestVersion) {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
return getVersion(slug, latestVersion);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Resolve and get a skill version based on constraint
|
|
120
|
+
*
|
|
121
|
+
* @param slug - Skill slug
|
|
122
|
+
* @param constraint - Optional semver constraint
|
|
123
|
+
* @returns The resolved skill, or null if no match
|
|
124
|
+
*/
|
|
125
|
+
export function resolveAndGet(slug, constraint) {
|
|
126
|
+
const resolvedVersion = resolveVersionInternal(slug, constraint);
|
|
127
|
+
if (!resolvedVersion) {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
return getVersion(slug, resolvedVersion);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Check if a skill exists in the registry
|
|
134
|
+
*/
|
|
135
|
+
export function skillExists(slug) {
|
|
136
|
+
return pathSkillExists(slug);
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* List all skills in the registry
|
|
140
|
+
*/
|
|
141
|
+
export function listSkills() {
|
|
142
|
+
const skillsDir = getSkillsDir();
|
|
143
|
+
if (!fs.existsSync(skillsDir)) {
|
|
144
|
+
return [];
|
|
145
|
+
}
|
|
146
|
+
const slugs = fs.readdirSync(skillsDir).filter((name) => {
|
|
147
|
+
// Only include directories with both meta.yaml and versions.yaml
|
|
148
|
+
return pathSkillExists(name);
|
|
149
|
+
});
|
|
150
|
+
const summaries = [];
|
|
151
|
+
for (const slug of slugs) {
|
|
152
|
+
const meta = readMeta(slug);
|
|
153
|
+
const latestVersion = getLatestVersion(slug);
|
|
154
|
+
if (meta && latestVersion) {
|
|
155
|
+
summaries.push({
|
|
156
|
+
slug,
|
|
157
|
+
latestVersion,
|
|
158
|
+
meta,
|
|
159
|
+
versionCount: getVersionCount(slug),
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
// Sort by slug
|
|
164
|
+
summaries.sort((a, b) => a.slug.localeCompare(b.slug));
|
|
165
|
+
return summaries;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Search skills by query
|
|
169
|
+
*
|
|
170
|
+
* Searches in: slug, name, tags, description
|
|
171
|
+
*/
|
|
172
|
+
export function searchSkills(query) {
|
|
173
|
+
const allSkills = listSkills();
|
|
174
|
+
const lowerQuery = query.toLowerCase();
|
|
175
|
+
const results = [];
|
|
176
|
+
for (const skill of allSkills) {
|
|
177
|
+
let matchedOn = null;
|
|
178
|
+
// Check slug (highest priority)
|
|
179
|
+
if (skill.slug.toLowerCase().includes(lowerQuery)) {
|
|
180
|
+
matchedOn = 'slug';
|
|
181
|
+
}
|
|
182
|
+
// Check name
|
|
183
|
+
else if (skill.meta.name.toLowerCase().includes(lowerQuery)) {
|
|
184
|
+
matchedOn = 'name';
|
|
185
|
+
}
|
|
186
|
+
// Check tags
|
|
187
|
+
else if (skill.meta.tags.some((tag) => tag.toLowerCase().includes(lowerQuery))) {
|
|
188
|
+
matchedOn = 'tags';
|
|
189
|
+
}
|
|
190
|
+
// Check description
|
|
191
|
+
else if (skill.meta.description?.toLowerCase().includes(lowerQuery)) {
|
|
192
|
+
matchedOn = 'description';
|
|
193
|
+
}
|
|
194
|
+
if (matchedOn) {
|
|
195
|
+
results.push({
|
|
196
|
+
slug: skill.slug,
|
|
197
|
+
latestVersion: skill.latestVersion,
|
|
198
|
+
meta: skill.meta,
|
|
199
|
+
matchedOn,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
// Sort by match type priority (slug > name > tags > description)
|
|
204
|
+
const priority = { slug: 0, name: 1, tags: 2, description: 3 };
|
|
205
|
+
results.sort((a, b) => priority[a.matchedOn] - priority[b.matchedOn]);
|
|
206
|
+
return results;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Search skills by tags
|
|
210
|
+
*/
|
|
211
|
+
export function searchByTags(tags) {
|
|
212
|
+
const allSkills = listSkills();
|
|
213
|
+
const lowerTags = tags.map((t) => t.toLowerCase());
|
|
214
|
+
return allSkills.filter((skill) => skill.meta.tags.some((tag) => lowerTags.includes(tag.toLowerCase())));
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Search skills by compatibility
|
|
218
|
+
*/
|
|
219
|
+
export function searchByCompat(compat) {
|
|
220
|
+
const allSkills = listSkills();
|
|
221
|
+
const lowerCompat = compat.map((c) => c.toLowerCase());
|
|
222
|
+
return allSkills.filter((skill) => skill.meta.compat.some((c) => lowerCompat.includes(c.toLowerCase())));
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Delete a skill entirely from the registry
|
|
226
|
+
* Note: This does not delete the objects (they may be shared)
|
|
227
|
+
*/
|
|
228
|
+
export function deleteSkill(slug) {
|
|
229
|
+
const skillDir = getSkillDir(slug);
|
|
230
|
+
if (!fs.existsSync(skillDir)) {
|
|
231
|
+
return false;
|
|
232
|
+
}
|
|
233
|
+
fs.rmSync(skillDir, { recursive: true });
|
|
234
|
+
return true;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Get skill info including all versions
|
|
238
|
+
*/
|
|
239
|
+
export function getSkillInfo(slug) {
|
|
240
|
+
const meta = readMeta(slug);
|
|
241
|
+
if (!meta) {
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
const versions = getAllVersions(slug);
|
|
245
|
+
return {
|
|
246
|
+
meta,
|
|
247
|
+
versions: versions.map((v) => ({
|
|
248
|
+
version: v.version,
|
|
249
|
+
sha256: v.sha256,
|
|
250
|
+
createdAt: v.createdAt,
|
|
251
|
+
provenance: v.provenance,
|
|
252
|
+
changelog: v.changelog,
|
|
253
|
+
})),
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
// Re-export commonly used functions from other modules
|
|
257
|
+
export { resolveVersion } from './versions.js';
|
|
258
|
+
export { getLatestVersion, getAllVersions, getVersionCount, versionExists } from './versions.js';
|
|
259
|
+
export { objectExists, readObject } from './objects.js';
|
|
260
|
+
export { ensureRegistryStructure, getRoot } from './paths.js';
|
|
261
|
+
//# sourceMappingURL=skills.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills.js","sourceRoot":"","sources":["../../../src/lib/local-registry/skills.ts"],"names":[],"mappings":"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"}
|