@skillbase/spm 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/CHANGELOG.md +341 -0
- package/LICENSE +21 -0
- package/README.md +90 -0
- package/dist/cli/commands/connect.d.ts +3 -0
- package/dist/cli/commands/connect.d.ts.map +1 -0
- package/dist/cli/commands/connect.js +95 -0
- package/dist/cli/commands/connect.js.map +1 -0
- package/dist/cli/commands/convert.d.ts +9 -0
- package/dist/cli/commands/convert.d.ts.map +1 -0
- package/dist/cli/commands/convert.js +189 -0
- package/dist/cli/commands/convert.js.map +1 -0
- package/dist/cli/commands/create.d.ts +4 -0
- package/dist/cli/commands/create.d.ts.map +1 -0
- package/dist/cli/commands/create.js +104 -0
- package/dist/cli/commands/create.js.map +1 -0
- package/dist/cli/commands/info.d.ts +2 -0
- package/dist/cli/commands/info.d.ts.map +1 -0
- package/dist/cli/commands/info.js +51 -0
- package/dist/cli/commands/info.js.map +1 -0
- package/dist/cli/commands/init.d.ts +4 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +53 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/install.d.ts +6 -0
- package/dist/cli/commands/install.d.ts.map +1 -0
- package/dist/cli/commands/install.js +272 -0
- package/dist/cli/commands/install.js.map +1 -0
- package/dist/cli/commands/list.d.ts +4 -0
- package/dist/cli/commands/list.d.ts.map +1 -0
- package/dist/cli/commands/list.js +29 -0
- package/dist/cli/commands/list.js.map +1 -0
- package/dist/cli/commands/login.d.ts +10 -0
- package/dist/cli/commands/login.d.ts.map +1 -0
- package/dist/cli/commands/login.js +141 -0
- package/dist/cli/commands/login.js.map +1 -0
- package/dist/cli/commands/publish.d.ts +6 -0
- package/dist/cli/commands/publish.d.ts.map +1 -0
- package/dist/cli/commands/publish.js +109 -0
- package/dist/cli/commands/publish.js.map +1 -0
- package/dist/cli/commands/rate.d.ts +5 -0
- package/dist/cli/commands/rate.d.ts.map +1 -0
- package/dist/cli/commands/rate.js +22 -0
- package/dist/cli/commands/rate.js.map +1 -0
- package/dist/cli/commands/search.d.ts +5 -0
- package/dist/cli/commands/search.d.ts.map +1 -0
- package/dist/cli/commands/search.js +70 -0
- package/dist/cli/commands/search.js.map +1 -0
- package/dist/cli/commands/stats.d.ts +2 -0
- package/dist/cli/commands/stats.d.ts.map +1 -0
- package/dist/cli/commands/stats.js +33 -0
- package/dist/cli/commands/stats.js.map +1 -0
- package/dist/cli/commands/uninstall.d.ts +2 -0
- package/dist/cli/commands/uninstall.d.ts.map +1 -0
- package/dist/cli/commands/uninstall.js +37 -0
- package/dist/cli/commands/uninstall.js.map +1 -0
- package/dist/cli/commands/update.d.ts +5 -0
- package/dist/cli/commands/update.d.ts.map +1 -0
- package/dist/cli/commands/update.js +97 -0
- package/dist/cli/commands/update.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +2 -0
- package/dist/cli/commands/validate.d.ts.map +1 -0
- package/dist/cli/commands/validate.js +72 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +159 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/config.d.ts +7 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +72 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/feedback.d.ts +22 -0
- package/dist/core/feedback.d.ts.map +1 -0
- package/dist/core/feedback.js +93 -0
- package/dist/core/feedback.js.map +1 -0
- package/dist/core/github/client.d.ts +18 -0
- package/dist/core/github/client.d.ts.map +1 -0
- package/dist/core/github/client.js +141 -0
- package/dist/core/github/client.js.map +1 -0
- package/dist/core/indexer.d.ts +4 -0
- package/dist/core/indexer.d.ts.map +1 -0
- package/dist/core/indexer.js +90 -0
- package/dist/core/indexer.js.map +1 -0
- package/dist/core/loader.d.ts +3 -0
- package/dist/core/loader.d.ts.map +1 -0
- package/dist/core/loader.js +37 -0
- package/dist/core/loader.js.map +1 -0
- package/dist/core/lock.d.ts +4 -0
- package/dist/core/lock.d.ts.map +1 -0
- package/dist/core/lock.js +86 -0
- package/dist/core/lock.js.map +1 -0
- package/dist/core/manifest.d.ts +6 -0
- package/dist/core/manifest.d.ts.map +1 -0
- package/dist/core/manifest.js +33 -0
- package/dist/core/manifest.js.map +1 -0
- package/dist/core/paths.d.ts +8 -0
- package/dist/core/paths.d.ts.map +1 -0
- package/dist/core/paths.js +30 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/core/plugins/index.d.ts +8 -0
- package/dist/core/plugins/index.d.ts.map +1 -0
- package/dist/core/plugins/index.js +30 -0
- package/dist/core/plugins/index.js.map +1 -0
- package/dist/core/plugins/loader.d.ts +9 -0
- package/dist/core/plugins/loader.d.ts.map +1 -0
- package/dist/core/plugins/loader.js +57 -0
- package/dist/core/plugins/loader.js.map +1 -0
- package/dist/core/plugins/types.d.ts +79 -0
- package/dist/core/plugins/types.d.ts.map +1 -0
- package/dist/core/plugins/types.js +3 -0
- package/dist/core/plugins/types.js.map +1 -0
- package/dist/core/registry-client.d.ts +80 -0
- package/dist/core/registry-client.d.ts.map +1 -0
- package/dist/core/registry-client.js +166 -0
- package/dist/core/registry-client.js.map +1 -0
- package/dist/core/registry.d.ts +11 -0
- package/dist/core/registry.d.ts.map +1 -0
- package/dist/core/registry.js +44 -0
- package/dist/core/registry.js.map +1 -0
- package/dist/core/resolver.d.ts +17 -0
- package/dist/core/resolver.d.ts.map +1 -0
- package/dist/core/resolver.js +44 -0
- package/dist/core/resolver.js.map +1 -0
- package/dist/core/storage/index.d.ts +9 -0
- package/dist/core/storage/index.d.ts.map +1 -0
- package/dist/core/storage/index.js +34 -0
- package/dist/core/storage/index.js.map +1 -0
- package/dist/core/storage/local-provider.d.ts +12 -0
- package/dist/core/storage/local-provider.d.ts.map +1 -0
- package/dist/core/storage/local-provider.js +44 -0
- package/dist/core/storage/local-provider.js.map +1 -0
- package/dist/core/storage/packager.d.ts +10 -0
- package/dist/core/storage/packager.d.ts.map +1 -0
- package/dist/core/storage/packager.js +185 -0
- package/dist/core/storage/packager.js.map +1 -0
- package/dist/core/storage/s3-provider.d.ts +12 -0
- package/dist/core/storage/s3-provider.d.ts.map +1 -0
- package/dist/core/storage/s3-provider.js +84 -0
- package/dist/core/storage/s3-provider.js.map +1 -0
- package/dist/core/storage/types.d.ts +27 -0
- package/dist/core/storage/types.d.ts.map +1 -0
- package/dist/core/storage/types.js +4 -0
- package/dist/core/storage/types.js.map +1 -0
- package/dist/mcp/server.d.ts +3 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +349 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/schema/skill-schema.d.ts +6 -0
- package/dist/schema/skill-schema.d.ts.map +1 -0
- package/dist/schema/skill-schema.js +147 -0
- package/dist/schema/skill-schema.js.map +1 -0
- package/dist/scripts/reindex.d.ts +3 -0
- package/dist/scripts/reindex.d.ts.map +1 -0
- package/dist/scripts/reindex.js +37 -0
- package/dist/scripts/reindex.js.map +1 -0
- package/dist/types/index.d.ts +191 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +62 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import { getConfigPath, getGlobalSkillsDir } from "./paths.js";
|
|
3
|
+
const DEFAULT_CONFIG = {
|
|
4
|
+
feedback: {
|
|
5
|
+
enabled: true,
|
|
6
|
+
automatic: true,
|
|
7
|
+
},
|
|
8
|
+
tools: {
|
|
9
|
+
skill_list: true,
|
|
10
|
+
skill_load: true,
|
|
11
|
+
skill_context: true,
|
|
12
|
+
skill_feedback: true,
|
|
13
|
+
skill_search: true,
|
|
14
|
+
skill_install: true,
|
|
15
|
+
},
|
|
16
|
+
search: {
|
|
17
|
+
remote_enabled: true,
|
|
18
|
+
auto_suggest: true,
|
|
19
|
+
},
|
|
20
|
+
registries: [
|
|
21
|
+
{
|
|
22
|
+
name: "public",
|
|
23
|
+
url: "https://skillbase-registry.fly.dev",
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
scopes: {
|
|
27
|
+
"*": "public",
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
export function getDefaultConfig() {
|
|
31
|
+
return structuredClone(DEFAULT_CONFIG);
|
|
32
|
+
}
|
|
33
|
+
export async function readConfig(skillsDir) {
|
|
34
|
+
const dir = skillsDir ?? getGlobalSkillsDir();
|
|
35
|
+
const configPath = getConfigPath(dir);
|
|
36
|
+
try {
|
|
37
|
+
const raw = await fs.readFile(configPath, "utf-8");
|
|
38
|
+
const parsed = JSON.parse(raw);
|
|
39
|
+
return mergeWithDefaults(parsed);
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return getDefaultConfig();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export async function writeConfig(config, skillsDir) {
|
|
46
|
+
const dir = skillsDir ?? getGlobalSkillsDir();
|
|
47
|
+
const configPath = getConfigPath(dir);
|
|
48
|
+
await fs.writeFile(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
49
|
+
}
|
|
50
|
+
function mergeWithDefaults(partial) {
|
|
51
|
+
const defaults = getDefaultConfig();
|
|
52
|
+
return {
|
|
53
|
+
feedback: { ...defaults.feedback, ...partial.feedback },
|
|
54
|
+
tools: { ...defaults.tools, ...partial.tools },
|
|
55
|
+
search: { ...defaults.search, ...partial.search },
|
|
56
|
+
registries: partial.registries ?? defaults.registries,
|
|
57
|
+
scopes: partial.scopes ?? defaults.scopes,
|
|
58
|
+
github: partial.github,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export function resolveRegistry(config, _skillRef) {
|
|
62
|
+
const registryName = config.scopes["*"];
|
|
63
|
+
if (!registryName)
|
|
64
|
+
return null;
|
|
65
|
+
const registry = config.registries.find((r) => r.name === registryName);
|
|
66
|
+
return registry?.url ?? null;
|
|
67
|
+
}
|
|
68
|
+
export function getRegistryToken(config, registryName) {
|
|
69
|
+
const registry = config.registries.find((r) => r.name === registryName);
|
|
70
|
+
return registry?.token;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { FeedbackEntry, FeedbackResult, FeedbackType, SkillStats } from "../types/index.js";
|
|
2
|
+
export declare function addFeedback(skill: string, version: string, result: FeedbackResult, type?: FeedbackType, options?: {
|
|
3
|
+
rating?: number;
|
|
4
|
+
comment?: string;
|
|
5
|
+
task_type?: string;
|
|
6
|
+
file_types?: string[];
|
|
7
|
+
tokens_used?: number;
|
|
8
|
+
}, skillsDir?: string): Promise<FeedbackEntry>;
|
|
9
|
+
export declare function getEntriesForSkill(skillName: string, skillsDir?: string): Promise<FeedbackEntry[]>;
|
|
10
|
+
export declare function getAllStats(skillsDir?: string): Promise<SkillStats[]>;
|
|
11
|
+
export declare function getStatsForSkill(skillName: string, skillsDir?: string): Promise<SkillStats | null>;
|
|
12
|
+
/**
|
|
13
|
+
* Confidence = success_rate × usage_weight
|
|
14
|
+
* usage_weight = min(1, log2(usage_count + 1) / 5)
|
|
15
|
+
*
|
|
16
|
+
* This ensures:
|
|
17
|
+
* - New skills (few uses) have low confidence regardless of success rate
|
|
18
|
+
* - Well-used skills converge toward their true success rate
|
|
19
|
+
* - ~32 uses needed for usage_weight to reach 1.0
|
|
20
|
+
*/
|
|
21
|
+
export declare function calculateConfidence(successRate: number, usageCount: number): number;
|
|
22
|
+
//# sourceMappingURL=feedback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback.d.ts","sourceRoot":"","sources":["../../src/core/feedback.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EAEd,YAAY,EACZ,UAAU,EACX,MAAM,mBAAmB,CAAC;AAgC3B,wBAAsB,WAAW,CAC/B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,cAAc,EACtB,IAAI,GAAE,YAA0B,EAChC,OAAO,CAAC,EAAE;IACR,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,EACD,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,aAAa,CAAC,CAuBxB;AAED,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,aAAa,EAAE,CAAC,CAG1B;AAED,wBAAsB,WAAW,CAC/B,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,UAAU,EAAE,CAAC,CAiBvB;AAED,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAI5B;AAID;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,GACjB,MAAM,CAGR"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import { getFeedbackPath, getGlobalSkillsDir } from "./paths.js";
|
|
3
|
+
// -- Storage --
|
|
4
|
+
async function readStore(skillsDir) {
|
|
5
|
+
const dir = skillsDir ?? getGlobalSkillsDir();
|
|
6
|
+
const feedbackPath = getFeedbackPath(dir);
|
|
7
|
+
try {
|
|
8
|
+
const raw = await fs.readFile(feedbackPath, "utf-8");
|
|
9
|
+
return JSON.parse(raw);
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return { entries: [] };
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
async function writeStore(store, skillsDir) {
|
|
16
|
+
const dir = skillsDir ?? getGlobalSkillsDir();
|
|
17
|
+
const feedbackPath = getFeedbackPath(dir);
|
|
18
|
+
await fs.writeFile(feedbackPath, JSON.stringify(store, null, 2) + "\n", "utf-8");
|
|
19
|
+
}
|
|
20
|
+
// -- Public API --
|
|
21
|
+
export async function addFeedback(skill, version, result, type = "automatic", options, skillsDir) {
|
|
22
|
+
const store = await readStore(skillsDir);
|
|
23
|
+
const entry = {
|
|
24
|
+
skill,
|
|
25
|
+
version,
|
|
26
|
+
timestamp: new Date().toISOString(),
|
|
27
|
+
type,
|
|
28
|
+
result,
|
|
29
|
+
...(options?.rating !== undefined && { rating: options.rating }),
|
|
30
|
+
...(options?.comment && { comment: options.comment }),
|
|
31
|
+
...((options?.task_type || options?.file_types || options?.tokens_used) && {
|
|
32
|
+
context: {
|
|
33
|
+
...(options.task_type && { task_type: options.task_type }),
|
|
34
|
+
...(options.file_types && { file_types: options.file_types }),
|
|
35
|
+
...(options.tokens_used && { tokens_used: options.tokens_used }),
|
|
36
|
+
},
|
|
37
|
+
}),
|
|
38
|
+
};
|
|
39
|
+
store.entries.push(entry);
|
|
40
|
+
await writeStore(store, skillsDir);
|
|
41
|
+
return entry;
|
|
42
|
+
}
|
|
43
|
+
export async function getEntriesForSkill(skillName, skillsDir) {
|
|
44
|
+
const store = await readStore(skillsDir);
|
|
45
|
+
return store.entries.filter((e) => e.skill === skillName);
|
|
46
|
+
}
|
|
47
|
+
export async function getAllStats(skillsDir) {
|
|
48
|
+
const store = await readStore(skillsDir);
|
|
49
|
+
const grouped = new Map();
|
|
50
|
+
for (const entry of store.entries) {
|
|
51
|
+
const existing = grouped.get(entry.skill) ?? [];
|
|
52
|
+
existing.push(entry);
|
|
53
|
+
grouped.set(entry.skill, existing);
|
|
54
|
+
}
|
|
55
|
+
const stats = [];
|
|
56
|
+
for (const [skill, entries] of grouped) {
|
|
57
|
+
stats.push(computeStats(skill, entries));
|
|
58
|
+
}
|
|
59
|
+
return stats.sort((a, b) => b.confidence - a.confidence);
|
|
60
|
+
}
|
|
61
|
+
export async function getStatsForSkill(skillName, skillsDir) {
|
|
62
|
+
const entries = await getEntriesForSkill(skillName, skillsDir);
|
|
63
|
+
if (entries.length === 0)
|
|
64
|
+
return null;
|
|
65
|
+
return computeStats(skillName, entries);
|
|
66
|
+
}
|
|
67
|
+
// -- Confidence calculation --
|
|
68
|
+
/**
|
|
69
|
+
* Confidence = success_rate × usage_weight
|
|
70
|
+
* usage_weight = min(1, log2(usage_count + 1) / 5)
|
|
71
|
+
*
|
|
72
|
+
* This ensures:
|
|
73
|
+
* - New skills (few uses) have low confidence regardless of success rate
|
|
74
|
+
* - Well-used skills converge toward their true success rate
|
|
75
|
+
* - ~32 uses needed for usage_weight to reach 1.0
|
|
76
|
+
*/
|
|
77
|
+
export function calculateConfidence(successRate, usageCount) {
|
|
78
|
+
const usageWeight = Math.min(1, Math.log2(usageCount + 1) / 5);
|
|
79
|
+
return Math.round(successRate * usageWeight * 100) / 100;
|
|
80
|
+
}
|
|
81
|
+
// -- Internal --
|
|
82
|
+
function computeStats(skill, entries) {
|
|
83
|
+
const usageCount = entries.length;
|
|
84
|
+
const successCount = entries.filter((e) => e.result === "success" || e.result === "partial").length;
|
|
85
|
+
const successRate = usageCount > 0 ? Math.round((successCount / usageCount) * 100) / 100 : 0;
|
|
86
|
+
const rated = entries.filter((e) => e.rating !== undefined);
|
|
87
|
+
const avgRating = rated.length > 0
|
|
88
|
+
? Math.round((rated.reduce((sum, e) => sum + e.rating, 0) / rated.length) * 100) / 100
|
|
89
|
+
: null;
|
|
90
|
+
const confidence = calculateConfidence(successRate, usageCount);
|
|
91
|
+
return { skill, usage_count: usageCount, success_rate: successRate, avg_rating: avgRating, confidence };
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=feedback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback.js","sourceRoot":"","sources":["../../src/core/feedback.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Octokit } from "@octokit/rest";
|
|
2
|
+
import type { SkillManifest } from "../../types/index.js";
|
|
3
|
+
export interface GitHubSource {
|
|
4
|
+
owner: string;
|
|
5
|
+
repo: string;
|
|
6
|
+
ref?: string;
|
|
7
|
+
path?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface FetchedSkill {
|
|
10
|
+
manifest: SkillManifest;
|
|
11
|
+
entryContent: string;
|
|
12
|
+
compactContent?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function parseGitHubUrl(url: string): GitHubSource;
|
|
15
|
+
export declare function createOctokit(token?: string): Octokit;
|
|
16
|
+
export declare function fetchSkillFromGitHub(source: GitHubSource, token?: string): Promise<FetchedSkill>;
|
|
17
|
+
export declare function downloadSkillFiles(source: GitHubSource, token?: string): Promise<Map<string, string>>;
|
|
18
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/core/github/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,aAAa,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAiDxD;AAED,wBAAgB,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAErD;AAED,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,YAAY,EACpB,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,YAAY,CAAC,CAmDvB;AAGD,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,YAAY,EACpB,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAoD9B"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { Octokit } from "@octokit/rest";
|
|
2
|
+
export function parseGitHubUrl(url) {
|
|
3
|
+
// Supports:
|
|
4
|
+
// https://github.com/owner/repo
|
|
5
|
+
// https://github.com/owner/repo/tree/main/path/to/skill
|
|
6
|
+
// github:owner/repo
|
|
7
|
+
// github:owner/repo/path/to/skill
|
|
8
|
+
// owner/repo (shorthand)
|
|
9
|
+
let cleaned = url.trim();
|
|
10
|
+
// Remove trailing slash
|
|
11
|
+
cleaned = cleaned.replace(/\/$/, "");
|
|
12
|
+
// github:owner/repo[/path]
|
|
13
|
+
if (cleaned.startsWith("github:")) {
|
|
14
|
+
const rest = cleaned.slice(7);
|
|
15
|
+
const parts = rest.split("/");
|
|
16
|
+
if (parts.length < 2)
|
|
17
|
+
throw new Error(`Invalid GitHub URL: ${url}`);
|
|
18
|
+
return {
|
|
19
|
+
owner: parts[0],
|
|
20
|
+
repo: parts[1],
|
|
21
|
+
path: parts.length > 2 ? parts.slice(2).join("/") : undefined,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
// https://github.com/owner/repo[/tree/ref/path]
|
|
25
|
+
if (cleaned.includes("github.com")) {
|
|
26
|
+
const match = cleaned.match(/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?(?:\/tree\/([^/]+)(?:\/(.+))?)?$/);
|
|
27
|
+
if (!match)
|
|
28
|
+
throw new Error(`Invalid GitHub URL: ${url}`);
|
|
29
|
+
return {
|
|
30
|
+
owner: match[1],
|
|
31
|
+
repo: match[2],
|
|
32
|
+
ref: match[3] || undefined,
|
|
33
|
+
path: match[4] || undefined,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
// owner/repo shorthand
|
|
37
|
+
const parts = cleaned.split("/");
|
|
38
|
+
if (parts.length >= 2) {
|
|
39
|
+
return {
|
|
40
|
+
owner: parts[0],
|
|
41
|
+
repo: parts[1],
|
|
42
|
+
path: parts.length > 2 ? parts.slice(2).join("/") : undefined,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
throw new Error(`Cannot parse GitHub source: ${url}`);
|
|
46
|
+
}
|
|
47
|
+
export function createOctokit(token) {
|
|
48
|
+
return new Octokit(token ? { auth: token } : {});
|
|
49
|
+
}
|
|
50
|
+
export async function fetchSkillFromGitHub(source, token) {
|
|
51
|
+
const octokit = createOctokit(token);
|
|
52
|
+
const basePath = source.path ? `${source.path}/` : "";
|
|
53
|
+
const params = {
|
|
54
|
+
owner: source.owner,
|
|
55
|
+
repo: source.repo,
|
|
56
|
+
};
|
|
57
|
+
if (source.ref)
|
|
58
|
+
params.ref = source.ref;
|
|
59
|
+
// Fetch skill.json
|
|
60
|
+
const manifestResponse = await octokit.repos.getContent({
|
|
61
|
+
...params,
|
|
62
|
+
path: `${basePath}skill.json`,
|
|
63
|
+
});
|
|
64
|
+
if (!("content" in manifestResponse.data)) {
|
|
65
|
+
throw new Error("skill.json not found or is a directory");
|
|
66
|
+
}
|
|
67
|
+
const manifestRaw = Buffer.from(manifestResponse.data.content, "base64").toString("utf-8");
|
|
68
|
+
const manifest = JSON.parse(manifestRaw);
|
|
69
|
+
// Fetch entry file (SKILL.md)
|
|
70
|
+
const entryResponse = await octokit.repos.getContent({
|
|
71
|
+
...params,
|
|
72
|
+
path: `${basePath}${manifest.entry}`,
|
|
73
|
+
});
|
|
74
|
+
if (!("content" in entryResponse.data)) {
|
|
75
|
+
throw new Error(`Entry file "${manifest.entry}" not found`);
|
|
76
|
+
}
|
|
77
|
+
const entryContent = Buffer.from(entryResponse.data.content, "base64").toString("utf-8");
|
|
78
|
+
// Fetch compact entry if defined
|
|
79
|
+
let compactContent;
|
|
80
|
+
if (manifest.compact_entry) {
|
|
81
|
+
try {
|
|
82
|
+
const compactResponse = await octokit.repos.getContent({
|
|
83
|
+
...params,
|
|
84
|
+
path: `${basePath}${manifest.compact_entry}`,
|
|
85
|
+
});
|
|
86
|
+
if ("content" in compactResponse.data) {
|
|
87
|
+
compactContent = Buffer.from(compactResponse.data.content, "base64").toString("utf-8");
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
// Compact entry is optional
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return { manifest, entryContent, compactContent };
|
|
95
|
+
}
|
|
96
|
+
// Download full skill directory as files map (for install)
|
|
97
|
+
export async function downloadSkillFiles(source, token) {
|
|
98
|
+
const octokit = createOctokit(token);
|
|
99
|
+
const files = new Map();
|
|
100
|
+
const basePath = source.path ?? "";
|
|
101
|
+
async function fetchDir(dirPath) {
|
|
102
|
+
const response = await octokit.repos.getContent({
|
|
103
|
+
owner: source.owner,
|
|
104
|
+
repo: source.repo,
|
|
105
|
+
ref: source.ref ?? undefined,
|
|
106
|
+
path: dirPath || ".",
|
|
107
|
+
});
|
|
108
|
+
if (!Array.isArray(response.data)) {
|
|
109
|
+
// Single file
|
|
110
|
+
if ("content" in response.data) {
|
|
111
|
+
const relativePath = basePath
|
|
112
|
+
? response.data.path.slice(basePath.length + 1)
|
|
113
|
+
: response.data.path;
|
|
114
|
+
files.set(relativePath, Buffer.from(response.data.content, "base64").toString("utf-8"));
|
|
115
|
+
}
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
for (const item of response.data) {
|
|
119
|
+
if (item.type === "file") {
|
|
120
|
+
const fileResp = await octokit.repos.getContent({
|
|
121
|
+
owner: source.owner,
|
|
122
|
+
repo: source.repo,
|
|
123
|
+
ref: source.ref,
|
|
124
|
+
path: item.path,
|
|
125
|
+
});
|
|
126
|
+
if ("content" in fileResp.data) {
|
|
127
|
+
const relativePath = basePath
|
|
128
|
+
? fileResp.data.path.slice(basePath.length + 1)
|
|
129
|
+
: fileResp.data.path;
|
|
130
|
+
files.set(relativePath, Buffer.from(fileResp.data.content, "base64").toString("utf-8"));
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
else if (item.type === "dir") {
|
|
134
|
+
await fetchDir(item.path);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
await fetchDir(basePath);
|
|
139
|
+
return files;
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/core/github/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indexer.d.ts","sourceRoot":"","sources":["../../src/core/indexer.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAiB,UAAU,EAAmB,MAAM,mBAAmB,CAAC;AA6BpF,wBAAsB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAuDvE;AAED,wBAAsB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAMvE"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { getInstalledDir, getIndexPath } from "./paths.js";
|
|
4
|
+
import { validateSkillManifest } from "../schema/skill-schema.js";
|
|
5
|
+
async function estimateTokens(filePath) {
|
|
6
|
+
try {
|
|
7
|
+
const content = await fs.readFile(filePath, "utf-8");
|
|
8
|
+
// Rough estimate: ~4 chars per token for English text
|
|
9
|
+
return Math.ceil(content.length / 4);
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return 0;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
async function readSkillManifest(skillDir) {
|
|
16
|
+
const manifestPath = path.join(skillDir, "skill.json");
|
|
17
|
+
try {
|
|
18
|
+
const raw = await fs.readFile(manifestPath, "utf-8");
|
|
19
|
+
const data = JSON.parse(raw);
|
|
20
|
+
const result = validateSkillManifest(data);
|
|
21
|
+
if (!result.valid) {
|
|
22
|
+
console.error(`Invalid skill.json in ${skillDir}:`, result.errors);
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
return data;
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
console.error(`Failed to read skill.json in ${skillDir}:`, err);
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export async function buildIndex(skillsDir) {
|
|
33
|
+
const installedDir = getInstalledDir(skillsDir);
|
|
34
|
+
const index = { version: "1.0.0", skills: [] };
|
|
35
|
+
let scopes;
|
|
36
|
+
try {
|
|
37
|
+
scopes = await fs.readdir(installedDir);
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return index;
|
|
41
|
+
}
|
|
42
|
+
for (const author of scopes) {
|
|
43
|
+
const authorDir = path.join(installedDir, author);
|
|
44
|
+
const stat = await fs.stat(authorDir);
|
|
45
|
+
if (!stat.isDirectory())
|
|
46
|
+
continue;
|
|
47
|
+
const skillNames = await fs.readdir(authorDir);
|
|
48
|
+
for (const skillName of skillNames) {
|
|
49
|
+
const skillDir = path.join(authorDir, skillName);
|
|
50
|
+
const skillStat = await fs.stat(skillDir);
|
|
51
|
+
if (!skillStat.isDirectory())
|
|
52
|
+
continue;
|
|
53
|
+
const manifest = await readSkillManifest(skillDir);
|
|
54
|
+
if (!manifest)
|
|
55
|
+
continue;
|
|
56
|
+
// Skip bundles (no entry or trigger = not a loadable skill)
|
|
57
|
+
if (!manifest.entry || !manifest.trigger)
|
|
58
|
+
continue;
|
|
59
|
+
const entryPath = path.join(skillDir, manifest.entry);
|
|
60
|
+
const tokensEstimate = await estimateTokens(entryPath);
|
|
61
|
+
const entry = {
|
|
62
|
+
name: manifest.name,
|
|
63
|
+
v: manifest.version,
|
|
64
|
+
trigger: manifest.trigger.description,
|
|
65
|
+
tags: manifest.trigger.tags,
|
|
66
|
+
priority: manifest.trigger.priority,
|
|
67
|
+
entry: entryPath,
|
|
68
|
+
tokens_estimate: tokensEstimate,
|
|
69
|
+
};
|
|
70
|
+
if (manifest.trigger.file_patterns) {
|
|
71
|
+
entry.file_patterns = manifest.trigger.file_patterns;
|
|
72
|
+
}
|
|
73
|
+
if (manifest.compact_entry) {
|
|
74
|
+
entry.compact_entry = path.join(skillDir, manifest.compact_entry);
|
|
75
|
+
}
|
|
76
|
+
index.skills.push(entry);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Sort by priority descending
|
|
80
|
+
index.skills.sort((a, b) => b.priority - a.priority);
|
|
81
|
+
return index;
|
|
82
|
+
}
|
|
83
|
+
export async function writeIndex(skillsDir) {
|
|
84
|
+
const index = await buildIndex(skillsDir);
|
|
85
|
+
const indexPath = getIndexPath(skillsDir);
|
|
86
|
+
await fs.mkdir(skillsDir, { recursive: true });
|
|
87
|
+
await fs.writeFile(indexPath, JSON.stringify(index, null, 2), "utf-8");
|
|
88
|
+
return index;
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=indexer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indexer.js","sourceRoot":"","sources":["../../src/core/indexer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/core/loader.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAiB,MAAM,mBAAmB,CAAC;AAGrF,wBAAsB,SAAS,CAC7B,KAAK,EAAE,eAAe,EACtB,OAAO,GAAE,OAAe,GACvB,OAAO,CAAC,WAAW,CAAC,CAmCtB"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { runLoadHooks } from "./plugins/index.js";
|
|
4
|
+
export async function loadSkill(entry, compact = false) {
|
|
5
|
+
const entryPath = compact && entry.compact_entry ? entry.compact_entry : entry.entry;
|
|
6
|
+
const raw = await fs.readFile(entryPath, "utf-8");
|
|
7
|
+
// Read skill.json for extra metadata
|
|
8
|
+
const skillDir = path.dirname(entryPath);
|
|
9
|
+
const manifestPath = path.join(skillDir, "skill.json");
|
|
10
|
+
let permissions = [];
|
|
11
|
+
let worksWithList = undefined;
|
|
12
|
+
try {
|
|
13
|
+
const manifestRaw = await fs.readFile(manifestPath, "utf-8");
|
|
14
|
+
const manifest = JSON.parse(manifestRaw);
|
|
15
|
+
permissions = manifest.security?.permissions ?? [];
|
|
16
|
+
worksWithList = manifest.works_with;
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
// Metadata unavailable — continue with defaults
|
|
20
|
+
}
|
|
21
|
+
// Run load plugins (e.g. spotlighting)
|
|
22
|
+
const content = await runLoadHooks({
|
|
23
|
+
content: raw,
|
|
24
|
+
name: entry.name,
|
|
25
|
+
version: entry.v,
|
|
26
|
+
permissions,
|
|
27
|
+
});
|
|
28
|
+
return {
|
|
29
|
+
name: entry.name,
|
|
30
|
+
version: entry.v,
|
|
31
|
+
content,
|
|
32
|
+
permissions,
|
|
33
|
+
tokens_estimate: entry.tokens_estimate,
|
|
34
|
+
works_with: worksWithList,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/core/loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,KAAsB,EACtB,UAAmB,KAAK;IAExB,MAAM,SAAS,GAAG,OAAO,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC;IACrF,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAElD,qCAAqC;IACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACzC,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IACvD,IAAI,WAAW,GAAa,EAAE,CAAC;IAC/B,IAAI,aAAa,GAA8B,SAAS,CAAC;IAEzD,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAC7D,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAkB,CAAC;QAC1D,WAAW,GAAG,QAAQ,CAAC,QAAQ,EAAE,WAAW,IAAI,EAAE,CAAC;QACnD,aAAa,GAAG,QAAQ,CAAC,UAAU,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,gDAAgD;IAClD,CAAC;IAED,uCAAuC;IACvC,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC;QACjC,OAAO,EAAE,GAAG;QACZ,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,OAAO,EAAE,KAAK,CAAC,CAAC;QAChB,WAAW;KACZ,CAAC,CAAC;IAEH,OAAO;QACL,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,OAAO,EAAE,KAAK,CAAC,CAAC;QAChB,OAAO;QACP,WAAW;QACX,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,UAAU,EAAE,aAAa;KAC1B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../src/core/lock.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAiB,UAAU,EAAkB,MAAM,mBAAmB,CAAC;AA4BnF,wBAAsB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAuDtE;AAED,wBAAsB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAKtE"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import crypto from "node:crypto";
|
|
4
|
+
import { getInstalledDir } from "./paths.js";
|
|
5
|
+
async function hashDirectory(dir) {
|
|
6
|
+
const hash = crypto.createHash("sha256");
|
|
7
|
+
const entries = await fs.readdir(dir, { recursive: true });
|
|
8
|
+
entries.sort();
|
|
9
|
+
for (const entry of entries) {
|
|
10
|
+
const fullPath = path.join(dir, entry.toString());
|
|
11
|
+
const stat = await fs.stat(fullPath);
|
|
12
|
+
if (stat.isFile()) {
|
|
13
|
+
const content = await fs.readFile(fullPath);
|
|
14
|
+
hash.update(content);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return hash.digest("hex");
|
|
18
|
+
}
|
|
19
|
+
async function estimateTokensForFile(filePath) {
|
|
20
|
+
try {
|
|
21
|
+
const content = await fs.readFile(filePath, "utf-8");
|
|
22
|
+
return Math.ceil(content.length / 4);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return 0;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export async function buildLock(skillsDir) {
|
|
29
|
+
const installedDir = getInstalledDir(skillsDir);
|
|
30
|
+
const lock = {
|
|
31
|
+
lock_version: 1,
|
|
32
|
+
generated: new Date().toISOString(),
|
|
33
|
+
total_tokens_estimate: 0,
|
|
34
|
+
skills: {},
|
|
35
|
+
};
|
|
36
|
+
let scopes;
|
|
37
|
+
try {
|
|
38
|
+
scopes = await fs.readdir(installedDir);
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return lock;
|
|
42
|
+
}
|
|
43
|
+
for (const author of scopes) {
|
|
44
|
+
const authorDir = path.join(installedDir, author);
|
|
45
|
+
const stat = await fs.stat(authorDir);
|
|
46
|
+
if (!stat.isDirectory())
|
|
47
|
+
continue;
|
|
48
|
+
const skillNames = await fs.readdir(authorDir);
|
|
49
|
+
for (const skillName of skillNames) {
|
|
50
|
+
const skillDir = path.join(authorDir, skillName);
|
|
51
|
+
const skillStat = await fs.stat(skillDir);
|
|
52
|
+
if (!skillStat.isDirectory())
|
|
53
|
+
continue;
|
|
54
|
+
const manifestPath = path.join(skillDir, "skill.json");
|
|
55
|
+
let manifest;
|
|
56
|
+
try {
|
|
57
|
+
const raw = await fs.readFile(manifestPath, "utf-8");
|
|
58
|
+
manifest = JSON.parse(raw);
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
const integrity = await hashDirectory(skillDir);
|
|
64
|
+
const tokensEstimate = manifest.entry
|
|
65
|
+
? await estimateTokensForFile(path.join(skillDir, manifest.entry))
|
|
66
|
+
: 0;
|
|
67
|
+
const entry = {
|
|
68
|
+
version: manifest.version,
|
|
69
|
+
resolved: skillDir,
|
|
70
|
+
integrity: `sha256-${integrity}`,
|
|
71
|
+
tokens_estimate: tokensEstimate,
|
|
72
|
+
dependencies: manifest.dependencies,
|
|
73
|
+
};
|
|
74
|
+
lock.skills[manifest.name] = entry;
|
|
75
|
+
lock.total_tokens_estimate += tokensEstimate;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return lock;
|
|
79
|
+
}
|
|
80
|
+
export async function writeLock(skillsDir) {
|
|
81
|
+
const lock = await buildLock(skillsDir);
|
|
82
|
+
const lockPath = path.join(skillsDir, "skills.lock");
|
|
83
|
+
await fs.writeFile(lockPath, JSON.stringify(lock, null, 2), "utf-8");
|
|
84
|
+
return lock;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=lock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lock.js","sourceRoot":"","sources":["../../src/core/lock.ts"],"names":[],"mappings":"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"}
|