skilld 0.15.3 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -5
- package/dist/_chunks/{detect-imports.mjs → agent.mjs} +48 -15
- package/dist/_chunks/agent.mjs.map +1 -0
- package/dist/_chunks/{storage.mjs → cache.mjs} +81 -1
- package/dist/_chunks/cache.mjs.map +1 -0
- package/dist/_chunks/cache2.mjs +71 -0
- package/dist/_chunks/cache2.mjs.map +1 -0
- package/dist/_chunks/config.mjs +23 -0
- package/dist/_chunks/config.mjs.map +1 -1
- package/dist/_chunks/{embedding-cache2.mjs → embedding-cache.mjs} +1 -1
- package/dist/_chunks/embedding-cache.mjs.map +1 -0
- package/dist/_chunks/formatting.mjs +634 -0
- package/dist/_chunks/formatting.mjs.map +1 -0
- package/dist/_chunks/{version.d.mts → index.d.mts} +1 -1
- package/dist/_chunks/index.d.mts.map +1 -0
- package/dist/_chunks/{utils.d.mts → index2.d.mts} +1 -1
- package/dist/_chunks/index2.d.mts.map +1 -0
- package/dist/_chunks/install.mjs +539 -0
- package/dist/_chunks/install.mjs.map +1 -0
- package/dist/_chunks/list.mjs +70 -0
- package/dist/_chunks/list.mjs.map +1 -0
- package/dist/_chunks/markdown.mjs +7 -0
- package/dist/_chunks/markdown.mjs.map +1 -1
- package/dist/_chunks/pool.mjs +174 -0
- package/dist/_chunks/pool.mjs.map +1 -0
- package/dist/_chunks/pool2.mjs +1 -6
- package/dist/_chunks/pool2.mjs.map +1 -1
- package/dist/_chunks/prompts.mjs +234 -2
- package/dist/_chunks/prompts.mjs.map +1 -1
- package/dist/_chunks/sanitize.mjs +71 -0
- package/dist/_chunks/sanitize.mjs.map +1 -1
- package/dist/_chunks/search-interactive.mjs +245 -0
- package/dist/_chunks/search-interactive.mjs.map +1 -0
- package/dist/_chunks/search.mjs +12 -0
- package/dist/_chunks/shared.mjs +4 -0
- package/dist/_chunks/shared.mjs.map +1 -1
- package/dist/_chunks/{npm.mjs → sources.mjs} +401 -4
- package/dist/_chunks/sources.mjs.map +1 -0
- package/dist/_chunks/sync.mjs +1937 -0
- package/dist/_chunks/sync.mjs.map +1 -0
- package/dist/_chunks/sync2.mjs +13 -0
- package/dist/_chunks/uninstall.mjs +207 -0
- package/dist/_chunks/uninstall.mjs.map +1 -0
- package/dist/_chunks/validate.mjs +3 -0
- package/dist/_chunks/validate.mjs.map +1 -1
- package/dist/_chunks/yaml.mjs +19 -0
- package/dist/_chunks/yaml.mjs.map +1 -1
- package/dist/agent/index.d.mts +1 -1
- package/dist/agent/index.mjs +4 -3
- package/dist/cache/index.d.mts +2 -2
- package/dist/cache/index.mjs +2 -1
- package/dist/cli.mjs +146 -3823
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +2 -3
- package/dist/index.mjs +4 -4
- package/dist/retriv/index.mjs +14 -2
- package/dist/retriv/index.mjs.map +1 -1
- package/dist/retriv/worker.mjs +3 -3
- package/dist/sources/index.d.mts +2 -2
- package/dist/sources/index.mjs +2 -1
- package/dist/types.d.mts +2 -3
- package/package.json +9 -9
- package/dist/_chunks/detect-imports.mjs.map +0 -1
- package/dist/_chunks/embedding-cache2.mjs.map +0 -1
- package/dist/_chunks/npm.mjs.map +0 -1
- package/dist/_chunks/storage.mjs.map +0 -1
- package/dist/_chunks/utils.d.mts.map +0 -1
- package/dist/_chunks/version.d.mts.map +0 -1
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { t as CACHE_DIR } from "./config.mjs";
|
|
2
|
+
import "./sanitize.mjs";
|
|
3
|
+
import "./cache.mjs";
|
|
4
|
+
import { n as clearEmbeddingCache } from "./embedding-cache.mjs";
|
|
5
|
+
import { join } from "pathe";
|
|
6
|
+
import { existsSync, readFileSync, readdirSync, rmSync, statSync } from "node:fs";
|
|
7
|
+
import * as p from "@clack/prompts";
|
|
8
|
+
import { defineCommand } from "citty";
|
|
9
|
+
/**
|
|
10
|
+
* Cache management commands
|
|
11
|
+
*/
|
|
12
|
+
const LLM_CACHE_DIR = join(CACHE_DIR, "llm-cache");
|
|
13
|
+
const LLM_CACHE_MAX_AGE = 10080 * 60 * 1e3;
|
|
14
|
+
async function cacheCleanCommand() {
|
|
15
|
+
let expiredLlm = 0;
|
|
16
|
+
let freedBytes = 0;
|
|
17
|
+
if (existsSync(LLM_CACHE_DIR)) {
|
|
18
|
+
const now = Date.now();
|
|
19
|
+
for (const entry of readdirSync(LLM_CACHE_DIR)) {
|
|
20
|
+
const path = join(LLM_CACHE_DIR, entry);
|
|
21
|
+
try {
|
|
22
|
+
const { timestamp } = JSON.parse(readFileSync(path, "utf-8"));
|
|
23
|
+
if (now - timestamp > LLM_CACHE_MAX_AGE) {
|
|
24
|
+
const size = statSync(path).size;
|
|
25
|
+
rmSync(path);
|
|
26
|
+
expiredLlm++;
|
|
27
|
+
freedBytes += size;
|
|
28
|
+
}
|
|
29
|
+
} catch {
|
|
30
|
+
const size = statSync(path).size;
|
|
31
|
+
rmSync(path);
|
|
32
|
+
expiredLlm++;
|
|
33
|
+
freedBytes += size;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const embeddingDbPath = join(CACHE_DIR, "embeddings.db");
|
|
38
|
+
let embeddingCleared = false;
|
|
39
|
+
if (existsSync(embeddingDbPath)) {
|
|
40
|
+
const size = statSync(embeddingDbPath).size;
|
|
41
|
+
clearEmbeddingCache();
|
|
42
|
+
freedBytes += size;
|
|
43
|
+
embeddingCleared = true;
|
|
44
|
+
}
|
|
45
|
+
const freedKB = Math.round(freedBytes / 1024);
|
|
46
|
+
if (expiredLlm > 0 || embeddingCleared) {
|
|
47
|
+
const parts = [];
|
|
48
|
+
if (expiredLlm > 0) parts.push(`${expiredLlm} expired LLM cache entries`);
|
|
49
|
+
if (embeddingCleared) parts.push("embedding cache");
|
|
50
|
+
p.log.success(`Removed ${parts.join(" + ")} (${freedKB}KB freed)`);
|
|
51
|
+
} else p.log.info("Cache is clean — no expired entries");
|
|
52
|
+
}
|
|
53
|
+
const cacheCommandDef = defineCommand({
|
|
54
|
+
meta: {
|
|
55
|
+
name: "cache",
|
|
56
|
+
description: "Cache management",
|
|
57
|
+
hidden: true
|
|
58
|
+
},
|
|
59
|
+
args: { clean: {
|
|
60
|
+
type: "boolean",
|
|
61
|
+
description: "Remove expired LLM cache entries",
|
|
62
|
+
default: true
|
|
63
|
+
} },
|
|
64
|
+
async run() {
|
|
65
|
+
p.intro(`\x1B[1m\x1B[35mskilld\x1B[0m cache clean`);
|
|
66
|
+
await cacheCleanCommand();
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
export { cacheCommandDef };
|
|
70
|
+
|
|
71
|
+
//# sourceMappingURL=cache2.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache2.mjs","names":[],"sources":["../../src/commands/cache.ts"],"sourcesContent":["/**\n * Cache management commands\n */\n\nimport { existsSync, readdirSync, readFileSync, rmSync, statSync } from 'node:fs'\nimport * as p from '@clack/prompts'\nimport { defineCommand } from 'citty'\nimport { join } from 'pathe'\nimport { CACHE_DIR } from '../cache/index.ts'\nimport { clearEmbeddingCache } from '../retriv/embedding-cache.ts'\n\nconst LLM_CACHE_DIR = join(CACHE_DIR, 'llm-cache')\nconst LLM_CACHE_MAX_AGE = 7 * 24 * 60 * 60 * 1000\n\nexport async function cacheCleanCommand(): Promise<void> {\n let expiredLlm = 0\n let freedBytes = 0\n\n // Clean expired LLM cache entries\n if (existsSync(LLM_CACHE_DIR)) {\n const now = Date.now()\n for (const entry of readdirSync(LLM_CACHE_DIR)) {\n const path = join(LLM_CACHE_DIR, entry)\n try {\n const { timestamp } = JSON.parse(readFileSync(path, 'utf-8'))\n if (now - timestamp > LLM_CACHE_MAX_AGE) {\n const size = statSync(path).size\n rmSync(path)\n expiredLlm++\n freedBytes += size\n }\n }\n catch {\n // Corrupt cache entry — remove it\n const size = statSync(path).size\n rmSync(path)\n expiredLlm++\n freedBytes += size\n }\n }\n }\n\n // Clear embedding cache\n const embeddingDbPath = join(CACHE_DIR, 'embeddings.db')\n let embeddingCleared = false\n if (existsSync(embeddingDbPath)) {\n const size = statSync(embeddingDbPath).size\n clearEmbeddingCache()\n freedBytes += size\n embeddingCleared = true\n }\n\n const freedKB = Math.round(freedBytes / 1024)\n if (expiredLlm > 0 || embeddingCleared) {\n const parts: string[] = []\n if (expiredLlm > 0)\n parts.push(`${expiredLlm} expired LLM cache entries`)\n if (embeddingCleared)\n parts.push('embedding cache')\n p.log.success(`Removed ${parts.join(' + ')} (${freedKB}KB freed)`)\n }\n else {\n p.log.info('Cache is clean — no expired entries')\n }\n}\n\nexport const cacheCommandDef = defineCommand({\n meta: { name: 'cache', description: 'Cache management', hidden: true },\n args: {\n clean: {\n type: 'boolean',\n description: 'Remove expired LLM cache entries',\n default: true,\n },\n },\n async run() {\n p.intro(`\\x1B[1m\\x1B[35mskilld\\x1B[0m cache clean`)\n await cacheCleanCommand()\n },\n})\n"],"mappings":";;;;;;;;;;;AAWA,MAAM,gBAAgB,KAAK,WAAW,YAAY;AAClD,MAAM,oBAAoB,QAAc,KAAK;AAE7C,eAAsB,oBAAmC;CACvD,IAAI,aAAa;CACjB,IAAI,aAAa;AAGjB,KAAI,WAAW,cAAc,EAAE;EAC7B,MAAM,MAAM,KAAK,KAAK;AACtB,OAAK,MAAM,SAAS,YAAY,cAAc,EAAE;GAC9C,MAAM,OAAO,KAAK,eAAe,MAAM;AACvC,OAAI;IACF,MAAM,EAAE,cAAc,KAAK,MAAM,aAAa,MAAM,QAAQ,CAAC;AAC7D,QAAI,MAAM,YAAY,mBAAmB;KACvC,MAAM,OAAO,SAAS,KAAK,CAAC;AAC5B,YAAO,KAAK;AACZ;AACA,mBAAc;;WAGZ;IAEJ,MAAM,OAAO,SAAS,KAAK,CAAC;AAC5B,WAAO,KAAK;AACZ;AACA,kBAAc;;;;CAMpB,MAAM,kBAAkB,KAAK,WAAW,gBAAgB;CACxD,IAAI,mBAAmB;AACvB,KAAI,WAAW,gBAAgB,EAAE;EAC/B,MAAM,OAAO,SAAS,gBAAgB,CAAC;AACvC,uBAAqB;AACrB,gBAAc;AACd,qBAAmB;;CAGrB,MAAM,UAAU,KAAK,MAAM,aAAa,KAAK;AAC7C,KAAI,aAAa,KAAK,kBAAkB;EACtC,MAAM,QAAkB,EAAE;AAC1B,MAAI,aAAa,EACf,OAAM,KAAK,GAAG,WAAW,4BAA4B;AACvD,MAAI,iBACF,OAAM,KAAK,kBAAkB;AAC/B,IAAE,IAAI,QAAQ,WAAW,MAAM,KAAK,MAAM,CAAC,IAAI,QAAQ,WAAW;OAGlE,GAAE,IAAI,KAAK,sCAAsC;;AAIrD,MAAa,kBAAkB,cAAc;CAC3C,MAAM;EAAE,MAAM;EAAS,aAAa;EAAoB,QAAQ;EAAM;CACtE,MAAM,EACJ,OAAO;EACL,MAAM;EACN,aAAa;EACb,SAAS;EACV,EACF;CACD,MAAM,MAAM;AACV,IAAE,MAAM,2CAA2C;AACnD,QAAM,mBAAmB;;CAE5B,CAAC"}
|
package/dist/_chunks/config.mjs
CHANGED
|
@@ -1,13 +1,28 @@
|
|
|
1
1
|
import { homedir } from "node:os";
|
|
2
2
|
import { join, resolve } from "pathe";
|
|
3
|
+
/**
|
|
4
|
+
* Version utilities
|
|
5
|
+
*/
|
|
6
|
+
/** Validate npm package name (scoped or unscoped) */
|
|
3
7
|
const VALID_PKG_NAME = /^(?:@[a-z0-9][-a-z0-9._]*\/)?[a-z0-9][-a-z0-9._]*$/;
|
|
8
|
+
/** Validate version string (semver-ish, no path separators) */
|
|
4
9
|
const VALID_VERSION = /^[a-z0-9][-\w.+]*$/i;
|
|
10
|
+
/**
|
|
11
|
+
* Get exact version key for cache keying
|
|
12
|
+
*/
|
|
5
13
|
function getVersionKey(version) {
|
|
6
14
|
return version;
|
|
7
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* Get cache key for a package: name@version
|
|
18
|
+
*/
|
|
8
19
|
function getCacheKey(name, version) {
|
|
9
20
|
return `${name}@${getVersionKey(version)}`;
|
|
10
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Get path to cached package references.
|
|
24
|
+
* Validates name/version to prevent path traversal.
|
|
25
|
+
*/
|
|
11
26
|
function getCacheDir(name, version) {
|
|
12
27
|
if (!VALID_PKG_NAME.test(name)) throw new Error(`Invalid package name: ${name}`);
|
|
13
28
|
if (!VALID_VERSION.test(version)) throw new Error(`Invalid version: ${version}`);
|
|
@@ -15,13 +30,21 @@ function getCacheDir(name, version) {
|
|
|
15
30
|
if (!dir.startsWith(REFERENCES_DIR)) throw new Error(`Path traversal detected: ${dir}`);
|
|
16
31
|
return dir;
|
|
17
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* Cache configuration
|
|
35
|
+
*/
|
|
36
|
+
/** Global cache directory */
|
|
18
37
|
const CACHE_DIR = join(homedir(), ".skilld");
|
|
38
|
+
/** References subdirectory */
|
|
19
39
|
const REFERENCES_DIR = join(CACHE_DIR, "references");
|
|
40
|
+
/** Repo-level cache (issues, discussions, releases shared across monorepo packages) */
|
|
20
41
|
const REPOS_DIR = join(CACHE_DIR, "repos");
|
|
42
|
+
/** Get repo cache dir for owner/repo with path traversal validation */
|
|
21
43
|
function getRepoCacheDir(owner, repo) {
|
|
22
44
|
if (owner.includes("..") || repo.includes("..") || owner.includes("/") || repo.includes("/")) throw new Error(`Invalid repo path: ${owner}/${repo}`);
|
|
23
45
|
return join(REPOS_DIR, owner, repo);
|
|
24
46
|
}
|
|
47
|
+
/** Get search DB path for a specific package@version */
|
|
25
48
|
function getPackageDbPath(name, version) {
|
|
26
49
|
return join(REFERENCES_DIR, getCacheKey(name, version), "search.db");
|
|
27
50
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.mjs","names":[],"sources":["../../src/cache/version.ts","../../src/cache/config.ts"],"sourcesContent":["/**\n * Version utilities\n */\n\nimport { resolve } from 'pathe'\nimport { REFERENCES_DIR } from './config.ts'\n\n/** Validate npm package name (scoped or unscoped) */\nconst VALID_PKG_NAME = /^(?:@[a-z0-9][-a-z0-9._]*\\/)?[a-z0-9][-a-z0-9._]*$/\n\n/** Validate version string (semver-ish, no path separators) */\nconst VALID_VERSION = /^[a-z0-9][-\\w.+]*$/i\n\n/**\n * Get exact version key for cache keying\n */\nexport function getVersionKey(version: string): string {\n return version\n}\n\n/**\n * Get cache key for a package: name@version\n */\nexport function getCacheKey(name: string, version: string): string {\n return `${name}@${getVersionKey(version)}`\n}\n\n/**\n * Get path to cached package references.\n * Validates name/version to prevent path traversal.\n */\nexport function getCacheDir(name: string, version: string): string {\n if (!VALID_PKG_NAME.test(name))\n throw new Error(`Invalid package name: ${name}`)\n if (!VALID_VERSION.test(version))\n throw new Error(`Invalid version: ${version}`)\n\n const dir = resolve(REFERENCES_DIR, getCacheKey(name, version))\n if (!dir.startsWith(REFERENCES_DIR))\n throw new Error(`Path traversal detected: ${dir}`)\n return dir\n}\n","/**\n * Cache configuration\n */\n\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\nimport { getCacheKey } from './version.ts'\n\n/** Global cache directory */\nexport const CACHE_DIR = join(homedir(), '.skilld')\n\n/** References subdirectory */\nexport const REFERENCES_DIR = join(CACHE_DIR, 'references')\n\n/** Repo-level cache (issues, discussions, releases shared across monorepo packages) */\nexport const REPOS_DIR = join(CACHE_DIR, 'repos')\n\n/** Get repo cache dir for owner/repo with path traversal validation */\nexport function getRepoCacheDir(owner: string, repo: string): string {\n if (owner.includes('..') || repo.includes('..') || owner.includes('/') || repo.includes('/'))\n throw new Error(`Invalid repo path: ${owner}/${repo}`)\n return join(REPOS_DIR, owner, repo)\n}\n\n/** Get search DB path for a specific package@version */\nexport function getPackageDbPath(name: string, version: string): string {\n return join(REFERENCES_DIR, getCacheKey(name, version), 'search.db')\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.mjs","names":[],"sources":["../../src/cache/version.ts","../../src/cache/config.ts"],"sourcesContent":["/**\n * Version utilities\n */\n\nimport { resolve } from 'pathe'\nimport { REFERENCES_DIR } from './config.ts'\n\n/** Validate npm package name (scoped or unscoped) */\nconst VALID_PKG_NAME = /^(?:@[a-z0-9][-a-z0-9._]*\\/)?[a-z0-9][-a-z0-9._]*$/\n\n/** Validate version string (semver-ish, no path separators) */\nconst VALID_VERSION = /^[a-z0-9][-\\w.+]*$/i\n\n/**\n * Get exact version key for cache keying\n */\nexport function getVersionKey(version: string): string {\n return version\n}\n\n/**\n * Get cache key for a package: name@version\n */\nexport function getCacheKey(name: string, version: string): string {\n return `${name}@${getVersionKey(version)}`\n}\n\n/**\n * Get path to cached package references.\n * Validates name/version to prevent path traversal.\n */\nexport function getCacheDir(name: string, version: string): string {\n if (!VALID_PKG_NAME.test(name))\n throw new Error(`Invalid package name: ${name}`)\n if (!VALID_VERSION.test(version))\n throw new Error(`Invalid version: ${version}`)\n\n const dir = resolve(REFERENCES_DIR, getCacheKey(name, version))\n if (!dir.startsWith(REFERENCES_DIR))\n throw new Error(`Path traversal detected: ${dir}`)\n return dir\n}\n","/**\n * Cache configuration\n */\n\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\nimport { getCacheKey } from './version.ts'\n\n/** Global cache directory */\nexport const CACHE_DIR = join(homedir(), '.skilld')\n\n/** References subdirectory */\nexport const REFERENCES_DIR = join(CACHE_DIR, 'references')\n\n/** Repo-level cache (issues, discussions, releases shared across monorepo packages) */\nexport const REPOS_DIR = join(CACHE_DIR, 'repos')\n\n/** Get repo cache dir for owner/repo with path traversal validation */\nexport function getRepoCacheDir(owner: string, repo: string): string {\n if (owner.includes('..') || repo.includes('..') || owner.includes('/') || repo.includes('/'))\n throw new Error(`Invalid repo path: ${owner}/${repo}`)\n return join(REPOS_DIR, owner, repo)\n}\n\n/** Get search DB path for a specific package@version */\nexport function getPackageDbPath(name: string, version: string): string {\n return join(REFERENCES_DIR, getCacheKey(name, version), 'search.db')\n}\n"],"mappings":";;;;;;AAQA,MAAM,iBAAiB;;AAGvB,MAAM,gBAAgB;;;;AAKtB,SAAgB,cAAc,SAAyB;AACrD,QAAO;;;;;AAMT,SAAgB,YAAY,MAAc,SAAyB;AACjE,QAAO,GAAG,KAAK,GAAG,cAAc,QAAQ;;;;;;AAO1C,SAAgB,YAAY,MAAc,SAAyB;AACjE,KAAI,CAAC,eAAe,KAAK,KAAK,CAC5B,OAAM,IAAI,MAAM,yBAAyB,OAAO;AAClD,KAAI,CAAC,cAAc,KAAK,QAAQ,CAC9B,OAAM,IAAI,MAAM,oBAAoB,UAAU;CAEhD,MAAM,MAAM,QAAQ,gBAAgB,YAAY,MAAM,QAAQ,CAAC;AAC/D,KAAI,CAAC,IAAI,WAAW,eAAe,CACjC,OAAM,IAAI,MAAM,4BAA4B,MAAM;AACpD,QAAO;;;;;;AC/BT,MAAa,YAAY,KAAK,SAAS,EAAE,UAAU;;AAGnD,MAAa,iBAAiB,KAAK,WAAW,aAAa;;AAG3D,MAAa,YAAY,KAAK,WAAW,QAAQ;;AAGjD,SAAgB,gBAAgB,OAAe,MAAsB;AACnE,KAAI,MAAM,SAAS,KAAK,IAAI,KAAK,SAAS,KAAK,IAAI,MAAM,SAAS,IAAI,IAAI,KAAK,SAAS,IAAI,CAC1F,OAAM,IAAI,MAAM,sBAAsB,MAAM,GAAG,OAAO;AACxD,QAAO,KAAK,WAAW,OAAO,KAAK;;;AAIrC,SAAgB,iBAAiB,MAAc,SAAyB;AACtE,QAAO,KAAK,gBAAgB,YAAY,MAAM,QAAQ,EAAE,YAAY"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embedding-cache.mjs","names":[],"sources":["../../src/retriv/embedding-cache.ts"],"sourcesContent":["import type { DatabaseSync } from 'node:sqlite'\nimport type { Embedding } from 'retriv'\nimport { rmSync } from 'node:fs'\nimport { join } from 'pathe'\nimport { CACHE_DIR } from '../cache/index.ts'\n\ninterface EmbeddingConfig {\n resolve: () => Promise<{ embedder: (texts: string[]) => Promise<Embedding[]>, dimensions: number, maxTokens?: number }>\n}\n\nconst EMBEDDINGS_DB_PATH = join(CACHE_DIR, 'embeddings.db')\n\nfunction openDb(): DatabaseSync {\n // eslint-disable-next-line ts/no-require-imports\n const { DatabaseSync: DB } = require('node:sqlite') as typeof import('node:sqlite')\n const db = new DB(EMBEDDINGS_DB_PATH)\n db.exec('PRAGMA journal_mode=WAL')\n db.exec('PRAGMA busy_timeout=5000')\n db.exec(`CREATE TABLE IF NOT EXISTS embeddings (text_hash TEXT PRIMARY KEY, embedding BLOB NOT NULL)`)\n db.exec(`CREATE TABLE IF NOT EXISTS meta (key TEXT PRIMARY KEY, value TEXT NOT NULL)`)\n return db\n}\n\nfunction createSqliteStorage(db: DatabaseSync) {\n const getStmt = db.prepare('SELECT embedding FROM embeddings WHERE text_hash = ?')\n const setStmt = db.prepare('INSERT OR IGNORE INTO embeddings (text_hash, embedding) VALUES (?, ?)')\n\n return {\n get: (hash: string): Embedding | null => {\n const row = getStmt.get(hash) as { embedding: Buffer } | undefined\n if (!row)\n return null\n return new Float32Array(row.embedding.buffer, row.embedding.byteOffset, row.embedding.byteLength / 4)\n },\n set: (hash: string, embedding: Embedding): void => {\n const arr = embedding instanceof Float32Array ? embedding : new Float32Array(embedding)\n setStmt.run(hash, Buffer.from(arr.buffer, arr.byteOffset, arr.byteLength))\n },\n }\n}\n\nexport async function cachedEmbeddings(config: EmbeddingConfig): Promise<EmbeddingConfig> {\n const { cachedEmbeddings: retrivCached } = await import('retriv/embeddings/cached')\n const db = openDb()\n const storage = createSqliteStorage(db)\n\n const originalResolve = config.resolve\n const validatedConfig: EmbeddingConfig = {\n async resolve() {\n const resolved = await originalResolve()\n const getMetaStmt = db.prepare('SELECT value FROM meta WHERE key = ?')\n const setMetaStmt = db.prepare('INSERT OR REPLACE INTO meta (key, value) VALUES (?, ?)')\n\n const storedDims = getMetaStmt.get('dimensions') as { value: string } | undefined\n if (storedDims && Number(storedDims.value) !== resolved.dimensions) {\n db.exec('DELETE FROM embeddings')\n }\n setMetaStmt.run('dimensions', String(resolved.dimensions))\n\n return resolved\n },\n }\n\n return retrivCached(validatedConfig, { storage })\n}\n\nexport function clearEmbeddingCache(): void {\n rmSync(EMBEDDINGS_DB_PATH, { force: true })\n}\n"],"mappings":";;;;;;;;AAUA,MAAM,qBAAqB,KAAK,WAAW,gBAAgB;AAE3D,SAAS,SAAuB;CAE9B,MAAM,EAAE,cAAc,OAAA,UAAe,cAAc;CACnD,MAAM,KAAK,IAAI,GAAG,mBAAmB;AACrC,IAAG,KAAK,0BAA0B;AAClC,IAAG,KAAK,2BAA2B;AACnC,IAAG,KAAK,8FAA8F;AACtG,IAAG,KAAK,8EAA8E;AACtF,QAAO;;AAGT,SAAS,oBAAoB,IAAkB;CAC7C,MAAM,UAAU,GAAG,QAAQ,uDAAuD;CAClF,MAAM,UAAU,GAAG,QAAQ,wEAAwE;AAEnG,QAAO;EACL,MAAM,SAAmC;GACvC,MAAM,MAAM,QAAQ,IAAI,KAAK;AAC7B,OAAI,CAAC,IACH,QAAO;AACT,UAAO,IAAI,aAAa,IAAI,UAAU,QAAQ,IAAI,UAAU,YAAY,IAAI,UAAU,aAAa,EAAE;;EAEvG,MAAM,MAAc,cAA+B;GACjD,MAAM,MAAM,qBAAqB,eAAe,YAAY,IAAI,aAAa,UAAU;AACvF,WAAQ,IAAI,MAAM,OAAO,KAAK,IAAI,QAAQ,IAAI,YAAY,IAAI,WAAW,CAAC;;EAE7E;;AAGH,eAAsB,iBAAiB,QAAmD;CACxF,MAAM,EAAE,kBAAkB,iBAAiB,MAAM,OAAO;CACxD,MAAM,KAAK,QAAQ;CACnB,MAAM,UAAU,oBAAoB,GAAG;CAEvC,MAAM,kBAAkB,OAAO;AAiB/B,QAAO,aAhBkC,EACvC,MAAM,UAAU;EACd,MAAM,WAAW,MAAM,iBAAiB;EACxC,MAAM,cAAc,GAAG,QAAQ,uCAAuC;EACtE,MAAM,cAAc,GAAG,QAAQ,yDAAyD;EAExF,MAAM,aAAa,YAAY,IAAI,aAAa;AAChD,MAAI,cAAc,OAAO,WAAW,MAAM,KAAK,SAAS,WACtD,IAAG,KAAK,yBAAyB;AAEnC,cAAY,IAAI,cAAc,OAAO,SAAS,WAAW,CAAC;AAE1D,SAAO;IAEV,EAEoC,EAAE,SAAS,CAAC;;AAGnD,SAAgB,sBAA4B;AAC1C,QAAO,oBAAoB,EAAE,OAAO,MAAM,CAAC"}
|