@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/handlers/store.js
CHANGED
|
@@ -1,27 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
});
|
|
11
|
-
const _uuid = require("uuid");
|
|
12
|
-
const _database = require("../database");
|
|
13
|
-
const _validator = require("../services/validator");
|
|
14
|
-
const _normalizer = require("../services/normalizer");
|
|
15
|
-
const _errors = require("../utils/errors");
|
|
16
|
-
function storeKnowledge(input) {
|
|
17
|
-
(0, _validator.validateStoreInput)(input);
|
|
18
|
-
const db = (0, _database.getDatabase)();
|
|
1
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
2
|
+
import { getDatabase } from '../database/index.js';
|
|
3
|
+
import { validateStoreInput } from '../services/validator.js';
|
|
4
|
+
import { normalizeTitle, normalizeScope, normalizeTags, hashContent } from '../services/normalizer.js';
|
|
5
|
+
import { DuplicateError, StorageError } from '../utils/errors.js';
|
|
6
|
+
export function storeKnowledge(input) {
|
|
7
|
+
validateStoreInput(input);
|
|
8
|
+
const db = getDatabase();
|
|
19
9
|
const now = new Date().toISOString();
|
|
20
|
-
const normalizedTitle =
|
|
21
|
-
const scope =
|
|
22
|
-
const tags =
|
|
23
|
-
const contentHash =
|
|
24
|
-
const id = (
|
|
10
|
+
const normalizedTitle = normalizeTitle(input.title);
|
|
11
|
+
const scope = normalizeScope(input.scope);
|
|
12
|
+
const tags = normalizeTags(input.tags ?? []);
|
|
13
|
+
const contentHash = hashContent(input.content);
|
|
14
|
+
const id = uuidv4();
|
|
25
15
|
try {
|
|
26
16
|
return db.transaction(()=>{
|
|
27
17
|
const existingByTitle = db.queryOne('SELECT id FROM knowledge WHERE normalized_title = ? AND scope = ?', [
|
|
@@ -29,14 +19,14 @@ function storeKnowledge(input) {
|
|
|
29
19
|
scope
|
|
30
20
|
]);
|
|
31
21
|
if (existingByTitle) {
|
|
32
|
-
throw new
|
|
22
|
+
throw new DuplicateError('Knowledge with similar title already exists in this scope', existingByTitle.id, 'title');
|
|
33
23
|
}
|
|
34
24
|
const existingByHash = db.queryOne('SELECT id FROM knowledge WHERE content_hash = ? AND scope = ?', [
|
|
35
25
|
contentHash,
|
|
36
26
|
scope
|
|
37
27
|
]);
|
|
38
28
|
if (existingByHash) {
|
|
39
|
-
throw new
|
|
29
|
+
throw new DuplicateError('Knowledge with identical content already exists in this scope', existingByHash.id, 'content');
|
|
40
30
|
}
|
|
41
31
|
db.execute(`INSERT INTO knowledge (
|
|
42
32
|
id, title, content, tags, scope,
|
|
@@ -59,10 +49,10 @@ function storeKnowledge(input) {
|
|
|
59
49
|
};
|
|
60
50
|
});
|
|
61
51
|
} catch (error) {
|
|
62
|
-
if (error instanceof
|
|
52
|
+
if (error instanceof DuplicateError) {
|
|
63
53
|
throw error;
|
|
64
54
|
}
|
|
65
|
-
throw new
|
|
55
|
+
throw new StorageError('Failed to store knowledge', {
|
|
66
56
|
originalError: error instanceof Error ? error.message : String(error)
|
|
67
57
|
});
|
|
68
58
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/handlers/store.ts"],"sourcesContent":["import { v4 as uuidv4 } from 'uuid';\nimport { getDatabase } from '../database';\nimport { validateStoreInput } from '../services/validator';\nimport { normalizeTitle, normalizeScope, normalizeTags, hashContent } from '../services/normalizer';\nimport { DuplicateError, StorageError } from '../utils/errors';\nimport type { StoreKnowledgeInput, StoreKnowledgeResult, KnowledgeRow } from '../types';\n\nexport function storeKnowledge(input: StoreKnowledgeInput): StoreKnowledgeResult {\n validateStoreInput(input);\n\n const db = getDatabase();\n const now = new Date().toISOString();\n const normalizedTitle = normalizeTitle(input.title);\n const scope = normalizeScope(input.scope);\n const tags = normalizeTags(input.tags ?? []);\n const contentHash = hashContent(input.content);\n const id = uuidv4();\n\n try {\n return db.transaction(() => {\n const existingByTitle = db.queryOne<KnowledgeRow>(\n 'SELECT id FROM knowledge WHERE normalized_title = ? AND scope = ?',\n [normalizedTitle, scope]\n );\n\n if (existingByTitle) {\n throw new DuplicateError(\n 'Knowledge with similar title already exists in this scope',\n existingByTitle.id,\n 'title'\n );\n }\n\n const existingByHash = db.queryOne<KnowledgeRow>(\n 'SELECT id FROM knowledge WHERE content_hash = ? AND scope = ?',\n [contentHash, scope]\n );\n\n if (existingByHash) {\n throw new DuplicateError(\n 'Knowledge with identical content already exists in this scope',\n existingByHash.id,\n 'content'\n );\n }\n\n db.execute(\n `INSERT INTO knowledge (\n id, title, content, tags, scope,\n normalized_title, content_hash, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n [\n id,\n input.title.trim(),\n input.content.trim(),\n JSON.stringify(tags),\n scope,\n normalizedTitle,\n contentHash,\n now,\n now\n ]\n );\n\n return {\n success: true,\n id,\n message: 'Knowledge stored successfully'\n };\n });\n } catch (error) {\n if (error instanceof DuplicateError) {\n throw error;\n }\n throw new StorageError(\n 'Failed to store knowledge',\n { originalError: error instanceof Error ? error.message : String(error) }\n );\n }\n}"],"names":["
|
|
1
|
+
{"version":3,"sources":["../../src/handlers/store.ts"],"sourcesContent":["import { v4 as uuidv4 } from 'uuid';\nimport { getDatabase } from '../database/index.js';\nimport { validateStoreInput } from '../services/validator.js';\nimport { normalizeTitle, normalizeScope, normalizeTags, hashContent } from '../services/normalizer.js';\nimport { DuplicateError, StorageError } from '../utils/errors.js';\nimport type { StoreKnowledgeInput, StoreKnowledgeResult, KnowledgeRow } from '../types/index.js';\n\nexport function storeKnowledge(input: StoreKnowledgeInput): StoreKnowledgeResult {\n validateStoreInput(input);\n\n const db = getDatabase();\n const now = new Date().toISOString();\n const normalizedTitle = normalizeTitle(input.title);\n const scope = normalizeScope(input.scope);\n const tags = normalizeTags(input.tags ?? []);\n const contentHash = hashContent(input.content);\n const id = uuidv4();\n\n try {\n return db.transaction(() => {\n const existingByTitle = db.queryOne<KnowledgeRow>(\n 'SELECT id FROM knowledge WHERE normalized_title = ? AND scope = ?',\n [normalizedTitle, scope]\n );\n\n if (existingByTitle) {\n throw new DuplicateError(\n 'Knowledge with similar title already exists in this scope',\n existingByTitle.id,\n 'title'\n );\n }\n\n const existingByHash = db.queryOne<KnowledgeRow>(\n 'SELECT id FROM knowledge WHERE content_hash = ? AND scope = ?',\n [contentHash, scope]\n );\n\n if (existingByHash) {\n throw new DuplicateError(\n 'Knowledge with identical content already exists in this scope',\n existingByHash.id,\n 'content'\n );\n }\n\n db.execute(\n `INSERT INTO knowledge (\n id, title, content, tags, scope,\n normalized_title, content_hash, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n [\n id,\n input.title.trim(),\n input.content.trim(),\n JSON.stringify(tags),\n scope,\n normalizedTitle,\n contentHash,\n now,\n now\n ]\n );\n\n return {\n success: true,\n id,\n message: 'Knowledge stored successfully'\n };\n });\n } catch (error) {\n if (error instanceof DuplicateError) {\n throw error;\n }\n throw new StorageError(\n 'Failed to store knowledge',\n { originalError: error instanceof Error ? error.message : String(error) }\n );\n }\n}"],"names":["v4","uuidv4","getDatabase","validateStoreInput","normalizeTitle","normalizeScope","normalizeTags","hashContent","DuplicateError","StorageError","storeKnowledge","input","db","now","Date","toISOString","normalizedTitle","title","scope","tags","contentHash","content","id","transaction","existingByTitle","queryOne","existingByHash","execute","trim","JSON","stringify","success","message","error","originalError","Error","String"],"mappings":"AAAA,SAASA,MAAMC,MAAM,QAAQ,OAAO;AACpC,SAASC,WAAW,QAAQ,uBAAuB;AACnD,SAASC,kBAAkB,QAAQ,2BAA2B;AAC9D,SAASC,cAAc,EAAEC,cAAc,EAAEC,aAAa,EAAEC,WAAW,QAAQ,4BAA4B;AACvG,SAASC,cAAc,EAAEC,YAAY,QAAQ,qBAAqB;AAGlE,OAAO,SAASC,eAAeC,KAA0B;IACrDR,mBAAmBQ;IAEnB,MAAMC,KAAKV;IACX,MAAMW,MAAM,IAAIC,OAAOC,WAAW;IAClC,MAAMC,kBAAkBZ,eAAeO,MAAMM,KAAK;IAClD,MAAMC,QAAQb,eAAeM,MAAMO,KAAK;IACxC,MAAMC,OAAOb,cAAcK,MAAMQ,IAAI,IAAI,EAAE;IAC3C,MAAMC,cAAcb,YAAYI,MAAMU,OAAO;IAC7C,MAAMC,KAAKrB;IAEX,IAAI;QACA,OAAOW,GAAGW,WAAW,CAAC;YAClB,MAAMC,kBAAkBZ,GAAGa,QAAQ,CAC/B,qEACA;gBAACT;gBAAiBE;aAAM;YAG5B,IAAIM,iBAAiB;gBACjB,MAAM,IAAIhB,eACN,6DACAgB,gBAAgBF,EAAE,EAClB;YAER;YAEA,MAAMI,iBAAiBd,GAAGa,QAAQ,CAC9B,iEACA;gBAACL;gBAAaF;aAAM;YAGxB,IAAIQ,gBAAgB;gBAChB,MAAM,IAAIlB,eACN,iEACAkB,eAAeJ,EAAE,EACjB;YAER;YAEAV,GAAGe,OAAO,CACN,CAAC;;;4CAG2B,CAAC,EAC7B;gBACIL;gBACAX,MAAMM,KAAK,CAACW,IAAI;gBAChBjB,MAAMU,OAAO,CAACO,IAAI;gBAClBC,KAAKC,SAAS,CAACX;gBACfD;gBACAF;gBACAI;gBACAP;gBACAA;aACH;YAGL,OAAO;gBACHkB,SAAS;gBACTT;gBACAU,SAAS;YACb;QACJ;IACJ,EAAE,OAAOC,OAAO;QACZ,IAAIA,iBAAiBzB,gBAAgB;YACjC,MAAMyB;QACV;QACA,MAAM,IAAIxB,aACN,6BACA;YAAEyB,eAAeD,iBAAiBE,QAAQF,MAAMD,OAAO,GAAGI,OAAOH;QAAO;IAEhF;AACJ"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { UpdateKnowledgeInput, UpdateKnowledgeResult } from '../types';
|
|
1
|
+
import type { UpdateKnowledgeInput, UpdateKnowledgeResult } from '../types/index.js';
|
|
2
2
|
export declare function updateKnowledge(input: UpdateKnowledgeInput): UpdateKnowledgeResult;
|
|
3
3
|
//# sourceMappingURL=update.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/handlers/update.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,qBAAqB,EAAgB,MAAM,
|
|
1
|
+
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/handlers/update.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,qBAAqB,EAAgB,MAAM,mBAAmB,CAAC;AAEnG,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,qBAAqB,CAkFlF"}
|
package/dist/handlers/update.js
CHANGED
|
@@ -1,20 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
return updateKnowledge;
|
|
9
|
-
}
|
|
10
|
-
});
|
|
11
|
-
const _database = require("../database");
|
|
12
|
-
const _validator = require("../services/validator");
|
|
13
|
-
const _normalizer = require("../services/normalizer");
|
|
14
|
-
const _errors = require("../utils/errors");
|
|
15
|
-
function updateKnowledge(input) {
|
|
16
|
-
(0, _validator.validateUpdateInput)(input);
|
|
17
|
-
const db = (0, _database.getDatabase)();
|
|
1
|
+
import { getDatabase } from '../database/index.js';
|
|
2
|
+
import { validateUpdateInput } from '../services/validator.js';
|
|
3
|
+
import { normalizeTitle, normalizeScope, normalizeTags, hashContent } from '../services/normalizer.js';
|
|
4
|
+
import { DuplicateError, NotFoundError, StorageError } from '../utils/errors.js';
|
|
5
|
+
export function updateKnowledge(input) {
|
|
6
|
+
validateUpdateInput(input);
|
|
7
|
+
const db = getDatabase();
|
|
18
8
|
const now = new Date().toISOString();
|
|
19
9
|
try {
|
|
20
10
|
return db.transaction(()=>{
|
|
@@ -22,21 +12,21 @@ function updateKnowledge(input) {
|
|
|
22
12
|
input.id
|
|
23
13
|
]);
|
|
24
14
|
if (!existing) {
|
|
25
|
-
throw new
|
|
15
|
+
throw new NotFoundError(`Knowledge item not found: ${input.id}`, input.id);
|
|
26
16
|
}
|
|
27
17
|
const title = input.title !== undefined ? input.title.trim() : existing.title;
|
|
28
18
|
const content = input.content !== undefined ? input.content.trim() : existing.content;
|
|
29
|
-
const tags = input.tags !== undefined ?
|
|
30
|
-
const scope = input.scope !== undefined ?
|
|
31
|
-
const normalizedTitle =
|
|
32
|
-
const contentHash =
|
|
19
|
+
const tags = input.tags !== undefined ? normalizeTags(input.tags) : JSON.parse(existing.tags);
|
|
20
|
+
const scope = input.scope !== undefined ? normalizeScope(input.scope) : existing.scope;
|
|
21
|
+
const normalizedTitle = normalizeTitle(title);
|
|
22
|
+
const contentHash = hashContent(content);
|
|
33
23
|
const existingByTitle = db.queryOne('SELECT id FROM knowledge WHERE normalized_title = ? AND scope = ? AND id != ?', [
|
|
34
24
|
normalizedTitle,
|
|
35
25
|
scope,
|
|
36
26
|
input.id
|
|
37
27
|
]);
|
|
38
28
|
if (existingByTitle) {
|
|
39
|
-
throw new
|
|
29
|
+
throw new DuplicateError('Knowledge with similar title already exists in this scope', existingByTitle.id, 'title');
|
|
40
30
|
}
|
|
41
31
|
const existingByHash = db.queryOne('SELECT id FROM knowledge WHERE content_hash = ? AND scope = ? AND id != ?', [
|
|
42
32
|
contentHash,
|
|
@@ -44,7 +34,7 @@ function updateKnowledge(input) {
|
|
|
44
34
|
input.id
|
|
45
35
|
]);
|
|
46
36
|
if (existingByHash) {
|
|
47
|
-
throw new
|
|
37
|
+
throw new DuplicateError('Knowledge with identical content already exists in this scope', existingByHash.id, 'content');
|
|
48
38
|
}
|
|
49
39
|
db.execute(`UPDATE knowledge SET
|
|
50
40
|
title = ?, content = ?, tags = ?, scope = ?,
|
|
@@ -66,10 +56,10 @@ function updateKnowledge(input) {
|
|
|
66
56
|
};
|
|
67
57
|
});
|
|
68
58
|
} catch (error) {
|
|
69
|
-
if (error instanceof
|
|
59
|
+
if (error instanceof DuplicateError || error instanceof NotFoundError) {
|
|
70
60
|
throw error;
|
|
71
61
|
}
|
|
72
|
-
throw new
|
|
62
|
+
throw new StorageError('Failed to update knowledge', {
|
|
73
63
|
originalError: error instanceof Error ? error.message : String(error)
|
|
74
64
|
});
|
|
75
65
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/handlers/update.ts"],"sourcesContent":["import { getDatabase } from '../database';\nimport { validateUpdateInput } from '../services/validator';\nimport { normalizeTitle, normalizeScope, normalizeTags, hashContent } from '../services/normalizer';\nimport { DuplicateError, NotFoundError, StorageError } from '../utils/errors';\nimport type { UpdateKnowledgeInput, UpdateKnowledgeResult, KnowledgeRow } from '../types';\n\nexport function updateKnowledge(input: UpdateKnowledgeInput): UpdateKnowledgeResult {\n validateUpdateInput(input);\n\n const db = getDatabase();\n const now = new Date().toISOString();\n\n try {\n return db.transaction(() => {\n const existing = db.queryOne<KnowledgeRow>(\n 'SELECT * FROM knowledge WHERE id = ?',\n [input.id]\n );\n\n if (!existing) {\n throw new NotFoundError(`Knowledge item not found: ${input.id}`, input.id);\n }\n\n const title = input.title !== undefined ? input.title.trim() : existing.title;\n const content = input.content !== undefined ? input.content.trim() : existing.content;\n const tags = input.tags !== undefined ? normalizeTags(input.tags) : JSON.parse(existing.tags);\n const scope = input.scope !== undefined ? normalizeScope(input.scope) : existing.scope;\n const normalizedTitle = normalizeTitle(title);\n const contentHash = hashContent(content);\n\n const existingByTitle = db.queryOne<KnowledgeRow>(\n 'SELECT id FROM knowledge WHERE normalized_title = ? AND scope = ? AND id != ?',\n [normalizedTitle, scope, input.id]\n );\n\n if (existingByTitle) {\n throw new DuplicateError(\n 'Knowledge with similar title already exists in this scope',\n existingByTitle.id,\n 'title'\n );\n }\n\n const existingByHash = db.queryOne<KnowledgeRow>(\n 'SELECT id FROM knowledge WHERE content_hash = ? AND scope = ? AND id != ?',\n [contentHash, scope, input.id]\n );\n\n if (existingByHash) {\n throw new DuplicateError(\n 'Knowledge with identical content already exists in this scope',\n existingByHash.id,\n 'content'\n );\n }\n\n db.execute(\n `UPDATE knowledge SET\n title = ?, content = ?, tags = ?, scope = ?,\n normalized_title = ?, content_hash = ?, updated_at = ?\n WHERE id = ?`,\n [\n title,\n content,\n JSON.stringify(tags),\n scope,\n normalizedTitle,\n contentHash,\n now,\n input.id\n ]\n );\n\n return {\n success: true,\n id: input.id,\n message: 'Knowledge updated successfully'\n };\n });\n } catch (error) {\n if (error instanceof DuplicateError || error instanceof NotFoundError) {\n throw error;\n }\n throw new StorageError(\n 'Failed to update knowledge',\n { originalError: error instanceof Error ? error.message : String(error) }\n );\n }\n}\n"],"names":["
|
|
1
|
+
{"version":3,"sources":["../../src/handlers/update.ts"],"sourcesContent":["import { getDatabase } from '../database/index.js';\nimport { validateUpdateInput } from '../services/validator.js';\nimport { normalizeTitle, normalizeScope, normalizeTags, hashContent } from '../services/normalizer.js';\nimport { DuplicateError, NotFoundError, StorageError } from '../utils/errors.js';\nimport type { UpdateKnowledgeInput, UpdateKnowledgeResult, KnowledgeRow } from '../types/index.js';\n\nexport function updateKnowledge(input: UpdateKnowledgeInput): UpdateKnowledgeResult {\n validateUpdateInput(input);\n\n const db = getDatabase();\n const now = new Date().toISOString();\n\n try {\n return db.transaction(() => {\n const existing = db.queryOne<KnowledgeRow>(\n 'SELECT * FROM knowledge WHERE id = ?',\n [input.id]\n );\n\n if (!existing) {\n throw new NotFoundError(`Knowledge item not found: ${input.id}`, input.id);\n }\n\n const title = input.title !== undefined ? input.title.trim() : existing.title;\n const content = input.content !== undefined ? input.content.trim() : existing.content;\n const tags = input.tags !== undefined ? normalizeTags(input.tags) : JSON.parse(existing.tags);\n const scope = input.scope !== undefined ? normalizeScope(input.scope) : existing.scope;\n const normalizedTitle = normalizeTitle(title);\n const contentHash = hashContent(content);\n\n const existingByTitle = db.queryOne<KnowledgeRow>(\n 'SELECT id FROM knowledge WHERE normalized_title = ? AND scope = ? AND id != ?',\n [normalizedTitle, scope, input.id]\n );\n\n if (existingByTitle) {\n throw new DuplicateError(\n 'Knowledge with similar title already exists in this scope',\n existingByTitle.id,\n 'title'\n );\n }\n\n const existingByHash = db.queryOne<KnowledgeRow>(\n 'SELECT id FROM knowledge WHERE content_hash = ? AND scope = ? AND id != ?',\n [contentHash, scope, input.id]\n );\n\n if (existingByHash) {\n throw new DuplicateError(\n 'Knowledge with identical content already exists in this scope',\n existingByHash.id,\n 'content'\n );\n }\n\n db.execute(\n `UPDATE knowledge SET\n title = ?, content = ?, tags = ?, scope = ?,\n normalized_title = ?, content_hash = ?, updated_at = ?\n WHERE id = ?`,\n [\n title,\n content,\n JSON.stringify(tags),\n scope,\n normalizedTitle,\n contentHash,\n now,\n input.id\n ]\n );\n\n return {\n success: true,\n id: input.id,\n message: 'Knowledge updated successfully'\n };\n });\n } catch (error) {\n if (error instanceof DuplicateError || error instanceof NotFoundError) {\n throw error;\n }\n throw new StorageError(\n 'Failed to update knowledge',\n { originalError: error instanceof Error ? error.message : String(error) }\n );\n }\n}\n"],"names":["getDatabase","validateUpdateInput","normalizeTitle","normalizeScope","normalizeTags","hashContent","DuplicateError","NotFoundError","StorageError","updateKnowledge","input","db","now","Date","toISOString","transaction","existing","queryOne","id","title","undefined","trim","content","tags","JSON","parse","scope","normalizedTitle","contentHash","existingByTitle","existingByHash","execute","stringify","success","message","error","originalError","Error","String"],"mappings":"AAAA,SAASA,WAAW,QAAQ,uBAAuB;AACnD,SAASC,mBAAmB,QAAQ,2BAA2B;AAC/D,SAASC,cAAc,EAAEC,cAAc,EAAEC,aAAa,EAAEC,WAAW,QAAQ,4BAA4B;AACvG,SAASC,cAAc,EAAEC,aAAa,EAAEC,YAAY,QAAQ,qBAAqB;AAGjF,OAAO,SAASC,gBAAgBC,KAA2B;IACvDT,oBAAoBS;IAEpB,MAAMC,KAAKX;IACX,MAAMY,MAAM,IAAIC,OAAOC,WAAW;IAElC,IAAI;QACA,OAAOH,GAAGI,WAAW,CAAC;YAClB,MAAMC,WAAWL,GAAGM,QAAQ,CACxB,wCACA;gBAACP,MAAMQ,EAAE;aAAC;YAGd,IAAI,CAACF,UAAU;gBACX,MAAM,IAAIT,cAAc,CAAC,0BAA0B,EAAEG,MAAMQ,EAAE,EAAE,EAAER,MAAMQ,EAAE;YAC7E;YAEA,MAAMC,QAAQT,MAAMS,KAAK,KAAKC,YAAYV,MAAMS,KAAK,CAACE,IAAI,KAAKL,SAASG,KAAK;YAC7E,MAAMG,UAAUZ,MAAMY,OAAO,KAAKF,YAAYV,MAAMY,OAAO,CAACD,IAAI,KAAKL,SAASM,OAAO;YACrF,MAAMC,OAAOb,MAAMa,IAAI,KAAKH,YAAYhB,cAAcM,MAAMa,IAAI,IAAIC,KAAKC,KAAK,CAACT,SAASO,IAAI;YAC5F,MAAMG,QAAQhB,MAAMgB,KAAK,KAAKN,YAAYjB,eAAeO,MAAMgB,KAAK,IAAIV,SAASU,KAAK;YACtF,MAAMC,kBAAkBzB,eAAeiB;YACvC,MAAMS,cAAcvB,YAAYiB;YAEhC,MAAMO,kBAAkBlB,GAAGM,QAAQ,CAC/B,iFACA;gBAACU;gBAAiBD;gBAAOhB,MAAMQ,EAAE;aAAC;YAGtC,IAAIW,iBAAiB;gBACjB,MAAM,IAAIvB,eACN,6DACAuB,gBAAgBX,EAAE,EAClB;YAER;YAEA,MAAMY,iBAAiBnB,GAAGM,QAAQ,CAC9B,6EACA;gBAACW;gBAAaF;gBAAOhB,MAAMQ,EAAE;aAAC;YAGlC,IAAIY,gBAAgB;gBAChB,MAAM,IAAIxB,eACN,iEACAwB,eAAeZ,EAAE,EACjB;YAER;YAEAP,GAAGoB,OAAO,CACN,CAAC;;;4BAGW,CAAC,EACb;gBACIZ;gBACAG;gBACAE,KAAKQ,SAAS,CAACT;gBACfG;gBACAC;gBACAC;gBACAhB;gBACAF,MAAMQ,EAAE;aACX;YAGL,OAAO;gBACHe,SAAS;gBACTf,IAAIR,MAAMQ,EAAE;gBACZgB,SAAS;YACb;QACJ;IACJ,EAAE,OAAOC,OAAO;QACZ,IAAIA,iBAAiB7B,kBAAkB6B,iBAAiB5B,eAAe;YACnE,MAAM4B;QACV;QACA,MAAM,IAAI3B,aACN,8BACA;YAAE4B,eAAeD,iBAAiBE,QAAQF,MAAMD,OAAO,GAAGI,OAAOH;QAAO;IAEhF;AACJ"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAKA,cAAc,UAAU,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,27 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
});
|
|
6
|
-
const _server = require("./server");
|
|
7
|
-
_export_star(require("./api"), exports);
|
|
8
|
-
function _export_star(from, to) {
|
|
9
|
-
Object.keys(from).forEach(function(k) {
|
|
10
|
-
if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
|
|
11
|
-
Object.defineProperty(to, k, {
|
|
12
|
-
enumerable: true,
|
|
13
|
-
get: function() {
|
|
14
|
-
return from[k];
|
|
15
|
-
}
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
return from;
|
|
20
|
-
}
|
|
2
|
+
import { fileURLToPath } from 'url';
|
|
3
|
+
import { runServer } from './server.js';
|
|
4
|
+
export * from './api.js';
|
|
21
5
|
// Only start MCP server when this file is run directly as a binary
|
|
22
6
|
// Not when imported as a library (e.g., by CLI commands)
|
|
23
|
-
if (
|
|
24
|
-
|
|
7
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
8
|
+
runServer().catch((error)=>{
|
|
25
9
|
console.error('Failed to start server:', error);
|
|
26
10
|
process.exit(1);
|
|
27
11
|
});
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { runServer } from './server';\n\nexport * from './api';\n\n// Only start MCP server when this file is run directly as a binary\n// Not when imported as a library (e.g., by CLI commands)\nif (
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { fileURLToPath } from 'url';\nimport { runServer } from './server.js';\n\nexport * from './api.js';\n\n// Only start MCP server when this file is run directly as a binary\n// Not when imported as a library (e.g., by CLI commands)\nif (process.argv[1] === fileURLToPath(import.meta.url)) {\n runServer().catch((error: Error) => {\n console.error('Failed to start server:', error);\n process.exit(1);\n });\n}\n"],"names":["fileURLToPath","runServer","process","argv","url","catch","error","console","exit"],"mappings":";AAEA,SAASA,aAAa,QAAQ,MAAM;AACpC,SAASC,SAAS,QAAQ,cAAc;AAExC,cAAc,WAAW;AAEzB,mEAAmE;AACnE,yDAAyD;AACzD,IAAIC,QAAQC,IAAI,CAAC,EAAE,KAAKH,cAAc,YAAYI,GAAG,GAAG;IACpDH,YAAYI,KAAK,CAAC,CAACC;QACfC,QAAQD,KAAK,CAAC,2BAA2BA;QACzCJ,QAAQM,IAAI,CAAC;IACjB;AACJ"}
|
package/dist/server.js
CHANGED
|
@@ -1,31 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
-
});
|
|
10
|
-
}
|
|
11
|
-
_export(exports, {
|
|
12
|
-
get TOOLS () {
|
|
13
|
-
return TOOLS;
|
|
14
|
-
},
|
|
15
|
-
get createServer () {
|
|
16
|
-
return createServer;
|
|
17
|
-
},
|
|
18
|
-
get runServer () {
|
|
19
|
-
return runServer;
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
|
-
const _index = require("@modelcontextprotocol/sdk/server/index.js");
|
|
23
|
-
const _stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
24
|
-
const _types = require("@modelcontextprotocol/sdk/types.js");
|
|
25
|
-
const _store = require("./handlers/store");
|
|
26
|
-
const _search = require("./handlers/search");
|
|
27
|
-
const _update = require("./handlers/update");
|
|
28
|
-
const _errors = require("./utils/errors");
|
|
1
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
2
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
|
+
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
4
|
+
import { storeKnowledge } from './handlers/store.js';
|
|
5
|
+
import { searchKnowledge } from './handlers/search.js';
|
|
6
|
+
import { updateKnowledge } from './handlers/update.js';
|
|
7
|
+
import { KnowledgeMemoryError } from './utils/errors.js';
|
|
29
8
|
const SERVER_NAME = 'ai-devkit-memory';
|
|
30
9
|
const SERVER_VERSION = '0.1.0';
|
|
31
10
|
const STORE_TOOL = {
|
|
@@ -126,13 +105,13 @@ const SEARCH_TOOL = {
|
|
|
126
105
|
]
|
|
127
106
|
}
|
|
128
107
|
};
|
|
129
|
-
const TOOLS = [
|
|
108
|
+
export const TOOLS = [
|
|
130
109
|
STORE_TOOL,
|
|
131
110
|
UPDATE_TOOL,
|
|
132
111
|
SEARCH_TOOL
|
|
133
112
|
];
|
|
134
|
-
function createServer() {
|
|
135
|
-
const server = new
|
|
113
|
+
export function createServer() {
|
|
114
|
+
const server = new Server({
|
|
136
115
|
name: SERVER_NAME,
|
|
137
116
|
version: SERVER_VERSION
|
|
138
117
|
}, {
|
|
@@ -141,7 +120,7 @@ function createServer() {
|
|
|
141
120
|
}
|
|
142
121
|
});
|
|
143
122
|
// List available tools
|
|
144
|
-
server.setRequestHandler(
|
|
123
|
+
server.setRequestHandler(ListToolsRequestSchema, async ()=>{
|
|
145
124
|
return {
|
|
146
125
|
tools: [
|
|
147
126
|
STORE_TOOL,
|
|
@@ -151,14 +130,14 @@ function createServer() {
|
|
|
151
130
|
};
|
|
152
131
|
});
|
|
153
132
|
// Handle tool calls
|
|
154
|
-
server.setRequestHandler(
|
|
133
|
+
server.setRequestHandler(CallToolRequestSchema, async (request)=>{
|
|
155
134
|
const { name, arguments: args } = request.params;
|
|
156
135
|
try {
|
|
157
136
|
// Backward-compat: accept deprecated dotted names so agents with
|
|
158
137
|
// stale prompts/templates continue to work. Remove in next major.
|
|
159
138
|
if (name === 'memory_storeKnowledge' || name === 'memory.storeKnowledge') {
|
|
160
139
|
const input = args;
|
|
161
|
-
const result =
|
|
140
|
+
const result = storeKnowledge(input);
|
|
162
141
|
return {
|
|
163
142
|
content: [
|
|
164
143
|
{
|
|
@@ -170,7 +149,7 @@ function createServer() {
|
|
|
170
149
|
}
|
|
171
150
|
if (name === 'memory_updateKnowledge' || name === 'memory.updateKnowledge') {
|
|
172
151
|
const input = args;
|
|
173
|
-
const result =
|
|
152
|
+
const result = updateKnowledge(input);
|
|
174
153
|
return {
|
|
175
154
|
content: [
|
|
176
155
|
{
|
|
@@ -182,7 +161,7 @@ function createServer() {
|
|
|
182
161
|
}
|
|
183
162
|
if (name === 'memory_searchKnowledge' || name === 'memory.searchKnowledge') {
|
|
184
163
|
const input = args;
|
|
185
|
-
const result =
|
|
164
|
+
const result = searchKnowledge(input);
|
|
186
165
|
return {
|
|
187
166
|
content: [
|
|
188
167
|
{
|
|
@@ -205,7 +184,7 @@ function createServer() {
|
|
|
205
184
|
isError: true
|
|
206
185
|
};
|
|
207
186
|
} catch (error) {
|
|
208
|
-
const errorResponse = error instanceof
|
|
187
|
+
const errorResponse = error instanceof KnowledgeMemoryError ? error.toJSON() : {
|
|
209
188
|
error: 'INTERNAL_ERROR',
|
|
210
189
|
message: error instanceof Error ? error.message : String(error)
|
|
211
190
|
};
|
|
@@ -222,9 +201,9 @@ function createServer() {
|
|
|
222
201
|
});
|
|
223
202
|
return server;
|
|
224
203
|
}
|
|
225
|
-
async function runServer() {
|
|
204
|
+
export async function runServer() {
|
|
226
205
|
const server = createServer();
|
|
227
|
-
const transport = new
|
|
206
|
+
const transport = new StdioServerTransport();
|
|
228
207
|
await server.connect(transport);
|
|
229
208
|
}
|
|
230
209
|
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server.ts"],"sourcesContent":["import { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\nimport { storeKnowledge } from './handlers/store';\nimport { searchKnowledge } from './handlers/search';\nimport { updateKnowledge } from './handlers/update';\nimport { KnowledgeMemoryError } from './utils/errors';\nimport type { StoreKnowledgeInput, SearchKnowledgeInput, UpdateKnowledgeInput } from './types';\n\nconst SERVER_NAME = 'ai-devkit-memory';\nconst SERVER_VERSION = '0.1.0';\n\nconst STORE_TOOL = {\n name: 'memory_storeKnowledge',\n description: 'Store a new knowledge item. Use this to save actionable guidelines, rules, or patterns for future reference.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n title: {\n type: 'string',\n description: 'Short, explicit description of the rule (5-12 words, 10-100 chars)',\n },\n content: {\n type: 'string',\n description: 'Detailed explanation in markdown format. Supports code blocks and examples. (50-5000 chars)',\n },\n tags: {\n type: 'array',\n items: { type: 'string' },\n description: 'Optional domain keywords (e.g., [\"api\", \"backend\"]). Max 10 tags.',\n },\n scope: {\n type: 'string',\n description: 'Optional scope: \"global\", \"project:<name>\", or \"repo:<name>\". Default: \"global\"',\n },\n },\n required: ['title', 'content'],\n },\n};\n\nconst UPDATE_TOOL = {\n name: 'memory_updateKnowledge',\n description: 'Update an existing knowledge item by ID. Use this to correct outdated or inaccurate knowledge.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n id: {\n type: 'string',\n description: 'UUID of the knowledge item to update',\n },\n title: {\n type: 'string',\n description: 'New title (10-100 chars). Only provide if changing.',\n },\n content: {\n type: 'string',\n description: 'New content in markdown format (50-5000 chars). Only provide if changing.',\n },\n tags: {\n type: 'array',\n items: { type: 'string' },\n description: 'New tags (replaces existing). Only provide if changing. Max 10 tags.',\n },\n scope: {\n type: 'string',\n description: 'New scope: \"global\", \"project:<name>\", or \"repo:<name>\". Only provide if changing.',\n },\n },\n required: ['id'],\n },\n};\n\nconst SEARCH_TOOL = {\n name: 'memory_searchKnowledge',\n description: 'Search for relevant knowledge based on a task description. Returns ranked results.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n query: {\n type: 'string',\n description: 'Natural language task description to search for relevant knowledge (3-500 chars)',\n },\n contextTags: {\n type: 'array',\n items: { type: 'string' },\n description: 'Optional tags to boost matching results (e.g., [\"api\", \"backend\"])',\n },\n scope: {\n type: 'string',\n description: 'Optional project/repo scope filter. Results from this scope are prioritized.',\n },\n limit: {\n type: 'number',\n description: 'Maximum number of results to return (1-20, default: 5)',\n },\n },\n required: ['query'],\n },\n};\n\nexport const TOOLS = [STORE_TOOL, UPDATE_TOOL, SEARCH_TOOL];\n\nexport function createServer(): Server {\n const server = new Server(\n {\n name: SERVER_NAME,\n version: SERVER_VERSION,\n },\n {\n capabilities: {\n tools: {},\n },\n }\n );\n\n // List available tools\n server.setRequestHandler(ListToolsRequestSchema, async () => {\n return {\n tools: [STORE_TOOL, UPDATE_TOOL, SEARCH_TOOL],\n };\n });\n\n // Handle tool calls\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n\n try {\n // Backward-compat: accept deprecated dotted names so agents with\n // stale prompts/templates continue to work. Remove in next major.\n if (name === 'memory_storeKnowledge' || name === 'memory.storeKnowledge') {\n const input = args as unknown as StoreKnowledgeInput;\n const result = storeKnowledge(input);\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n\n if (name === 'memory_updateKnowledge' || name === 'memory.updateKnowledge') {\n const input = args as unknown as UpdateKnowledgeInput;\n const result = updateKnowledge(input);\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n\n if (name === 'memory_searchKnowledge' || name === 'memory.searchKnowledge') {\n const input = args as unknown as SearchKnowledgeInput;\n const result = searchKnowledge(input);\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify({ error: 'UNKNOWN_TOOL', message: `Unknown tool: ${name}` }),\n },\n ],\n isError: true,\n };\n } catch (error) {\n const errorResponse = error instanceof KnowledgeMemoryError\n ? error.toJSON()\n : { error: 'INTERNAL_ERROR', message: error instanceof Error ? error.message : String(error) };\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(errorResponse, null, 2),\n },\n ],\n isError: true,\n };\n }\n });\n\n return server;\n}\n\nexport async function runServer(): Promise<void> {\n const server = createServer();\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n"],"names":["TOOLS","createServer","runServer","SERVER_NAME","SERVER_VERSION","STORE_TOOL","name","description","inputSchema","type","properties","title","content","tags","items","scope","required","UPDATE_TOOL","id","SEARCH_TOOL","query","contextTags","limit","server","Server","version","capabilities","tools","setRequestHandler","ListToolsRequestSchema","CallToolRequestSchema","request","arguments","args","params","input","result","storeKnowledge","text","JSON","stringify","updateKnowledge","searchKnowledge","error","message","isError","errorResponse","KnowledgeMemoryError","toJSON","Error","String","transport","StdioServerTransport","connect"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/server.ts"],"sourcesContent":["import { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\nimport { storeKnowledge } from './handlers/store.js';\nimport { searchKnowledge } from './handlers/search.js';\nimport { updateKnowledge } from './handlers/update.js';\nimport { KnowledgeMemoryError } from './utils/errors.js';\nimport type { StoreKnowledgeInput, SearchKnowledgeInput, UpdateKnowledgeInput } from './types/index.js';\n\nconst SERVER_NAME = 'ai-devkit-memory';\nconst SERVER_VERSION = '0.1.0';\n\nconst STORE_TOOL = {\n name: 'memory_storeKnowledge',\n description: 'Store a new knowledge item. Use this to save actionable guidelines, rules, or patterns for future reference.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n title: {\n type: 'string',\n description: 'Short, explicit description of the rule (5-12 words, 10-100 chars)',\n },\n content: {\n type: 'string',\n description: 'Detailed explanation in markdown format. Supports code blocks and examples. (50-5000 chars)',\n },\n tags: {\n type: 'array',\n items: { type: 'string' },\n description: 'Optional domain keywords (e.g., [\"api\", \"backend\"]). Max 10 tags.',\n },\n scope: {\n type: 'string',\n description: 'Optional scope: \"global\", \"project:<name>\", or \"repo:<name>\". Default: \"global\"',\n },\n },\n required: ['title', 'content'],\n },\n};\n\nconst UPDATE_TOOL = {\n name: 'memory_updateKnowledge',\n description: 'Update an existing knowledge item by ID. Use this to correct outdated or inaccurate knowledge.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n id: {\n type: 'string',\n description: 'UUID of the knowledge item to update',\n },\n title: {\n type: 'string',\n description: 'New title (10-100 chars). Only provide if changing.',\n },\n content: {\n type: 'string',\n description: 'New content in markdown format (50-5000 chars). Only provide if changing.',\n },\n tags: {\n type: 'array',\n items: { type: 'string' },\n description: 'New tags (replaces existing). Only provide if changing. Max 10 tags.',\n },\n scope: {\n type: 'string',\n description: 'New scope: \"global\", \"project:<name>\", or \"repo:<name>\". Only provide if changing.',\n },\n },\n required: ['id'],\n },\n};\n\nconst SEARCH_TOOL = {\n name: 'memory_searchKnowledge',\n description: 'Search for relevant knowledge based on a task description. Returns ranked results.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n query: {\n type: 'string',\n description: 'Natural language task description to search for relevant knowledge (3-500 chars)',\n },\n contextTags: {\n type: 'array',\n items: { type: 'string' },\n description: 'Optional tags to boost matching results (e.g., [\"api\", \"backend\"])',\n },\n scope: {\n type: 'string',\n description: 'Optional project/repo scope filter. Results from this scope are prioritized.',\n },\n limit: {\n type: 'number',\n description: 'Maximum number of results to return (1-20, default: 5)',\n },\n },\n required: ['query'],\n },\n};\n\nexport const TOOLS = [STORE_TOOL, UPDATE_TOOL, SEARCH_TOOL];\n\nexport function createServer(): Server {\n const server = new Server(\n {\n name: SERVER_NAME,\n version: SERVER_VERSION,\n },\n {\n capabilities: {\n tools: {},\n },\n }\n );\n\n // List available tools\n server.setRequestHandler(ListToolsRequestSchema, async () => {\n return {\n tools: [STORE_TOOL, UPDATE_TOOL, SEARCH_TOOL],\n };\n });\n\n // Handle tool calls\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n\n try {\n // Backward-compat: accept deprecated dotted names so agents with\n // stale prompts/templates continue to work. Remove in next major.\n if (name === 'memory_storeKnowledge' || name === 'memory.storeKnowledge') {\n const input = args as unknown as StoreKnowledgeInput;\n const result = storeKnowledge(input);\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n\n if (name === 'memory_updateKnowledge' || name === 'memory.updateKnowledge') {\n const input = args as unknown as UpdateKnowledgeInput;\n const result = updateKnowledge(input);\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n\n if (name === 'memory_searchKnowledge' || name === 'memory.searchKnowledge') {\n const input = args as unknown as SearchKnowledgeInput;\n const result = searchKnowledge(input);\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify({ error: 'UNKNOWN_TOOL', message: `Unknown tool: ${name}` }),\n },\n ],\n isError: true,\n };\n } catch (error) {\n const errorResponse = error instanceof KnowledgeMemoryError\n ? error.toJSON()\n : { error: 'INTERNAL_ERROR', message: error instanceof Error ? error.message : String(error) };\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(errorResponse, null, 2),\n },\n ],\n isError: true,\n };\n }\n });\n\n return server;\n}\n\nexport async function runServer(): Promise<void> {\n const server = createServer();\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n"],"names":["Server","StdioServerTransport","CallToolRequestSchema","ListToolsRequestSchema","storeKnowledge","searchKnowledge","updateKnowledge","KnowledgeMemoryError","SERVER_NAME","SERVER_VERSION","STORE_TOOL","name","description","inputSchema","type","properties","title","content","tags","items","scope","required","UPDATE_TOOL","id","SEARCH_TOOL","query","contextTags","limit","TOOLS","createServer","server","version","capabilities","tools","setRequestHandler","request","arguments","args","params","input","result","text","JSON","stringify","error","message","isError","errorResponse","toJSON","Error","String","runServer","transport","connect"],"mappings":"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"}
|
|
@@ -1,48 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
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 hashContent () {
|
|
13
|
-
return hashContent;
|
|
14
|
-
},
|
|
15
|
-
get normalizeContent () {
|
|
16
|
-
return normalizeContent;
|
|
17
|
-
},
|
|
18
|
-
get normalizeScope () {
|
|
19
|
-
return normalizeScope;
|
|
20
|
-
},
|
|
21
|
-
get normalizeTags () {
|
|
22
|
-
return normalizeTags;
|
|
23
|
-
},
|
|
24
|
-
get normalizeTitle () {
|
|
25
|
-
return normalizeTitle;
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
const _crypto = require("crypto");
|
|
29
|
-
function normalizeTitle(title) {
|
|
1
|
+
import { createHash } from 'crypto';
|
|
2
|
+
/**
|
|
3
|
+
* Normalize title for deduplication
|
|
4
|
+
*/ export function normalizeTitle(title) {
|
|
30
5
|
return title.toLowerCase().trim().replace(/\s+/g, ' ');
|
|
31
6
|
}
|
|
32
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Normalize content for hashing
|
|
9
|
+
*/ export function normalizeContent(content) {
|
|
33
10
|
return content.trim().replace(/\r\n/g, '\n').replace(/\r/g, '\n').replace(/\n{3,}/g, '\n\n');
|
|
34
11
|
}
|
|
35
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Generate SHA-256 hash of normalized content for deduplication
|
|
14
|
+
*/ export function hashContent(content) {
|
|
36
15
|
const normalized = normalizeContent(content);
|
|
37
|
-
return
|
|
16
|
+
return createHash('sha256').update(normalized, 'utf8').digest('hex');
|
|
38
17
|
}
|
|
39
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Normalize tags
|
|
20
|
+
*/ export function normalizeTags(tags) {
|
|
40
21
|
const normalized = tags.map((tag)=>tag.toLowerCase().trim()).filter((tag)=>tag.length > 0);
|
|
41
22
|
return [
|
|
42
23
|
...new Set(normalized)
|
|
43
24
|
];
|
|
44
25
|
}
|
|
45
|
-
|
|
26
|
+
/**
|
|
27
|
+
* Validate and normalize scope
|
|
28
|
+
*/ export function normalizeScope(scope) {
|
|
46
29
|
if (!scope || scope.trim() === '') {
|
|
47
30
|
return 'global';
|
|
48
31
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/services/normalizer.ts"],"sourcesContent":["import { createHash } from 'crypto';\n\n/**\n * Normalize title for deduplication\n */\nexport function normalizeTitle(title: string): string {\n return title\n .toLowerCase()\n .trim()\n .replace(/\\s+/g, ' ');\n}\n\n/**\n * Normalize content for hashing\n */\nexport function normalizeContent(content: string): string {\n return content\n .trim()\n .replace(/\\r\\n/g, '\\n')\n .replace(/\\r/g, '\\n')\n .replace(/\\n{3,}/g, '\\n\\n');\n}\n\n/**\n * Generate SHA-256 hash of normalized content for deduplication\n */\nexport function hashContent(content: string): string {\n const normalized = normalizeContent(content);\n return createHash('sha256').update(normalized, 'utf8').digest('hex');\n}\n\n/**\n * Normalize tags\n */\nexport function normalizeTags(tags: string[]): string[] {\n const normalized = tags\n .map(tag => tag.toLowerCase().trim())\n .filter(tag => tag.length > 0);\n\n return [...new Set(normalized)];\n}\n\n/**\n * Validate and normalize scope\n */\nexport function normalizeScope(scope?: string): string {\n if (!scope || scope.trim() === '') {\n return 'global';\n }\n return scope.trim().toLowerCase();\n}"],"names":["
|
|
1
|
+
{"version":3,"sources":["../../src/services/normalizer.ts"],"sourcesContent":["import { createHash } from 'crypto';\n\n/**\n * Normalize title for deduplication\n */\nexport function normalizeTitle(title: string): string {\n return title\n .toLowerCase()\n .trim()\n .replace(/\\s+/g, ' ');\n}\n\n/**\n * Normalize content for hashing\n */\nexport function normalizeContent(content: string): string {\n return content\n .trim()\n .replace(/\\r\\n/g, '\\n')\n .replace(/\\r/g, '\\n')\n .replace(/\\n{3,}/g, '\\n\\n');\n}\n\n/**\n * Generate SHA-256 hash of normalized content for deduplication\n */\nexport function hashContent(content: string): string {\n const normalized = normalizeContent(content);\n return createHash('sha256').update(normalized, 'utf8').digest('hex');\n}\n\n/**\n * Normalize tags\n */\nexport function normalizeTags(tags: string[]): string[] {\n const normalized = tags\n .map(tag => tag.toLowerCase().trim())\n .filter(tag => tag.length > 0);\n\n return [...new Set(normalized)];\n}\n\n/**\n * Validate and normalize scope\n */\nexport function normalizeScope(scope?: string): string {\n if (!scope || scope.trim() === '') {\n return 'global';\n }\n return scope.trim().toLowerCase();\n}"],"names":["createHash","normalizeTitle","title","toLowerCase","trim","replace","normalizeContent","content","hashContent","normalized","update","digest","normalizeTags","tags","map","tag","filter","length","Set","normalizeScope","scope"],"mappings":"AAAA,SAASA,UAAU,QAAQ,SAAS;AAEpC;;CAEC,GACD,OAAO,SAASC,eAAeC,KAAa;IACxC,OAAOA,MACFC,WAAW,GACXC,IAAI,GACJC,OAAO,CAAC,QAAQ;AACzB;AAEA;;CAEC,GACD,OAAO,SAASC,iBAAiBC,OAAe;IAC5C,OAAOA,QACFH,IAAI,GACJC,OAAO,CAAC,SAAS,MACjBA,OAAO,CAAC,OAAO,MACfA,OAAO,CAAC,WAAW;AAC5B;AAEA;;CAEC,GACD,OAAO,SAASG,YAAYD,OAAe;IACvC,MAAME,aAAaH,iBAAiBC;IACpC,OAAOP,WAAW,UAAUU,MAAM,CAACD,YAAY,QAAQE,MAAM,CAAC;AAClE;AAEA;;CAEC,GACD,OAAO,SAASC,cAAcC,IAAc;IACxC,MAAMJ,aAAaI,KACdC,GAAG,CAACC,CAAAA,MAAOA,IAAIZ,WAAW,GAAGC,IAAI,IACjCY,MAAM,CAACD,CAAAA,MAAOA,IAAIE,MAAM,GAAG;IAEhC,OAAO;WAAI,IAAIC,IAAIT;KAAY;AACnC;AAEA;;CAEC,GACD,OAAO,SAASU,eAAeC,KAAc;IACzC,IAAI,CAACA,SAASA,MAAMhB,IAAI,OAAO,IAAI;QAC/B,OAAO;IACX;IACA,OAAOgB,MAAMhB,IAAI,GAAGD,WAAW;AACnC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ranker.d.ts","sourceRoot":"","sources":["../../src/services/ranker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"ranker.d.ts","sourceRoot":"","sources":["../../src/services/ranker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,UAAU,eAAe;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,UAAU,cAAc;IACpB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAwCD;;;;GAIG;AACH,wBAAgB,WAAW,CACvB,OAAO,EAAE,eAAe,EAAE,EAC1B,OAAO,EAAE,cAAc,GACxB,gBAAgB,EAAE,CAgCpB"}
|
package/dist/services/ranker.js
CHANGED
|
@@ -1,13 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", {
|
|
3
|
-
value: true
|
|
4
|
-
});
|
|
5
|
-
Object.defineProperty(exports, "rankResults", {
|
|
6
|
-
enumerable: true,
|
|
7
|
-
get: function() {
|
|
8
|
-
return rankResults;
|
|
9
|
-
}
|
|
10
|
-
});
|
|
11
1
|
/**
|
|
12
2
|
* Calculate tag boost based on matching contextTags
|
|
13
3
|
* +10% per matching tag
|
|
@@ -39,7 +29,11 @@ Object.defineProperty(exports, "rankResults", {
|
|
|
39
29
|
}
|
|
40
30
|
return 0;
|
|
41
31
|
}
|
|
42
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Apply ranking formula to search results
|
|
34
|
+
*
|
|
35
|
+
* Formula: final_score = bm25_score × tag_boost + scope_boost
|
|
36
|
+
*/ export function rankResults(results, context) {
|
|
43
37
|
const ranked = results.map((result)=>{
|
|
44
38
|
let tags;
|
|
45
39
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/services/ranker.ts"],"sourcesContent":["import type { SearchResultItem } from '../types';\n\ninterface RawSearchResult {\n id: string;\n title: string;\n content: string;\n tags: string;\n scope: string;\n bm25_score: number;\n}\n\ninterface RankingContext {\n contextTags?: string[];\n queryScope?: string | null;\n}\n\n/**\n * Calculate tag boost based on matching contextTags\n * +10% per matching tag\n */\nfunction calculateTagBoost(itemTags: string[], contextTags: string[]): number {\n if (!contextTags || contextTags.length === 0) {\n return 1.0;\n }\n\n const itemTagsLower = itemTags.map(t => t.toLowerCase());\n const contextTagsLower = contextTags.map(t => t.toLowerCase());\n\n let matchCount = 0;\n for (const tag of contextTagsLower) {\n if (itemTagsLower.includes(tag)) {\n matchCount++;\n }\n }\n\n return 1 + (matchCount * 0.1);\n}\n\n/**\n * Calculate scope boost\n * +0.5 if scope matches query scope\n * +0.2 if global\n * 0 otherwise\n */\nfunction calculateScopeBoost(itemScope: string, queryScope?: string | null): number {\n if (queryScope && itemScope === queryScope) {\n return 0.5;\n }\n if (itemScope === 'global') {\n return 0.2;\n }\n return 0;\n}\n\n/**\n * Apply ranking formula to search results\n * \n * Formula: final_score = bm25_score × tag_boost + scope_boost\n */\nexport function rankResults(\n results: RawSearchResult[],\n context: RankingContext\n): SearchResultItem[] {\n const ranked = results.map(result => {\n let tags: string[];\n try {\n tags = JSON.parse(result.tags) as string[];\n } catch {\n tags = [];\n }\n\n const tagBoost = calculateTagBoost(tags, context.contextTags ?? []);\n const scopeBoost = calculateScopeBoost(result.scope, context.queryScope);\n\n // BM25 returns negative values (closer to 0 = better match)\n // We negate it to make higher values better\n const normalizedBm25 = -result.bm25_score;\n\n const finalScore = (normalizedBm25 * tagBoost) + scopeBoost;\n\n return {\n id: result.id,\n title: result.title,\n content: result.content,\n tags,\n scope: result.scope,\n score: Math.round(finalScore * 1000) / 1000,\n };\n });\n\n // Sort by score descending\n ranked.sort((a, b) => b.score - a.score);\n\n return ranked;\n}\n"],"names":["
|
|
1
|
+
{"version":3,"sources":["../../src/services/ranker.ts"],"sourcesContent":["import type { SearchResultItem } from '../types/index.js';\n\ninterface RawSearchResult {\n id: string;\n title: string;\n content: string;\n tags: string;\n scope: string;\n bm25_score: number;\n}\n\ninterface RankingContext {\n contextTags?: string[];\n queryScope?: string | null;\n}\n\n/**\n * Calculate tag boost based on matching contextTags\n * +10% per matching tag\n */\nfunction calculateTagBoost(itemTags: string[], contextTags: string[]): number {\n if (!contextTags || contextTags.length === 0) {\n return 1.0;\n }\n\n const itemTagsLower = itemTags.map(t => t.toLowerCase());\n const contextTagsLower = contextTags.map(t => t.toLowerCase());\n\n let matchCount = 0;\n for (const tag of contextTagsLower) {\n if (itemTagsLower.includes(tag)) {\n matchCount++;\n }\n }\n\n return 1 + (matchCount * 0.1);\n}\n\n/**\n * Calculate scope boost\n * +0.5 if scope matches query scope\n * +0.2 if global\n * 0 otherwise\n */\nfunction calculateScopeBoost(itemScope: string, queryScope?: string | null): number {\n if (queryScope && itemScope === queryScope) {\n return 0.5;\n }\n if (itemScope === 'global') {\n return 0.2;\n }\n return 0;\n}\n\n/**\n * Apply ranking formula to search results\n * \n * Formula: final_score = bm25_score × tag_boost + scope_boost\n */\nexport function rankResults(\n results: RawSearchResult[],\n context: RankingContext\n): SearchResultItem[] {\n const ranked = results.map(result => {\n let tags: string[];\n try {\n tags = JSON.parse(result.tags) as string[];\n } catch {\n tags = [];\n }\n\n const tagBoost = calculateTagBoost(tags, context.contextTags ?? []);\n const scopeBoost = calculateScopeBoost(result.scope, context.queryScope);\n\n // BM25 returns negative values (closer to 0 = better match)\n // We negate it to make higher values better\n const normalizedBm25 = -result.bm25_score;\n\n const finalScore = (normalizedBm25 * tagBoost) + scopeBoost;\n\n return {\n id: result.id,\n title: result.title,\n content: result.content,\n tags,\n scope: result.scope,\n score: Math.round(finalScore * 1000) / 1000,\n };\n });\n\n // Sort by score descending\n ranked.sort((a, b) => b.score - a.score);\n\n return ranked;\n}\n"],"names":["calculateTagBoost","itemTags","contextTags","length","itemTagsLower","map","t","toLowerCase","contextTagsLower","matchCount","tag","includes","calculateScopeBoost","itemScope","queryScope","rankResults","results","context","ranked","result","tags","JSON","parse","tagBoost","scopeBoost","scope","normalizedBm25","bm25_score","finalScore","id","title","content","score","Math","round","sort","a","b"],"mappings":"AAgBA;;;CAGC,GACD,SAASA,kBAAkBC,QAAkB,EAAEC,WAAqB;IAChE,IAAI,CAACA,eAAeA,YAAYC,MAAM,KAAK,GAAG;QAC1C,OAAO;IACX;IAEA,MAAMC,gBAAgBH,SAASI,GAAG,CAACC,CAAAA,IAAKA,EAAEC,WAAW;IACrD,MAAMC,mBAAmBN,YAAYG,GAAG,CAACC,CAAAA,IAAKA,EAAEC,WAAW;IAE3D,IAAIE,aAAa;IACjB,KAAK,MAAMC,OAAOF,iBAAkB;QAChC,IAAIJ,cAAcO,QAAQ,CAACD,MAAM;YAC7BD;QACJ;IACJ;IAEA,OAAO,IAAKA,aAAa;AAC7B;AAEA;;;;;CAKC,GACD,SAASG,oBAAoBC,SAAiB,EAAEC,UAA0B;IACtE,IAAIA,cAAcD,cAAcC,YAAY;QACxC,OAAO;IACX;IACA,IAAID,cAAc,UAAU;QACxB,OAAO;IACX;IACA,OAAO;AACX;AAEA;;;;CAIC,GACD,OAAO,SAASE,YACZC,OAA0B,EAC1BC,OAAuB;IAEvB,MAAMC,SAASF,QAAQX,GAAG,CAACc,CAAAA;QACvB,IAAIC;QACJ,IAAI;YACAA,OAAOC,KAAKC,KAAK,CAACH,OAAOC,IAAI;QACjC,EAAE,OAAM;YACJA,OAAO,EAAE;QACb;QAEA,MAAMG,WAAWvB,kBAAkBoB,MAAMH,QAAQf,WAAW,IAAI,EAAE;QAClE,MAAMsB,aAAaZ,oBAAoBO,OAAOM,KAAK,EAAER,QAAQH,UAAU;QAEvE,4DAA4D;QAC5D,4CAA4C;QAC5C,MAAMY,iBAAiB,CAACP,OAAOQ,UAAU;QAEzC,MAAMC,aAAa,AAACF,iBAAiBH,WAAYC;QAEjD,OAAO;YACHK,IAAIV,OAAOU,EAAE;YACbC,OAAOX,OAAOW,KAAK;YACnBC,SAASZ,OAAOY,OAAO;YACvBX;YACAK,OAAON,OAAOM,KAAK;YACnBO,OAAOC,KAAKC,KAAK,CAACN,aAAa,QAAQ;QAC3C;IACJ;IAEA,2BAA2B;IAC3BV,OAAOiB,IAAI,CAAC,CAACC,GAAGC,IAAMA,EAAEL,KAAK,GAAGI,EAAEJ,KAAK;IAEvC,OAAOd;AACX"}
|