@skillsmith/core 0.5.8 → 0.6.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 +13 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/audit/exclusions.d.ts +67 -0
- package/dist/src/audit/exclusions.d.ts.map +1 -0
- package/dist/src/audit/exclusions.js +133 -0
- package/dist/src/audit/exclusions.js.map +1 -0
- package/dist/src/audit/exclusions.types.d.ts +45 -0
- package/dist/src/audit/exclusions.types.d.ts.map +1 -0
- package/dist/src/audit/exclusions.types.js +11 -0
- package/dist/src/audit/exclusions.types.js.map +1 -0
- package/dist/src/audit/index.d.ts +15 -0
- package/dist/src/audit/index.d.ts.map +1 -0
- package/dist/src/audit/index.js +14 -0
- package/dist/src/audit/index.js.map +1 -0
- package/dist/src/benchmarks/embeddingBenchmark.d.ts.map +1 -1
- package/dist/src/benchmarks/embeddingBenchmark.js +5 -2
- package/dist/src/benchmarks/embeddingBenchmark.js.map +1 -1
- package/dist/src/config/audit-mode.d.ts +71 -0
- package/dist/src/config/audit-mode.d.ts.map +1 -0
- package/dist/src/config/audit-mode.js +69 -0
- package/dist/src/config/audit-mode.js.map +1 -0
- package/dist/src/config/index.d.ts +13 -0
- package/dist/src/config/index.d.ts.map +1 -1
- package/dist/src/config/index.js +24 -0
- package/dist/src/config/index.js.map +1 -1
- package/dist/src/db/migration-runner.d.ts +9 -2
- package/dist/src/db/migration-runner.d.ts.map +1 -1
- package/dist/src/db/migration-runner.js +30 -3
- package/dist/src/db/migration-runner.js.map +1 -1
- package/dist/src/db/migration.d.ts.map +1 -1
- package/dist/src/db/migration.js +9 -1
- package/dist/src/db/migration.js.map +1 -1
- package/dist/src/db/migrations/v16-skill-source.d.ts +41 -0
- package/dist/src/db/migrations/v16-skill-source.d.ts.map +1 -0
- package/dist/src/db/migrations/v16-skill-source.js +87 -0
- package/dist/src/db/migrations/v16-skill-source.js.map +1 -0
- package/dist/src/db/schema-sql.d.ts +1 -1
- package/dist/src/db/schema-sql.d.ts.map +1 -1
- package/dist/src/db/schema-sql.js +2 -1
- package/dist/src/db/schema-sql.js.map +1 -1
- package/dist/src/db/schema.d.ts +9 -3
- package/dist/src/db/schema.d.ts.map +1 -1
- package/dist/src/db/schema.js +12 -2
- package/dist/src/db/schema.js.map +1 -1
- package/dist/src/embeddings/embedding-utils.d.ts +23 -0
- package/dist/src/embeddings/embedding-utils.d.ts.map +1 -1
- package/dist/src/embeddings/embedding-utils.js +39 -0
- package/dist/src/embeddings/embedding-utils.js.map +1 -1
- package/dist/src/embeddings/hnsw-search.d.ts +133 -0
- package/dist/src/embeddings/hnsw-search.d.ts.map +1 -0
- package/dist/src/embeddings/hnsw-search.js +387 -0
- package/dist/src/embeddings/hnsw-search.js.map +1 -0
- package/dist/src/embeddings/hnsw-store.d.ts +9 -3
- package/dist/src/embeddings/hnsw-store.d.ts.map +1 -1
- package/dist/src/embeddings/hnsw-store.js +17 -7
- package/dist/src/embeddings/hnsw-store.js.map +1 -1
- package/dist/src/embeddings/hnsw-store.types.d.ts +17 -4
- package/dist/src/embeddings/hnsw-store.types.d.ts.map +1 -1
- package/dist/src/embeddings/hnsw-store.types.js.map +1 -1
- package/dist/src/embeddings/index.d.ts +50 -4
- package/dist/src/embeddings/index.d.ts.map +1 -1
- package/dist/src/embeddings/index.js +166 -24
- package/dist/src/embeddings/index.js.map +1 -1
- package/dist/src/index.d.ts +4 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +5 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/install/fan-out.d.ts +81 -0
- package/dist/src/install/fan-out.d.ts.map +1 -0
- package/dist/src/install/fan-out.js +236 -0
- package/dist/src/install/fan-out.js.map +1 -0
- package/dist/src/install/index.d.ts +16 -0
- package/dist/src/install/index.d.ts.map +1 -0
- package/dist/src/install/index.js +14 -0
- package/dist/src/install/index.js.map +1 -0
- package/dist/src/install/paths.d.ts +16 -0
- package/dist/src/install/paths.d.ts.map +1 -0
- package/dist/src/install/paths.js +56 -0
- package/dist/src/install/paths.js.map +1 -0
- package/dist/src/repositories/AdvisoryRepository.test.js +2 -2
- package/dist/src/repositories/AdvisoryRepository.test.js.map +1 -1
- package/dist/src/repositories/SkillRepository.d.ts.map +1 -1
- package/dist/src/repositories/SkillRepository.js +12 -4
- package/dist/src/repositories/SkillRepository.js.map +1 -1
- package/dist/src/search/hybrid.js +2 -2
- package/dist/src/search/hybrid.js.map +1 -1
- package/dist/src/security/pathValidation.d.ts +6 -1
- package/dist/src/security/pathValidation.d.ts.map +1 -1
- package/dist/src/security/pathValidation.js +6 -1
- package/dist/src/security/pathValidation.js.map +1 -1
- package/dist/src/services/skill-installation.service.d.ts.map +1 -1
- package/dist/src/services/skill-installation.service.js +4 -2
- package/dist/src/services/skill-installation.service.js.map +1 -1
- package/dist/src/skills/index-local.d.ts +107 -0
- package/dist/src/skills/index-local.d.ts.map +1 -0
- package/dist/src/skills/index-local.js +208 -0
- package/dist/src/skills/index-local.js.map +1 -0
- package/dist/src/sync/SyncEngine.d.ts.map +1 -1
- package/dist/src/sync/SyncEngine.js +20 -3
- package/dist/src/sync/SyncEngine.js.map +1 -1
- package/dist/src/types/skill.d.ts +19 -4
- package/dist/src/types/skill.d.ts.map +1 -1
- package/dist/src/types/skill.js.map +1 -1
- package/dist/tests/EmbeddingService.test.js +1 -1
- package/dist/tests/EmbeddingService.test.js.map +1 -1
- package/dist/tests/SkillVersionRepository.test.js +2 -2
- package/dist/tests/SkillVersionRepository.test.js.map +1 -1
- package/dist/tests/db/migration.test.js +13 -5
- package/dist/tests/db/migration.test.js.map +1 -1
- package/dist/tests/embeddings/hnsw-bench-gate.test.d.ts +15 -0
- package/dist/tests/embeddings/hnsw-bench-gate.test.d.ts.map +1 -0
- package/dist/tests/embeddings/hnsw-bench-gate.test.js +117 -0
- package/dist/tests/embeddings/hnsw-bench-gate.test.js.map +1 -0
- package/dist/tests/embeddings/hnsw-integration.test.d.ts +14 -0
- package/dist/tests/embeddings/hnsw-integration.test.d.ts.map +1 -0
- package/dist/tests/embeddings/hnsw-integration.test.js +160 -0
- package/dist/tests/embeddings/hnsw-integration.test.js.map +1 -0
- package/dist/tests/embeddings/hnsw-vs-brute-force.bench.d.ts +15 -0
- package/dist/tests/embeddings/hnsw-vs-brute-force.bench.d.ts.map +1 -0
- package/dist/tests/embeddings/hnsw-vs-brute-force.bench.js +64 -0
- package/dist/tests/embeddings/hnsw-vs-brute-force.bench.js.map +1 -0
- package/dist/tests/embeddings/seed-bench.d.ts +15 -0
- package/dist/tests/embeddings/seed-bench.d.ts.map +1 -0
- package/dist/tests/embeddings/seed-bench.js +61 -0
- package/dist/tests/embeddings/seed-bench.js.map +1 -0
- package/dist/tests/helpers/database.d.ts +11 -2
- package/dist/tests/helpers/database.d.ts.map +1 -1
- package/dist/tests/helpers/database.js +23 -7
- package/dist/tests/helpers/database.js.map +1 -1
- package/dist/tests/install/fan-out.test.d.ts +2 -0
- package/dist/tests/install/fan-out.test.d.ts.map +1 -0
- package/dist/tests/install/fan-out.test.js +238 -0
- package/dist/tests/install/fan-out.test.js.map +1 -0
- package/dist/tests/install/paths.test.d.ts +2 -0
- package/dist/tests/install/paths.test.d.ts.map +1 -0
- package/dist/tests/install/paths.test.js +79 -0
- package/dist/tests/install/paths.test.js.map +1 -0
- package/dist/tests/repositories/CoInstallRepository.test.js +2 -2
- package/dist/tests/repositories/CoInstallRepository.test.js.map +1 -1
- package/dist/tests/repositories/SkillDependencyRepository.test.js +2 -2
- package/dist/tests/repositories/SkillDependencyRepository.test.js.map +1 -1
- package/dist/tests/schema.test.js +12 -0
- package/dist/tests/schema.test.js.map +1 -1
- package/dist/tests/skill-scanner/allowlist.test.js +27 -4
- package/dist/tests/skill-scanner/allowlist.test.js.map +1 -1
- package/dist/tests/unit/audit/exclusions.test.d.ts +7 -0
- package/dist/tests/unit/audit/exclusions.test.d.ts.map +1 -0
- package/dist/tests/unit/audit/exclusions.test.js +157 -0
- package/dist/tests/unit/audit/exclusions.test.js.map +1 -0
- package/dist/tests/unit/config/audit-mode.test.d.ts +11 -0
- package/dist/tests/unit/config/audit-mode.test.d.ts.map +1 -0
- package/dist/tests/unit/config/audit-mode.test.js +86 -0
- package/dist/tests/unit/config/audit-mode.test.js.map +1 -0
- package/dist/tests/unit/migrations/migration-v16.test.d.ts +11 -0
- package/dist/tests/unit/migrations/migration-v16.test.d.ts.map +1 -0
- package/dist/tests/unit/migrations/migration-v16.test.js +134 -0
- package/dist/tests/unit/migrations/migration-v16.test.js.map +1 -0
- package/dist/tests/unit/migrations/v10-dependencies.test.js +2 -2
- package/dist/tests/unit/migrations/v10-dependencies.test.js.map +1 -1
- package/dist/tests/unit/services/skill-installation-extended.test.js +1 -1
- package/dist/tests/unit/services/skill-installation-extended.test.js.map +1 -1
- package/dist/tests/unit/services/skill-installation.service.test.js +1 -1
- package/dist/tests/unit/services/skill-installation.service.test.js.map +1 -1
- package/dist/tests/unit/skills/index-local.test.d.ts +11 -0
- package/dist/tests/unit/skills/index-local.test.d.ts.map +1 -0
- package/dist/tests/unit/skills/index-local.test.js +88 -0
- package/dist/tests/unit/skills/index-local.test.js.map +1 -0
- package/dist/tests/unit/sync-engine.source-aware.test.d.ts +11 -0
- package/dist/tests/unit/sync-engine.source-aware.test.d.ts.map +1 -0
- package/dist/tests/unit/sync-engine.source-aware.test.js +147 -0
- package/dist/tests/unit/sync-engine.source-aware.test.js.map +1 -0
- package/package.json +26 -3
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { type ClientId } from './paths.js';
|
|
2
|
+
export type LinkKind = 'symlink' | 'copy';
|
|
3
|
+
export interface LinkRecord {
|
|
4
|
+
skillId: string;
|
|
5
|
+
from: string;
|
|
6
|
+
to: string;
|
|
7
|
+
kind: LinkKind;
|
|
8
|
+
createdAt: string;
|
|
9
|
+
}
|
|
10
|
+
export interface LinkManifest {
|
|
11
|
+
version: 1;
|
|
12
|
+
links: LinkRecord[];
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Resolve the manifest file path. Sits under `~/.skillsmith/` so it shares
|
|
16
|
+
* the existing allow-list entry for that directory (DEFAULT_ALLOWED_DIRS in
|
|
17
|
+
* `pathValidation.ts`).
|
|
18
|
+
*/
|
|
19
|
+
export declare function getLinkManifestPath(): string;
|
|
20
|
+
/**
|
|
21
|
+
* Load the manifest from disk. Returns an empty manifest if the file is
|
|
22
|
+
* missing or unreadable — fan-out is best-effort, never crash on cold start.
|
|
23
|
+
*/
|
|
24
|
+
export declare function loadManifest(): Promise<LinkManifest>;
|
|
25
|
+
/**
|
|
26
|
+
* Persist the manifest atomically (write-temp + rename) so a crash mid-write
|
|
27
|
+
* never leaves the file in a partial state.
|
|
28
|
+
*/
|
|
29
|
+
export declare function saveManifest(manifest: LinkManifest): Promise<void>;
|
|
30
|
+
export interface AddLinkOptions {
|
|
31
|
+
/** Skill identifier (e.g. `author/name`). Used as the directory name on disk. */
|
|
32
|
+
skillId: string;
|
|
33
|
+
/** Source-of-truth client (almost always `claude-code`). */
|
|
34
|
+
fromClient: ClientId;
|
|
35
|
+
/** Destination client (must differ from `fromClient`). */
|
|
36
|
+
toClient: ClientId;
|
|
37
|
+
/** Try `fs.symlink` first; fall back to copy on EPERM. Default: false (copy). */
|
|
38
|
+
preferSymlink?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Overwrite if destination already contains an entry of the same name.
|
|
41
|
+
* Without `--force`, addLink refuses to clobber a different on-disk skill.
|
|
42
|
+
*/
|
|
43
|
+
force?: boolean;
|
|
44
|
+
}
|
|
45
|
+
export interface AddLinkResult {
|
|
46
|
+
record: LinkRecord;
|
|
47
|
+
/** True if `preferSymlink` was set but EPERM forced a fallback to copy. */
|
|
48
|
+
fellBackToCopy: boolean;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Create a fan-out link from one client's skill directory into another's.
|
|
52
|
+
*
|
|
53
|
+
* - Default kind is `'copy'` (recursive directory copy). `preferSymlink`
|
|
54
|
+
* opts into a relative symlink and falls back to copy on EPERM (Windows
|
|
55
|
+
* non-developer-mode users).
|
|
56
|
+
* - Refuses on cycle. Refuses on conflict unless `force: true`.
|
|
57
|
+
* - Appends a `LinkRecord` to the manifest at
|
|
58
|
+
* `~/.skillsmith/links/manifest.json` so uninstall can tear it down.
|
|
59
|
+
*/
|
|
60
|
+
export declare function addLink(opts: AddLinkOptions): Promise<AddLinkResult>;
|
|
61
|
+
/**
|
|
62
|
+
* Remove every fan-out link recorded for `skillId`. Returns the number of
|
|
63
|
+
* destinations removed. Safe to call when no manifest exists (returns 0).
|
|
64
|
+
*
|
|
65
|
+
* Uninstall callers should invoke this BEFORE removing the canonical
|
|
66
|
+
* directory so symlinks resolve cleanly during their lstat checks.
|
|
67
|
+
*/
|
|
68
|
+
export declare function removeLinks(skillId: string): Promise<number>;
|
|
69
|
+
/**
|
|
70
|
+
* List all fan-out links for a skill (or all skills when `skillId` is
|
|
71
|
+
* undefined). Read-only — for `skillsmith list --client X` and the
|
|
72
|
+
* cross-client `getInstalledSkills` consolidator.
|
|
73
|
+
*/
|
|
74
|
+
export declare function listLinks(skillId?: string): Promise<LinkRecord[]>;
|
|
75
|
+
/**
|
|
76
|
+
* Convenience: derive the default `fromClient` for fan-out (the canonical
|
|
77
|
+
* client). Exists so callers don't have to import `CANONICAL_CLIENT`
|
|
78
|
+
* separately when they only need the fan-out helpers.
|
|
79
|
+
*/
|
|
80
|
+
export declare function getDefaultFromClient(): ClientId;
|
|
81
|
+
//# sourceMappingURL=fan-out.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fan-out.d.ts","sourceRoot":"","sources":["../../../src/install/fan-out.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAyC,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAA;AAEjF,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAA;AAEzC,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,QAAQ,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,CAAC,CAAA;IACV,KAAK,EAAE,UAAU,EAAE,CAAA;CACpB;AAID;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED;;;GAGG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,YAAY,CAAC,CAY1D;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAOxE;AAED,MAAM,WAAW,cAAc;IAC7B,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAA;IACf,4DAA4D;IAC5D,UAAU,EAAE,QAAQ,CAAA;IACpB,0DAA0D;IAC1D,QAAQ,EAAE,QAAQ,CAAA;IAClB,iFAAiF;IACjF,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,UAAU,CAAA;IAClB,2EAA2E;IAC3E,cAAc,EAAE,OAAO,CAAA;CACxB;AAuED;;;;;;;;;GASG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAiE1E;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAYlE;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAIvE;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,QAAQ,CAE/C"}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-4578: Multi-client install fan-out + link manifest.
|
|
3
|
+
*
|
|
4
|
+
* When a user installs a skill via `--also-link <client>`, the canonical
|
|
5
|
+
* directory (`~/.claude/skills/<skill>`) is fanned out to the named client's
|
|
6
|
+
* directory (e.g. `~/.cursor/skills/<skill>`). By default the fan-out is a
|
|
7
|
+
* recursive directory copy — per SMI-4287, `LocalFilesystemAdapter` rejects
|
|
8
|
+
* symlinks whose target resolves outside `rootDir`, so a scanner pointed at
|
|
9
|
+
* `~/.cursor/skills/` would silently skip a symlinked entry. `--symlink` is
|
|
10
|
+
* the explicit POSIX opt-in for users who accept that tradeoff.
|
|
11
|
+
*
|
|
12
|
+
* Every fan-out is recorded in `~/.skillsmith/links/manifest.json` so
|
|
13
|
+
* `removeLinks(skillId)` can tear down both copies and symlinks atomically
|
|
14
|
+
* during uninstall.
|
|
15
|
+
*
|
|
16
|
+
* @module @skillsmith/core/install/fan-out
|
|
17
|
+
*/
|
|
18
|
+
import { homedir } from 'node:os';
|
|
19
|
+
import * as path from 'node:path';
|
|
20
|
+
import * as fs from 'node:fs';
|
|
21
|
+
import * as fsp from 'node:fs/promises';
|
|
22
|
+
import { CLIENT_NATIVE_PATHS, CANONICAL_CLIENT } from './paths.js';
|
|
23
|
+
const MANIFEST_VERSION = 1;
|
|
24
|
+
/**
|
|
25
|
+
* Resolve the manifest file path. Sits under `~/.skillsmith/` so it shares
|
|
26
|
+
* the existing allow-list entry for that directory (DEFAULT_ALLOWED_DIRS in
|
|
27
|
+
* `pathValidation.ts`).
|
|
28
|
+
*/
|
|
29
|
+
export function getLinkManifestPath() {
|
|
30
|
+
return path.join(homedir(), '.skillsmith', 'links', 'manifest.json');
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Load the manifest from disk. Returns an empty manifest if the file is
|
|
34
|
+
* missing or unreadable — fan-out is best-effort, never crash on cold start.
|
|
35
|
+
*/
|
|
36
|
+
export async function loadManifest() {
|
|
37
|
+
const manifestPath = getLinkManifestPath();
|
|
38
|
+
try {
|
|
39
|
+
const raw = await fsp.readFile(manifestPath, 'utf-8');
|
|
40
|
+
const parsed = JSON.parse(raw);
|
|
41
|
+
if (parsed?.version !== MANIFEST_VERSION || !Array.isArray(parsed.links)) {
|
|
42
|
+
return { version: MANIFEST_VERSION, links: [] };
|
|
43
|
+
}
|
|
44
|
+
return parsed;
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return { version: MANIFEST_VERSION, links: [] };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Persist the manifest atomically (write-temp + rename) so a crash mid-write
|
|
52
|
+
* never leaves the file in a partial state.
|
|
53
|
+
*/
|
|
54
|
+
export async function saveManifest(manifest) {
|
|
55
|
+
const manifestPath = getLinkManifestPath();
|
|
56
|
+
const dir = path.dirname(manifestPath);
|
|
57
|
+
await fsp.mkdir(dir, { recursive: true });
|
|
58
|
+
const tmp = `${manifestPath}.${process.pid}.tmp`;
|
|
59
|
+
await fsp.writeFile(tmp, JSON.stringify(manifest, null, 2), 'utf-8');
|
|
60
|
+
await fsp.rename(tmp, manifestPath);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Detect a fan-out cycle: refuses to link `from → to` when `to` is already
|
|
64
|
+
* the source of any entry, OR when `from` is already the destination of any
|
|
65
|
+
* entry pointing back at us. Compares via resolved-path so a chain like
|
|
66
|
+
* `claude-code → agents → claude-code` is caught even if one hop uses a
|
|
67
|
+
* symlinked agents directory that resolves back to claude-code.
|
|
68
|
+
*/
|
|
69
|
+
function detectCycle(manifest, from, to) {
|
|
70
|
+
const resolvedFrom = path.resolve(from);
|
|
71
|
+
const resolvedTo = path.resolve(to);
|
|
72
|
+
if (resolvedFrom === resolvedTo) {
|
|
73
|
+
return `from and to resolve to the same path (${resolvedFrom}) — refusing to link a directory to itself`;
|
|
74
|
+
}
|
|
75
|
+
for (const link of manifest.links) {
|
|
76
|
+
const linkFrom = path.resolve(link.from);
|
|
77
|
+
const linkTo = path.resolve(link.to);
|
|
78
|
+
if (linkFrom === resolvedTo && linkTo === resolvedFrom) {
|
|
79
|
+
return `cycle detected: ${linkFrom} ↔ ${linkTo} is already linked in the reverse direction`;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Recursively copy a directory. Mirrors the install command's existing
|
|
86
|
+
* symlink-rejection policy: any symlink encountered inside the source tree
|
|
87
|
+
* is skipped (not followed) so the destination stays a clean materialized
|
|
88
|
+
* copy.
|
|
89
|
+
*/
|
|
90
|
+
async function copyDirectoryRecursive(src, dest) {
|
|
91
|
+
await fsp.mkdir(dest, { recursive: true });
|
|
92
|
+
const entries = await fsp.readdir(src, { withFileTypes: true });
|
|
93
|
+
for (const entry of entries) {
|
|
94
|
+
const srcPath = path.join(src, entry.name);
|
|
95
|
+
const destPath = path.join(dest, entry.name);
|
|
96
|
+
if (entry.isSymbolicLink()) {
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
if (entry.isDirectory()) {
|
|
100
|
+
await copyDirectoryRecursive(srcPath, destPath);
|
|
101
|
+
}
|
|
102
|
+
else if (entry.isFile()) {
|
|
103
|
+
await fsp.copyFile(srcPath, destPath);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
async function pathExists(p) {
|
|
108
|
+
try {
|
|
109
|
+
await fsp.access(p, fs.constants.F_OK);
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
async function removePath(p) {
|
|
117
|
+
try {
|
|
118
|
+
const stat = await fsp.lstat(p);
|
|
119
|
+
if (stat.isSymbolicLink() || stat.isFile()) {
|
|
120
|
+
await fsp.unlink(p);
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
await fsp.rm(p, { recursive: true, force: true });
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
// Best-effort — uninstall should not fail because cleanup races with
|
|
128
|
+
// an external editor that already moved the file.
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Create a fan-out link from one client's skill directory into another's.
|
|
133
|
+
*
|
|
134
|
+
* - Default kind is `'copy'` (recursive directory copy). `preferSymlink`
|
|
135
|
+
* opts into a relative symlink and falls back to copy on EPERM (Windows
|
|
136
|
+
* non-developer-mode users).
|
|
137
|
+
* - Refuses on cycle. Refuses on conflict unless `force: true`.
|
|
138
|
+
* - Appends a `LinkRecord` to the manifest at
|
|
139
|
+
* `~/.skillsmith/links/manifest.json` so uninstall can tear it down.
|
|
140
|
+
*/
|
|
141
|
+
export async function addLink(opts) {
|
|
142
|
+
const { skillId, fromClient, toClient, preferSymlink = false, force = false } = opts;
|
|
143
|
+
if (fromClient === toClient) {
|
|
144
|
+
throw new Error(`addLink: fromClient and toClient must differ (both were '${fromClient}')`);
|
|
145
|
+
}
|
|
146
|
+
const fromDir = path.join(CLIENT_NATIVE_PATHS[fromClient], skillId);
|
|
147
|
+
const toDir = path.join(CLIENT_NATIVE_PATHS[toClient], skillId);
|
|
148
|
+
if (!(await pathExists(fromDir))) {
|
|
149
|
+
throw new Error(`addLink: source skill '${skillId}' does not exist at ${fromDir} — install for ${fromClient} first`);
|
|
150
|
+
}
|
|
151
|
+
const manifest = await loadManifest();
|
|
152
|
+
const cycle = detectCycle(manifest, fromDir, toDir);
|
|
153
|
+
if (cycle)
|
|
154
|
+
throw new Error(`addLink: ${cycle}`);
|
|
155
|
+
if (await pathExists(toDir)) {
|
|
156
|
+
if (!force) {
|
|
157
|
+
throw new Error(`addLink: ${toDir} already exists. Pass force: true (CLI: --force) to overwrite.`);
|
|
158
|
+
}
|
|
159
|
+
await removePath(toDir);
|
|
160
|
+
}
|
|
161
|
+
await fsp.mkdir(path.dirname(toDir), { recursive: true });
|
|
162
|
+
let kind = 'copy';
|
|
163
|
+
let fellBackToCopy = false;
|
|
164
|
+
if (preferSymlink) {
|
|
165
|
+
// Use a relative symlink so the manifest entry stays portable across
|
|
166
|
+
// homedir changes (matters for users who rsync their home directory).
|
|
167
|
+
const relTarget = path.relative(path.dirname(toDir), fromDir);
|
|
168
|
+
try {
|
|
169
|
+
await fsp.symlink(relTarget, toDir, 'dir');
|
|
170
|
+
kind = 'symlink';
|
|
171
|
+
}
|
|
172
|
+
catch (err) {
|
|
173
|
+
const code = err.code;
|
|
174
|
+
if (code === 'EPERM' || code === 'ENOSYS') {
|
|
175
|
+
await copyDirectoryRecursive(fromDir, toDir);
|
|
176
|
+
kind = 'copy';
|
|
177
|
+
fellBackToCopy = true;
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
throw err;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
await copyDirectoryRecursive(fromDir, toDir);
|
|
186
|
+
}
|
|
187
|
+
const record = {
|
|
188
|
+
skillId,
|
|
189
|
+
from: fromDir,
|
|
190
|
+
to: toDir,
|
|
191
|
+
kind,
|
|
192
|
+
createdAt: new Date().toISOString(),
|
|
193
|
+
};
|
|
194
|
+
manifest.links.push(record);
|
|
195
|
+
await saveManifest(manifest);
|
|
196
|
+
return { record, fellBackToCopy };
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Remove every fan-out link recorded for `skillId`. Returns the number of
|
|
200
|
+
* destinations removed. Safe to call when no manifest exists (returns 0).
|
|
201
|
+
*
|
|
202
|
+
* Uninstall callers should invoke this BEFORE removing the canonical
|
|
203
|
+
* directory so symlinks resolve cleanly during their lstat checks.
|
|
204
|
+
*/
|
|
205
|
+
export async function removeLinks(skillId) {
|
|
206
|
+
const manifest = await loadManifest();
|
|
207
|
+
const matching = manifest.links.filter((l) => l.skillId === skillId);
|
|
208
|
+
if (matching.length === 0)
|
|
209
|
+
return 0;
|
|
210
|
+
for (const link of matching) {
|
|
211
|
+
await removePath(link.to);
|
|
212
|
+
}
|
|
213
|
+
manifest.links = manifest.links.filter((l) => l.skillId !== skillId);
|
|
214
|
+
await saveManifest(manifest);
|
|
215
|
+
return matching.length;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* List all fan-out links for a skill (or all skills when `skillId` is
|
|
219
|
+
* undefined). Read-only — for `skillsmith list --client X` and the
|
|
220
|
+
* cross-client `getInstalledSkills` consolidator.
|
|
221
|
+
*/
|
|
222
|
+
export async function listLinks(skillId) {
|
|
223
|
+
const manifest = await loadManifest();
|
|
224
|
+
if (skillId === undefined)
|
|
225
|
+
return [...manifest.links];
|
|
226
|
+
return manifest.links.filter((l) => l.skillId === skillId);
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Convenience: derive the default `fromClient` for fan-out (the canonical
|
|
230
|
+
* client). Exists so callers don't have to import `CANONICAL_CLIENT`
|
|
231
|
+
* separately when they only need the fan-out helpers.
|
|
232
|
+
*/
|
|
233
|
+
export function getDefaultFromClient() {
|
|
234
|
+
return CANONICAL_CLIENT;
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=fan-out.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fan-out.js","sourceRoot":"","sources":["../../../src/install/fan-out.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-4578: Public surface for `@skillsmith/core/install`.
|
|
3
|
+
*
|
|
4
|
+
* Subpath export — consumers import as:
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* import { getCanonicalInstallPath, type ClientId } from '@skillsmith/core/install'
|
|
8
|
+
* ```
|
|
9
|
+
*
|
|
10
|
+
* @module @skillsmith/core/install
|
|
11
|
+
*/
|
|
12
|
+
export { CANONICAL_CLIENT, CLIENT_IDS, CLIENT_NATIVE_PATHS, assertClientId, getCanonicalInstallPath, getInstallPath, resolveClientId, resolveClientPath, } from './paths.js';
|
|
13
|
+
export type { ClientId } from './paths.js';
|
|
14
|
+
export { addLink, getDefaultFromClient, getLinkManifestPath, listLinks, loadManifest, removeLinks, saveManifest, } from './fan-out.js';
|
|
15
|
+
export type { AddLinkOptions, AddLinkResult, LinkKind, LinkManifest, LinkRecord, } from './fan-out.js';
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/install/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,mBAAmB,EACnB,cAAc,EACd,uBAAuB,EACvB,cAAc,EACd,eAAe,EACf,iBAAiB,GAClB,MAAM,YAAY,CAAA;AACnB,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAE1C,OAAO,EACL,OAAO,EACP,oBAAoB,EACpB,mBAAmB,EACnB,SAAS,EACT,YAAY,EACZ,WAAW,EACX,YAAY,GACb,MAAM,cAAc,CAAA;AACrB,YAAY,EACV,cAAc,EACd,aAAa,EACb,QAAQ,EACR,YAAY,EACZ,UAAU,GACX,MAAM,cAAc,CAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-4578: Public surface for `@skillsmith/core/install`.
|
|
3
|
+
*
|
|
4
|
+
* Subpath export — consumers import as:
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* import { getCanonicalInstallPath, type ClientId } from '@skillsmith/core/install'
|
|
8
|
+
* ```
|
|
9
|
+
*
|
|
10
|
+
* @module @skillsmith/core/install
|
|
11
|
+
*/
|
|
12
|
+
export { CANONICAL_CLIENT, CLIENT_IDS, CLIENT_NATIVE_PATHS, assertClientId, getCanonicalInstallPath, getInstallPath, resolveClientId, resolveClientPath, } from './paths.js';
|
|
13
|
+
export { addLink, getDefaultFromClient, getLinkManifestPath, listLinks, loadManifest, removeLinks, saveManifest, } from './fan-out.js';
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/install/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,mBAAmB,EACnB,cAAc,EACd,uBAAuB,EACvB,cAAc,EACd,eAAe,EACf,iBAAiB,GAClB,MAAM,YAAY,CAAA;AAGnB,OAAO,EACL,OAAO,EACP,oBAAoB,EACpB,mBAAmB,EACnB,SAAS,EACT,YAAY,EACZ,WAAW,EACX,YAAY,GACb,MAAM,cAAc,CAAA"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type ClientId = 'claude-code' | 'cursor' | 'copilot' | 'windsurf' | 'agents';
|
|
2
|
+
export declare const CLIENT_NATIVE_PATHS: Record<ClientId, string>;
|
|
3
|
+
export declare const CANONICAL_CLIENT: ClientId;
|
|
4
|
+
export declare const CLIENT_IDS: ReadonlyArray<ClientId>;
|
|
5
|
+
export declare function getCanonicalInstallPath(): string;
|
|
6
|
+
export declare function getInstallPath(client?: ClientId): string;
|
|
7
|
+
export declare function assertClientId(value: unknown): asserts value is ClientId;
|
|
8
|
+
export declare function resolveClientId(raw: string | undefined): ClientId;
|
|
9
|
+
/**
|
|
10
|
+
* Resolve the active client from `SKILLSMITH_CLIENT` (or any explicit
|
|
11
|
+
* override). Returns the matching install path. Computed at call time so
|
|
12
|
+
* a process that mutates `SKILLSMITH_CLIENT` at runtime sees the new
|
|
13
|
+
* value — used by the MCP server to pick `~/.cursor/skills/` etc.
|
|
14
|
+
*/
|
|
15
|
+
export declare function resolveClientPath(override?: string | undefined): string;
|
|
16
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../src/install/paths.ts"],"names":[],"mappings":"AAmBA,MAAM,MAAM,QAAQ,GAAG,aAAa,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAA;AAEnF,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAMxD,CAAA;AAED,eAAO,MAAM,gBAAgB,EAAE,QAAwB,CAAA;AAEvD,eAAO,MAAM,UAAU,EAAE,aAAa,CAAC,QAAQ,CAM7C,CAAA;AAEF,wBAAgB,uBAAuB,IAAI,MAAM,CAEhD;AAED,wBAAgB,cAAc,CAAC,MAAM,GAAE,QAA2B,GAAG,MAAM,CAE1E;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,QAAQ,CAOxE;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,CAIjE;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAGvE"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-4578: Multi-client install paths.
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for the per-agent skill directory table. The CLI
|
|
5
|
+
* `--client` flag, the MCP `SKILLSMITH_CLIENT` env var, and every reader of
|
|
6
|
+
* `~/.claude/skills` route through the helpers below so the canonical path is
|
|
7
|
+
* defined in exactly one place.
|
|
8
|
+
*
|
|
9
|
+
* @module @skillsmith/core/install/paths
|
|
10
|
+
*/
|
|
11
|
+
import { homedir } from 'node:os';
|
|
12
|
+
import { join } from 'node:path';
|
|
13
|
+
export const CLIENT_NATIVE_PATHS = {
|
|
14
|
+
'claude-code': join(homedir(), '.claude', 'skills'),
|
|
15
|
+
cursor: join(homedir(), '.cursor', 'skills'),
|
|
16
|
+
copilot: join(homedir(), '.copilot', 'skills'),
|
|
17
|
+
windsurf: join(homedir(), '.codeium', 'windsurf', 'skills'),
|
|
18
|
+
agents: join(homedir(), '.agents', 'skills'),
|
|
19
|
+
};
|
|
20
|
+
export const CANONICAL_CLIENT = 'claude-code';
|
|
21
|
+
export const CLIENT_IDS = Object.freeze([
|
|
22
|
+
'claude-code',
|
|
23
|
+
'cursor',
|
|
24
|
+
'copilot',
|
|
25
|
+
'windsurf',
|
|
26
|
+
'agents',
|
|
27
|
+
]);
|
|
28
|
+
export function getCanonicalInstallPath() {
|
|
29
|
+
return CLIENT_NATIVE_PATHS[CANONICAL_CLIENT];
|
|
30
|
+
}
|
|
31
|
+
export function getInstallPath(client = CANONICAL_CLIENT) {
|
|
32
|
+
return CLIENT_NATIVE_PATHS[client];
|
|
33
|
+
}
|
|
34
|
+
export function assertClientId(value) {
|
|
35
|
+
if (typeof value !== 'string' || !CLIENT_IDS.includes(value)) {
|
|
36
|
+
throw new Error(`Invalid client '${String(value)}'. Valid: ${CLIENT_IDS.join(', ')}. ` +
|
|
37
|
+
`For Codex, pass --client agents (the path is shared via the open-standard cross-agent convention).`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export function resolveClientId(raw) {
|
|
41
|
+
if (raw === undefined || raw === '')
|
|
42
|
+
return CANONICAL_CLIENT;
|
|
43
|
+
assertClientId(raw);
|
|
44
|
+
return raw;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Resolve the active client from `SKILLSMITH_CLIENT` (or any explicit
|
|
48
|
+
* override). Returns the matching install path. Computed at call time so
|
|
49
|
+
* a process that mutates `SKILLSMITH_CLIENT` at runtime sees the new
|
|
50
|
+
* value — used by the MCP server to pick `~/.cursor/skills/` etc.
|
|
51
|
+
*/
|
|
52
|
+
export function resolveClientPath(override) {
|
|
53
|
+
const raw = override !== undefined ? override : process.env['SKILLSMITH_CLIENT'];
|
|
54
|
+
return getInstallPath(resolveClientId(raw));
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../src/install/paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAUhC,MAAM,CAAC,MAAM,mBAAmB,GAA6B;IAC3D,aAAa,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,QAAQ,CAAC;IACnD,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,QAAQ,CAAC;IAC5C,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,QAAQ,CAAC;IAC9C,QAAQ,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,CAAC;IAC3D,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,QAAQ,CAAC;CAC7C,CAAA;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAa,aAAa,CAAA;AAEvD,MAAM,CAAC,MAAM,UAAU,GAA4B,MAAM,CAAC,MAAM,CAAC;IAC/D,aAAa;IACb,QAAQ;IACR,SAAS;IACT,UAAU;IACV,QAAQ;CACT,CAAC,CAAA;AAEF,MAAM,UAAU,uBAAuB;IACrC,OAAO,mBAAmB,CAAC,gBAAgB,CAAC,CAAA;AAC9C,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,SAAmB,gBAAgB;IAChE,OAAO,mBAAmB,CAAC,MAAM,CAAC,CAAA;AACpC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAiB,CAAC,EAAE,CAAC;QACzE,MAAM,IAAI,KAAK,CACb,mBAAmB,MAAM,CAAC,KAAK,CAAC,aAAa,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;YACpE,oGAAoG,CACvG,CAAA;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAAuB;IACrD,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,EAAE;QAAE,OAAO,gBAAgB,CAAA;IAC5D,cAAc,CAAC,GAAG,CAAC,CAAA;IACnB,OAAO,GAAG,CAAA;AACZ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAA6B;IAC7D,MAAM,GAAG,GAAG,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAA;IAChF,OAAO,cAAc,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAA;AAC7C,CAAC"}
|
|
@@ -25,8 +25,8 @@ function makeAdvisory(overrides = {}) {
|
|
|
25
25
|
describe('AdvisoryRepository', () => {
|
|
26
26
|
let db;
|
|
27
27
|
let repo;
|
|
28
|
-
beforeEach(() => {
|
|
29
|
-
db = createTestDatabase();
|
|
28
|
+
beforeEach(async () => {
|
|
29
|
+
db = await createTestDatabase();
|
|
30
30
|
repo = new AdvisoryRepository(db);
|
|
31
31
|
});
|
|
32
32
|
afterEach(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdvisoryRepository.test.js","sourceRoot":"","sources":["../../../src/repositories/AdvisoryRepository.test.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AACpE,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAA;AACnF,OAAO,EAAE,kBAAkB,EAAsB,MAAM,yBAAyB,CAAA;AAGhF,+EAA+E;AAC/E,eAAe;AACf,+EAA+E;AAE/E,SAAS,YAAY,CAAC,YAAoC,EAAE;IAC1D,OAAO;QACL,EAAE,EAAE,cAAc;QAClB,OAAO,EAAE,yBAAyB;QAClC,QAAQ,EAAE,MAAM;QAChB,KAAK,EAAE,mCAAmC;QAC1C,WAAW,EAAE,mEAAmE;QAChF,WAAW,EAAE,sBAAsB;QACnC,GAAG,SAAS;KACb,CAAA;AACH,CAAC;AAED,+EAA+E;AAC/E,QAAQ;AACR,+EAA+E;AAE/E,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,IAAI,EAAgB,CAAA;IACpB,IAAI,IAAwB,CAAA;IAE5B,UAAU,CAAC,
|
|
1
|
+
{"version":3,"file":"AdvisoryRepository.test.js","sourceRoot":"","sources":["../../../src/repositories/AdvisoryRepository.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SkillRepository.d.ts","sourceRoot":"","sources":["../../../src/repositories/SkillRepository.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,QAAQ,IAAI,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAE3E,OAAO,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"SkillRepository.d.ts","sourceRoot":"","sources":["../../../src/repositories/SkillRepository.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,QAAQ,IAAI,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAE3E,OAAO,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAyBpG;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,EAAE,CAAc;gBAEZ,EAAE,EAAE,YAAY;IAK5B,OAAO,CAAC,KAAK,CAYZ;IAED,OAAO,CAAC,iBAAiB;IAoDzB;;OAEG;IACH,OAAO,CAAC,UAAU;IA8BlB;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,gBAAgB,GAAG,KAAK;IA4BtC;;OAEG;IACH,WAAW,CAAC,MAAM,EAAE,gBAAgB,EAAE,GAAG,KAAK,EAAE;IA6ChD;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI;IAKlC;;OAEG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI;IAK5C;;;OAGG;IACH,OAAO,CAAC,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,gBAAgB,CAAC,KAAK,CAAC;IAC/E,OAAO,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAC,KAAK,CAAC;IA+BjE;;OAEG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,KAAK,GAAG,IAAI;IA4BzD;;OAEG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAK3B;;OAEG;IACH,SAAS,IAAI,MAAM;IAKnB;;OAEG;IACH,KAAK,IAAI,MAAM;IAKf;;OAEG;IACH,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC;IAI9B;;OAEG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAK3B;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,gBAAgB,GAAG,KAAK;CASvC"}
|
|
@@ -22,8 +22,8 @@ export class SkillRepository {
|
|
|
22
22
|
// Cast to our custom types for better-sqlite3 compatibility
|
|
23
23
|
this.stmts = {
|
|
24
24
|
insert: this.db.prepare(`
|
|
25
|
-
INSERT INTO skills (id, name, description, author, repo_url, quality_score, trust_tier, tags, risk_score, security_findings_count, security_scanned_at, security_passed, compatibility, created_at, updated_at)
|
|
26
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, datetime('now'), datetime('now'))
|
|
25
|
+
INSERT INTO skills (id, name, description, author, repo_url, quality_score, trust_tier, tags, risk_score, security_findings_count, security_scanned_at, security_passed, compatibility, source, created_at, updated_at)
|
|
26
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, datetime('now'), datetime('now'))
|
|
27
27
|
`),
|
|
28
28
|
selectById: this.db.prepare(`
|
|
29
29
|
SELECT * FROM skills WHERE id = ?
|
|
@@ -85,6 +85,10 @@ export class SkillRepository {
|
|
|
85
85
|
compatibility: row.compatibility && row.compatibility !== '[]'
|
|
86
86
|
? JSON.parse(row.compatibility)
|
|
87
87
|
: undefined,
|
|
88
|
+
// SMI-4665: Provenance — fall back to 'registry' for legacy rows that
|
|
89
|
+
// somehow lack the column (defence in depth; the NOT NULL DEFAULT in
|
|
90
|
+
// the schema should prevent this in practice).
|
|
91
|
+
source: row.source === 'local' ? 'local' : 'registry',
|
|
88
92
|
createdAt: row.created_at,
|
|
89
93
|
updatedAt: row.updated_at,
|
|
90
94
|
};
|
|
@@ -99,7 +103,9 @@ export class SkillRepository {
|
|
|
99
103
|
// SMI-825: Security scan fields
|
|
100
104
|
input.riskScore ?? null, input.securityFindingsCount ?? 0, input.securityScannedAt ?? null, input.securityPassed === undefined ? null : input.securityPassed ? 1 : 0,
|
|
101
105
|
// SMI-2760: Compatibility tags
|
|
102
|
-
JSON.stringify(input.compatibility || [])
|
|
106
|
+
JSON.stringify(input.compatibility || []),
|
|
107
|
+
// SMI-4665: Provenance — defaults to 'registry' for back-compat
|
|
108
|
+
input.source ?? 'registry');
|
|
103
109
|
const row = this.stmts.selectById.get(id);
|
|
104
110
|
return this.rowToSkill(row);
|
|
105
111
|
}
|
|
@@ -117,7 +123,9 @@ export class SkillRepository {
|
|
|
117
123
|
// SMI-825: Security scan fields
|
|
118
124
|
input.riskScore ?? null, input.securityFindingsCount ?? 0, input.securityScannedAt ?? null, input.securityPassed === undefined ? null : input.securityPassed ? 1 : 0,
|
|
119
125
|
// SMI-2760: Compatibility tags
|
|
120
|
-
JSON.stringify(input.compatibility || [])
|
|
126
|
+
JSON.stringify(input.compatibility || []),
|
|
127
|
+
// SMI-4665: Provenance — defaults to 'registry' for back-compat
|
|
128
|
+
input.source ?? 'registry');
|
|
121
129
|
const row = this.stmts.selectById.get(id);
|
|
122
130
|
created.push(this.rowToSkill(row));
|
|
123
131
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SkillRepository.js","sourceRoot":"","sources":["../../../src/repositories/SkillRepository.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"SkillRepository.js","sourceRoot":"","sources":["../../../src/repositories/SkillRepository.ts"],"names":[],"mappings":"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"}
|
|
@@ -152,8 +152,8 @@ export class HybridSearch {
|
|
|
152
152
|
try {
|
|
153
153
|
// Generate embedding for query
|
|
154
154
|
const queryEmbedding = await this.embeddings.embed(query);
|
|
155
|
-
// Find similar skills
|
|
156
|
-
const similar = this.embeddings.findSimilar(queryEmbedding, limit * 2);
|
|
155
|
+
// Find similar skills (HNSW-backed when available; brute-force fallback)
|
|
156
|
+
const similar = await this.embeddings.findSimilar(queryEmbedding, limit * 2);
|
|
157
157
|
for (const { skillId, score } of similar) {
|
|
158
158
|
results.set(skillId, score);
|
|
159
159
|
}
|