@ai-devkit/memory 0.10.0 → 0.12.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 +5 -1
- package/dist/api.d.ts +4 -4
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +17 -46
- package/dist/api.js.map +1 -1
- package/dist/database/connection.d.ts.map +1 -1
- package/dist/database/connection.js +15 -45
- package/dist/database/connection.js.map +1 -1
- package/dist/database/index.d.ts +3 -3
- package/dist/database/index.d.ts.map +1 -1
- package/dist/database/index.js +2 -35
- package/dist/database/index.js.map +1 -1
- package/dist/database/schema.d.ts +1 -1
- package/dist/database/schema.d.ts.map +1 -1
- package/dist/database/schema.js +12 -34
- package/dist/database/schema.js.map +1 -1
- package/dist/handlers/search.d.ts +1 -1
- package/dist/handlers/search.d.ts.map +1 -1
- package/dist/handlers/search.js +12 -22
- package/dist/handlers/search.js.map +1 -1
- package/dist/handlers/store.d.ts +1 -1
- package/dist/handlers/store.d.ts.map +1 -1
- package/dist/handlers/store.js +17 -27
- package/dist/handlers/store.js.map +1 -1
- package/dist/handlers/update.d.ts +1 -1
- package/dist/handlers/update.d.ts.map +1 -1
- package/dist/handlers/update.js +16 -26
- package/dist/handlers/update.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -21
- package/dist/index.js.map +1 -1
- package/dist/server.js +18 -39
- package/dist/server.js.map +1 -1
- package/dist/services/normalizer.js +17 -34
- package/dist/services/normalizer.js.map +1 -1
- package/dist/services/ranker.d.ts +1 -1
- package/dist/services/ranker.d.ts.map +1 -1
- package/dist/services/ranker.js +5 -11
- package/dist/services/ranker.js.map +1 -1
- package/dist/services/search.js +15 -24
- package/dist/services/search.js.map +1 -1
- package/dist/services/validator.d.ts +1 -1
- package/dist/services/validator.d.ts.map +1 -1
- package/dist/services/validator.js +9 -39
- package/dist/services/validator.js.map +1 -1
- package/dist/types/index.js +1 -4
- package/dist/types/index.js.map +1 -1
- package/dist/utils/errors.js +10 -37
- package/dist/utils/errors.js.map +1 -1
- package/package.json +12 -11
package/dist/services/search.js
CHANGED
|
@@ -1,24 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", {
|
|
3
|
-
value: true
|
|
4
|
-
});
|
|
5
|
-
function _export(target, all) {
|
|
6
|
-
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
-
enumerable: true,
|
|
8
|
-
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
-
});
|
|
10
|
-
}
|
|
11
|
-
_export(exports, {
|
|
12
|
-
get buildFtsQuery () {
|
|
13
|
-
return buildFtsQuery;
|
|
14
|
-
},
|
|
15
|
-
get buildSearchQuery () {
|
|
16
|
-
return buildSearchQuery;
|
|
17
|
-
},
|
|
18
|
-
get buildSimpleQuery () {
|
|
19
|
-
return buildSimpleQuery;
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
1
|
/**
|
|
23
2
|
* FTS5 Query Builder
|
|
24
3
|
* Converts natural language queries to FTS5 match expressions
|
|
@@ -31,7 +10,14 @@ _export(exports, {
|
|
|
31
10
|
.replace(/\b(AND|OR|NOT)\b/gi, '') // Remove boolean operators
|
|
32
11
|
.trim().replace(/\s+/g, ' '); // Collapse multiple spaces
|
|
33
12
|
}
|
|
34
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Build FTS5 query from natural language input
|
|
15
|
+
*
|
|
16
|
+
* Strategy:
|
|
17
|
+
* - Split query into words
|
|
18
|
+
* - Use prefix matching (*) for partial matches
|
|
19
|
+
* - Escape special characters
|
|
20
|
+
*/ export function buildFtsQuery(query) {
|
|
35
21
|
const escaped = escapeFtsSpecialChars(query);
|
|
36
22
|
const words = escaped.split(/\s+/).filter((w)=>w.length > 0);
|
|
37
23
|
if (words.length === 0) {
|
|
@@ -41,7 +27,10 @@ function buildFtsQuery(query) {
|
|
|
41
27
|
// This allows "api design" to match "API", "designing", etc.
|
|
42
28
|
return words.map((word)=>`${word}*`).join(' ');
|
|
43
29
|
}
|
|
44
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Build FTS5 query with column boosting
|
|
32
|
+
* Uses bm25() with weights: title=10, content=5, tags=1
|
|
33
|
+
*/ export function buildSearchQuery(ftsQuery, scope, limit = 5) {
|
|
45
34
|
const params = [];
|
|
46
35
|
let sql = `
|
|
47
36
|
SELECT
|
|
@@ -69,7 +58,9 @@ function buildSearchQuery(ftsQuery, scope, limit = 5) {
|
|
|
69
58
|
params
|
|
70
59
|
};
|
|
71
60
|
}
|
|
72
|
-
|
|
61
|
+
/**
|
|
62
|
+
* Build simple search query without FTS (fallback for empty queries)
|
|
63
|
+
*/ export function buildSimpleQuery(scope, limit = 5) {
|
|
73
64
|
const params = [];
|
|
74
65
|
let sql = `
|
|
75
66
|
SELECT
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/services/search.ts"],"sourcesContent":["/**\n * FTS5 Query Builder\n * Converts natural language queries to FTS5 match expressions\n */\n\n/**\n * Escape special FTS5 characters to prevent query syntax errors\n */\nfunction escapeFtsSpecialChars(text: string): string {\n // FTS5 special characters: \" * ^ - : OR AND NOT ( )\n return text\n .replace(/\"/g, '\"\"') // Escape quotes by doubling\n .replace(/[*^():-]/g, ' ') // Replace operators with space (including hyphen)\n .replace(/\\b(AND|OR|NOT)\\b/gi, '') // Remove boolean operators\n .trim()\n .replace(/\\s+/g, ' '); // Collapse multiple spaces\n}\n\n/**\n * Build FTS5 query from natural language input\n * \n * Strategy:\n * - Split query into words\n * - Use prefix matching (*) for partial matches\n * - Escape special characters\n */\nexport function buildFtsQuery(query: string): string {\n const escaped = escapeFtsSpecialChars(query);\n const words = escaped.split(/\\s+/).filter(w => w.length > 0);\n\n if (words.length === 0) {\n return '';\n }\n\n // Use prefix matching for each word\n // This allows \"api design\" to match \"API\", \"designing\", etc.\n return words.map(word => `${word}*`).join(' ');\n}\n\n/**\n * Build FTS5 query with column boosting\n * Uses bm25() with weights: title=10, content=5, tags=1\n */\nexport function buildSearchQuery(\n ftsQuery: string,\n scope?: string | null,\n limit = 5\n): { sql: string; params: unknown[] } {\n const params: unknown[] = [];\n\n let sql = `\n SELECT \n k.id,\n k.title,\n k.content,\n k.tags,\n k.scope,\n k.created_at,\n k.updated_at,\n bm25(knowledge_fts, 10.0, 5.0, 1.0) as bm25_score\n FROM knowledge k\n JOIN knowledge_fts fts ON k.rowid = fts.rowid\n WHERE knowledge_fts MATCH ?\n `;\n params.push(ftsQuery);\n\n if (scope) {\n sql += ` AND (k.scope = ? OR k.scope = 'global')`;\n params.push(scope);\n }\n\n sql += ` ORDER BY bm25_score LIMIT ?`;\n params.push(limit);\n\n return { sql, params };\n}\n\n/**\n * Build simple search query without FTS (fallback for empty queries)\n */\nexport function buildSimpleQuery(\n scope?: string | null,\n limit = 5\n): { sql: string; params: unknown[] } {\n const params: unknown[] = [];\n\n let sql = `\n SELECT \n id, title, content, tags, scope, created_at, updated_at,\n 0 as bm25_score\n FROM knowledge\n `;\n\n if (scope) {\n sql += ` WHERE scope = ? OR scope = 'global'`;\n params.push(scope);\n }\n\n sql += ` ORDER BY created_at DESC LIMIT ?`;\n params.push(limit);\n\n return { sql, params };\n}\n"],"names":["
|
|
1
|
+
{"version":3,"sources":["../../src/services/search.ts"],"sourcesContent":["/**\n * FTS5 Query Builder\n * Converts natural language queries to FTS5 match expressions\n */\n\n/**\n * Escape special FTS5 characters to prevent query syntax errors\n */\nfunction escapeFtsSpecialChars(text: string): string {\n // FTS5 special characters: \" * ^ - : OR AND NOT ( )\n return text\n .replace(/\"/g, '\"\"') // Escape quotes by doubling\n .replace(/[*^():-]/g, ' ') // Replace operators with space (including hyphen)\n .replace(/\\b(AND|OR|NOT)\\b/gi, '') // Remove boolean operators\n .trim()\n .replace(/\\s+/g, ' '); // Collapse multiple spaces\n}\n\n/**\n * Build FTS5 query from natural language input\n * \n * Strategy:\n * - Split query into words\n * - Use prefix matching (*) for partial matches\n * - Escape special characters\n */\nexport function buildFtsQuery(query: string): string {\n const escaped = escapeFtsSpecialChars(query);\n const words = escaped.split(/\\s+/).filter(w => w.length > 0);\n\n if (words.length === 0) {\n return '';\n }\n\n // Use prefix matching for each word\n // This allows \"api design\" to match \"API\", \"designing\", etc.\n return words.map(word => `${word}*`).join(' ');\n}\n\n/**\n * Build FTS5 query with column boosting\n * Uses bm25() with weights: title=10, content=5, tags=1\n */\nexport function buildSearchQuery(\n ftsQuery: string,\n scope?: string | null,\n limit = 5\n): { sql: string; params: unknown[] } {\n const params: unknown[] = [];\n\n let sql = `\n SELECT \n k.id,\n k.title,\n k.content,\n k.tags,\n k.scope,\n k.created_at,\n k.updated_at,\n bm25(knowledge_fts, 10.0, 5.0, 1.0) as bm25_score\n FROM knowledge k\n JOIN knowledge_fts fts ON k.rowid = fts.rowid\n WHERE knowledge_fts MATCH ?\n `;\n params.push(ftsQuery);\n\n if (scope) {\n sql += ` AND (k.scope = ? OR k.scope = 'global')`;\n params.push(scope);\n }\n\n sql += ` ORDER BY bm25_score LIMIT ?`;\n params.push(limit);\n\n return { sql, params };\n}\n\n/**\n * Build simple search query without FTS (fallback for empty queries)\n */\nexport function buildSimpleQuery(\n scope?: string | null,\n limit = 5\n): { sql: string; params: unknown[] } {\n const params: unknown[] = [];\n\n let sql = `\n SELECT \n id, title, content, tags, scope, created_at, updated_at,\n 0 as bm25_score\n FROM knowledge\n `;\n\n if (scope) {\n sql += ` WHERE scope = ? OR scope = 'global'`;\n params.push(scope);\n }\n\n sql += ` ORDER BY created_at DESC LIMIT ?`;\n params.push(limit);\n\n return { sql, params };\n}\n"],"names":["escapeFtsSpecialChars","text","replace","trim","buildFtsQuery","query","escaped","words","split","filter","w","length","map","word","join","buildSearchQuery","ftsQuery","scope","limit","params","sql","push","buildSimpleQuery"],"mappings":"AAAA;;;CAGC,GAED;;CAEC,GACD,SAASA,sBAAsBC,IAAY;IACvC,oDAAoD;IACpD,OAAOA,KACFC,OAAO,CAAC,MAAM,MAAO,4BAA4B;KACjDA,OAAO,CAAC,aAAa,KAAM,kDAAkD;KAC7EA,OAAO,CAAC,sBAAsB,IAAK,2BAA2B;KAC9DC,IAAI,GACJD,OAAO,CAAC,QAAQ,MAAO,2BAA2B;AAC3D;AAEA;;;;;;;CAOC,GACD,OAAO,SAASE,cAAcC,KAAa;IACvC,MAAMC,UAAUN,sBAAsBK;IACtC,MAAME,QAAQD,QAAQE,KAAK,CAAC,OAAOC,MAAM,CAACC,CAAAA,IAAKA,EAAEC,MAAM,GAAG;IAE1D,IAAIJ,MAAMI,MAAM,KAAK,GAAG;QACpB,OAAO;IACX;IAEA,oCAAoC;IACpC,6DAA6D;IAC7D,OAAOJ,MAAMK,GAAG,CAACC,CAAAA,OAAQ,GAAGA,KAAK,CAAC,CAAC,EAAEC,IAAI,CAAC;AAC9C;AAEA;;;CAGC,GACD,OAAO,SAASC,iBACZC,QAAgB,EAChBC,KAAqB,EACrBC,QAAQ,CAAC;IAET,MAAMC,SAAoB,EAAE;IAE5B,IAAIC,MAAM,CAAC;;;;;;;;;;;;;EAab,CAAC;IACCD,OAAOE,IAAI,CAACL;IAEZ,IAAIC,OAAO;QACPG,OAAO,CAAC,wCAAwC,CAAC;QACjDD,OAAOE,IAAI,CAACJ;IAChB;IAEAG,OAAO,CAAC,4BAA4B,CAAC;IACrCD,OAAOE,IAAI,CAACH;IAEZ,OAAO;QAAEE;QAAKD;IAAO;AACzB;AAEA;;CAEC,GACD,OAAO,SAASG,iBACZL,KAAqB,EACrBC,QAAQ,CAAC;IAET,MAAMC,SAAoB,EAAE;IAE5B,IAAIC,MAAM,CAAC;;;;;EAKb,CAAC;IAEC,IAAIH,OAAO;QACPG,OAAO,CAAC,oCAAoC,CAAC;QAC7CD,OAAOE,IAAI,CAACJ;IAChB;IAEAG,OAAO,CAAC,iCAAiC,CAAC;IAC1CD,OAAOE,IAAI,CAACH;IAEZ,OAAO;QAAEE;QAAKD;IAAO;AACzB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/services/validator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/services/validator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAsBnF,MAAM,WAAW,gBAAgB;IAC7B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,gBAAgB,CAgB7D;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,CAyBjE;AAED,wBAAgB,YAAY,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,gBAAgB,CAkB9D;AAED,wBAAgB,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAY9D;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,oBAAoB,GAAG,IAAI,CAqCrE;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI,CAkBnE"}
|
|
@@ -1,34 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", {
|
|
3
|
-
value: true
|
|
4
|
-
});
|
|
5
|
-
function _export(target, all) {
|
|
6
|
-
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
-
enumerable: true,
|
|
8
|
-
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
-
});
|
|
10
|
-
}
|
|
11
|
-
_export(exports, {
|
|
12
|
-
get validateContent () {
|
|
13
|
-
return validateContent;
|
|
14
|
-
},
|
|
15
|
-
get validateScope () {
|
|
16
|
-
return validateScope;
|
|
17
|
-
},
|
|
18
|
-
get validateStoreInput () {
|
|
19
|
-
return validateStoreInput;
|
|
20
|
-
},
|
|
21
|
-
get validateTags () {
|
|
22
|
-
return validateTags;
|
|
23
|
-
},
|
|
24
|
-
get validateTitle () {
|
|
25
|
-
return validateTitle;
|
|
26
|
-
},
|
|
27
|
-
get validateUpdateInput () {
|
|
28
|
-
return validateUpdateInput;
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
const _errors = require("../utils/errors");
|
|
1
|
+
import { ValidationError } from '../utils/errors.js';
|
|
32
2
|
const TITLE_MIN_LENGTH = 10;
|
|
33
3
|
const TITLE_MAX_LENGTH = 100;
|
|
34
4
|
const CONTENT_MIN_LENGTH = 50;
|
|
@@ -46,7 +16,7 @@ const GENERIC_PHRASES = [
|
|
|
46
16
|
'always do',
|
|
47
17
|
'never do'
|
|
48
18
|
];
|
|
49
|
-
function validateTitle(title) {
|
|
19
|
+
export function validateTitle(title) {
|
|
50
20
|
const errors = [];
|
|
51
21
|
if (!title || title.trim().length === 0) {
|
|
52
22
|
errors.push('Title is required');
|
|
@@ -64,7 +34,7 @@ function validateTitle(title) {
|
|
|
64
34
|
errors
|
|
65
35
|
};
|
|
66
36
|
}
|
|
67
|
-
function validateContent(content) {
|
|
37
|
+
export function validateContent(content) {
|
|
68
38
|
const errors = [];
|
|
69
39
|
if (!content || content.trim().length === 0) {
|
|
70
40
|
errors.push('Content is required');
|
|
@@ -90,7 +60,7 @@ function validateContent(content) {
|
|
|
90
60
|
errors
|
|
91
61
|
};
|
|
92
62
|
}
|
|
93
|
-
function validateTags(tags) {
|
|
63
|
+
export function validateTags(tags) {
|
|
94
64
|
const errors = [];
|
|
95
65
|
if (!tags || tags.length === 0) {
|
|
96
66
|
return {
|
|
@@ -111,7 +81,7 @@ function validateTags(tags) {
|
|
|
111
81
|
errors
|
|
112
82
|
};
|
|
113
83
|
}
|
|
114
|
-
function validateScope(scope) {
|
|
84
|
+
export function validateScope(scope) {
|
|
115
85
|
const errors = [];
|
|
116
86
|
if (!scope || scope === 'global') {
|
|
117
87
|
return {
|
|
@@ -127,7 +97,7 @@ function validateScope(scope) {
|
|
|
127
97
|
errors
|
|
128
98
|
};
|
|
129
99
|
}
|
|
130
|
-
function validateUpdateInput(input) {
|
|
100
|
+
export function validateUpdateInput(input) {
|
|
131
101
|
const allErrors = [];
|
|
132
102
|
if (!input.id || input.id.trim().length === 0) {
|
|
133
103
|
allErrors.push('ID is required');
|
|
@@ -153,12 +123,12 @@ function validateUpdateInput(input) {
|
|
|
153
123
|
allErrors.push(...scopeResult.errors);
|
|
154
124
|
}
|
|
155
125
|
if (allErrors.length > 0) {
|
|
156
|
-
throw new
|
|
126
|
+
throw new ValidationError(allErrors.join('; '), {
|
|
157
127
|
errors: allErrors
|
|
158
128
|
});
|
|
159
129
|
}
|
|
160
130
|
}
|
|
161
|
-
function validateStoreInput(input) {
|
|
131
|
+
export function validateStoreInput(input) {
|
|
162
132
|
const allErrors = [];
|
|
163
133
|
const titleResult = validateTitle(input.title);
|
|
164
134
|
allErrors.push(...titleResult.errors);
|
|
@@ -169,7 +139,7 @@ function validateStoreInput(input) {
|
|
|
169
139
|
const scopeResult = validateScope(input.scope);
|
|
170
140
|
allErrors.push(...scopeResult.errors);
|
|
171
141
|
if (allErrors.length > 0) {
|
|
172
|
-
throw new
|
|
142
|
+
throw new ValidationError(allErrors.join('; '), {
|
|
173
143
|
errors: allErrors
|
|
174
144
|
});
|
|
175
145
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/services/validator.ts"],"sourcesContent":["import { ValidationError } from '../utils/errors';\nimport type { StoreKnowledgeInput, UpdateKnowledgeInput } from '../types';\n\nconst TITLE_MIN_LENGTH = 10;\nconst TITLE_MAX_LENGTH = 100;\nconst CONTENT_MIN_LENGTH = 50;\nconst CONTENT_MAX_LENGTH = 5000;\nconst TAGS_MAX_COUNT = 10;\n\nconst SCOPE_PATTERN = /^(global|project:[a-z0-9_-]+|repo:[a-z0-9_-]+)$/i;\nconst TAG_PATTERN = /^[a-z0-9][a-z0-9-]*$/i;\n\nconst GENERIC_PHRASES = [\n 'this is important',\n 'remember this',\n 'note to self',\n 'todo',\n 'fix this',\n 'do this',\n 'always do',\n 'never do',\n];\n\nexport interface ValidationResult {\n valid: boolean;\n errors: string[];\n}\n\nexport function validateTitle(title: string): ValidationResult {\n const errors: string[] = [];\n\n if (!title || title.trim().length === 0) {\n errors.push('Title is required');\n } else {\n const trimmed = title.trim();\n if (trimmed.length < TITLE_MIN_LENGTH) {\n errors.push(`Title must be at least ${TITLE_MIN_LENGTH} characters`);\n }\n if (trimmed.length > TITLE_MAX_LENGTH) {\n errors.push(`Title must be at most ${TITLE_MAX_LENGTH} characters`);\n }\n }\n\n return { valid: errors.length === 0, errors };\n}\n\nexport function validateContent(content: string): ValidationResult {\n const errors: string[] = [];\n\n if (!content || content.trim().length === 0) {\n errors.push('Content is required');\n } else {\n const trimmed = content.trim();\n if (trimmed.length < CONTENT_MIN_LENGTH) {\n errors.push(`Content must be at least ${CONTENT_MIN_LENGTH} characters`);\n }\n if (trimmed.length > CONTENT_MAX_LENGTH) {\n errors.push(`Content must be at most ${CONTENT_MAX_LENGTH} characters`);\n }\n\n // Check for generic/low-quality content\n const lowerContent = trimmed.toLowerCase();\n for (const phrase of GENERIC_PHRASES) {\n if (lowerContent === phrase || lowerContent.startsWith(phrase + ' ')) {\n errors.push('Content appears too generic. Please provide specific, actionable knowledge.');\n break;\n }\n }\n }\n\n return { valid: errors.length === 0, errors };\n}\n\nexport function validateTags(tags?: string[]): ValidationResult {\n const errors: string[] = [];\n\n if (!tags || tags.length === 0) {\n return { valid: true, errors: [] };\n }\n\n if (tags.length > TAGS_MAX_COUNT) {\n errors.push(`Maximum ${TAGS_MAX_COUNT} tags allowed`);\n }\n\n for (const tag of tags) {\n if (!TAG_PATTERN.test(tag)) {\n errors.push(`Invalid tag \"${tag}\". Tags must be alphanumeric with hyphens.`);\n }\n }\n\n return { valid: errors.length === 0, errors };\n}\n\nexport function validateScope(scope?: string): ValidationResult {\n const errors: string[] = [];\n\n if (!scope || scope === 'global') {\n return { valid: true, errors: [] };\n }\n\n if (!SCOPE_PATTERN.test(scope)) {\n errors.push('Invalid scope. Must be \"global\", \"project:<name>\", or \"repo:<name>\"');\n }\n\n return { valid: errors.length === 0, errors };\n}\n\nexport function validateUpdateInput(input: UpdateKnowledgeInput): void {\n const allErrors: string[] = [];\n\n if (!input.id || input.id.trim().length === 0) {\n allErrors.push('ID is required');\n }\n\n const hasUpdateField = input.title !== undefined || input.content !== undefined ||\n input.tags !== undefined || input.scope !== undefined;\n\n if (!hasUpdateField) {\n allErrors.push('At least one field to update is required (title, content, tags, or scope)');\n }\n\n if (input.title !== undefined) {\n const titleResult = validateTitle(input.title);\n allErrors.push(...titleResult.errors);\n }\n\n if (input.content !== undefined) {\n const contentResult = validateContent(input.content);\n allErrors.push(...contentResult.errors);\n }\n\n if (input.tags !== undefined) {\n const tagsResult = validateTags(input.tags);\n allErrors.push(...tagsResult.errors);\n }\n\n if (input.scope !== undefined) {\n const scopeResult = validateScope(input.scope);\n allErrors.push(...scopeResult.errors);\n }\n\n if (allErrors.length > 0) {\n throw new ValidationError(allErrors.join('; '), { errors: allErrors });\n }\n}\n\nexport function validateStoreInput(input: StoreKnowledgeInput): void {\n const allErrors: string[] = [];\n\n const titleResult = validateTitle(input.title);\n allErrors.push(...titleResult.errors);\n\n const contentResult = validateContent(input.content);\n allErrors.push(...contentResult.errors);\n\n const tagsResult = validateTags(input.tags);\n allErrors.push(...tagsResult.errors);\n\n const scopeResult = validateScope(input.scope);\n allErrors.push(...scopeResult.errors);\n\n if (allErrors.length > 0) {\n throw new ValidationError(allErrors.join('; '), { errors: allErrors });\n }\n}\n"],"names":["
|
|
1
|
+
{"version":3,"sources":["../../src/services/validator.ts"],"sourcesContent":["import { ValidationError } from '../utils/errors.js';\nimport type { StoreKnowledgeInput, UpdateKnowledgeInput } from '../types/index.js';\n\nconst TITLE_MIN_LENGTH = 10;\nconst TITLE_MAX_LENGTH = 100;\nconst CONTENT_MIN_LENGTH = 50;\nconst CONTENT_MAX_LENGTH = 5000;\nconst TAGS_MAX_COUNT = 10;\n\nconst SCOPE_PATTERN = /^(global|project:[a-z0-9_-]+|repo:[a-z0-9_-]+)$/i;\nconst TAG_PATTERN = /^[a-z0-9][a-z0-9-]*$/i;\n\nconst GENERIC_PHRASES = [\n 'this is important',\n 'remember this',\n 'note to self',\n 'todo',\n 'fix this',\n 'do this',\n 'always do',\n 'never do',\n];\n\nexport interface ValidationResult {\n valid: boolean;\n errors: string[];\n}\n\nexport function validateTitle(title: string): ValidationResult {\n const errors: string[] = [];\n\n if (!title || title.trim().length === 0) {\n errors.push('Title is required');\n } else {\n const trimmed = title.trim();\n if (trimmed.length < TITLE_MIN_LENGTH) {\n errors.push(`Title must be at least ${TITLE_MIN_LENGTH} characters`);\n }\n if (trimmed.length > TITLE_MAX_LENGTH) {\n errors.push(`Title must be at most ${TITLE_MAX_LENGTH} characters`);\n }\n }\n\n return { valid: errors.length === 0, errors };\n}\n\nexport function validateContent(content: string): ValidationResult {\n const errors: string[] = [];\n\n if (!content || content.trim().length === 0) {\n errors.push('Content is required');\n } else {\n const trimmed = content.trim();\n if (trimmed.length < CONTENT_MIN_LENGTH) {\n errors.push(`Content must be at least ${CONTENT_MIN_LENGTH} characters`);\n }\n if (trimmed.length > CONTENT_MAX_LENGTH) {\n errors.push(`Content must be at most ${CONTENT_MAX_LENGTH} characters`);\n }\n\n // Check for generic/low-quality content\n const lowerContent = trimmed.toLowerCase();\n for (const phrase of GENERIC_PHRASES) {\n if (lowerContent === phrase || lowerContent.startsWith(phrase + ' ')) {\n errors.push('Content appears too generic. Please provide specific, actionable knowledge.');\n break;\n }\n }\n }\n\n return { valid: errors.length === 0, errors };\n}\n\nexport function validateTags(tags?: string[]): ValidationResult {\n const errors: string[] = [];\n\n if (!tags || tags.length === 0) {\n return { valid: true, errors: [] };\n }\n\n if (tags.length > TAGS_MAX_COUNT) {\n errors.push(`Maximum ${TAGS_MAX_COUNT} tags allowed`);\n }\n\n for (const tag of tags) {\n if (!TAG_PATTERN.test(tag)) {\n errors.push(`Invalid tag \"${tag}\". Tags must be alphanumeric with hyphens.`);\n }\n }\n\n return { valid: errors.length === 0, errors };\n}\n\nexport function validateScope(scope?: string): ValidationResult {\n const errors: string[] = [];\n\n if (!scope || scope === 'global') {\n return { valid: true, errors: [] };\n }\n\n if (!SCOPE_PATTERN.test(scope)) {\n errors.push('Invalid scope. Must be \"global\", \"project:<name>\", or \"repo:<name>\"');\n }\n\n return { valid: errors.length === 0, errors };\n}\n\nexport function validateUpdateInput(input: UpdateKnowledgeInput): void {\n const allErrors: string[] = [];\n\n if (!input.id || input.id.trim().length === 0) {\n allErrors.push('ID is required');\n }\n\n const hasUpdateField = input.title !== undefined || input.content !== undefined ||\n input.tags !== undefined || input.scope !== undefined;\n\n if (!hasUpdateField) {\n allErrors.push('At least one field to update is required (title, content, tags, or scope)');\n }\n\n if (input.title !== undefined) {\n const titleResult = validateTitle(input.title);\n allErrors.push(...titleResult.errors);\n }\n\n if (input.content !== undefined) {\n const contentResult = validateContent(input.content);\n allErrors.push(...contentResult.errors);\n }\n\n if (input.tags !== undefined) {\n const tagsResult = validateTags(input.tags);\n allErrors.push(...tagsResult.errors);\n }\n\n if (input.scope !== undefined) {\n const scopeResult = validateScope(input.scope);\n allErrors.push(...scopeResult.errors);\n }\n\n if (allErrors.length > 0) {\n throw new ValidationError(allErrors.join('; '), { errors: allErrors });\n }\n}\n\nexport function validateStoreInput(input: StoreKnowledgeInput): void {\n const allErrors: string[] = [];\n\n const titleResult = validateTitle(input.title);\n allErrors.push(...titleResult.errors);\n\n const contentResult = validateContent(input.content);\n allErrors.push(...contentResult.errors);\n\n const tagsResult = validateTags(input.tags);\n allErrors.push(...tagsResult.errors);\n\n const scopeResult = validateScope(input.scope);\n allErrors.push(...scopeResult.errors);\n\n if (allErrors.length > 0) {\n throw new ValidationError(allErrors.join('; '), { errors: allErrors });\n }\n}\n"],"names":["ValidationError","TITLE_MIN_LENGTH","TITLE_MAX_LENGTH","CONTENT_MIN_LENGTH","CONTENT_MAX_LENGTH","TAGS_MAX_COUNT","SCOPE_PATTERN","TAG_PATTERN","GENERIC_PHRASES","validateTitle","title","errors","trim","length","push","trimmed","valid","validateContent","content","lowerContent","toLowerCase","phrase","startsWith","validateTags","tags","tag","test","validateScope","scope","validateUpdateInput","input","allErrors","id","hasUpdateField","undefined","titleResult","contentResult","tagsResult","scopeResult","join","validateStoreInput"],"mappings":"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"}
|
package/dist/types/index.js
CHANGED
package/dist/types/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/types/index.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"sources":["../../src/types/index.ts"],"sourcesContent":["export interface KnowledgeItem {\n id: string;\n title: string;\n content: string;\n tags: string[];\n scope: string;\n normalizedTitle: string;\n contentHash: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport type KnowledgeScope = 'global' | `project:${string}` | `repo:${string}`;\n\nexport interface StoreKnowledgeInput {\n title: string;\n content: string;\n tags?: string[];\n scope?: string;\n}\n\nexport interface StoreKnowledgeResult {\n success: boolean;\n id?: string;\n message: string;\n}\n\nexport interface UpdateKnowledgeInput {\n id: string;\n title?: string;\n content?: string;\n tags?: string[];\n scope?: string;\n}\n\nexport interface UpdateKnowledgeResult {\n success: boolean;\n id: string;\n message: string;\n}\n\nexport interface SearchKnowledgeInput {\n query: string;\n contextTags?: string[];\n scope?: string;\n limit?: number;\n}\n\nexport interface SearchResultItem {\n id: string;\n title: string;\n content: string;\n tags: string[];\n scope: string;\n score: number;\n}\n\nexport interface SearchKnowledgeResult {\n results: SearchResultItem[];\n totalMatches: number;\n query: string;\n}\n\nexport interface KnowledgeRow {\n id: string;\n title: string;\n content: string;\n tags: string;\n scope: string;\n normalized_title: string;\n content_hash: string;\n created_at: string;\n updated_at: string;\n}\n\nexport interface MetaRow {\n key: string;\n value: string;\n}"],"names":[],"mappings":"AA2EA,WAGC"}
|
package/dist/utils/errors.js
CHANGED
|
@@ -1,31 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", {
|
|
3
|
-
value: true
|
|
4
|
-
});
|
|
5
|
-
function _export(target, all) {
|
|
6
|
-
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
-
enumerable: true,
|
|
8
|
-
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
-
});
|
|
10
|
-
}
|
|
11
|
-
_export(exports, {
|
|
12
|
-
get DuplicateError () {
|
|
13
|
-
return DuplicateError;
|
|
14
|
-
},
|
|
15
|
-
get KnowledgeMemoryError () {
|
|
16
|
-
return KnowledgeMemoryError;
|
|
17
|
-
},
|
|
18
|
-
get NotFoundError () {
|
|
19
|
-
return NotFoundError;
|
|
20
|
-
},
|
|
21
|
-
get StorageError () {
|
|
22
|
-
return StorageError;
|
|
23
|
-
},
|
|
24
|
-
get ValidationError () {
|
|
25
|
-
return ValidationError;
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
let KnowledgeMemoryError = class KnowledgeMemoryError extends Error {
|
|
1
|
+
export class KnowledgeMemoryError extends Error {
|
|
29
2
|
code;
|
|
30
3
|
details;
|
|
31
4
|
constructor(message, code, details){
|
|
@@ -40,14 +13,14 @@ let KnowledgeMemoryError = class KnowledgeMemoryError extends Error {
|
|
|
40
13
|
details: this.details
|
|
41
14
|
};
|
|
42
15
|
}
|
|
43
|
-
}
|
|
44
|
-
|
|
16
|
+
}
|
|
17
|
+
export class ValidationError extends KnowledgeMemoryError {
|
|
45
18
|
constructor(message, details){
|
|
46
19
|
super(message, 'VALIDATION_ERROR', details);
|
|
47
20
|
this.name = 'ValidationError';
|
|
48
21
|
}
|
|
49
|
-
}
|
|
50
|
-
|
|
22
|
+
}
|
|
23
|
+
export class DuplicateError extends KnowledgeMemoryError {
|
|
51
24
|
existingId;
|
|
52
25
|
duplicateType;
|
|
53
26
|
constructor(message, existingId, duplicateType){
|
|
@@ -57,20 +30,20 @@ let DuplicateError = class DuplicateError extends KnowledgeMemoryError {
|
|
|
57
30
|
}), this.existingId = existingId, this.duplicateType = duplicateType;
|
|
58
31
|
this.name = 'DuplicateError';
|
|
59
32
|
}
|
|
60
|
-
}
|
|
61
|
-
|
|
33
|
+
}
|
|
34
|
+
export class StorageError extends KnowledgeMemoryError {
|
|
62
35
|
constructor(message, details){
|
|
63
36
|
super(message, 'STORAGE_ERROR', details);
|
|
64
37
|
this.name = 'StorageError';
|
|
65
38
|
}
|
|
66
|
-
}
|
|
67
|
-
|
|
39
|
+
}
|
|
40
|
+
export class NotFoundError extends KnowledgeMemoryError {
|
|
68
41
|
constructor(message, id){
|
|
69
42
|
super(message, 'NOT_FOUND_ERROR', id ? {
|
|
70
43
|
id
|
|
71
44
|
} : undefined);
|
|
72
45
|
this.name = 'NotFoundError';
|
|
73
46
|
}
|
|
74
|
-
}
|
|
47
|
+
}
|
|
75
48
|
|
|
76
49
|
//# sourceMappingURL=errors.js.map
|
package/dist/utils/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/errors.ts"],"sourcesContent":["export class KnowledgeMemoryError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly details?: Record<string, unknown>\n ) {\n super(message);\n this.name = 'KnowledgeMemoryError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n toJSON(): Record<string, unknown> {\n return {\n error: this.code,\n message: this.message,\n details: this.details,\n };\n }\n}\n\nexport class ValidationError extends KnowledgeMemoryError {\n constructor(message: string, details?: Record<string, unknown>) {\n super(message, 'VALIDATION_ERROR', details);\n this.name = 'ValidationError';\n }\n}\n\nexport class DuplicateError extends KnowledgeMemoryError {\n constructor(\n message: string,\n public readonly existingId: string,\n public readonly duplicateType: 'title' | 'content'\n ) {\n super(message, 'DUPLICATE_ERROR', { existingId, duplicateType });\n this.name = 'DuplicateError';\n }\n}\n\nexport class StorageError extends KnowledgeMemoryError {\n constructor(message: string, details?: Record<string, unknown>) {\n super(message, 'STORAGE_ERROR', details);\n this.name = 'StorageError';\n }\n}\n\nexport class NotFoundError extends KnowledgeMemoryError {\n constructor(message: string, id?: string) {\n super(message, 'NOT_FOUND_ERROR', id ? { id } : undefined);\n this.name = 'NotFoundError';\n }\n}"],"names":["
|
|
1
|
+
{"version":3,"sources":["../../src/utils/errors.ts"],"sourcesContent":["export class KnowledgeMemoryError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly details?: Record<string, unknown>\n ) {\n super(message);\n this.name = 'KnowledgeMemoryError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n toJSON(): Record<string, unknown> {\n return {\n error: this.code,\n message: this.message,\n details: this.details,\n };\n }\n}\n\nexport class ValidationError extends KnowledgeMemoryError {\n constructor(message: string, details?: Record<string, unknown>) {\n super(message, 'VALIDATION_ERROR', details);\n this.name = 'ValidationError';\n }\n}\n\nexport class DuplicateError extends KnowledgeMemoryError {\n constructor(\n message: string,\n public readonly existingId: string,\n public readonly duplicateType: 'title' | 'content'\n ) {\n super(message, 'DUPLICATE_ERROR', { existingId, duplicateType });\n this.name = 'DuplicateError';\n }\n}\n\nexport class StorageError extends KnowledgeMemoryError {\n constructor(message: string, details?: Record<string, unknown>) {\n super(message, 'STORAGE_ERROR', details);\n this.name = 'StorageError';\n }\n}\n\nexport class NotFoundError extends KnowledgeMemoryError {\n constructor(message: string, id?: string) {\n super(message, 'NOT_FOUND_ERROR', id ? { id } : undefined);\n this.name = 'NotFoundError';\n }\n}"],"names":["KnowledgeMemoryError","Error","message","code","details","name","Object","setPrototypeOf","prototype","toJSON","error","ValidationError","DuplicateError","existingId","duplicateType","StorageError","NotFoundError","id","undefined"],"mappings":"AAAA,OAAO,MAAMA,6BAA6BC;;;IACtC,YACIC,OAAe,EACf,AAAgBC,IAAY,EAC5B,AAAgBC,OAAiC,CACnD;QACE,KAAK,CAACF,eAHUC,OAAAA,WACAC,UAAAA;QAGhB,IAAI,CAACC,IAAI,GAAG;QACZC,OAAOC,cAAc,CAAC,IAAI,EAAE,WAAWC,SAAS;IACpD;IAEAC,SAAkC;QAC9B,OAAO;YACHC,OAAO,IAAI,CAACP,IAAI;YAChBD,SAAS,IAAI,CAACA,OAAO;YACrBE,SAAS,IAAI,CAACA,OAAO;QACzB;IACJ;AACJ;AAEA,OAAO,MAAMO,wBAAwBX;IACjC,YAAYE,OAAe,EAAEE,OAAiC,CAAE;QAC5D,KAAK,CAACF,SAAS,oBAAoBE;QACnC,IAAI,CAACC,IAAI,GAAG;IAChB;AACJ;AAEA,OAAO,MAAMO,uBAAuBZ;;;IAChC,YACIE,OAAe,EACf,AAAgBW,UAAkB,EAClC,AAAgBC,aAAkC,CACpD;QACE,KAAK,CAACZ,SAAS,mBAAmB;YAAEW;YAAYC;QAAc,SAH9CD,aAAAA,iBACAC,gBAAAA;QAGhB,IAAI,CAACT,IAAI,GAAG;IAChB;AACJ;AAEA,OAAO,MAAMU,qBAAqBf;IAC9B,YAAYE,OAAe,EAAEE,OAAiC,CAAE;QAC5D,KAAK,CAACF,SAAS,iBAAiBE;QAChC,IAAI,CAACC,IAAI,GAAG;IAChB;AACJ;AAEA,OAAO,MAAMW,sBAAsBhB;IAC/B,YAAYE,OAAe,EAAEe,EAAW,CAAE;QACtC,KAAK,CAACf,SAAS,mBAAmBe,KAAK;YAAEA;QAAG,IAAIC;QAChD,IAAI,CAACb,IAAI,GAAG;IAChB;AACJ"}
|
package/package.json
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-devkit/memory",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
3
|
+
"version": "0.12.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Local MCP memory for AI coding agents to reuse project decisions, conventions, and fixes across sessions",
|
|
5
6
|
"main": "dist/index.js",
|
|
6
7
|
"types": "dist/index.d.ts",
|
|
7
8
|
"exports": {
|
|
8
9
|
".": {
|
|
9
10
|
"types": "./dist/index.d.ts",
|
|
10
|
-
"
|
|
11
|
+
"import": "./dist/index.js"
|
|
11
12
|
},
|
|
12
13
|
"./api": {
|
|
13
14
|
"types": "./dist/api.d.ts",
|
|
14
|
-
"
|
|
15
|
+
"import": "./dist/api.js"
|
|
15
16
|
}
|
|
16
17
|
},
|
|
17
18
|
"bin": {
|
|
@@ -23,11 +24,12 @@
|
|
|
23
24
|
"start": "node dist/index.js",
|
|
24
25
|
"inspect": "npm run build && npx @modelcontextprotocol/inspector node dist/index.js",
|
|
25
26
|
"typecheck": "tsc --noEmit",
|
|
26
|
-
"test": "
|
|
27
|
-
"test:
|
|
27
|
+
"test": "vitest run",
|
|
28
|
+
"test:watch": "vitest",
|
|
29
|
+
"test:coverage": "vitest run --coverage",
|
|
28
30
|
"lint": "eslint src/**/*.ts",
|
|
29
31
|
"clean": "rm -rf dist",
|
|
30
|
-
"benchmark": "
|
|
32
|
+
"benchmark": "node --import 'ts-node/register/esm' scripts/benchmark.ts --items=5000 --searches=300"
|
|
31
33
|
},
|
|
32
34
|
"keywords": [
|
|
33
35
|
"mcp",
|
|
@@ -48,15 +50,14 @@
|
|
|
48
50
|
"devDependencies": {
|
|
49
51
|
"@swc/cli": "^0.5.2",
|
|
50
52
|
"@swc/core": "^1.10.0",
|
|
51
|
-
"@swc/jest": "^0.2.37",
|
|
52
53
|
"@types/better-sqlite3": "^7.6.11",
|
|
53
|
-
"@types/jest": "^29.5.12",
|
|
54
54
|
"@types/node": "^20.14.0",
|
|
55
55
|
"@types/uuid": "^10.0.0",
|
|
56
|
+
"@vitest/coverage-v8": "^2.1.0",
|
|
56
57
|
"chokidar": "^3.6.0",
|
|
57
|
-
"jest": "^29.7.0",
|
|
58
58
|
"ts-node": "^10.9.2",
|
|
59
|
-
"typescript": "^5.
|
|
59
|
+
"typescript": "^5.5.0",
|
|
60
|
+
"vitest": "^2.1.0"
|
|
60
61
|
},
|
|
61
62
|
"engines": {
|
|
62
63
|
"node": ">=20.20.0"
|