@ai-devkit/memory 0.13.0 → 0.15.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/dist/api.d.ts CHANGED
@@ -1,9 +1,11 @@
1
1
  import { storeKnowledge } from './handlers/store.js';
2
2
  import { searchKnowledge } from './handlers/search.js';
3
3
  import { updateKnowledge } from './handlers/update.js';
4
- import type { StoreKnowledgeInput, SearchKnowledgeInput, StoreKnowledgeResult, SearchKnowledgeResult, UpdateKnowledgeInput, UpdateKnowledgeResult } from './types/index.js';
5
- export { storeKnowledge, searchKnowledge, updateKnowledge };
6
- export type { StoreKnowledgeInput, SearchKnowledgeInput, StoreKnowledgeResult, SearchKnowledgeResult, UpdateKnowledgeInput, UpdateKnowledgeResult };
4
+ import { listKnowledge } from './handlers/list.js';
5
+ import { getKnowledgeSummary } from './handlers/summary.js';
6
+ import type { StoreKnowledgeInput, SearchKnowledgeInput, StoreKnowledgeResult, SearchKnowledgeResult, UpdateKnowledgeInput, UpdateKnowledgeResult, ListKnowledgeInput, ListKnowledgeResult, ListKnowledgeSort, KnowledgeSummaryResult, KnowledgeItem } from './types/index.js';
7
+ export { storeKnowledge, searchKnowledge, updateKnowledge, listKnowledge, getKnowledgeSummary };
8
+ export type { StoreKnowledgeInput, SearchKnowledgeInput, StoreKnowledgeResult, SearchKnowledgeResult, UpdateKnowledgeInput, UpdateKnowledgeResult, ListKnowledgeInput, ListKnowledgeResult, ListKnowledgeSort, KnowledgeSummaryResult, KnowledgeItem };
7
9
  export interface MemoryStoreOptions {
8
10
  title: string;
9
11
  content: string;
@@ -26,7 +28,21 @@ export interface MemorySearchOptions {
26
28
  limit?: number;
27
29
  dbPath?: string;
28
30
  }
31
+ export interface MemoryListOptions {
32
+ query?: string;
33
+ tags?: string;
34
+ scope?: string;
35
+ limit?: number;
36
+ offset?: number;
37
+ sort?: ListKnowledgeSort;
38
+ dbPath?: string;
39
+ }
40
+ export interface MemorySummaryOptions {
41
+ dbPath?: string;
42
+ }
29
43
  export declare function memoryStoreCommand(options: MemoryStoreOptions): StoreKnowledgeResult;
30
44
  export declare function memoryUpdateCommand(options: MemoryUpdateOptions): UpdateKnowledgeResult;
31
45
  export declare function memorySearchCommand(options: MemorySearchOptions): SearchKnowledgeResult;
46
+ export declare function memoryListCommand(options?: MemoryListOptions): ListKnowledgeResult;
47
+ export declare function memorySummaryCommand(options?: MemorySummaryOptions): KnowledgeSummaryResult;
32
48
  //# sourceMappingURL=api.d.ts.map
package/dist/api.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,OAAO,KAAK,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAE5K,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,eAAe,EAAE,CAAC;AAC5D,YAAY,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,CAAC;AAGpJ,MAAM,WAAW,kBAAkB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,kBAAkB,GAAG,oBAAoB,CAcpF;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,mBAAmB,GAAG,qBAAqB,CAevF;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,mBAAmB,GAAG,qBAAqB,CAcvF"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,KAAK,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAE/Q,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,eAAe,EAAE,aAAa,EAAE,mBAAmB,EAAE,CAAC;AAChG,YAAY,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,aAAa,EAAE,CAAC;AAGvP,MAAM,WAAW,kBAAkB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,kBAAkB,GAAG,oBAAoB,CAcpF;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,mBAAmB,GAAG,qBAAqB,CAevF;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,mBAAmB,GAAG,qBAAqB,CAcvF;AAED,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,iBAAsB,GAAG,mBAAmB,CAgBtF;AAED,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,oBAAyB,GAAG,sBAAsB,CAO/F"}
package/dist/api.js CHANGED
@@ -1,8 +1,10 @@
1
1
  import { storeKnowledge } from './handlers/store.js';
2
2
  import { searchKnowledge } from './handlers/search.js';
3
3
  import { updateKnowledge } from './handlers/update.js';
4
+ import { listKnowledge } from './handlers/list.js';
5
+ import { getKnowledgeSummary } from './handlers/summary.js';
4
6
  import { closeDatabase, getDatabase } from './database/index.js';
