@ai-devkit/memory 0.1.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.
Files changed (59) hide show
  1. package/README.md +149 -0
  2. package/dist/api.d.ts +20 -0
  3. package/dist/api.d.ts.map +1 -0
  4. package/dist/api.js +46 -0
  5. package/dist/api.js.map +1 -0
  6. package/dist/database/connection.d.ts +27 -0
  7. package/dist/database/connection.d.ts.map +1 -0
  8. package/dist/database/connection.js +107 -0
  9. package/dist/database/connection.js.map +1 -0
  10. package/dist/database/index.d.ts +4 -0
  11. package/dist/database/index.d.ts.map +1 -0
  12. package/dist/database/index.js +37 -0
  13. package/dist/database/index.js.map +1 -0
  14. package/dist/database/migrations/001_initial.sql +50 -0
  15. package/dist/database/schema.d.ts +6 -0
  16. package/dist/database/schema.d.ts.map +1 -0
  17. package/dist/database/schema.js +89 -0
  18. package/dist/database/schema.js.map +1 -0
  19. package/dist/handlers/search.d.ts +3 -0
  20. package/dist/handlers/search.d.ts.map +1 -0
  21. package/dist/handlers/search.js +78 -0
  22. package/dist/handlers/search.js.map +1 -0
  23. package/dist/handlers/store.d.ts +3 -0
  24. package/dist/handlers/store.d.ts.map +1 -0
  25. package/dist/handlers/store.js +71 -0
  26. package/dist/handlers/store.js.map +1 -0
  27. package/dist/index.d.ts +3 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +93 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/server.d.ts +4 -0
  32. package/dist/server.d.ts.map +1 -0
  33. package/dist/server.js +172 -0
  34. package/dist/server.js.map +1 -0
  35. package/dist/services/normalizer.d.ts +21 -0
  36. package/dist/services/normalizer.d.ts.map +1 -0
  37. package/dist/services/normalizer.js +52 -0
  38. package/dist/services/normalizer.js.map +1 -0
  39. package/dist/services/ranker.d.ts +21 -0
  40. package/dist/services/ranker.d.ts.map +1 -0
  41. package/dist/services/ranker.js +70 -0
  42. package/dist/services/ranker.js.map +1 -0
  43. package/dist/services/search.d.ts +29 -0
  44. package/dist/services/search.d.ts.map +1 -0
  45. package/dist/services/search.js +92 -0
  46. package/dist/services/search.js.map +1 -0
  47. package/dist/services/validator.d.ts +11 -0
  48. package/dist/services/validator.d.ts.map +1 -0
  49. package/dist/services/validator.js +144 -0
  50. package/dist/services/validator.js.map +1 -0
  51. package/dist/types/index.d.ts +58 -0
  52. package/dist/types/index.d.ts.map +1 -0
  53. package/dist/types/index.js +6 -0
  54. package/dist/types/index.js.map +1 -0
  55. package/dist/utils/errors.d.ts +21 -0
  56. package/dist/utils/errors.d.ts.map +1 -0
  57. package/dist/utils/errors.js +76 -0
  58. package/dist/utils/errors.js.map +1 -0
  59. package/package.json +67 -0
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "searchKnowledge", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return searchKnowledge;
9
+ }
10
+ });
11
+ const _database = require("../database");
12
+ const _search = require("../services/search");
13
+ const _ranker = require("../services/ranker");
14
+ const _errors = require("../utils/errors");
15
+ const DEFAULT_LIMIT = 5;
16
+ const MAX_LIMIT = 20;
17
+ const MIN_QUERY_LENGTH = 3;
18
+ const MAX_QUERY_LENGTH = 500;
19
+ function searchKnowledge(input) {
20
+ validateSearchInput(input);
21
+ const db = (0, _database.getDatabase)();
22
+ const limit = Math.min(Math.max(input.limit ?? DEFAULT_LIMIT, 1), MAX_LIMIT);
23
+ const ftsQuery = (0, _search.buildFtsQuery)(input.query);
24
+ let rows;
25
+ if (ftsQuery === '') {
26
+ // Empty or invalid query - return recent items
27
+ const { sql, params } = (0, _search.buildSimpleQuery)(input.scope, limit);
28
+ rows = db.query(sql, params);
29
+ } else {
30
+ // Full-text search with BM25
31
+ const { sql, params } = (0, _search.buildSearchQuery)(ftsQuery, input.scope, limit * 2);
32
+ try {
33
+ rows = db.query(sql, params);
34
+ } catch (error) {
35
+ // FTS query syntax error - fallback to simple query
36
+ const { sql: fallbackSql, params: fallbackParams } = (0, _search.buildSimpleQuery)(input.scope, limit);
37
+ rows = db.query(fallbackSql, fallbackParams);
38
+ }
39
+ }
40
+ // Apply ranking with tag and scope boosts
41
+ const ranked = (0, _ranker.rankResults)(rows, {
42
+ contextTags: input.contextTags,
43
+ queryScope: input.scope
44
+ });
45
+ // Limit to requested count
46
+ const results = ranked.slice(0, limit);
47
+ return {
48
+ results,
49
+ totalMatches: ranked.length,
50
+ query: input.query
51
+ };
52
+ }
53
+ function validateSearchInput(input) {
54
+ const errors = [];
55
+ if (!input.query || typeof input.query !== 'string') {
56
+ errors.push('Query is required');
57
+ } else {
58
+ const trimmed = input.query.trim();
59
+ if (trimmed.length < MIN_QUERY_LENGTH) {
60
+ errors.push(`Query must be at least ${MIN_QUERY_LENGTH} characters`);
61
+ }
62
+ if (trimmed.length > MAX_QUERY_LENGTH) {
63
+ errors.push(`Query must be at most ${MAX_QUERY_LENGTH} characters`);
64
+ }
65
+ }
66
+ if (input.limit !== undefined) {
67
+ if (typeof input.limit !== 'number' || input.limit < 1) {
68
+ errors.push('Limit must be a positive number');
69
+ }
70
+ }
71
+ if (errors.length > 0) {
72
+ throw new _errors.ValidationError(errors.join('; '), {
73
+ errors
74
+ });
75
+ }
76
+ }
77
+
78
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/handlers/search.ts"],"sourcesContent":["import { getDatabase } from '../database';\nimport { buildFtsQuery, buildSearchQuery, buildSimpleQuery } from '../services/search';\nimport { rankResults } from '../services/ranker';\nimport { ValidationError } from '../utils/errors';\nimport type { SearchKnowledgeInput, SearchKnowledgeResult } from '../types';\n\nconst DEFAULT_LIMIT = 5;\nconst MAX_LIMIT = 20;\nconst MIN_QUERY_LENGTH = 3;\nconst MAX_QUERY_LENGTH = 500;\n\ninterface RawSearchRow {\n id: string;\n title: string;\n content: string;\n tags: string;\n scope: string;\n bm25_score: number;\n}\n\nexport function searchKnowledge(input: SearchKnowledgeInput): SearchKnowledgeResult {\n validateSearchInput(input);\n\n const db = getDatabase();\n const limit = Math.min(Math.max(input.limit ?? DEFAULT_LIMIT, 1), MAX_LIMIT);\n const ftsQuery = buildFtsQuery(input.query);\n\n let rows: RawSearchRow[];\n\n if (ftsQuery === '') {\n // Empty or invalid query - return recent items\n const { sql, params } = buildSimpleQuery(input.scope, limit);\n rows = db.query<RawSearchRow>(sql, params);\n } else {\n // Full-text search with BM25\n const { sql, params } = buildSearchQuery(ftsQuery, input.scope, limit * 2);\n\n try {\n rows = db.query<RawSearchRow>(sql, params);\n } catch (error) {\n // FTS query syntax error - fallback to simple query\n const { sql: fallbackSql, params: fallbackParams } = buildSimpleQuery(input.scope, limit);\n rows = db.query<RawSearchRow>(fallbackSql, fallbackParams);\n }\n }\n\n // Apply ranking with tag and scope boosts\n const ranked = rankResults(rows, {\n contextTags: input.contextTags,\n queryScope: input.scope,\n });\n\n // Limit to requested count\n const results = ranked.slice(0, limit);\n\n return {\n results,\n totalMatches: ranked.length,\n query: input.query,\n };\n}\n\nfunction validateSearchInput(input: SearchKnowledgeInput): void {\n const errors: string[] = [];\n\n if (!input.query || typeof input.query !== 'string') {\n errors.push('Query is required');\n } else {\n const trimmed = input.query.trim();\n if (trimmed.length < MIN_QUERY_LENGTH) {\n errors.push(`Query must be at least ${MIN_QUERY_LENGTH} characters`);\n }\n if (trimmed.length > MAX_QUERY_LENGTH) {\n errors.push(`Query must be at most ${MAX_QUERY_LENGTH} characters`);\n }\n }\n\n if (input.limit !== undefined) {\n if (typeof input.limit !== 'number' || input.limit < 1) {\n errors.push('Limit must be a positive number');\n }\n }\n\n if (errors.length > 0) {\n throw new ValidationError(errors.join('; '), { errors });\n }\n}\n"],"names":["searchKnowledge","DEFAULT_LIMIT","MAX_LIMIT","MIN_QUERY_LENGTH","MAX_QUERY_LENGTH","input","validateSearchInput","db","getDatabase","limit","Math","min","max","ftsQuery","buildFtsQuery","query","rows","sql","params","buildSimpleQuery","scope","buildSearchQuery","error","fallbackSql","fallbackParams","ranked","rankResults","contextTags","queryScope","results","slice","totalMatches","length","errors","push","trimmed","trim","undefined","ValidationError","join"],"mappings":";;;;+BAoBgBA;;;eAAAA;;;0BApBY;wBACsC;wBACtC;wBACI;AAGhC,MAAMC,gBAAgB;AACtB,MAAMC,YAAY;AAClB,MAAMC,mBAAmB;AACzB,MAAMC,mBAAmB;AAWlB,SAASJ,gBAAgBK,KAA2B;IACvDC,oBAAoBD;IAEpB,MAAME,KAAKC,IAAAA,qBAAW;IACtB,MAAMC,QAAQC,KAAKC,GAAG,CAACD,KAAKE,GAAG,CAACP,MAAMI,KAAK,IAAIR,eAAe,IAAIC;IAClE,MAAMW,WAAWC,IAAAA,qBAAa,EAACT,MAAMU,KAAK;IAE1C,IAAIC;IAEJ,IAAIH,aAAa,IAAI;QACjB,+CAA+C;QAC/C,MAAM,EAAEI,GAAG,EAAEC,MAAM,EAAE,GAAGC,IAAAA,wBAAgB,EAACd,MAAMe,KAAK,EAAEX;QACtDO,OAAOT,GAAGQ,KAAK,CAAeE,KAAKC;IACvC,OAAO;QACH,6BAA6B;QAC7B,MAAM,EAAED,GAAG,EAAEC,MAAM,EAAE,GAAGG,IAAAA,wBAAgB,EAACR,UAAUR,MAAMe,KAAK,EAAEX,QAAQ;QAExE,IAAI;YACAO,OAAOT,GAAGQ,KAAK,CAAeE,KAAKC;QACvC,EAAE,OAAOI,OAAO;YACZ,oDAAoD;YACpD,MAAM,EAAEL,KAAKM,WAAW,EAAEL,QAAQM,cAAc,EAAE,GAAGL,IAAAA,wBAAgB,EAACd,MAAMe,KAAK,EAAEX;YACnFO,OAAOT,GAAGQ,KAAK,CAAeQ,aAAaC;QAC/C;IACJ;IAEA,0CAA0C;IAC1C,MAAMC,SAASC,IAAAA,mBAAW,EAACV,MAAM;QAC7BW,aAAatB,MAAMsB,WAAW;QAC9BC,YAAYvB,MAAMe,KAAK;IAC3B;IAEA,2BAA2B;IAC3B,MAAMS,UAAUJ,OAAOK,KAAK,CAAC,GAAGrB;IAEhC,OAAO;QACHoB;QACAE,cAAcN,OAAOO,MAAM;QAC3BjB,OAAOV,MAAMU,KAAK;IACtB;AACJ;AAEA,SAAST,oBAAoBD,KAA2B;IACpD,MAAM4B,SAAmB,EAAE;IAE3B,IAAI,CAAC5B,MAAMU,KAAK,IAAI,OAAOV,MAAMU,KAAK,KAAK,UAAU;QACjDkB,OAAOC,IAAI,CAAC;IAChB,OAAO;QACH,MAAMC,UAAU9B,MAAMU,KAAK,CAACqB,IAAI;QAChC,IAAID,QAAQH,MAAM,GAAG7B,kBAAkB;YACnC8B,OAAOC,IAAI,CAAC,CAAC,uBAAuB,EAAE/B,iBAAiB,WAAW,CAAC;QACvE;QACA,IAAIgC,QAAQH,MAAM,GAAG5B,kBAAkB;YACnC6B,OAAOC,IAAI,CAAC,CAAC,sBAAsB,EAAE9B,iBAAiB,WAAW,CAAC;QACtE;IACJ;IAEA,IAAIC,MAAMI,KAAK,KAAK4B,WAAW;QAC3B,IAAI,OAAOhC,MAAMI,KAAK,KAAK,YAAYJ,MAAMI,KAAK,GAAG,GAAG;YACpDwB,OAAOC,IAAI,CAAC;QAChB;IACJ;IAEA,IAAID,OAAOD,MAAM,GAAG,GAAG;QACnB,MAAM,IAAIM,uBAAe,CAACL,OAAOM,IAAI,CAAC,OAAO;YAAEN;QAAO;IAC1D;AACJ"}
@@ -0,0 +1,3 @@
1
+ import type { StoreKnowledgeInput, StoreKnowledgeResult } from '../types';
2
+ export declare function storeKnowledge(input: StoreKnowledgeInput): StoreKnowledgeResult;
3
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/handlers/store.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oBAAoB,EAAgB,MAAM,UAAU,CAAC;AAExF,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,oBAAoB,CAwE/E"}
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "storeKnowledge", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return storeKnowledge;
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)();
19
+ const now = new Date().toISOString();
20
+ const normalizedTitle = (0, _normalizer.normalizeTitle)(input.title);
21
+ const scope = (0, _normalizer.normalizeScope)(input.scope);
22
+ const tags = (0, _normalizer.normalizeTags)(input.tags ?? []);
23
+ const contentHash = (0, _normalizer.hashContent)(input.content);
24
+ const id = (0, _uuid.v4)();
25
+ try {
26
+ return db.transaction(()=>{
27
+ const existingByTitle = db.queryOne('SELECT id FROM knowledge WHERE normalized_title = ? AND scope = ?', [
28
+ normalizedTitle,
29
+ scope
30
+ ]);
31
+ if (existingByTitle) {
32
+ throw new _errors.DuplicateError('Knowledge with similar title already exists in this scope', existingByTitle.id, 'title');
33
+ }
34
+ const existingByHash = db.queryOne('SELECT id FROM knowledge WHERE content_hash = ? AND scope = ?', [
35
+ contentHash,
36
+ scope
37
+ ]);
38
+ if (existingByHash) {
39
+ throw new _errors.DuplicateError('Knowledge with identical content already exists in this scope', existingByHash.id, 'content');
40
+ }
41
+ db.execute(`INSERT INTO knowledge (
42
+ id, title, content, tags, scope,
43
+ normalized_title, content_hash, created_at, updated_at
44
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
45
+ id,
46
+ input.title.trim(),
47
+ input.content.trim(),
48
+ JSON.stringify(tags),
49
+ scope,
50
+ normalizedTitle,
51
+ contentHash,
52
+ now,
53
+ now
54
+ ]);
55
+ return {
56
+ success: true,
57
+ id,
58
+ message: 'Knowledge stored successfully'
59
+ };
60
+ });
61
+ } catch (error) {
62
+ if (error instanceof _errors.DuplicateError) {
63
+ throw error;
64
+ }
65
+ throw new _errors.StorageError('Failed to store knowledge', {
66
+ originalError: error instanceof Error ? error.message : String(error)
67
+ });
68
+ }
69
+ }
70
+
71
+ //# sourceMappingURL=store.js.map
@@ -0,0 +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":["storeKnowledge","input","validateStoreInput","db","getDatabase","now","Date","toISOString","normalizedTitle","normalizeTitle","title","scope","normalizeScope","tags","normalizeTags","contentHash","hashContent","content","id","uuidv4","transaction","existingByTitle","queryOne","DuplicateError","existingByHash","execute","trim","JSON","stringify","success","message","error","StorageError","originalError","Error","String"],"mappings":";;;;+BAOgBA;;;eAAAA;;;sBAPa;0BACD;2BACO;4BACwC;wBAC9B;AAGtC,SAASA,eAAeC,KAA0B;IACrDC,IAAAA,6BAAkB,EAACD;IAEnB,MAAME,KAAKC,IAAAA,qBAAW;IACtB,MAAMC,MAAM,IAAIC,OAAOC,WAAW;IAClC,MAAMC,kBAAkBC,IAAAA,0BAAc,EAACR,MAAMS,KAAK;IAClD,MAAMC,QAAQC,IAAAA,0BAAc,EAACX,MAAMU,KAAK;IACxC,MAAME,OAAOC,IAAAA,yBAAa,EAACb,MAAMY,IAAI,IAAI,EAAE;IAC3C,MAAME,cAAcC,IAAAA,uBAAW,EAACf,MAAMgB,OAAO;IAC7C,MAAMC,KAAKC,IAAAA,QAAM;IAEjB,IAAI;QACA,OAAOhB,GAAGiB,WAAW,CAAC;YAClB,MAAMC,kBAAkBlB,GAAGmB,QAAQ,CAC/B,qEACA;gBAACd;gBAAiBG;aAAM;YAG5B,IAAIU,iBAAiB;gBACjB,MAAM,IAAIE,sBAAc,CACpB,6DACAF,gBAAgBH,EAAE,EAClB;YAER;YAEA,MAAMM,iBAAiBrB,GAAGmB,QAAQ,CAC9B,iEACA;gBAACP;gBAAaJ;aAAM;YAGxB,IAAIa,gBAAgB;gBAChB,MAAM,IAAID,sBAAc,CACpB,iEACAC,eAAeN,EAAE,EACjB;YAER;YAEAf,GAAGsB,OAAO,CACN,CAAC;;;4CAG2B,CAAC,EAC7B;gBACIP;gBACAjB,MAAMS,KAAK,CAACgB,IAAI;gBAChBzB,MAAMgB,OAAO,CAACS,IAAI;gBAClBC,KAAKC,SAAS,CAACf;gBACfF;gBACAH;gBACAO;gBACAV;gBACAA;aACH;YAGL,OAAO;gBACHwB,SAAS;gBACTX;gBACAY,SAAS;YACb;QACJ;IACJ,EAAE,OAAOC,OAAO;QACZ,IAAIA,iBAAiBR,sBAAc,EAAE;YACjC,MAAMQ;QACV;QACA,MAAM,IAAIC,oBAAY,CAClB,6BACA;YAAEC,eAAeF,iBAAiBG,QAAQH,MAAMD,OAAO,GAAGK,OAAOJ;QAAO;IAEhF;AACJ"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ const _commander = require("commander");
7
+ const _api = require("./api");
8
+ function _getRequireWildcardCache(nodeInterop) {
9
+ if (typeof WeakMap !== "function") return null;
10
+ var cacheBabelInterop = new WeakMap();
11
+ var cacheNodeInterop = new WeakMap();
12
+ return (_getRequireWildcardCache = function(nodeInterop) {
13
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
14
+ })(nodeInterop);
15
+ }
16
+ function _interop_require_wildcard(obj, nodeInterop) {
17
+ if (!nodeInterop && obj && obj.__esModule) {
18
+ return obj;
19
+ }
20
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
21
+ return {
22
+ default: obj
23
+ };
24
+ }
25
+ var cache = _getRequireWildcardCache(nodeInterop);
26
+ if (cache && cache.has(obj)) {
27
+ return cache.get(obj);
28
+ }
29
+ var newObj = {
30
+ __proto__: null
31
+ };
32
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
33
+ for(var key in obj){
34
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
35
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
36
+ if (desc && (desc.get || desc.set)) {
37
+ Object.defineProperty(newObj, key, desc);
38
+ } else {
39
+ newObj[key] = obj[key];
40
+ }
41
+ }
42
+ }
43
+ newObj.default = obj;
44
+ if (cache) {
45
+ cache.set(obj, newObj);
46
+ }
47
+ return newObj;
48
+ }
49
+ const program = new _commander.Command();
50
+ program.name('ai-devkit-memory').description('Knowledge memory service for AI agents').version('0.1.0');
51
+ program.command('store').description('Store a new knowledge item').requiredOption('-t, --title <title>', 'Title of the knowledge item (10-100 chars)').requiredOption('-c, --content <content>', 'Content of the knowledge item (50-5000 chars)').option('--tags <tags>', 'Comma-separated tags (e.g., "api,backend")').option('-s, --scope <scope>', 'Scope: global, project:<name>, or repo:<name>', 'global').action((options)=>{
52
+ try {
53
+ const result = (0, _api.memoryStoreCommand)(options);
54
+ console.log(JSON.stringify(result, null, 2));
55
+ } catch (error) {
56
+ console.error(JSON.stringify({
57
+ success: false,
58
+ error: error instanceof Error ? error.message : String(error)
59
+ }, null, 2));
60
+ process.exit(1);
61
+ }
62
+ });
63
+ program.command('search').description('Search for knowledge items').requiredOption('-q, --query <query>', 'Search query (3-500 chars)').option('--tags <tags>', 'Comma-separated context tags to boost results').option('-s, --scope <scope>', 'Scope filter').option('-l, --limit <limit>', 'Maximum results (1-20)', '5').action((options)=>{
64
+ try {
65
+ const result = (0, _api.memorySearchCommand)({
66
+ ...options,
67
+ limit: options.limit ? parseInt(options.limit, 10) : 5
68
+ });
69
+ console.log(JSON.stringify(result, null, 2));
70
+ } catch (error) {
71
+ console.error(JSON.stringify({
72
+ success: false,
73
+ error: error instanceof Error ? error.message : String(error)
74
+ }, null, 2));
75
+ process.exit(1);
76
+ }
77
+ });
78
+ program.command('serve').description('Start the MCP server (default mode)').action(async ()=>{
79
+ const { runServer } = await Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("./server")));
80
+ await runServer();
81
+ });
82
+ // Default to serve mode if no command specified
83
+ if (process.argv.length === 2) {
84
+ const { runServer } = require('./server');
85
+ runServer().catch((error)=>{
86
+ console.error('Failed to start server:', error);
87
+ process.exit(1);
88
+ });
89
+ } else {
90
+ program.parse();
91
+ }
92
+
93
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport { memoryStoreCommand, memorySearchCommand } from './api';\nimport type { MemoryStoreOptions, MemorySearchOptions } from './api';\n\nconst program = new Command();\n\nprogram\n .name('ai-devkit-memory')\n .description('Knowledge memory service for AI agents')\n .version('0.1.0');\n\nprogram\n .command('store')\n .description('Store a new knowledge item')\n .requiredOption('-t, --title <title>', 'Title of the knowledge item (10-100 chars)')\n .requiredOption('-c, --content <content>', 'Content of the knowledge item (50-5000 chars)')\n .option('--tags <tags>', 'Comma-separated tags (e.g., \"api,backend\")')\n .option('-s, --scope <scope>', 'Scope: global, project:<name>, or repo:<name>', 'global')\n .action((options: MemoryStoreOptions) => {\n try {\n const result = memoryStoreCommand(options);\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.error(JSON.stringify({\n success: false,\n error: error instanceof Error ? error.message : String(error)\n }, null, 2));\n process.exit(1);\n }\n });\n\nprogram\n .command('search')\n .description('Search for knowledge items')\n .requiredOption('-q, --query <query>', 'Search query (3-500 chars)')\n .option('--tags <tags>', 'Comma-separated context tags to boost results')\n .option('-s, --scope <scope>', 'Scope filter')\n .option('-l, --limit <limit>', 'Maximum results (1-20)', '5')\n .action((options: MemorySearchOptions & { limit?: string }) => {\n try {\n const result = memorySearchCommand({\n ...options,\n limit: options.limit ? parseInt(options.limit, 10) : 5,\n });\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.error(JSON.stringify({\n success: false,\n error: error instanceof Error ? error.message : String(error)\n }, null, 2));\n process.exit(1);\n }\n });\n\nprogram\n .command('serve')\n .description('Start the MCP server (default mode)')\n .action(async () => {\n const { runServer } = await import('./server');\n await runServer();\n });\n\n// Default to serve mode if no command specified\nif (process.argv.length === 2) {\n const { runServer } = require('./server');\n runServer().catch((error: Error) => {\n console.error('Failed to start server:', error);\n process.exit(1);\n });\n} else {\n program.parse();\n}\n"],"names":["program","Command","name","description","version","command","requiredOption","option","action","options","result","memoryStoreCommand","console","log","JSON","stringify","error","success","Error","message","String","process","exit","memorySearchCommand","limit","parseInt","runServer","argv","length","require","catch","parse"],"mappings":";;;;;2BAEwB;qBACgC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGxD,MAAMA,UAAU,IAAIC,kBAAO;AAE3BD,QACKE,IAAI,CAAC,oBACLC,WAAW,CAAC,0CACZC,OAAO,CAAC;AAEbJ,QACKK,OAAO,CAAC,SACRF,WAAW,CAAC,8BACZG,cAAc,CAAC,uBAAuB,8CACtCA,cAAc,CAAC,2BAA2B,iDAC1CC,MAAM,CAAC,iBAAiB,8CACxBA,MAAM,CAAC,uBAAuB,iDAAiD,UAC/EC,MAAM,CAAC,CAACC;IACL,IAAI;QACA,MAAMC,SAASC,IAAAA,uBAAkB,EAACF;QAClCG,QAAQC,GAAG,CAACC,KAAKC,SAAS,CAACL,QAAQ,MAAM;IAC7C,EAAE,OAAOM,OAAO;QACZJ,QAAQI,KAAK,CAACF,KAAKC,SAAS,CAAC;YACzBE,SAAS;YACTD,OAAOA,iBAAiBE,QAAQF,MAAMG,OAAO,GAAGC,OAAOJ;QAC3D,GAAG,MAAM;QACTK,QAAQC,IAAI,CAAC;IACjB;AACJ;AAEJtB,QACKK,OAAO,CAAC,UACRF,WAAW,CAAC,8BACZG,cAAc,CAAC,uBAAuB,8BACtCC,MAAM,CAAC,iBAAiB,iDACxBA,MAAM,CAAC,uBAAuB,gBAC9BA,MAAM,CAAC,uBAAuB,0BAA0B,KACxDC,MAAM,CAAC,CAACC;IACL,IAAI;QACA,MAAMC,SAASa,IAAAA,wBAAmB,EAAC;YAC/B,GAAGd,OAAO;YACVe,OAAOf,QAAQe,KAAK,GAAGC,SAAShB,QAAQe,KAAK,EAAE,MAAM;QACzD;QACAZ,QAAQC,GAAG,CAACC,KAAKC,SAAS,CAACL,QAAQ,MAAM;IAC7C,EAAE,OAAOM,OAAO;QACZJ,QAAQI,KAAK,CAACF,KAAKC,SAAS,CAAC;YACzBE,SAAS;YACTD,OAAOA,iBAAiBE,QAAQF,MAAMG,OAAO,GAAGC,OAAOJ;QAC3D,GAAG,MAAM;QACTK,QAAQC,IAAI,CAAC;IACjB;AACJ;AAEJtB,QACKK,OAAO,CAAC,SACRF,WAAW,CAAC,uCACZK,MAAM,CAAC;IACJ,MAAM,EAAEkB,SAAS,EAAE,GAAG,MAAM,mEAAA,QAAO;IACnC,MAAMA;AACV;AAEJ,gDAAgD;AAChD,IAAIL,QAAQM,IAAI,CAACC,MAAM,KAAK,GAAG;IAC3B,MAAM,EAAEF,SAAS,EAAE,GAAGG,QAAQ;IAC9BH,YAAYI,KAAK,CAAC,CAACd;QACfJ,QAAQI,KAAK,CAAC,2BAA2BA;QACzCK,QAAQC,IAAI,CAAC;IACjB;AACJ,OAAO;IACHtB,QAAQ+B,KAAK;AACjB"}
@@ -0,0 +1,4 @@
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+ export declare function createServer(): Server;
3
+ export declare function runServer(): Promise<void>;
4
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAsEnE,wBAAgB,YAAY,IAAI,MAAM,CA8ErC;AAED,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAI/C"}
package/dist/server.js ADDED
@@ -0,0 +1,172 @@
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 createServer () {
13
+ return createServer;
14
+ },
15
+ get runServer () {
16
+ return runServer;
17
+ }
18
+ });
19
+ const _index = require("@modelcontextprotocol/sdk/server/index.js");
20
+ const _stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
21
+ const _types = require("@modelcontextprotocol/sdk/types.js");
22
+ const _store = require("./handlers/store");
23
+ const _search = require("./handlers/search");
24
+ const _errors = require("./utils/errors");
25
+ const SERVER_NAME = 'ai-devkit-memory';
26
+ const SERVER_VERSION = '0.1.0';
27
+ const STORE_TOOL = {
28
+ name: 'memory.storeKnowledge',
29
+ description: 'Store a new knowledge item. Use this to save actionable guidelines, rules, or patterns for future reference.',
30
+ inputSchema: {
31
+ type: 'object',
32
+ properties: {
33
+ title: {
34
+ type: 'string',
35
+ description: 'Short, explicit description of the rule (5-12 words, 10-100 chars)'
36
+ },
37
+ content: {
38
+ type: 'string',
39
+ description: 'Detailed explanation in markdown format. Supports code blocks and examples. (50-5000 chars)'
40
+ },
41
+ tags: {
42
+ type: 'array',
43
+ items: {
44
+ type: 'string'
45
+ },
46
+ description: 'Optional domain keywords (e.g., ["api", "backend"]). Max 10 tags.'
47
+ },
48
+ scope: {
49
+ type: 'string',
50
+ description: 'Optional scope: "global", "project:<name>", or "repo:<name>". Default: "global"'
51
+ }
52
+ },
53
+ required: [
54
+ 'title',
55
+ 'content'
56
+ ]
57
+ }
58
+ };
59
+ const SEARCH_TOOL = {
60
+ name: 'memory.searchKnowledge',
61
+ description: 'Search for relevant knowledge based on a task description. Returns ranked results.',
62
+ inputSchema: {
63
+ type: 'object',
64
+ properties: {
65
+ query: {
66
+ type: 'string',
67
+ description: 'Natural language task description to search for relevant knowledge (3-500 chars)'
68
+ },
69
+ contextTags: {
70
+ type: 'array',
71
+ items: {
72
+ type: 'string'
73
+ },
74
+ description: 'Optional tags to boost matching results (e.g., ["api", "backend"])'
75
+ },
76
+ scope: {
77
+ type: 'string',
78
+ description: 'Optional project/repo scope filter. Results from this scope are prioritized.'
79
+ },
80
+ limit: {
81
+ type: 'number',
82
+ description: 'Maximum number of results to return (1-20, default: 5)'
83
+ }
84
+ },
85
+ required: [
86
+ 'query'
87
+ ]
88
+ }
89
+ };
90
+ function createServer() {
91
+ const server = new _index.Server({
92
+ name: SERVER_NAME,
93
+ version: SERVER_VERSION
94
+ }, {
95
+ capabilities: {
96
+ tools: {}
97
+ }
98
+ });
99
+ // List available tools
100
+ server.setRequestHandler(_types.ListToolsRequestSchema, async ()=>{
101
+ return {
102
+ tools: [
103
+ STORE_TOOL,
104
+ SEARCH_TOOL
105
+ ]
106
+ };
107
+ });
108
+ // Handle tool calls
109
+ server.setRequestHandler(_types.CallToolRequestSchema, async (request)=>{
110
+ const { name, arguments: args } = request.params;
111
+ try {
112
+ if (name === 'memory.storeKnowledge') {
113
+ const input = args;
114
+ const result = (0, _store.storeKnowledge)(input);
115
+ return {
116
+ content: [
117
+ {
118
+ type: 'text',
119
+ text: JSON.stringify(result, null, 2)
120
+ }
121
+ ]
122
+ };
123
+ }
124
+ if (name === 'memory.searchKnowledge') {
125
+ const input = args;
126
+ const result = (0, _search.searchKnowledge)(input);
127
+ return {
128
+ content: [
129
+ {
130
+ type: 'text',
131
+ text: JSON.stringify(result, null, 2)
132
+ }
133
+ ]
134
+ };
135
+ }
136
+ return {
137
+ content: [
138
+ {
139
+ type: 'text',
140
+ text: JSON.stringify({
141
+ error: 'UNKNOWN_TOOL',
142
+ message: `Unknown tool: ${name}`
143
+ })
144
+ }
145
+ ],
146
+ isError: true
147
+ };
148
+ } catch (error) {
149
+ const errorResponse = error instanceof _errors.KnowledgeMemoryError ? error.toJSON() : {
150
+ error: 'INTERNAL_ERROR',
151
+ message: error instanceof Error ? error.message : String(error)
152
+ };
153
+ return {
154
+ content: [
155
+ {
156
+ type: 'text',
157
+ text: JSON.stringify(errorResponse, null, 2)
158
+ }
159
+ ],
160
+ isError: true
161
+ };
162
+ }
163
+ });
164
+ return server;
165
+ }
166
+ async function runServer() {
167
+ const server = createServer();
168
+ const transport = new _stdio.StdioServerTransport();
169
+ await server.connect(transport);
170
+ }
171
+
172
+ //# sourceMappingURL=server.js.map
@@ -0,0 +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 { KnowledgeMemoryError } from './utils/errors';\nimport type { StoreKnowledgeInput, SearchKnowledgeInput } 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 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 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, 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 if (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.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":["createServer","runServer","SERVER_NAME","SERVER_VERSION","STORE_TOOL","name","description","inputSchema","type","properties","title","content","tags","items","scope","required","SEARCH_TOOL","query","contextTags","limit","server","Server","version","capabilities","tools","setRequestHandler","ListToolsRequestSchema","CallToolRequestSchema","request","arguments","args","params","input","result","storeKnowledge","text","JSON","stringify","searchKnowledge","error","message","isError","errorResponse","KnowledgeMemoryError","toJSON","Error","String","transport","StdioServerTransport","connect"],"mappings":";;;;;;;;;;;QAsEgBA;eAAAA;;QAgFMC;eAAAA;;;uBAtJC;uBACc;uBAI9B;uBACwB;wBACC;wBACK;AAGrC,MAAMC,cAAc;AACpB,MAAMC,iBAAiB;AAEvB,MAAMC,aAAa;IACfC,MAAM;IACNC,aAAa;IACbC,aAAa;QACTC,MAAM;QACNC,YAAY;YACRC,OAAO;gBACHF,MAAM;gBACNF,aAAa;YACjB;YACAK,SAAS;gBACLH,MAAM;gBACNF,aAAa;YACjB;YACAM,MAAM;gBACFJ,MAAM;gBACNK,OAAO;oBAAEL,MAAM;gBAAS;gBACxBF,aAAa;YACjB;YACAQ,OAAO;gBACHN,MAAM;gBACNF,aAAa;YACjB;QACJ;QACAS,UAAU;YAAC;YAAS;SAAU;IAClC;AACJ;AAEA,MAAMC,cAAc;IAChBX,MAAM;IACNC,aAAa;IACbC,aAAa;QACTC,MAAM;QACNC,YAAY;YACRQ,OAAO;gBACHT,MAAM;gBACNF,aAAa;YACjB;YACAY,aAAa;gBACTV,MAAM;gBACNK,OAAO;oBAAEL,MAAM;gBAAS;gBACxBF,aAAa;YACjB;YACAQ,OAAO;gBACHN,MAAM;gBACNF,aAAa;YACjB;YACAa,OAAO;gBACHX,MAAM;gBACNF,aAAa;YACjB;QACJ;QACAS,UAAU;YAAC;SAAQ;IACvB;AACJ;AAEO,SAASf;IACZ,MAAMoB,SAAS,IAAIC,aAAM,CACrB;QACIhB,MAAMH;QACNoB,SAASnB;IACb,GACA;QACIoB,cAAc;YACVC,OAAO,CAAC;QACZ;IACJ;IAGJ,uBAAuB;IACvBJ,OAAOK,iBAAiB,CAACC,6BAAsB,EAAE;QAC7C,OAAO;YACHF,OAAO;gBAACpB;gBAAYY;aAAY;QACpC;IACJ;IAEA,oBAAoB;IACpBI,OAAOK,iBAAiB,CAACE,4BAAqB,EAAE,OAAOC;QACnD,MAAM,EAAEvB,IAAI,EAAEwB,WAAWC,IAAI,EAAE,GAAGF,QAAQG,MAAM;QAEhD,IAAI;YACA,IAAI1B,SAAS,yBAAyB;gBAClC,MAAM2B,QAAQF;gBACd,MAAMG,SAASC,IAAAA,qBAAc,EAACF;gBAC9B,OAAO;oBACHrB,SAAS;wBACL;4BACIH,MAAM;4BACN2B,MAAMC,KAAKC,SAAS,CAACJ,QAAQ,MAAM;wBACvC;qBACH;gBACL;YACJ;YAEA,IAAI5B,SAAS,0BAA0B;gBACnC,MAAM2B,QAAQF;gBACd,MAAMG,SAASK,IAAAA,uBAAe,EAACN;gBAC/B,OAAO;oBACHrB,SAAS;wBACL;4BACIH,MAAM;4BACN2B,MAAMC,KAAKC,SAAS,CAACJ,QAAQ,MAAM;wBACvC;qBACH;gBACL;YACJ;YAEA,OAAO;gBACHtB,SAAS;oBACL;wBACIH,MAAM;wBACN2B,MAAMC,KAAKC,SAAS,CAAC;4BAAEE,OAAO;4BAAgBC,SAAS,CAAC,cAAc,EAAEnC,MAAM;wBAAC;oBACnF;iBACH;gBACDoC,SAAS;YACb;QACJ,EAAE,OAAOF,OAAO;YACZ,MAAMG,gBAAgBH,iBAAiBI,4BAAoB,GACrDJ,MAAMK,MAAM,KACZ;gBAAEL,OAAO;gBAAkBC,SAASD,iBAAiBM,QAAQN,MAAMC,OAAO,GAAGM,OAAOP;YAAO;YAEjG,OAAO;gBACH5B,SAAS;oBACL;wBACIH,MAAM;wBACN2B,MAAMC,KAAKC,SAAS,CAACK,eAAe,MAAM;oBAC9C;iBACH;gBACDD,SAAS;YACb;QACJ;IACJ;IAEA,OAAOrB;AACX;AAEO,eAAenB;IAClB,MAAMmB,SAASpB;IACf,MAAM+C,YAAY,IAAIC,2BAAoB;IAC1C,MAAM5B,OAAO6B,OAAO,CAACF;AACzB"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Normalize title for deduplication
3
+ */
4
+ export declare function normalizeTitle(title: string): string;
5
+ /**
6
+ * Normalize content for hashing
7
+ */
8
+ export declare function normalizeContent(content: string): string;
9
+ /**
10
+ * Generate SHA-256 hash of normalized content for deduplication
11
+ */
12
+ export declare function hashContent(content: string): string;
13
+ /**
14
+ * Normalize tags
15
+ */
16
+ export declare function normalizeTags(tags: string[]): string[];
17
+ /**
18
+ * Validate and normalize scope
19
+ */
20
+ export declare function normalizeScope(scope?: string): string;
21
+ //# sourceMappingURL=normalizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalizer.d.ts","sourceRoot":"","sources":["../../src/services/normalizer.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKpD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAMxD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGnD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAMtD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAKrD"}
@@ -0,0 +1,52 @@
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 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) {
30
+ return title.toLowerCase().trim().replace(/\s+/g, ' ');
31
+ }
32
+ function normalizeContent(content) {
33
+ return content.trim().replace(/\r\n/g, '\n').replace(/\r/g, '\n').replace(/\n{3,}/g, '\n\n');
34
+ }
35
+ function hashContent(content) {
36
+ const normalized = normalizeContent(content);
37
+ return (0, _crypto.createHash)('sha256').update(normalized, 'utf8').digest('hex');
38
+ }
39
+ function normalizeTags(tags) {
40
+ const normalized = tags.map((tag)=>tag.toLowerCase().trim()).filter((tag)=>tag.length > 0);
41
+ return [
42
+ ...new Set(normalized)
43
+ ];
44
+ }
45
+ function normalizeScope(scope) {
46
+ if (!scope || scope.trim() === '') {
47
+ return 'global';
48
+ }
49
+ return scope.trim().toLowerCase();
50
+ }
51
+
52
+ //# sourceMappingURL=normalizer.js.map
@@ -0,0 +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":["hashContent","normalizeContent","normalizeScope","normalizeTags","normalizeTitle","title","toLowerCase","trim","replace","content","normalized","createHash","update","digest","tags","map","tag","filter","length","Set","scope"],"mappings":";;;;;;;;;;;QA0BgBA;eAAAA;;QAXAC;eAAAA;;QA8BAC;eAAAA;;QAXAC;eAAAA;;QA7BAC;eAAAA;;;wBALW;AAKpB,SAASA,eAAeC,KAAa;IACxC,OAAOA,MACFC,WAAW,GACXC,IAAI,GACJC,OAAO,CAAC,QAAQ;AACzB;AAKO,SAASP,iBAAiBQ,OAAe;IAC5C,OAAOA,QACFF,IAAI,GACJC,OAAO,CAAC,SAAS,MACjBA,OAAO,CAAC,OAAO,MACfA,OAAO,CAAC,WAAW;AAC5B;AAKO,SAASR,YAAYS,OAAe;IACvC,MAAMC,aAAaT,iBAAiBQ;IACpC,OAAOE,IAAAA,kBAAU,EAAC,UAAUC,MAAM,CAACF,YAAY,QAAQG,MAAM,CAAC;AAClE;AAKO,SAASV,cAAcW,IAAc;IACxC,MAAMJ,aAAaI,KACdC,GAAG,CAACC,CAAAA,MAAOA,IAAIV,WAAW,GAAGC,IAAI,IACjCU,MAAM,CAACD,CAAAA,MAAOA,IAAIE,MAAM,GAAG;IAEhC,OAAO;WAAI,IAAIC,IAAIT;KAAY;AACnC;AAKO,SAASR,eAAekB,KAAc;IACzC,IAAI,CAACA,SAASA,MAAMb,IAAI,OAAO,IAAI;QAC/B,OAAO;IACX;IACA,OAAOa,MAAMb,IAAI,GAAGD,WAAW;AACnC"}
@@ -0,0 +1,21 @@
1
+ import type { SearchResultItem } from '../types';
2
+ interface RawSearchResult {
3
+ id: string;
4
+ title: string;
5
+ content: string;
6
+ tags: string;
7
+ scope: string;
8
+ bm25_score: number;
9
+ }
10
+ interface RankingContext {
11
+ contextTags?: string[];
12
+ queryScope?: string | null;
13
+ }
14
+ /**
15
+ * Apply ranking formula to search results
16
+ *
17
+ * Formula: final_score = bm25_score × tag_boost + scope_boost
18
+ */
19
+ export declare function rankResults(results: RawSearchResult[], context: RankingContext): SearchResultItem[];
20
+ export {};
21
+ //# sourceMappingURL=ranker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ranker.d.ts","sourceRoot":"","sources":["../../src/services/ranker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAEjD,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"}