skills-manager-cli 2026.8.26-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +103 -0
- package/README.zh-CN.md +103 -0
- package/dist/cli/main.js +261 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli.js +3 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/catalog/agent-catalog.json +1134 -0
- package/dist/core/catalog/evaluate-detection.js +41 -0
- package/dist/core/catalog/evaluate-detection.js.map +1 -0
- package/dist/core/catalog/extract.js +388 -0
- package/dist/core/catalog/extract.js.map +1 -0
- package/dist/core/catalog/resolve-path.js +29 -0
- package/dist/core/catalog/resolve-path.js.map +1 -0
- package/dist/core/catalog/validate-snapshot.js +117 -0
- package/dist/core/catalog/validate-snapshot.js.map +1 -0
- package/dist/core/index.js +6 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/model/catalog.js +7 -0
- package/dist/core/model/catalog.js.map +1 -0
- package/dist/core/model/index.js +7 -0
- package/dist/core/model/index.js.map +1 -0
- package/dist/core/ports/filesystem.js +2 -0
- package/dist/core/ports/filesystem.js.map +1 -0
- package/dist/core/ports/git.js +2 -0
- package/dist/core/ports/git.js.map +1 -0
- package/dist/core/ports/process-runner.js +2 -0
- package/dist/core/ports/process-runner.js.map +1 -0
- package/dist/core/services/activity-service.js +36 -0
- package/dist/core/services/activity-service.js.map +1 -0
- package/dist/core/services/adopt-service.js +7 -0
- package/dist/core/services/adopt-service.js.map +1 -0
- package/dist/core/services/archive-service.js +35 -0
- package/dist/core/services/archive-service.js.map +1 -0
- package/dist/core/services/backup-service.js +94 -0
- package/dist/core/services/backup-service.js.map +1 -0
- package/dist/core/services/catalog-service.js +123 -0
- package/dist/core/services/catalog-service.js.map +1 -0
- package/dist/core/services/distribute-service.js +474 -0
- package/dist/core/services/distribute-service.js.map +1 -0
- package/dist/core/services/doctor-service.js +75 -0
- package/dist/core/services/doctor-service.js.map +1 -0
- package/dist/core/services/index.js +54 -0
- package/dist/core/services/index.js.map +1 -0
- package/dist/core/services/init-service.js +234 -0
- package/dist/core/services/init-service.js.map +1 -0
- package/dist/core/services/install-service.js +73 -0
- package/dist/core/services/install-service.js.map +1 -0
- package/dist/core/services/migration-service.js +102 -0
- package/dist/core/services/migration-service.js.map +1 -0
- package/dist/core/services/package-service.js +33 -0
- package/dist/core/services/package-service.js.map +1 -0
- package/dist/core/services/registry-service.js +133 -0
- package/dist/core/services/registry-service.js.map +1 -0
- package/dist/core/services/skill-home-resolver.js +33 -0
- package/dist/core/services/skill-home-resolver.js.map +1 -0
- package/dist/core/services/skill-home-service.js +35 -0
- package/dist/core/services/skill-home-service.js.map +1 -0
- package/dist/core/services/source-service.js +109 -0
- package/dist/core/services/source-service.js.map +1 -0
- package/dist/core/services/update-service.js +93 -0
- package/dist/core/services/update-service.js.map +1 -0
- package/dist/core/services/view-service.js +45 -0
- package/dist/core/services/view-service.js.map +1 -0
- package/dist/dashboard/server/main.js +427 -0
- package/dist/dashboard/server/main.js.map +1 -0
- package/dist/dashboard/server/render-markdown.js +75 -0
- package/dist/dashboard/server/render-markdown.js.map +1 -0
- package/dist/dashboard/server/skill-file.js +129 -0
- package/dist/dashboard/server/skill-file.js.map +1 -0
- package/dist/dashboard-web/assets/index-B43GPIpA.js +13 -0
- package/dist/dashboard-web/assets/index-CzbkHV2A.css +1 -0
- package/dist/dashboard-web/index.html +13 -0
- package/dist/infra/fs-skill-home.js +87 -0
- package/dist/infra/fs-skill-home.js.map +1 -0
- package/dist/infra/git-cli.js +36 -0
- package/dist/infra/git-cli.js.map +1 -0
- package/dist/infra/index.js +5 -0
- package/dist/infra/index.js.map +1 -0
- package/dist/infra/runtime.js +23 -0
- package/dist/infra/runtime.js.map +1 -0
- package/dist/infra/shell-runner.js +18 -0
- package/dist/infra/shell-runner.js.map +1 -0
- package/dist/shared/errors.js +17 -0
- package/dist/shared/errors.js.map +1 -0
- package/dist/shared/result.js +17 -0
- package/dist/shared/result.js.map +1 -0
- package/dist/shared/validation.js +92 -0
- package/dist/shared/validation.js.map +1 -0
- package/docs/CLI.md +75 -0
- package/package.json +73 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Catalog snapshot types. The snapshot is the vercel-labs/skills agent table
|
|
3
|
+
* extracted as data (see ADR-0004): agent ids, runtime paths, and detection
|
|
4
|
+
* rules all travel inside it; code never hard-codes agent lists.
|
|
5
|
+
*/
|
|
6
|
+
export {};
|
|
7
|
+
//# sourceMappingURL=catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../../src/core/model/catalog.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Legacy consumer words (pre-catalog). Kept as a local constant only where
|
|
3
|
+
* the one-shot migration bridge and leftover-view cleanup need to recognize
|
|
4
|
+
* them; they are no longer a model-level closed set.
|
|
5
|
+
*/
|
|
6
|
+
export const LEGACY_CONSUMERS = ['agents', 'claude'];
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/model/index.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filesystem.js","sourceRoot":"","sources":["../../../src/core/ports/filesystem.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../../src/core/ports/git.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-runner.js","sourceRoot":"","sources":["../../../src/core/ports/process-runner.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
export class ActivityService {
|
|
4
|
+
fs;
|
|
5
|
+
git;
|
|
6
|
+
home;
|
|
7
|
+
constructor(fs, git, home) {
|
|
8
|
+
this.fs = fs;
|
|
9
|
+
this.git = git;
|
|
10
|
+
this.home = home;
|
|
11
|
+
}
|
|
12
|
+
record(input) {
|
|
13
|
+
const record = {
|
|
14
|
+
id: input.id || randomUUID(),
|
|
15
|
+
timestamp: input.timestamp || new Date().toISOString(),
|
|
16
|
+
action: input.action,
|
|
17
|
+
summary: input.summary,
|
|
18
|
+
actor: input.actor,
|
|
19
|
+
details: input.details,
|
|
20
|
+
};
|
|
21
|
+
this.fs.makeDirectory(path.dirname(this.home.activityFile));
|
|
22
|
+
this.fs.appendText(this.home.activityFile, `${JSON.stringify(record)}\n`);
|
|
23
|
+
return record;
|
|
24
|
+
}
|
|
25
|
+
list(options = {}) {
|
|
26
|
+
if (!this.fs.exists(this.home.activityFile))
|
|
27
|
+
return [];
|
|
28
|
+
const lines = this.fs.readText(this.home.activityFile).split('\n').filter(Boolean);
|
|
29
|
+
const records = lines.map((line) => JSON.parse(line)).sort((a, b) => b.timestamp.localeCompare(a.timestamp));
|
|
30
|
+
return typeof options.limit === 'number' ? records.slice(0, options.limit) : records;
|
|
31
|
+
}
|
|
32
|
+
gitHistory(options = {}) {
|
|
33
|
+
return this.git.log(this.home.root, options.limit || 20);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=activity-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activity-service.js","sourceRoot":"","sources":["../../../src/core/services/activity-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAK7B,MAAM,OAAO,eAAe;IACG,EAAE;IAAmC,GAAG;IAA4B,IAAI;IAArG,YAA6B,EAAkB,EAAmB,GAAY,EAAmB,IAAe;kBAAnF,EAAE;mBAAmC,GAAG;oBAA4B,IAAI;IAAc,CAAC;IAEpH,MAAM,CAAC,KAAqF;QAC1F,MAAM,MAAM,GAAmB;YAC7B,EAAE,EAAE,KAAK,CAAC,EAAE,IAAI,UAAU,EAAE;YAC5B,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACtD,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,OAAO,EAAE,KAAK,CAAC,OAAO;SACvB,CAAC;QACF,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;QAC5D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC1E,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,CAAC,OAAO,GAAuB,EAAE;QACnC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC;YAAE,OAAO,EAAE,CAAC;QACvD,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACnF,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;QAC/H,OAAO,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IACvF,CAAC;IAED,UAAU,CAAC,OAAO,GAAuB,EAAE;QACzC,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;IAC3D,CAAC;CACF"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { SkillsManagerError } from '../../shared/errors.js';
|
|
2
|
+
export class AdoptService {
|
|
3
|
+
adopt(_view, _skill, _alsoConsumers = []) {
|
|
4
|
+
throw new SkillsManagerError('adopt_removed', 'Adopt from hub views/ is removed. Place the skill under hub skills/ then distribute.');
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=adopt-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adopt-service.js","sourceRoot":"","sources":["../../../src/core/services/adopt-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,MAAM,OAAO,YAAY;IACvB,KAAK,CAAC,KAAa,EAAE,MAAc,EAAE,cAAc,GAAsB,EAAE;QACzE,MAAM,IAAI,kBAAkB,CAAC,eAAe,EAAE,sFAAsF,CAAC,CAAC;IACxI,CAAC;CACF"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { SkillsManagerError } from '../../shared/errors.js';
|
|
3
|
+
import { assertPathInside } from '../../shared/validation.js';
|
|
4
|
+
export class ArchiveService {
|
|
5
|
+
fs;
|
|
6
|
+
home;
|
|
7
|
+
registry;
|
|
8
|
+
views;
|
|
9
|
+
constructor(fs, home, registry, views) {
|
|
10
|
+
this.fs = fs;
|
|
11
|
+
this.home = home;
|
|
12
|
+
this.registry = registry;
|
|
13
|
+
this.views = views;
|
|
14
|
+
}
|
|
15
|
+
archiveSkills(skills) {
|
|
16
|
+
const archived = [];
|
|
17
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
18
|
+
const archiveRoot = path.join(this.home.root, '.skills', 'archive', timestamp);
|
|
19
|
+
this.fs.makeDirectory(archiveRoot);
|
|
20
|
+
for (const skill of skills) {
|
|
21
|
+
if (!this.registry.skillExists(skill))
|
|
22
|
+
throw new SkillsManagerError('skill_missing', `Skill not found: ${skill}`);
|
|
23
|
+
const source = this.registry.skillDir(skill);
|
|
24
|
+
const destination = path.join(archiveRoot, skill);
|
|
25
|
+
assertPathInside(destination, archiveRoot);
|
|
26
|
+
this.fs.move(source, destination);
|
|
27
|
+
const existing = this.registry.getEntry(skill) || this.registry.defaultEntry(skill);
|
|
28
|
+
this.registry.ensureEntry(skill, { ...existing, archived: true, consumers: [], archived_at: new Date().toISOString(), archive_path: path.relative(this.home.root, destination) });
|
|
29
|
+
archived.push(skill);
|
|
30
|
+
}
|
|
31
|
+
this.views.rebuildCollections();
|
|
32
|
+
return { archived, archiveRoot };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=archive-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archive-service.js","sourceRoot":"","sources":["../../../src/core/services/archive-service.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAK7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAE9D,MAAM,OAAO,cAAc;IACI,EAAE;IAAmC,IAAI;IAA8B,QAAQ;IAAoC,KAAK;IAArJ,YAA6B,EAAkB,EAAmB,IAAe,EAAmB,QAAyB,EAAmB,KAAkB;kBAArI,EAAE;oBAAmC,IAAI;wBAA8B,QAAQ;qBAAoC,KAAK;IAAgB,CAAC;IAEtK,aAAa,CAAC,MAAyB;QACrC,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QACjE,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QAC/E,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;QACnC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC;gBAAE,MAAM,IAAI,kBAAkB,CAAC,eAAe,EAAE,oBAAoB,KAAK,EAAE,CAAC,CAAC;YAClH,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YAC7C,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;YAClD,gBAAgB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;YAC3C,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;YAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YACpF,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,KAAK,EAAE,EAAE,GAAG,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC;YAClL,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,kBAAkB,EAAE,CAAC;QAChC,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;IACnC,CAAC;CACF"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { SkillsManagerError } from '../../shared/errors.js';
|
|
3
|
+
const RETENTION_MS = 30 * 24 * 60 * 60 * 1000;
|
|
4
|
+
/**
|
|
5
|
+
* Recovery aid for `init` (ADR-0006): the displaced original recorded before a
|
|
6
|
+
* runtime path became a back-symlink. Never a second skill store.
|
|
7
|
+
*/
|
|
8
|
+
export class BackupService {
|
|
9
|
+
fs;
|
|
10
|
+
home;
|
|
11
|
+
registry;
|
|
12
|
+
distribute;
|
|
13
|
+
constructor(fs, home, registry, distribute) {
|
|
14
|
+
this.fs = fs;
|
|
15
|
+
this.home = home;
|
|
16
|
+
this.registry = registry;
|
|
17
|
+
this.distribute = distribute;
|
|
18
|
+
}
|
|
19
|
+
root() {
|
|
20
|
+
return path.join(this.home.root, '.backups');
|
|
21
|
+
}
|
|
22
|
+
list() {
|
|
23
|
+
if (this.fs.kind(this.root()) !== 'directory')
|
|
24
|
+
return [];
|
|
25
|
+
return this.fs.readDirectory(this.root())
|
|
26
|
+
.filter((entry) => entry.kind === 'directory')
|
|
27
|
+
.flatMap((entry) => {
|
|
28
|
+
const parsed = parseBackupName(entry.name);
|
|
29
|
+
return parsed ? [{ ...parsed, dir: path.join(this.root(), entry.name) }] : [];
|
|
30
|
+
})
|
|
31
|
+
.sort((a, b) => a.skill.localeCompare(b.skill) || a.timestamp.localeCompare(b.timestamp));
|
|
32
|
+
}
|
|
33
|
+
/** Roll one skill fully back: remove managed symlinks, delete the hub entity and registry entry, return each origin its original. */
|
|
34
|
+
restore(skill) {
|
|
35
|
+
const available = this.list().filter((item) => item.skill === skill);
|
|
36
|
+
if (available.length === 0) {
|
|
37
|
+
throw new SkillsManagerError('backup_not_found', `No backup found for skill "${skill}". Run \`skills-manager backup list\` to see what exists.`);
|
|
38
|
+
}
|
|
39
|
+
const runtimePaths = this.managedRuntimePaths(skill);
|
|
40
|
+
if (runtimePaths.length > 0) {
|
|
41
|
+
const agents = [...new Set(this.userIndexEntries(skill).flatMap((entry) => entry.agents))];
|
|
42
|
+
this.distribute.undistribute({ to: 'user', skills: [skill], agents });
|
|
43
|
+
}
|
|
44
|
+
const hubDir = path.join(this.home.skillsDir, skill);
|
|
45
|
+
if (this.fs.kind(hubDir) !== 'missing')
|
|
46
|
+
this.fs.removeTree(hubDir);
|
|
47
|
+
this.registry.removeEntry(skill);
|
|
48
|
+
// Consume the newest remaining backup per origin; older ones stay until pruned.
|
|
49
|
+
const restoredPaths = [];
|
|
50
|
+
const pending = [...available].reverse(); // newest first
|
|
51
|
+
for (const runtimePath of runtimePaths) {
|
|
52
|
+
const backup = pending.shift();
|
|
53
|
+
if (!backup)
|
|
54
|
+
break;
|
|
55
|
+
this.fs.makeDirectory(path.dirname(runtimePath));
|
|
56
|
+
this.fs.move(backup.dir, runtimePath);
|
|
57
|
+
restoredPaths.push(runtimePath);
|
|
58
|
+
}
|
|
59
|
+
return { restored: true, skill, runtimePaths: restoredPaths };
|
|
60
|
+
}
|
|
61
|
+
/** Drop backups older than the 30-day retention window; init runs this alongside a real import. */
|
|
62
|
+
prune(now = new Date()) {
|
|
63
|
+
const cutoff = now.getTime() - RETENTION_MS;
|
|
64
|
+
let removed = 0;
|
|
65
|
+
for (const item of this.list()) {
|
|
66
|
+
if (backupTime(item.timestamp) < cutoff) {
|
|
67
|
+
this.fs.removeTree(item.dir);
|
|
68
|
+
removed += 1;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return removed;
|
|
72
|
+
}
|
|
73
|
+
userIndexEntries(skill) {
|
|
74
|
+
return this.distribute.listIndex()
|
|
75
|
+
.filter((record) => record.kind === 'user')
|
|
76
|
+
.flatMap((record) => record.entries.filter((entry) => entry.skill === skill));
|
|
77
|
+
}
|
|
78
|
+
managedRuntimePaths(skill) {
|
|
79
|
+
return this.userIndexEntries(skill).map((entry) => entry.runtimePath);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/** Backup dirs are `<skill>-<iso-timestamp>` (with an optional -N uniqueness suffix); the skill name may itself contain dashes. */
|
|
83
|
+
export function parseBackupName(name) {
|
|
84
|
+
const match = /^(.+)-(\d{4}-\d{2}-\d{2}T[\d-]+Z?)(?:-\d+)?$/.exec(name);
|
|
85
|
+
return match ? { skill: match[1], timestamp: match[2] } : null;
|
|
86
|
+
}
|
|
87
|
+
/** Timestamps are ISO with `:`/`.` dash-encoded for filesystem safety; decode back to a real time. */
|
|
88
|
+
function backupTime(timestamp) {
|
|
89
|
+
const iso = timestamp
|
|
90
|
+
.replace(/T(\d{2})-(\d{2})-(\d{2})-(\d{3})Z$/, 'T$1:$2:$3.$4Z')
|
|
91
|
+
.replace(/T(\d{2})-(\d{2})-(\d{2})Z$/, 'T$1:$2:$3Z');
|
|
92
|
+
return new Date(iso).getTime();
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=backup-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backup-service.js","sourceRoot":"","sources":["../../../src/core/services/backup-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { SkillsManagerError } from '../../shared/errors.js';
|
|
4
|
+
import { detectAgents } from '../catalog/evaluate-detection.js';
|
|
5
|
+
import { extractCatalogSnapshot } from '../catalog/extract.js';
|
|
6
|
+
import { resolveCatalogTemplate } from '../catalog/resolve-path.js';
|
|
7
|
+
import { validateCatalogSnapshot } from '../catalog/validate-snapshot.js';
|
|
8
|
+
const RAW_BASE = 'https://raw.githubusercontent.com/vercel-labs/skills/main';
|
|
9
|
+
const COMMIT_API = 'https://api.github.com/repos/vercel-labs/skills/commits?path=src/agents.ts&per_page=1';
|
|
10
|
+
const BUNDLED_SNAPSHOT_URL = new URL('../catalog/agent-catalog.json', import.meta.url);
|
|
11
|
+
async function defaultFetchText(url) {
|
|
12
|
+
const response = await fetch(url);
|
|
13
|
+
if (!response.ok)
|
|
14
|
+
throw new SkillsManagerError('catalog_refresh_failed', `Failed to fetch ${url}: ${response.status} ${response.statusText}`);
|
|
15
|
+
return response.text();
|
|
16
|
+
}
|
|
17
|
+
export class CatalogService {
|
|
18
|
+
fs;
|
|
19
|
+
home;
|
|
20
|
+
options;
|
|
21
|
+
loaded = null;
|
|
22
|
+
loadedFrom = null;
|
|
23
|
+
constructor(fs, home, options = {}) {
|
|
24
|
+
this.fs = fs;
|
|
25
|
+
this.home = home;
|
|
26
|
+
this.options = options;
|
|
27
|
+
}
|
|
28
|
+
/** Effective snapshot: injected fixture > hub refresh override > bundled file. */
|
|
29
|
+
load() {
|
|
30
|
+
if (this.loaded)
|
|
31
|
+
return this.loaded;
|
|
32
|
+
if (this.options.snapshot) {
|
|
33
|
+
this.loaded = validateCatalogSnapshot(this.options.snapshot);
|
|
34
|
+
this.loadedFrom = 'injected';
|
|
35
|
+
return this.loaded;
|
|
36
|
+
}
|
|
37
|
+
const overridePath = this.overridePath();
|
|
38
|
+
if (this.fs.kind(overridePath) === 'file') {
|
|
39
|
+
this.loaded = validateCatalogSnapshot(this.parseJson(this.fs.readText(overridePath), overridePath));
|
|
40
|
+
this.loadedFrom = 'hub';
|
|
41
|
+
return this.loaded;
|
|
42
|
+
}
|
|
43
|
+
this.loaded = validateCatalogSnapshot(this.parseJson(this.fs.readText(BUNDLED_SNAPSHOT_URL.pathname), 'bundled snapshot'));
|
|
44
|
+
this.loadedFrom = 'bundled';
|
|
45
|
+
return this.loaded;
|
|
46
|
+
}
|
|
47
|
+
/** The detected agent set on this machine — same rules, same data as `npx skills` with no -a. */
|
|
48
|
+
detected() {
|
|
49
|
+
const snapshot = this.load();
|
|
50
|
+
const homeDir = this.options.userHomeDir ?? os.homedir();
|
|
51
|
+
const env = this.options.env ?? process.env;
|
|
52
|
+
return detectAgents(snapshot, {
|
|
53
|
+
variables: snapshot.pathVariables,
|
|
54
|
+
env,
|
|
55
|
+
homeDir,
|
|
56
|
+
cwd: process.cwd(),
|
|
57
|
+
pathExists: (absolute) => this.fs.exists(absolute),
|
|
58
|
+
cwdPathExists: (relative) => this.fs.exists(path.resolve(process.cwd(), relative)),
|
|
59
|
+
packageHasDependency: (name) => this.packageJsonInCwdDeclares(name),
|
|
60
|
+
isTty: process.stdout.isTTY === true,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
snapshotInfo() {
|
|
64
|
+
const snapshot = this.load();
|
|
65
|
+
const now = this.options.now ? this.options.now() : new Date();
|
|
66
|
+
const ageDays = Math.floor((now.getTime() - new Date(snapshot.source.date).getTime()) / (24 * 60 * 60 * 1000));
|
|
67
|
+
return { source: this.loadedFrom ?? 'bundled', commit: snapshot.source.commit, date: snapshot.source.date, ageDays };
|
|
68
|
+
}
|
|
69
|
+
/** Pull upstream and overwrite the hub-local snapshot; doctor age follows on next read. */
|
|
70
|
+
async refresh() {
|
|
71
|
+
const fetchText = this.options.fetchText ?? defaultFetchText;
|
|
72
|
+
const [agentsTs, detectAgentTs, commitJson] = await Promise.all([
|
|
73
|
+
fetchText(`${RAW_BASE}/src/agents.ts`),
|
|
74
|
+
fetchText(`${RAW_BASE}/src/detect-agent.ts`),
|
|
75
|
+
fetchText(COMMIT_API),
|
|
76
|
+
]);
|
|
77
|
+
const [entry] = JSON.parse(commitJson);
|
|
78
|
+
if (!entry)
|
|
79
|
+
throw new SkillsManagerError('catalog_refresh_failed', 'Upstream commit endpoint returned no entries');
|
|
80
|
+
const snapshot = extractCatalogSnapshot({ agentsTs, detectAgentTs, commit: entry.sha, date: entry.commit.committer.date });
|
|
81
|
+
const wroteTo = this.overridePath();
|
|
82
|
+
this.fs.makeDirectory(path.dirname(wroteTo));
|
|
83
|
+
this.fs.writeText(wroteTo, `${JSON.stringify(snapshot, null, 2)}\n`);
|
|
84
|
+
this.loaded = snapshot;
|
|
85
|
+
this.loadedFrom = 'hub';
|
|
86
|
+
return { commit: entry.sha, date: entry.commit.committer.date, agentCount: snapshot.agents.length, wroteTo };
|
|
87
|
+
}
|
|
88
|
+
overridePath() {
|
|
89
|
+
return path.join(this.home.root, '.skills', 'agent-catalog.json');
|
|
90
|
+
}
|
|
91
|
+
/** Resolve an agent's global runtime dir against this machine's env/user home; null when it cannot resolve here. */
|
|
92
|
+
resolveGlobalDir(agentId) {
|
|
93
|
+
const agent = this.load().agents.find((item) => item.id === agentId);
|
|
94
|
+
if (!agent || !agent.globalSkillsDir)
|
|
95
|
+
return null;
|
|
96
|
+
return resolveCatalogTemplate(agent.globalSkillsDir, {
|
|
97
|
+
variables: this.load().pathVariables,
|
|
98
|
+
homeDir: this.options.userHomeDir ?? os.homedir(),
|
|
99
|
+
env: this.options.env ?? process.env,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
parseJson(text, origin) {
|
|
103
|
+
try {
|
|
104
|
+
return JSON.parse(text);
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
throw new SkillsManagerError('catalog_invalid', `Cannot parse ${origin}: ${error.message}. Run \`skills-manager catalog refresh\` to rebuild it.`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
packageJsonInCwdDeclares(name) {
|
|
111
|
+
const file = path.resolve(process.cwd(), 'package.json');
|
|
112
|
+
if (!this.fs.exists(file))
|
|
113
|
+
return false;
|
|
114
|
+
try {
|
|
115
|
+
const parsed = JSON.parse(this.fs.readText(file));
|
|
116
|
+
return Boolean(parsed.dependencies?.[name] || parsed.devDependencies?.[name]);
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=catalog-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog-service.js","sourceRoot":"","sources":["../../../src/core/services/catalog-service.ts"],"names":[],"mappings":"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"}
|