5
- export { storeKnowledge, searchKnowledge, updateKnowledge };
7
+ export { storeKnowledge, searchKnowledge, updateKnowledge, listKnowledge, getKnowledgeSummary };
6
8
  export function memoryStoreCommand(options) {
7
9
  try {
8
10
  getDatabase({
@@ -52,5 +54,33 @@ export function memorySearchCommand(options) {
52
54
  closeDatabase();
53
55
  }
54
56
  }
57
+ export function memoryListCommand(options = {}) {
58
+ try {
59
+ getDatabase({
60
+ dbPath: options.dbPath
61
+ });
62
+ const input = {
63
+ query: options.query,
64
+ tags: options.tags ? options.tags.split(',').map((t)=>t.trim()) : undefined,
65
+ scope: options.scope,
66
+ limit: options.limit,
67
+ offset: options.offset,
68
+ sort: options.sort
69
+ };
70
+ return listKnowledge(input);
71
+ } finally{
72
+ closeDatabase();
73
+ }
74
+ }
75
+ export function memorySummaryCommand(options = {}) {
76
+ try {
77
+ getDatabase({
78
+ dbPath: options.dbPath
79
+ });
80
+ return getKnowledgeSummary();
81
+ } finally{
82
+ closeDatabase();
83
+ }
84
+ }
55
85
 
56
86
  //# sourceMappingURL=api.js.map
package/dist/api.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/api.ts"],"sourcesContent":["import { storeKnowledge } from './handlers/store.js';\nimport { searchKnowledge } from './handlers/search.js';\nimport { updateKnowledge } from './handlers/update.js';\nimport { closeDatabase, getDatabase } from './database/index.js';\nimport type { StoreKnowledgeInput, SearchKnowledgeInput, StoreKnowledgeResult, SearchKnowledgeResult, UpdateKnowledgeInput, UpdateKnowledgeResult } from './types/index.js';\n\nexport { storeKnowledge, searchKnowledge, updateKnowledge };\nexport type { StoreKnowledgeInput, SearchKnowledgeInput, StoreKnowledgeResult, SearchKnowledgeResult, UpdateKnowledgeInput, UpdateKnowledgeResult };\n\n// CLI command handlers for integration with main ai-devkit CLI\nexport interface MemoryStoreOptions {\n title: string;\n content: string;\n tags?: string;\n scope?: string;\n dbPath?: string;\n}\n\nexport interface MemoryUpdateOptions {\n id: string;\n title?: string;\n content?: string;\n tags?: string;\n scope?: string;\n dbPath?: string;\n}\n\nexport interface MemorySearchOptions {\n query: string;\n tags?: string;\n scope?: string;\n limit?: number;\n dbPath?: string;\n}\n\nexport function memoryStoreCommand(options: MemoryStoreOptions): StoreKnowledgeResult {\n try {\n getDatabase({ dbPath: options.dbPath });\n const input: StoreKnowledgeInput = {\n title: options.title,\n content: options.content,\n tags: options.tags ? options.tags.split(',').map(t => t.trim()) : undefined,\n scope: options.scope,\n };\n\n return storeKnowledge(input);\n } finally {\n closeDatabase();\n }\n}\n\nexport function memoryUpdateCommand(options: MemoryUpdateOptions): UpdateKnowledgeResult {\n try {\n getDatabase({ dbPath: options.dbPath });\n const input: UpdateKnowledgeInput = {\n id: options.id,\n title: options.title,\n content: options.content,\n tags: options.tags ? options.tags.split(',').map(t => t.trim()) : undefined,\n scope: options.scope,\n };\n\n return updateKnowledge(input);\n } finally {\n closeDatabase();\n }\n}\n\nexport function memorySearchCommand(options: MemorySearchOptions): SearchKnowledgeResult {\n try {\n getDatabase({ dbPath: options.dbPath });\n const input: SearchKnowledgeInput = {\n query: options.query,\n contextTags: options.tags ? options.tags.split(',').map(t => t.trim()) : undefined,\n scope: options.scope,\n limit: options.limit,\n };\n\n return searchKnowledge(input);\n } finally {\n closeDatabase();\n }\n}\n"],"names":["storeKnowledge","searchKnowledge","updateKnowledge","closeDatabase","getDatabase","memoryStoreCommand","options","dbPath","input","title","content","tags","split","map","t","trim","undefined","scope","memoryUpdateCommand","id","memorySearchCommand","query","contextTags","limit"],"mappings":"AAAA,SAASA,cAAc,QAAQ,sBAAsB;AACrD,SAASC,eAAe,QAAQ,uBAAuB;AACvD,SAASC,eAAe,QAAQ,uBAAuB;AACvD,SAASC,aAAa,EAAEC,WAAW,QAAQ,sBAAsB;AAGjE,SAASJ,cAAc,EAAEC,eAAe,EAAEC,eAAe,GAAG;AA6B5D,OAAO,SAASG,mBAAmBC,OAA2B;IAC1D,IAAI;QACAF,YAAY;YAAEG,QAAQD,QAAQC,MAAM;QAAC;QACrC,MAAMC,QAA6B;YAC/BC,OAAOH,QAAQG,KAAK;YACpBC,SAASJ,QAAQI,OAAO;YACxBC,MAAML,QAAQK,IAAI,GAAGL,QAAQK,IAAI,CAACC,KAAK,CAAC,KAAKC,GAAG,CAACC,CAAAA,IAAKA,EAAEC,IAAI,MAAMC;YAClEC,OAAOX,QAAQW,KAAK;QACxB;QAEA,OAAOjB,eAAeQ;IAC1B,SAAU;QACNL;IACJ;AACJ;AAEA,OAAO,SAASe,oBAAoBZ,OAA4B;IAC5D,IAAI;QACAF,YAAY;YAAEG,QAAQD,QAAQC,MAAM;QAAC;QACrC,MAAMC,QAA8B;YAChCW,IAAIb,QAAQa,EAAE;YACdV,OAAOH,QAAQG,KAAK;YACpBC,SAASJ,QAAQI,OAAO;YACxBC,MAAML,QAAQK,IAAI,GAAGL,QAAQK,IAAI,CAACC,KAAK,CAAC,KAAKC,GAAG,CAACC,CAAAA,IAAKA,EAAEC,IAAI,MAAMC;YAClEC,OAAOX,QAAQW,KAAK;QACxB;QAEA,OAAOf,gBAAgBM;IAC3B,SAAU;QACNL;IACJ;AACJ;AAEA,OAAO,SAASiB,oBAAoBd,OAA4B;IAC5D,IAAI;QACAF,YAAY;YAAEG,QAAQD,QAAQC,MAAM;QAAC;QACrC,MAAMC,QAA8B;YAChCa,OAAOf,QAAQe,KAAK;YACpBC,aAAahB,QAAQK,IAAI,GAAGL,QAAQK,IAAI,CAACC,KAAK,CAAC,KAAKC,GAAG,CAACC,CAAAA,IAAKA,EAAEC,IAAI,MAAMC;YACzEC,OAAOX,QAAQW,KAAK;YACpBM,OAAOjB,QAAQiB,KAAK;QACxB;QAEA,OAAOtB,gBAAgBO;IAC3B,SAAU;QACNL;IACJ;AACJ"}
1
+ {"version":3,"sources":["../src/api.ts"],"sourcesContent":["import { storeKnowledge } from './handlers/store.js';\nimport { searchKnowledge } from './handlers/search.js';\nimport { updateKnowledge } from './handlers/update.js';\nimport { listKnowledge } from './handlers/list.js';\nimport { getKnowledgeSummary } from './handlers/summary.js';\nimport { closeDatabase, getDatabase } from './database/index.js';\nimport type { StoreKnowledgeInput, SearchKnowledgeInput, StoreKnowledgeResult, SearchKnowledgeResult, UpdateKnowledgeInput, UpdateKnowledgeResult, ListKnowledgeInput, ListKnowledgeResult, ListKnowledgeSort, KnowledgeSummaryResult, KnowledgeItem } from './types/index.js';\n\nexport { storeKnowledge, searchKnowledge, updateKnowledge, listKnowledge, getKnowledgeSummary };\nexport type { StoreKnowledgeInput, SearchKnowledgeInput, StoreKnowledgeResult, SearchKnowledgeResult, UpdateKnowledgeInput, UpdateKnowledgeResult, ListKnowledgeInput, ListKnowledgeResult, ListKnowledgeSort, KnowledgeSummaryResult, KnowledgeItem };\n\n// CLI command handlers for integration with main ai-devkit CLI\nexport interface MemoryStoreOptions {\n title: string;\n content: string;\n tags?: string;\n scope?: string;\n dbPath?: string;\n}\n\nexport interface MemoryUpdateOptions {\n id: string;\n title?: string;\n content?: string;\n tags?: string;\n scope?: string;\n dbPath?: string;\n}\n\nexport interface MemorySearchOptions {\n query: string;\n tags?: string;\n scope?: string;\n limit?: number;\n dbPath?: string;\n}\n\nexport interface MemoryListOptions {\n query?: string;\n tags?: string;\n scope?: string;\n limit?: number;\n offset?: number;\n sort?: ListKnowledgeSort;\n dbPath?: string;\n}\n\nexport interface MemorySummaryOptions {\n dbPath?: string;\n}\n\nexport function memoryStoreCommand(options: MemoryStoreOptions): StoreKnowledgeResult {\n try {\n getDatabase({ dbPath: options.dbPath });\n const input: StoreKnowledgeInput = {\n title: options.title,\n content: options.content,\n tags: options.tags ? options.tags.split(',').map(t => t.trim()) : undefined,\n scope: options.scope,\n };\n\n return storeKnowledge(input);\n } finally {\n closeDatabase();\n }\n}\n\nexport function memoryUpdateCommand(options: MemoryUpdateOptions): UpdateKnowledgeResult {\n try {\n getDatabase({ dbPath: options.dbPath });\n const input: UpdateKnowledgeInput = {\n id: options.id,\n title: options.title,\n content: options.content,\n tags: options.tags ? options.tags.split(',').map(t => t.trim()) : undefined,\n scope: options.scope,\n };\n\n return updateKnowledge(input);\n } finally {\n closeDatabase();\n }\n}\n\nexport function memorySearchCommand(options: MemorySearchOptions): SearchKnowledgeResult {\n try {\n getDatabase({ dbPath: options.dbPath });\n const input: SearchKnowledgeInput = {\n query: options.query,\n contextTags: options.tags ? options.tags.split(',').map(t => t.trim()) : undefined,\n scope: options.scope,\n limit: options.limit,\n };\n\n return searchKnowledge(input);\n } finally {\n closeDatabase();\n }\n}\n\nexport function memoryListCommand(options: MemoryListOptions = {}): ListKnowledgeResult {\n try {\n getDatabase({ dbPath: options.dbPath });\n const input: ListKnowledgeInput = {\n query: options.query,\n tags: options.tags ? options.tags.split(',').map(t => t.trim()) : undefined,\n scope: options.scope,\n limit: options.limit,\n offset: options.offset,\n sort: options.sort,\n };\n\n return listKnowledge(input);\n } finally {\n closeDatabase();\n }\n}\n\nexport function memorySummaryCommand(options: MemorySummaryOptions = {}): KnowledgeSummaryResult {\n try {\n getDatabase({ dbPath: options.dbPath });\n return getKnowledgeSummary();\n } finally {\n closeDatabase();\n }\n}\n"],"names":["storeKnowledge","searchKnowledge","updateKnowledge","listKnowledge","getKnowledgeSummary","closeDatabase","getDatabase","memoryStoreCommand","options","dbPath","input","title","content","tags","split","map","t","trim","undefined","scope","memoryUpdateCommand","id","memorySearchCommand","query","contextTags","limit","memoryListCommand","offset","sort","memorySummaryCommand"],"mappings":"AAAA,SAASA,cAAc,QAAQ,sBAAsB;AACrD,SAASC,eAAe,QAAQ,uBAAuB;AACvD,SAASC,eAAe,QAAQ,uBAAuB;AACvD,SAASC,aAAa,QAAQ,qBAAqB;AACnD,SAASC,mBAAmB,QAAQ,wBAAwB;AAC5D,SAASC,aAAa,EAAEC,WAAW,QAAQ,sBAAsB;AAGjE,SAASN,cAAc,EAAEC,eAAe,EAAEC,eAAe,EAAEC,aAAa,EAAEC,mBAAmB,GAAG;AA2ChG,OAAO,SAASG,mBAAmBC,OAA2B;IAC1D,IAAI;QACAF,YAAY;YAAEG,QAAQD,QAAQC,MAAM;QAAC;QACrC,MAAMC,QAA6B;YAC/BC,OAAOH,QAAQG,KAAK;YACpBC,SAASJ,QAAQI,OAAO;YACxBC,MAAML,QAAQK,IAAI,GAAGL,QAAQK,IAAI,CAACC,KAAK,CAAC,KAAKC,GAAG,CAACC,CAAAA,IAAKA,EAAEC,IAAI,MAAMC;YAClEC,OAAOX,QAAQW,KAAK;QACxB;QAEA,OAAOnB,eAAeU;IAC1B,SAAU;QACNL;IACJ;AACJ;AAEA,OAAO,SAASe,oBAAoBZ,OAA4B;IAC5D,IAAI;QACAF,YAAY;YAAEG,QAAQD,QAAQC,MAAM;QAAC;QACrC,MAAMC,QAA8B;YAChCW,IAAIb,QAAQa,EAAE;YACdV,OAAOH,QAAQG,KAAK;YACpBC,SAASJ,QAAQI,OAAO;YACxBC,MAAML,QAAQK,IAAI,GAAGL,QAAQK,IAAI,CAACC,KAAK,CAAC,KAAKC,GAAG,CAACC,CAAAA,IAAKA,EAAEC,IAAI,MAAMC;YAClEC,OAAOX,QAAQW,KAAK;QACxB;QAEA,OAAOjB,gBAAgBQ;IAC3B,SAAU;QACNL;IACJ;AACJ;AAEA,OAAO,SAASiB,oBAAoBd,OAA4B;IAC5D,IAAI;QACAF,YAAY;YAAEG,QAAQD,QAAQC,MAAM;QAAC;QACrC,MAAMC,QAA8B;YAChCa,OAAOf,QAAQe,KAAK;YACpBC,aAAahB,QAAQK,IAAI,GAAGL,QAAQK,IAAI,CAACC,KAAK,CAAC,KAAKC,GAAG,CAACC,CAAAA,IAAKA,EAAEC,IAAI,MAAMC;YACzEC,OAAOX,QAAQW,KAAK;YACpBM,OAAOjB,QAAQiB,KAAK;QACxB;QAEA,OAAOxB,gBAAgBS;IAC3B,SAAU;QACNL;IACJ;AACJ;AAEA,OAAO,SAASqB,kBAAkBlB,UAA6B,CAAC,CAAC;IAC7D,IAAI;QACAF,YAAY;YAAEG,QAAQD,QAAQC,MAAM;QAAC;QACrC,MAAMC,QAA4B;YAC9Ba,OAAOf,QAAQe,KAAK;YACpBV,MAAML,QAAQK,IAAI,GAAGL,QAAQK,IAAI,CAACC,KAAK,CAAC,KAAKC,GAAG,CAACC,CAAAA,IAAKA,EAAEC,IAAI,MAAMC;YAClEC,OAAOX,QAAQW,KAAK;YACpBM,OAAOjB,QAAQiB,KAAK;YACpBE,QAAQnB,QAAQmB,MAAM;YACtBC,MAAMpB,QAAQoB,IAAI;QACtB;QAEA,OAAOzB,cAAcO;IACzB,SAAU;QACNL;IACJ;AACJ;AAEA,OAAO,SAASwB,qBAAqBrB,UAAgC,CAAC,CAAC;IACnE,IAAI;QACAF,YAAY;YAAEG,QAAQD,QAAQC,MAAM;QAAC;QACrC,OAAOL;IACX,SAAU;QACNC;IACJ;AACJ"}
@@ -0,0 +1,3 @@
1
+ import type { ListKnowledgeInput, ListKnowledgeResult } from '../types/index.js';
2
+ export declare function listKnowledge(input?: ListKnowledgeInput): ListKnowledgeResult;
3
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/handlers/list.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAA+B,kBAAkB,EAAE,mBAAmB,EAAqB,MAAM,mBAAmB,CAAC;AAYjI,wBAAgB,aAAa,CAAC,KAAK,GAAE,kBAAuB,GAAG,mBAAmB,CAqCjF"}
@@ -0,0 +1,133 @@
1
+ import { getDatabase } from '../database/index.js';
2
+ import { buildFtsQuery } from '../services/search.js';
3
+ import { normalizeScope, normalizeTags } from '../services/normalizer.js';
4
+ import { ValidationError } from '../utils/errors.js';
5
+ const DEFAULT_LIMIT = 50;
6
+ const MAX_LIMIT = 200;
7
+ const MAX_OFFSET = 100_000;
8
+ const MAX_QUERY_LENGTH = 500;
9
+ export function listKnowledge(input = {}) {
10
+ validateListInput(input);
11
+ const db = getDatabase();
12
+ const limit = clampLimit(input.limit);
13
+ const offset = clampOffset(input.offset);
14
+ const query = buildListQuery(input);
15
+ const orderBy = getOrderBy(input.sort);
16
+ const whereSql = query.where.length > 0 ? `WHERE ${query.where.join(' AND ')}` : '';
17
+ const totalRow = db.queryOne(`SELECT COUNT(*) as total FROM knowledge k ${whereSql}`, query.params);
18
+ const rows = db.query(`SELECT
19
+ k.id,
20
+ k.title,
21
+ k.content,
22
+ k.tags,
23
+ k.scope,
24
+ k.normalized_title,
25
+ k.content_hash,
26
+ k.created_at,
27
+ k.updated_at
28
+ FROM knowledge k
29
+ ${whereSql}
30
+ ${orderBy}
31
+ LIMIT ? OFFSET ?`, [
32
+ ...query.params,
33
+ limit,
34
+ offset
35
+ ]);
36
+ return {
37
+ items: rows.map(mapKnowledgeRow),
38
+ total: totalRow?.total ?? 0
39
+ };
40
+ }
41
+ function validateListInput(input) {
42
+ const errors = [];
43
+ if (input.query !== undefined && typeof input.query !== 'string') {
44
+ errors.push('Query must be a string');
45
+ }
46
+ if (typeof input.query === 'string' && input.query.length > MAX_QUERY_LENGTH) {
47
+ errors.push(`Query must be at most ${MAX_QUERY_LENGTH} characters`);
48
+ }
49
+ if (input.limit !== undefined && (!Number.isInteger(input.limit) || input.limit < 1)) {
50
+ errors.push('Limit must be a positive integer');
51
+ }
52
+ if (input.offset !== undefined && (!Number.isInteger(input.offset) || input.offset < 0)) {
53
+ errors.push('Offset must be a non-negative integer');
54
+ }
55
+ if (input.sort !== undefined && !isSupportedSort(input.sort)) {
56
+ errors.push('Sort must be one of updated-desc, created-desc, or title-asc');
57
+ }
58
+ if (errors.length > 0) {
59
+ throw new ValidationError(errors.join('; '), {
60
+ errors
61
+ });
62
+ }
63
+ }
64
+ function buildListQuery(input) {
65
+ const where = [];
66
+ const params = [];
67
+ const query = input.query?.trim();
68
+ if (query) {
69
+ const ftsQuery = buildFtsQuery(query);
70
+ if (ftsQuery) {
71
+ where.push(`k.rowid IN (
72
+ SELECT rowid FROM knowledge_fts WHERE knowledge_fts MATCH ?
73
+ )`);
74
+ params.push(ftsQuery);
75
+ }
76
+ }
77
+ if (input.scope) {
78
+ where.push('k.scope = ?');
79
+ params.push(normalizeScope(input.scope));
80
+ }
81
+ const tags = normalizeTags(input.tags ?? []);
82
+ for (const tag of tags){
83
+ where.push('k.tags LIKE ?');
84
+ params.push(`%"${tag}"%`);
85
+ }
86
+ return {
87
+ where,
88
+ params
89
+ };
90
+ }
91
+ function mapKnowledgeRow(row) {
92
+ return {
93
+ id: row.id,
94
+ title: row.title,
95
+ content: row.content,
96
+ tags: parseTags(row.tags),
97
+ scope: row.scope,
98
+ normalizedTitle: row.normalized_title,
99
+ contentHash: row.content_hash,
100
+ createdAt: row.created_at,
101
+ updatedAt: row.updated_at
102
+ };
103
+ }
104
+ function parseTags(rawTags) {
105
+ try {
106
+ const tags = JSON.parse(rawTags);
107
+ return Array.isArray(tags) ? tags.filter((tag)=>typeof tag === 'string') : [];
108
+ } catch {
109
+ return [];
110
+ }
111
+ }
112
+ function clampLimit(limit) {
113
+ return Math.min(Math.max(limit ?? DEFAULT_LIMIT, 1), MAX_LIMIT);
114
+ }
115
+ function clampOffset(offset) {
116
+ return Math.min(Math.max(offset ?? 0, 0), MAX_OFFSET);
117
+ }
118
+ function getOrderBy(sort) {
119
+ switch(sort){
120
+ case 'created-desc':
121
+ return 'ORDER BY k.created_at DESC, k.title ASC';
122
+ case 'title-asc':
123
+ return 'ORDER BY k.title ASC, k.created_at DESC';
124
+ case 'updated-desc':
125
+ case undefined:
126
+ return 'ORDER BY k.updated_at DESC, k.title ASC';
127
+ }
128
+ }
129
+ function isSupportedSort(sort) {
130
+ return sort === 'updated-desc' || sort === 'created-desc' || sort === 'title-asc';
131
+ }
132
+
133
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/handlers/list.ts"],"sourcesContent":["import { getDatabase } from '../database/index.js';\nimport { buildFtsQuery } from '../services/search.js';\nimport { normalizeScope, normalizeTags } from '../services/normalizer.js';\nimport { ValidationError } from '../utils/errors.js';\nimport type { KnowledgeItem, KnowledgeRow, ListKnowledgeInput, ListKnowledgeResult, ListKnowledgeSort } from '../types/index.js';\n\nconst DEFAULT_LIMIT = 50;\nconst MAX_LIMIT = 200;\nconst MAX_OFFSET = 100_000;\nconst MAX_QUERY_LENGTH = 500;\n\ninterface ListQuery {\n where: string[];\n params: unknown[];\n}\n\nexport function listKnowledge(input: ListKnowledgeInput = {}): ListKnowledgeResult {\n validateListInput(input);\n\n const db = getDatabase();\n const limit = clampLimit(input.limit);\n const offset = clampOffset(input.offset);\n const query = buildListQuery(input);\n const orderBy = getOrderBy(input.sort);\n const whereSql = query.where.length > 0 ? `WHERE ${query.where.join(' AND ')}` : '';\n\n const totalRow = db.queryOne<{ total: number }>(\n `SELECT COUNT(*) as total FROM knowledge k ${whereSql}`,\n query.params\n );\n\n const rows = db.query<KnowledgeRow>(\n `SELECT\n k.id,\n k.title,\n k.content,\n k.tags,\n k.scope,\n k.normalized_title,\n k.content_hash,\n k.created_at,\n k.updated_at\n FROM knowledge k\n ${whereSql}\n ${orderBy}\n LIMIT ? OFFSET ?`,\n [...query.params, limit, offset]\n );\n\n return {\n items: rows.map(mapKnowledgeRow),\n total: totalRow?.total ?? 0,\n };\n}\n\nfunction validateListInput(input: ListKnowledgeInput): void {\n const errors: string[] = [];\n\n if (input.query !== undefined && typeof input.query !== 'string') {\n errors.push('Query must be a string');\n }\n\n if (typeof input.query === 'string' && input.query.length > MAX_QUERY_LENGTH) {\n errors.push(`Query must be at most ${MAX_QUERY_LENGTH} characters`);\n }\n\n if (input.limit !== undefined && (!Number.isInteger(input.limit) || input.limit < 1)) {\n errors.push('Limit must be a positive integer');\n }\n\n if (input.offset !== undefined && (!Number.isInteger(input.offset) || input.offset < 0)) {\n errors.push('Offset must be a non-negative integer');\n }\n\n if (input.sort !== undefined && !isSupportedSort(input.sort)) {\n errors.push('Sort must be one of updated-desc, created-desc, or title-asc');\n }\n\n if (errors.length > 0) {\n throw new ValidationError(errors.join('; '), { errors });\n }\n}\n\nfunction buildListQuery(input: ListKnowledgeInput): ListQuery {\n const where: string[] = [];\n const params: unknown[] = [];\n const query = input.query?.trim();\n\n if (query) {\n const ftsQuery = buildFtsQuery(query);\n if (ftsQuery) {\n where.push(`k.rowid IN (\n SELECT rowid FROM knowledge_fts WHERE knowledge_fts MATCH ?\n )`);\n params.push(ftsQuery);\n }\n }\n\n if (input.scope) {\n where.push('k.scope = ?');\n params.push(normalizeScope(input.scope));\n }\n\n const tags = normalizeTags(input.tags ?? []);\n for (const tag of tags) {\n where.push('k.tags LIKE ?');\n params.push(`%\"${tag}\"%`);\n }\n\n return { where, params };\n}\n\nfunction mapKnowledgeRow(row: KnowledgeRow): KnowledgeItem {\n return {\n id: row.id,\n title: row.title,\n content: row.content,\n tags: parseTags(row.tags),\n scope: row.scope,\n normalizedTitle: row.normalized_title,\n contentHash: row.content_hash,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n}\n\nfunction parseTags(rawTags: string): string[] {\n try {\n const tags = JSON.parse(rawTags) as unknown;\n return Array.isArray(tags)\n ? tags.filter((tag): tag is string => typeof tag === 'string')\n : [];\n } catch {\n return [];\n }\n}\n\nfunction clampLimit(limit: number | undefined): number {\n return Math.min(Math.max(limit ?? DEFAULT_LIMIT, 1), MAX_LIMIT);\n}\n\nfunction clampOffset(offset: number | undefined): number {\n return Math.min(Math.max(offset ?? 0, 0), MAX_OFFSET);\n}\n\nfunction getOrderBy(sort: ListKnowledgeSort | undefined): string {\n switch (sort) {\n case 'created-desc':\n return 'ORDER BY k.created_at DESC, k.title ASC';\n case 'title-asc':\n return 'ORDER BY k.title ASC, k.created_at DESC';\n case 'updated-desc':\n case undefined:\n return 'ORDER BY k.updated_at DESC, k.title ASC';\n }\n}\n\nfunction isSupportedSort(sort: string): sort is ListKnowledgeSort {\n return sort === 'updated-desc' || sort === 'created-desc' || sort === 'title-asc';\n}\n"],"names":["getDatabase","buildFtsQuery","normalizeScope","normalizeTags","ValidationError","DEFAULT_LIMIT","MAX_LIMIT","MAX_OFFSET","MAX_QUERY_LENGTH","listKnowledge","input","validateListInput","db","limit","clampLimit","offset","clampOffset","query","buildListQuery","orderBy","getOrderBy","sort","whereSql","where","length","join","totalRow","queryOne","params","rows","items","map","mapKnowledgeRow","total","errors","undefined","push","Number","isInteger","isSupportedSort","trim","ftsQuery","scope","tags","tag","row","id","title","content","parseTags","normalizedTitle","normalized_title","contentHash","content_hash","createdAt","created_at","updatedAt","updated_at","rawTags","JSON","parse","Array","isArray","filter","Math","min","max"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { KnowledgeSummaryResult } from '../types/index.js';
2
+ export declare function getKnowledgeSummary(): KnowledgeSummaryResult;
3
+ //# sourceMappingURL=summary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summary.d.ts","sourceRoot":"","sources":["../../src/handlers/summary.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAgB,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAM9E,wBAAgB,mBAAmB,IAAI,sBAAsB,CAoB5D"}
@@ -0,0 +1,78 @@
1
+ import { getDatabase } from '../database/index.js';
2
+ const RECENCY_BUCKETS = [
3
+ 'today',
4
+ 'week',
5
+ 'month',
6
+ 'older'
7
+ ];
8
+ export function getKnowledgeSummary() {
9
+ const db = getDatabase();
10
+ const totalRow = db.queryOne('SELECT COUNT(*) as total FROM knowledge');
11
+ const scopes = db.query(`SELECT scope, COUNT(*) as count
12
+ FROM knowledge
13
+ GROUP BY scope
14
+ ORDER BY scope ASC`);
15
+ const rows = db.query(`SELECT id, title, content, tags, scope, normalized_title, content_hash, created_at, updated_at
16
+ FROM knowledge`);
17
+ return {
18
+ totalItems: totalRow?.total ?? 0,
19
+ scopes,
20
+ tags: buildTagCounts(rows),
21
+ recency: buildRecencyCounts(rows)
22
+ };
23
+ }
24
+ function buildTagCounts(rows) {
25
+ const counts = new Map();
26
+ for (const row of rows){
27
+ for (const tag of parseTags(row.tags)){
28
+ counts.set(tag, (counts.get(tag) ?? 0) + 1);
29
+ }
30
+ }
31
+ return Array.from(counts.entries()).map(([tag, count])=>({
32
+ tag,
33
+ count
34
+ })).sort((left, right)=>right.count - left.count || left.tag.localeCompare(right.tag));
35
+ }
36
+ function buildRecencyCounts(rows) {
37
+ const counts = new Map(RECENCY_BUCKETS.map((bucket)=>[
38
+ bucket,
39
+ 0
40
+ ]));
41
+ const now = Date.now();
42
+ for (const row of rows){
43
+ const bucket = getRecencyBucket(row.updated_at, now);
44
+ counts.set(bucket, (counts.get(bucket) ?? 0) + 1);
45
+ }
46
+ return RECENCY_BUCKETS.map((bucket)=>({
47
+ bucket,
48
+ count: counts.get(bucket) ?? 0
49
+ }));
50
+ }
51
+ function getRecencyBucket(updatedAt, now) {
52
+ const timestamp = Date.parse(updatedAt);
53
+ if (Number.isNaN(timestamp)) {
54
+ return 'older';
55
+ }
56
+ const ageMs = now - timestamp;
57
+ const dayMs = 24 * 60 * 60 * 1000;
58
+ if (ageMs <= dayMs) {
59
+ return 'today';
60
+ }
61
+ if (ageMs <= 7 * dayMs) {
62
+ return 'week';
63
+ }
64
+ if (ageMs <= 30 * dayMs) {
65
+ return 'month';
66
+ }
67
+ return 'older';
68
+ }
69
+ function parseTags(rawTags) {
70
+ try {
71
+ const tags = JSON.parse(rawTags);
72
+ return Array.isArray(tags) ? tags.filter((tag)=>typeof tag === 'string') : [];
73
+ } catch {
74
+ return [];
75
+ }
76
+ }
77
+
78
+ //# sourceMappingURL=summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/handlers/summary.ts"],"sourcesContent":["import { getDatabase } from '../database/index.js';\nimport type { KnowledgeRow, KnowledgeSummaryResult } from '../types/index.js';\n\ntype RecencyBucket = 'today' | 'week' | 'month' | 'older';\n\nconst RECENCY_BUCKETS: RecencyBucket[] = ['today', 'week', 'month', 'older'];\n\nexport function getKnowledgeSummary(): KnowledgeSummaryResult {\n const db = getDatabase();\n const totalRow = db.queryOne<{ total: number }>('SELECT COUNT(*) as total FROM knowledge');\n const scopes = db.query<{ scope: string; count: number }>(\n `SELECT scope, COUNT(*) as count\n FROM knowledge\n GROUP BY scope\n ORDER BY scope ASC`\n );\n const rows = db.query<KnowledgeRow>(\n `SELECT id, title, content, tags, scope, normalized_title, content_hash, created_at, updated_at\n FROM knowledge`\n );\n\n return {\n totalItems: totalRow?.total ?? 0,\n scopes,\n tags: buildTagCounts(rows),\n recency: buildRecencyCounts(rows),\n };\n}\n\nfunction buildTagCounts(rows: KnowledgeRow[]): Array<{ tag: string; count: number }> {\n const counts = new Map<string, number>();\n\n for (const row of rows) {\n for (const tag of parseTags(row.tags)) {\n counts.set(tag, (counts.get(tag) ?? 0) + 1);\n }\n }\n\n return Array.from(counts.entries())\n .map(([tag, count]) => ({ tag, count }))\n .sort((left, right) => right.count - left.count || left.tag.localeCompare(right.tag));\n}\n\nfunction buildRecencyCounts(rows: KnowledgeRow[]): Array<{ bucket: string; count: number }> {\n const counts = new Map<RecencyBucket, number>(\n RECENCY_BUCKETS.map(bucket => [bucket, 0])\n );\n const now = Date.now();\n\n for (const row of rows) {\n const bucket = getRecencyBucket(row.updated_at, now);\n counts.set(bucket, (counts.get(bucket) ?? 0) + 1);\n }\n\n return RECENCY_BUCKETS.map(bucket => ({\n bucket,\n count: counts.get(bucket) ?? 0,\n }));\n}\n\nfunction getRecencyBucket(updatedAt: string, now: number): RecencyBucket {\n const timestamp = Date.parse(updatedAt);\n if (Number.isNaN(timestamp)) {\n return 'older';\n }\n\n const ageMs = now - timestamp;\n const dayMs = 24 * 60 * 60 * 1000;\n\n if (ageMs <= dayMs) {\n return 'today';\n }\n\n if (ageMs <= 7 * dayMs) {\n return 'week';\n }\n\n if (ageMs <= 30 * dayMs) {\n return 'month';\n }\n\n return 'older';\n}\n\nfunction parseTags(rawTags: string): string[] {\n try {\n const tags = JSON.parse(rawTags) as unknown;\n return Array.isArray(tags)\n ? tags.filter((tag): tag is string => typeof tag === 'string')\n : [];\n } catch {\n return [];\n }\n}\n"],"names":["getDatabase","RECENCY_BUCKETS","getKnowledgeSummary","db","totalRow","queryOne","scopes","query","rows","totalItems","total","tags","buildTagCounts","recency","buildRecencyCounts","counts","Map","row","tag","parseTags","set","get","Array","from","entries","map","count","sort","left","right","localeCompare","bucket","now","Date","getRecencyBucket","updated_at","updatedAt","timestamp","parse","Number","isNaN","ageMs","dayMs","rawTags","JSON","isArray","filter"],"mappings":"AAAA,SAASA,WAAW,QAAQ,uBAAuB;AAKnD,MAAMC,kBAAmC;IAAC;IAAS;IAAQ;IAAS;CAAQ;AAE5E,OAAO,SAASC;IACZ,MAAMC,KAAKH;IACX,MAAMI,WAAWD,GAAGE,QAAQ,CAAoB;IAChD,MAAMC,SAASH,GAAGI,KAAK,CACnB,CAAC;;;2BAGkB,CAAC;IAExB,MAAMC,OAAOL,GAAGI,KAAK,CACjB,CAAC;uBACc,CAAC;IAGpB,OAAO;QACHE,YAAYL,UAAUM,SAAS;QAC/BJ;QACAK,MAAMC,eAAeJ;QACrBK,SAASC,mBAAmBN;IAChC;AACJ;AAEA,SAASI,eAAeJ,IAAoB;IACxC,MAAMO,SAAS,IAAIC;IAEnB,KAAK,MAAMC,OAAOT,KAAM;QACpB,KAAK,MAAMU,OAAOC,UAAUF,IAAIN,IAAI,EAAG;YACnCI,OAAOK,GAAG,CAACF,KAAK,AAACH,CAAAA,OAAOM,GAAG,CAACH,QAAQ,CAAA,IAAK;QAC7C;IACJ;IAEA,OAAOI,MAAMC,IAAI,CAACR,OAAOS,OAAO,IAC3BC,GAAG,CAAC,CAAC,CAACP,KAAKQ,MAAM,GAAM,CAAA;YAAER;YAAKQ;QAAM,CAAA,GACpCC,IAAI,CAAC,CAACC,MAAMC,QAAUA,MAAMH,KAAK,GAAGE,KAAKF,KAAK,IAAIE,KAAKV,GAAG,CAACY,aAAa,CAACD,MAAMX,GAAG;AAC3F;AAEA,SAASJ,mBAAmBN,IAAoB;IAC5C,MAAMO,SAAS,IAAIC,IACff,gBAAgBwB,GAAG,CAACM,CAAAA,SAAU;YAACA;YAAQ;SAAE;IAE7C,MAAMC,MAAMC,KAAKD,GAAG;IAEpB,KAAK,MAAMf,OAAOT,KAAM;QACpB,MAAMuB,SAASG,iBAAiBjB,IAAIkB,UAAU,EAAEH;QAChDjB,OAAOK,GAAG,CAACW,QAAQ,AAAChB,CAAAA,OAAOM,GAAG,CAACU,WAAW,CAAA,IAAK;IACnD;IAEA,OAAO9B,gBAAgBwB,GAAG,CAACM,CAAAA,SAAW,CAAA;YAClCA;YACAL,OAAOX,OAAOM,GAAG,CAACU,WAAW;QACjC,CAAA;AACJ;AAEA,SAASG,iBAAiBE,SAAiB,EAAEJ,GAAW;IACpD,MAAMK,YAAYJ,KAAKK,KAAK,CAACF;IAC7B,IAAIG,OAAOC,KAAK,CAACH,YAAY;QACzB,OAAO;IACX;IAEA,MAAMI,QAAQT,MAAMK;IACpB,MAAMK,QAAQ,KAAK,KAAK,KAAK;IAE7B,IAAID,SAASC,OAAO;QAChB,OAAO;IACX;IAEA,IAAID,SAAS,IAAIC,OAAO;QACpB,OAAO;IACX;IAEA,IAAID,SAAS,KAAKC,OAAO;QACrB,OAAO;IACX;IAEA,OAAO;AACX;AAEA,SAASvB,UAAUwB,OAAe;IAC9B,IAAI;QACA,MAAMhC,OAAOiC,KAAKN,KAAK,CAACK;QACxB,OAAOrB,MAAMuB,OAAO,CAAClC,QACfA,KAAKmC,MAAM,CAAC,CAAC5B,MAAuB,OAAOA,QAAQ,YACnD,EAAE;IACZ,EAAE,OAAM;QACJ,OAAO,EAAE;IACb;AACJ"}
@@ -52,6 +52,34 @@ export interface SearchKnowledgeResult {
52
52
  totalMatches: number;
53
53
  query: string;
54
54
  }
55
+ export type ListKnowledgeSort = 'updated-desc' | 'created-desc' | 'title-asc';
56
+ export interface ListKnowledgeInput {
57
+ query?: string;
58
+ tags?: string[];
59
+ scope?: string;
60
+ limit?: number;
61
+ offset?: number;
62
+ sort?: ListKnowledgeSort;
63
+ }
64
+ export interface ListKnowledgeResult {
65
+ items: KnowledgeItem[];
66
+ total: number;
67
+ }
68
+ export interface KnowledgeSummaryResult {
69
+ totalItems: number;
70
+ scopes: Array<{
71
+ scope: string;
72
+ count: number;
73
+ }>;
74
+ tags: Array<{
75
+ tag: string;
76
+ count: number;
77
+ }>;
78
+ recency: Array<{
79
+ bucket: string;
80
+ count: number;
81
+ }>;
82
+ }
55
83
  export interface KnowledgeRow {
56
84
  id: string;
57
85
  title: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,WAAW,MAAM,EAAE,GAAG,QAAQ,MAAM,EAAE,CAAC;AAE/E,MAAM,WAAW,mBAAmB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,qBAAqB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,qBAAqB;IAClC,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IACzB,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,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,OAAO;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACjB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/types/index.ts"],"sourcesContent":["export interface KnowledgeItem {\n id: string;\n title: string;\n content: string;\n tags: string[];\n scope: string;\n normalizedTitle: string;\n contentHash: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport type KnowledgeScope = 'global' | `project:${string}` | `repo:${string}`;\n\nexport interface StoreKnowledgeInput {\n title: string;\n content: string;\n tags?: string[];\n scope?: string;\n}\n\nexport interface StoreKnowledgeResult {\n success: boolean;\n id?: string;\n message: string;\n}\n\nexport interface UpdateKnowledgeInput {\n id: string;\n title?: string;\n content?: string;\n tags?: string[];\n scope?: string;\n}\n\nexport interface UpdateKnowledgeResult {\n success: boolean;\n id: string;\n message: string;\n}\n\nexport interface SearchKnowledgeInput {\n query: string;\n contextTags?: string[];\n scope?: string;\n limit?: number;\n}\n\nexport interface SearchResultItem {\n id: string;\n title: string;\n content: string;\n tags: string[];\n scope: string;\n score: number;\n}\n\nexport interface SearchKnowledgeResult {\n results: SearchResultItem[];\n totalMatches: number;\n query: string;\n}\n\nexport interface KnowledgeRow {\n id: string;\n title: string;\n content: string;\n tags: string;\n scope: string;\n normalized_title: string;\n content_hash: string;\n created_at: string;\n updated_at: string;\n}\n\nexport interface MetaRow {\n key: string;\n value: string;\n}"],"names":[],"mappings":"AA2EA,WAGC"}
1
+ {"version":3,"sources":["../../src/types/index.ts"],"sourcesContent":["export interface KnowledgeItem {\n id: string;\n title: string;\n content: string;\n tags: string[];\n scope: string;\n normalizedTitle: string;\n contentHash: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport type KnowledgeScope = 'global' | `project:${string}` | `repo:${string}`;\n\nexport interface StoreKnowledgeInput {\n title: string;\n content: string;\n tags?: string[];\n scope?: string;\n}\n\nexport interface StoreKnowledgeResult {\n success: boolean;\n id?: string;\n message: string;\n}\n\nexport interface UpdateKnowledgeInput {\n id: string;\n title?: string;\n content?: string;\n tags?: string[];\n scope?: string;\n}\n\nexport interface UpdateKnowledgeResult {\n success: boolean;\n id: string;\n message: string;\n}\n\nexport interface SearchKnowledgeInput {\n query: string;\n contextTags?: string[];\n scope?: string;\n limit?: number;\n}\n\nexport interface SearchResultItem {\n id: string;\n title: string;\n content: string;\n tags: string[];\n scope: string;\n score: number;\n}\n\nexport interface SearchKnowledgeResult {\n results: SearchResultItem[];\n totalMatches: number;\n query: string;\n}\n\nexport type ListKnowledgeSort = 'updated-desc' | 'created-desc' | 'title-asc';\n\nexport interface ListKnowledgeInput {\n query?: string;\n tags?: string[];\n scope?: string;\n limit?: number;\n offset?: number;\n sort?: ListKnowledgeSort;\n}\n\nexport interface ListKnowledgeResult {\n items: KnowledgeItem[];\n total: number;\n}\n\nexport interface KnowledgeSummaryResult {\n totalItems: number;\n scopes: Array<{ scope: string; count: number }>;\n tags: Array<{ tag: string; count: number }>;\n recency: Array<{ bucket: string; count: number }>;\n}\n\nexport interface KnowledgeRow {\n id: string;\n title: string;\n content: string;\n tags: string;\n scope: string;\n normalized_title: string;\n content_hash: string;\n created_at: string;\n updated_at: string;\n}\n\nexport interface MetaRow {\n key: string;\n value: string;\n}\n"],"names":[],"mappings":"AAkGA,WAGC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-devkit/memory",
3
- "version": "0.13.0",
3
+ "version": "0.15.0",
4
4
  "type": "module",
5
5
  "description": "Local MCP memory for AI coding agents to reuse project decisions, conventions, and fixes across sessions",
6
6
  "main": "dist/index.js",
@@ -42,6 +42,11 @@
42
42
  ],
43
43
  "author": "",
44
44
  "license": "MIT",
45
+ "repository": {
46
+ "type": "git",
47
+ "url": "git+https://github.com/codeaholicguy/ai-devkit.git",
48
+ "directory": "packages/memory"
49
+ },
45
50
  "dependencies": {
46
51
  "@modelcontextprotocol/sdk": "^1.0.0",
47
52
  "@typescript-eslint/eslint-plugin": "8.60.1",