@ai-devkit/memory 0.1.0 → 0.3.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 CHANGED
@@ -63,27 +63,6 @@ Add to your MCP client configuration:
63
63
  }
64
64
  ```
65
65
 
66
- ### CLI Commands
67
-
68
- You can also use the CLI directly:
69
-
70
- ```bash
71
- # Store knowledge
72
- ai-devkit-memory store \
73
- -t "Always use Response DTOs for API endpoints" \
74
- -c "When building REST APIs, always use Response DTOs..." \
75
- --tags "api,backend,dto" \
76
- -s global
77
-
78
- # Search knowledge
79
- ai-devkit-memory search -q "API best practices" --tags "api" -l 5
80
-
81
- # Start MCP server (default)
82
- ai-devkit-memory serve
83
- # or just:
84
- ai-devkit-memory
85
- ```
86
-
87
66
  ## API Reference
88
67
 
89
68
  ### `memory.storeKnowledge`
@@ -1 +1 @@
1
- {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/database/connection.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAKtC;;GAEG;AACH,eAAO,MAAM,eAAe,QAA6C,CAAC;AAE1E,MAAM,WAAW,eAAe;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,qBAAa,kBAAkB;IAC3B,OAAO,CAAC,EAAE,CAAoB;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEpB,OAAO,GAAE,eAAoB;IAczC,OAAO,CAAC,SAAS;IAQjB,IAAI,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAEhC;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,CAAC,EAAE;IAIlD,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,CAAC,GAAG,SAAS;IAI/D,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,QAAQ,CAAC,SAAS;IAGhE,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC;IAI9B,KAAK,IAAI,IAAI;CAKhB;AAKD,wBAAgB,WAAW,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,kBAAkB,CAczE;AAED,wBAAgB,aAAa,IAAI,IAAI,CAMpC"}
1
+ {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/database/connection.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAKtC;;GAEG;AACH,eAAO,MAAM,eAAe,QAA6C,CAAC;AAE1E,MAAM,WAAW,eAAe;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,qBAAa,kBAAkB;IAC3B,OAAO,CAAC,EAAE,CAAoB;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEpB,OAAO,GAAE,eAAoB;IAczC,OAAO,CAAC,SAAS;IAQjB,IAAI,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAEhC;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,CAAC,EAAE;IAIlD,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,CAAC,GAAG,SAAS;IAI/D,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,QAAQ,CAAC,SAAS;IAGhE,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC;IAI9B,KAAK,IAAI,IAAI;CAKhB;AAKD,wBAAgB,WAAW,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,kBAAkB,CAezE;AAED,wBAAgB,aAAa,IAAI,IAAI,CAMpC"}
@@ -90,6 +90,7 @@ function getDatabase(options) {
90
90
  // Auto-run migrations on first access
91
91
  if (!schemaInitialized) {
92
92
  // Lazy import to avoid circular dependency
93
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
93
94
  const { initializeSchema } = require('./schema');
94
95
  initializeSchema(instance);
95
96
  schemaInitialized = true;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/database/connection.ts"],"sourcesContent":["import Database from 'better-sqlite3';\nimport { mkdirSync } from 'fs';\nimport { dirname, join } from 'path';\nimport { homedir } from 'os';\n\n/**\n * Default database path: ~/.ai-devkit/memory.db\n */\nexport const DEFAULT_DB_PATH = join(homedir(), '.ai-devkit', 'memory.db');\n\nexport interface DatabaseOptions {\n dbPath?: string;\n verbose?: boolean;\n readonly?: boolean;\n}\n\nexport class DatabaseConnection {\n private db: Database.Database;\n private readonly dbPath: string;\n\n constructor(options: DatabaseOptions = {}) {\n this.dbPath = options.dbPath ?? DEFAULT_DB_PATH;\n\n const dir = dirname(this.dbPath);\n mkdirSync(dir, { recursive: true });\n\n this.db = new Database(this.dbPath, {\n readonly: options.readonly ?? false,\n verbose: options.verbose ? console.log : undefined,\n });\n\n this.configure();\n }\n\n private configure(): void {\n this.db.pragma('journal_mode = WAL');\n this.db.pragma('foreign_keys = ON');\n this.db.pragma('synchronous = NORMAL');\n this.db.pragma('busy_timeout = 5000');\n this.db.pragma('mmap_size = 268435456');\n }\n\n get instance(): Database.Database {\n return this.db;\n }\n\n get path(): string {\n return this.dbPath;\n }\n\n get isOpen(): boolean {\n return this.db.open;\n }\n\n query<T>(sql: string, params: unknown[] = []): T[] {\n return this.db.prepare(sql).all(...params) as T[];\n }\n\n queryOne<T>(sql: string, params: unknown[] = []): T | undefined {\n return this.db.prepare(sql).get(...params) as T | undefined;\n }\n\n execute(sql: string, params: unknown[] = []): Database.RunResult {\n return this.db.prepare(sql).run(...params);\n }\n transaction<T>(fn: () => T): T {\n return this.db.transaction(fn)();\n }\n\n close(): void {\n if (this.db.open) {\n this.db.close();\n }\n }\n}\n\nlet instance: DatabaseConnection | null = null;\nlet schemaInitialized = false;\n\nexport function getDatabase(options?: DatabaseOptions): DatabaseConnection {\n if (!instance) {\n instance = new DatabaseConnection(options);\n }\n\n // Auto-run migrations on first access\n if (!schemaInitialized) {\n // Lazy import to avoid circular dependency\n const { initializeSchema } = require('./schema');\n initializeSchema(instance);\n schemaInitialized = true;\n }\n\n return instance;\n}\n\nexport function closeDatabase(): void {\n if (instance) {\n instance.close();\n instance = null;\n schemaInitialized = false;\n }\n}"],"names":["DEFAULT_DB_PATH","DatabaseConnection","closeDatabase","getDatabase","join","homedir","db","dbPath","options","dir","dirname","mkdirSync","recursive","Database","readonly","verbose","console","log","undefined","configure","pragma","instance","path","isOpen","open","query","sql","params","prepare","all","queryOne","get","execute","run","transaction","fn","close","schemaInitialized","initializeSchema","require"],"mappings":";;;;;;;;;;;QAQaA;eAAAA;;QAQAC;eAAAA;;QA+EGC;eAAAA;;QAhBAC;eAAAA;;;sEA/EK;oBACK;sBACI;oBACN;;;;;;AAKjB,MAAMH,kBAAkBI,IAAAA,UAAI,EAACC,IAAAA,WAAO,KAAI,cAAc;AAQtD,IAAA,AAAMJ,qBAAN,MAAMA;IACDK,GAAsB;IACbC,OAAe;IAEhC,YAAYC,UAA2B,CAAC,CAAC,CAAE;QACvC,IAAI,CAACD,MAAM,GAAGC,QAAQD,MAAM,IAAIP;QAEhC,MAAMS,MAAMC,IAAAA,aAAO,EAAC,IAAI,CAACH,MAAM;QAC/BI,IAAAA,aAAS,EAACF,KAAK;YAAEG,WAAW;QAAK;QAEjC,IAAI,CAACN,EAAE,GAAG,IAAIO,sBAAQ,CAAC,IAAI,CAACN,MAAM,EAAE;YAChCO,UAAUN,QAAQM,QAAQ,IAAI;YAC9BC,SAASP,QAAQO,OAAO,GAAGC,QAAQC,GAAG,GAAGC;QAC7C;QAEA,IAAI,CAACC,SAAS;IAClB;IAEQA,YAAkB;QACtB,IAAI,CAACb,EAAE,CAACc,MAAM,CAAC;QACf,IAAI,CAACd,EAAE,CAACc,MAAM,CAAC;QACf,IAAI,CAACd,EAAE,CAACc,MAAM,CAAC;QACf,IAAI,CAACd,EAAE,CAACc,MAAM,CAAC;QACf,IAAI,CAACd,EAAE,CAACc,MAAM,CAAC;IACnB;IAEA,IAAIC,WAA8B;QAC9B,OAAO,IAAI,CAACf,EAAE;IAClB;IAEA,IAAIgB,OAAe;QACf,OAAO,IAAI,CAACf,MAAM;IACtB;IAEA,IAAIgB,SAAkB;QAClB,OAAO,IAAI,CAACjB,EAAE,CAACkB,IAAI;IACvB;IAEAC,MAASC,GAAW,EAAEC,SAAoB,EAAE,EAAO;QAC/C,OAAO,IAAI,CAACrB,EAAE,CAACsB,OAAO,CAACF,KAAKG,GAAG,IAAIF;IACvC;IAEAG,SAAYJ,GAAW,EAAEC,SAAoB,EAAE,EAAiB;QAC5D,OAAO,IAAI,CAACrB,EAAE,CAACsB,OAAO,CAACF,KAAKK,GAAG,IAAIJ;IACvC;IAEAK,QAAQN,GAAW,EAAEC,SAAoB,EAAE,EAAsB;QAC7D,OAAO,IAAI,CAACrB,EAAE,CAACsB,OAAO,CAACF,KAAKO,GAAG,IAAIN;IACvC;IACAO,YAAeC,EAAW,EAAK;QAC3B,OAAO,IAAI,CAAC7B,EAAE,CAAC4B,WAAW,CAACC;IAC/B;IAEAC,QAAc;QACV,IAAI,IAAI,CAAC9B,EAAE,CAACkB,IAAI,EAAE;YACd,IAAI,CAAClB,EAAE,CAAC8B,KAAK;QACjB;IACJ;AACJ;AAEA,IAAIf,WAAsC;AAC1C,IAAIgB,oBAAoB;AAEjB,SAASlC,YAAYK,OAAyB;IACjD,IAAI,CAACa,UAAU;QACXA,WAAW,IAAIpB,mBAAmBO;IACtC;IAEA,sCAAsC;IACtC,IAAI,CAAC6B,mBAAmB;QACpB,2CAA2C;QAC3C,MAAM,EAAEC,gBAAgB,EAAE,GAAGC,QAAQ;QACrCD,iBAAiBjB;QACjBgB,oBAAoB;IACxB;IAEA,OAAOhB;AACX;AAEO,SAASnB;IACZ,IAAImB,UAAU;QACVA,SAASe,KAAK;QACdf,WAAW;QACXgB,oBAAoB;IACxB;AACJ"}
1
+ {"version":3,"sources":["../../src/database/connection.ts"],"sourcesContent":["import Database from 'better-sqlite3';\nimport { mkdirSync } from 'fs';\nimport { dirname, join } from 'path';\nimport { homedir } from 'os';\n\n/**\n * Default database path: ~/.ai-devkit/memory.db\n */\nexport const DEFAULT_DB_PATH = join(homedir(), '.ai-devkit', 'memory.db');\n\nexport interface DatabaseOptions {\n dbPath?: string;\n verbose?: boolean;\n readonly?: boolean;\n}\n\nexport class DatabaseConnection {\n private db: Database.Database;\n private readonly dbPath: string;\n\n constructor(options: DatabaseOptions = {}) {\n this.dbPath = options.dbPath ?? DEFAULT_DB_PATH;\n\n const dir = dirname(this.dbPath);\n mkdirSync(dir, { recursive: true });\n\n this.db = new Database(this.dbPath, {\n readonly: options.readonly ?? false,\n verbose: options.verbose ? console.log : undefined,\n });\n\n this.configure();\n }\n\n private configure(): void {\n this.db.pragma('journal_mode = WAL');\n this.db.pragma('foreign_keys = ON');\n this.db.pragma('synchronous = NORMAL');\n this.db.pragma('busy_timeout = 5000');\n this.db.pragma('mmap_size = 268435456');\n }\n\n get instance(): Database.Database {\n return this.db;\n }\n\n get path(): string {\n return this.dbPath;\n }\n\n get isOpen(): boolean {\n return this.db.open;\n }\n\n query<T>(sql: string, params: unknown[] = []): T[] {\n return this.db.prepare(sql).all(...params) as T[];\n }\n\n queryOne<T>(sql: string, params: unknown[] = []): T | undefined {\n return this.db.prepare(sql).get(...params) as T | undefined;\n }\n\n execute(sql: string, params: unknown[] = []): Database.RunResult {\n return this.db.prepare(sql).run(...params);\n }\n transaction<T>(fn: () => T): T {\n return this.db.transaction(fn)();\n }\n\n close(): void {\n if (this.db.open) {\n this.db.close();\n }\n }\n}\n\nlet instance: DatabaseConnection | null = null;\nlet schemaInitialized = false;\n\nexport function getDatabase(options?: DatabaseOptions): DatabaseConnection {\n if (!instance) {\n instance = new DatabaseConnection(options);\n }\n\n // Auto-run migrations on first access\n if (!schemaInitialized) {\n // Lazy import to avoid circular dependency\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const { initializeSchema } = require('./schema');\n initializeSchema(instance);\n schemaInitialized = true;\n }\n\n return instance;\n}\n\nexport function closeDatabase(): void {\n if (instance) {\n instance.close();\n instance = null;\n schemaInitialized = false;\n }\n}"],"names":["DEFAULT_DB_PATH","DatabaseConnection","closeDatabase","getDatabase","join","homedir","db","dbPath","options","dir","dirname","mkdirSync","recursive","Database","readonly","verbose","console","log","undefined","configure","pragma","instance","path","isOpen","open","query","sql","params","prepare","all","queryOne","get","execute","run","transaction","fn","close","schemaInitialized","initializeSchema","require"],"mappings":";;;;;;;;;;;QAQaA;eAAAA;;QAQAC;eAAAA;;QAgFGC;eAAAA;;QAjBAC;eAAAA;;;sEA/EK;oBACK;sBACI;oBACN;;;;;;AAKjB,MAAMH,kBAAkBI,IAAAA,UAAI,EAACC,IAAAA,WAAO,KAAI,cAAc;AAQtD,IAAA,AAAMJ,qBAAN,MAAMA;IACDK,GAAsB;IACbC,OAAe;IAEhC,YAAYC,UAA2B,CAAC,CAAC,CAAE;QACvC,IAAI,CAACD,MAAM,GAAGC,QAAQD,MAAM,IAAIP;QAEhC,MAAMS,MAAMC,IAAAA,aAAO,EAAC,IAAI,CAACH,MAAM;QAC/BI,IAAAA,aAAS,EAACF,KAAK;YAAEG,WAAW;QAAK;QAEjC,IAAI,CAACN,EAAE,GAAG,IAAIO,sBAAQ,CAAC,IAAI,CAACN,MAAM,EAAE;YAChCO,UAAUN,QAAQM,QAAQ,IAAI;YAC9BC,SAASP,QAAQO,OAAO,GAAGC,QAAQC,GAAG,GAAGC;QAC7C;QAEA,IAAI,CAACC,SAAS;IAClB;IAEQA,YAAkB;QACtB,IAAI,CAACb,EAAE,CAACc,MAAM,CAAC;QACf,IAAI,CAACd,EAAE,CAACc,MAAM,CAAC;QACf,IAAI,CAACd,EAAE,CAACc,MAAM,CAAC;QACf,IAAI,CAACd,EAAE,CAACc,MAAM,CAAC;QACf,IAAI,CAACd,EAAE,CAACc,MAAM,CAAC;IACnB;IAEA,IAAIC,WAA8B;QAC9B,OAAO,IAAI,CAACf,EAAE;IAClB;IAEA,IAAIgB,OAAe;QACf,OAAO,IAAI,CAACf,MAAM;IACtB;IAEA,IAAIgB,SAAkB;QAClB,OAAO,IAAI,CAACjB,EAAE,CAACkB,IAAI;IACvB;IAEAC,MAASC,GAAW,EAAEC,SAAoB,EAAE,EAAO;QAC/C,OAAO,IAAI,CAACrB,EAAE,CAACsB,OAAO,CAACF,KAAKG,GAAG,IAAIF;IACvC;IAEAG,SAAYJ,GAAW,EAAEC,SAAoB,EAAE,EAAiB;QAC5D,OAAO,IAAI,CAACrB,EAAE,CAACsB,OAAO,CAACF,KAAKK,GAAG,IAAIJ;IACvC;IAEAK,QAAQN,GAAW,EAAEC,SAAoB,EAAE,EAAsB;QAC7D,OAAO,IAAI,CAACrB,EAAE,CAACsB,OAAO,CAACF,KAAKO,GAAG,IAAIN;IACvC;IACAO,YAAeC,EAAW,EAAK;QAC3B,OAAO,IAAI,CAAC7B,EAAE,CAAC4B,WAAW,CAACC;IAC/B;IAEAC,QAAc;QACV,IAAI,IAAI,CAAC9B,EAAE,CAACkB,IAAI,EAAE;YACd,IAAI,CAAClB,EAAE,CAAC8B,KAAK;QACjB;IACJ;AACJ;AAEA,IAAIf,WAAsC;AAC1C,IAAIgB,oBAAoB;AAEjB,SAASlC,YAAYK,OAAyB;IACjD,IAAI,CAACa,UAAU;QACXA,WAAW,IAAIpB,mBAAmBO;IACtC;IAEA,sCAAsC;IACtC,IAAI,CAAC6B,mBAAmB;QACpB,2CAA2C;QAC3C,8DAA8D;QAC9D,MAAM,EAAEC,gBAAgB,EAAE,GAAGC,QAAQ;QACrCD,iBAAiBjB;QACjBgB,oBAAoB;IACxB;IAEA,OAAOhB;AACX;AAEO,SAASnB;IACZ,IAAImB,UAAU;QACVA,SAASe,KAAK;QACdf,WAAW;QACXgB,oBAAoB;IACxB;AACJ"}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- export {};
2
+ export * from './api';
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -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":";AAIA,cAAc,OAAO,CAAC"}
package/dist/index.js CHANGED
@@ -3,91 +3,24 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
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
- }
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
+ });
41
17
  }
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
18
  });
89
- } else {
90
- program.parse();
19
+ return from;
91
20
  }
21
+ (0, _server.runServer)().catch((error)=>{
22
+ console.error('Failed to start server:', error);
23
+ process.exit(1);
24
+ });
92
25
 
93
26
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +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"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { runServer } from './server';\n\nexport * from './api';\n\nrunServer().catch((error: Error) => {\n console.error('Failed to start server:', error);\n process.exit(1);\n});\n"],"names":["runServer","catch","error","console","process","exit"],"mappings":";;;;;wBAE0B;qBAEZ;;;;;;;;;;;;;;AAEdA,IAAAA,iBAAS,IAAGC,KAAK,CAAC,CAACC;IACfC,QAAQD,KAAK,CAAC,2BAA2BA;IACzCE,QAAQC,IAAI,CAAC;AACjB"}
@@ -27,7 +27,7 @@ _export(exports, {
27
27
  */ function escapeFtsSpecialChars(text) {
28
28
  // FTS5 special characters: " * ^ - : OR AND NOT ( )
29
29
  return text.replace(/"/g, '""') // Escape quotes by doubling
30
- .replace(/[*^():\-]/g, ' ') // Replace operators with space (including hyphen)
30
+ .replace(/[*^():-]/g, ' ') // Replace operators with space (including hyphen)
31
31
  .replace(/\b(AND|OR|NOT)\b/gi, '') // Remove boolean operators
32
32
  .trim().replace(/\s+/g, ' '); // Collapse multiple spaces
33
33
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/services/search.ts"],"sourcesContent":["/**\n * FTS5 Query Builder\n * Converts natural language queries to FTS5 match expressions\n */\n\n/**\n * Escape special FTS5 characters to prevent query syntax errors\n */\nfunction escapeFtsSpecialChars(text: string): string {\n // FTS5 special characters: \" * ^ - : OR AND NOT ( )\n return text\n .replace(/\"/g, '\"\"') // Escape quotes by doubling\n .replace(/[*^():\\-]/g, ' ') // Replace operators with space (including hyphen)\n .replace(/\\b(AND|OR|NOT)\\b/gi, '') // Remove boolean operators\n .trim()\n .replace(/\\s+/g, ' '); // Collapse multiple spaces\n}\n\n/**\n * Build FTS5 query from natural language input\n * \n * Strategy:\n * - Split query into words\n * - Use prefix matching (*) for partial matches\n * - Escape special characters\n */\nexport function buildFtsQuery(query: string): string {\n const escaped = escapeFtsSpecialChars(query);\n const words = escaped.split(/\\s+/).filter(w => w.length > 0);\n\n if (words.length === 0) {\n return '';\n }\n\n // Use prefix matching for each word\n // This allows \"api design\" to match \"API\", \"designing\", etc.\n return words.map(word => `${word}*`).join(' ');\n}\n\n/**\n * Build FTS5 query with column boosting\n * Uses bm25() with weights: title=10, content=5, tags=1\n */\nexport function buildSearchQuery(\n ftsQuery: string,\n scope?: string | null,\n limit = 5\n): { sql: string; params: unknown[] } {\n const params: unknown[] = [];\n\n let sql = `\n SELECT \n k.id,\n k.title,\n k.content,\n k.tags,\n k.scope,\n k.created_at,\n k.updated_at,\n bm25(knowledge_fts, 10.0, 5.0, 1.0) as bm25_score\n FROM knowledge k\n JOIN knowledge_fts fts ON k.rowid = fts.rowid\n WHERE knowledge_fts MATCH ?\n `;\n params.push(ftsQuery);\n\n if (scope) {\n sql += ` AND (k.scope = ? OR k.scope = 'global')`;\n params.push(scope);\n }\n\n sql += ` ORDER BY bm25_score LIMIT ?`;\n params.push(limit);\n\n return { sql, params };\n}\n\n/**\n * Build simple search query without FTS (fallback for empty queries)\n */\nexport function buildSimpleQuery(\n scope?: string | null,\n limit = 5\n): { sql: string; params: unknown[] } {\n const params: unknown[] = [];\n\n let sql = `\n SELECT \n id, title, content, tags, scope, created_at, updated_at,\n 0 as bm25_score\n FROM knowledge\n `;\n\n if (scope) {\n sql += ` WHERE scope = ? OR scope = 'global'`;\n params.push(scope);\n }\n\n sql += ` ORDER BY created_at DESC LIMIT ?`;\n params.push(limit);\n\n return { sql, params };\n}\n"],"names":["buildFtsQuery","buildSearchQuery","buildSimpleQuery","escapeFtsSpecialChars","text","replace","trim","query","escaped","words","split","filter","w","length","map","word","join","ftsQuery","scope","limit","params","sql","push"],"mappings":";;;;;;;;;;;QA0BgBA;eAAAA;;QAiBAC;eAAAA;;QAqCAC;eAAAA;;;AAhFhB;;;CAGC,GAED;;CAEC,GACD,SAASC,sBAAsBC,IAAY;IACvC,oDAAoD;IACpD,OAAOA,KACFC,OAAO,CAAC,MAAM,MAAO,4BAA4B;KACjDA,OAAO,CAAC,cAAc,KAAM,kDAAkD;KAC9EA,OAAO,CAAC,sBAAsB,IAAK,2BAA2B;KAC9DC,IAAI,GACJD,OAAO,CAAC,QAAQ,MAAO,2BAA2B;AAC3D;AAUO,SAASL,cAAcO,KAAa;IACvC,MAAMC,UAAUL,sBAAsBI;IACtC,MAAME,QAAQD,QAAQE,KAAK,CAAC,OAAOC,MAAM,CAACC,CAAAA,IAAKA,EAAEC,MAAM,GAAG;IAE1D,IAAIJ,MAAMI,MAAM,KAAK,GAAG;QACpB,OAAO;IACX;IAEA,oCAAoC;IACpC,6DAA6D;IAC7D,OAAOJ,MAAMK,GAAG,CAACC,CAAAA,OAAQ,GAAGA,KAAK,CAAC,CAAC,EAAEC,IAAI,CAAC;AAC9C;AAMO,SAASf,iBACZgB,QAAgB,EAChBC,KAAqB,EACrBC,QAAQ,CAAC;IAET,MAAMC,SAAoB,EAAE;IAE5B,IAAIC,MAAM,CAAC;;;;;;;;;;;;;EAab,CAAC;IACCD,OAAOE,IAAI,CAACL;IAEZ,IAAIC,OAAO;QACPG,OAAO,CAAC,wCAAwC,CAAC;QACjDD,OAAOE,IAAI,CAACJ;IAChB;IAEAG,OAAO,CAAC,4BAA4B,CAAC;IACrCD,OAAOE,IAAI,CAACH;IAEZ,OAAO;QAAEE;QAAKD;IAAO;AACzB;AAKO,SAASlB,iBACZgB,KAAqB,EACrBC,QAAQ,CAAC;IAET,MAAMC,SAAoB,EAAE;IAE5B,IAAIC,MAAM,CAAC;;;;;EAKb,CAAC;IAEC,IAAIH,OAAO;QACPG,OAAO,CAAC,oCAAoC,CAAC;QAC7CD,OAAOE,IAAI,CAACJ;IAChB;IAEAG,OAAO,CAAC,iCAAiC,CAAC;IAC1CD,OAAOE,IAAI,CAACH;IAEZ,OAAO;QAAEE;QAAKD;IAAO;AACzB"}
1
+ {"version":3,"sources":["../../src/services/search.ts"],"sourcesContent":["/**\n * FTS5 Query Builder\n * Converts natural language queries to FTS5 match expressions\n */\n\n/**\n * Escape special FTS5 characters to prevent query syntax errors\n */\nfunction escapeFtsSpecialChars(text: string): string {\n // FTS5 special characters: \" * ^ - : OR AND NOT ( )\n return text\n .replace(/\"/g, '\"\"') // Escape quotes by doubling\n .replace(/[*^():-]/g, ' ') // Replace operators with space (including hyphen)\n .replace(/\\b(AND|OR|NOT)\\b/gi, '') // Remove boolean operators\n .trim()\n .replace(/\\s+/g, ' '); // Collapse multiple spaces\n}\n\n/**\n * Build FTS5 query from natural language input\n * \n * Strategy:\n * - Split query into words\n * - Use prefix matching (*) for partial matches\n * - Escape special characters\n */\nexport function buildFtsQuery(query: string): string {\n const escaped = escapeFtsSpecialChars(query);\n const words = escaped.split(/\\s+/).filter(w => w.length > 0);\n\n if (words.length === 0) {\n return '';\n }\n\n // Use prefix matching for each word\n // This allows \"api design\" to match \"API\", \"designing\", etc.\n return words.map(word => `${word}*`).join(' ');\n}\n\n/**\n * Build FTS5 query with column boosting\n * Uses bm25() with weights: title=10, content=5, tags=1\n */\nexport function buildSearchQuery(\n ftsQuery: string,\n scope?: string | null,\n limit = 5\n): { sql: string; params: unknown[] } {\n const params: unknown[] = [];\n\n let sql = `\n SELECT \n k.id,\n k.title,\n k.content,\n k.tags,\n k.scope,\n k.created_at,\n k.updated_at,\n bm25(knowledge_fts, 10.0, 5.0, 1.0) as bm25_score\n FROM knowledge k\n JOIN knowledge_fts fts ON k.rowid = fts.rowid\n WHERE knowledge_fts MATCH ?\n `;\n params.push(ftsQuery);\n\n if (scope) {\n sql += ` AND (k.scope = ? OR k.scope = 'global')`;\n params.push(scope);\n }\n\n sql += ` ORDER BY bm25_score LIMIT ?`;\n params.push(limit);\n\n return { sql, params };\n}\n\n/**\n * Build simple search query without FTS (fallback for empty queries)\n */\nexport function buildSimpleQuery(\n scope?: string | null,\n limit = 5\n): { sql: string; params: unknown[] } {\n const params: unknown[] = [];\n\n let sql = `\n SELECT \n id, title, content, tags, scope, created_at, updated_at,\n 0 as bm25_score\n FROM knowledge\n `;\n\n if (scope) {\n sql += ` WHERE scope = ? OR scope = 'global'`;\n params.push(scope);\n }\n\n sql += ` ORDER BY created_at DESC LIMIT ?`;\n params.push(limit);\n\n return { sql, params };\n}\n"],"names":["buildFtsQuery","buildSearchQuery","buildSimpleQuery","escapeFtsSpecialChars","text","replace","trim","query","escaped","words","split","filter","w","length","map","word","join","ftsQuery","scope","limit","params","sql","push"],"mappings":";;;;;;;;;;;QA0BgBA;eAAAA;;QAiBAC;eAAAA;;QAqCAC;eAAAA;;;AAhFhB;;;CAGC,GAED;;CAEC,GACD,SAASC,sBAAsBC,IAAY;IACvC,oDAAoD;IACpD,OAAOA,KACFC,OAAO,CAAC,MAAM,MAAO,4BAA4B;KACjDA,OAAO,CAAC,aAAa,KAAM,kDAAkD;KAC7EA,OAAO,CAAC,sBAAsB,IAAK,2BAA2B;KAC9DC,IAAI,GACJD,OAAO,CAAC,QAAQ,MAAO,2BAA2B;AAC3D;AAUO,SAASL,cAAcO,KAAa;IACvC,MAAMC,UAAUL,sBAAsBI;IACtC,MAAME,QAAQD,QAAQE,KAAK,CAAC,OAAOC,MAAM,CAACC,CAAAA,IAAKA,EAAEC,MAAM,GAAG;IAE1D,IAAIJ,MAAMI,MAAM,KAAK,GAAG;QACpB,OAAO;IACX;IAEA,oCAAoC;IACpC,6DAA6D;IAC7D,OAAOJ,MAAMK,GAAG,CAACC,CAAAA,OAAQ,GAAGA,KAAK,CAAC,CAAC,EAAEC,IAAI,CAAC;AAC9C;AAMO,SAASf,iBACZgB,QAAgB,EAChBC,KAAqB,EACrBC,QAAQ,CAAC;IAET,MAAMC,SAAoB,EAAE;IAE5B,IAAIC,MAAM,CAAC;;;;;;;;;;;;;EAab,CAAC;IACCD,OAAOE,IAAI,CAACL;IAEZ,IAAIC,OAAO;QACPG,OAAO,CAAC,wCAAwC,CAAC;QACjDD,OAAOE,IAAI,CAACJ;IAChB;IAEAG,OAAO,CAAC,4BAA4B,CAAC;IACrCD,OAAOE,IAAI,CAACH;IAEZ,OAAO;QAAEE;QAAKD;IAAO;AACzB;AAKO,SAASlB,iBACZgB,KAAqB,EACrBC,QAAQ,CAAC;IAET,MAAMC,SAAoB,EAAE;IAE5B,IAAIC,MAAM,CAAC;;;;;EAKb,CAAC;IAEC,IAAIH,OAAO;QACPG,OAAO,CAAC,oCAAoC,CAAC;QAC7CD,OAAOE,IAAI,CAACJ;IAChB;IAEAG,OAAO,CAAC,iCAAiC,CAAC;IAC1CD,OAAOE,IAAI,CAACH;IAEZ,OAAO;QAAEE;QAAKD;IAAO;AACzB"}
package/package.json CHANGED
@@ -1,67 +1,68 @@
1
1
  {
2
- "name": "@ai-devkit/memory",
3
- "version": "0.1.0",
4
- "description": "Lightweight MCP-based memory service for AI agents - store and retrieve actionable knowledge",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
7
- "exports": {
8
- ".": {
9
- "types": "./dist/index.d.ts",
10
- "default": "./dist/index.js"
11
- },
12
- "./api": {
13
- "types": "./dist/api.d.ts",
14
- "default": "./dist/api.js"
15
- }
2
+ "name": "@ai-devkit/memory",
3
+ "version": "0.3.0",
4
+ "description": "Lightweight MCP-based memory service for AI agents - store and retrieve actionable knowledge",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "default": "./dist/index.js"
16
11
  },
17
- "bin": {
18
- "ai-devkit-memory": "./dist/index.js"
19
- },
20
- "scripts": {
21
- "build": "swc src -d dist --strip-leading-paths && tsc --emitDeclarationOnly && cp -r src/database/migrations dist/database/",
22
- "dev": "swc src -d dist --strip-leading-paths --watch",
23
- "start": "node dist/index.js",
24
- "inspect": "npm run build && npx @modelcontextprotocol/inspector node dist/index.js",
25
- "typecheck": "tsc --noEmit",
26
- "test": "jest",
27
- "test:coverage": "jest --coverage",
28
- "lint": "eslint src/**/*.ts",
29
- "clean": "rm -rf dist"
30
- },
31
- "keywords": [
32
- "mcp",
33
- "memory",
34
- "ai",
35
- "agent",
36
- "knowledge",
37
- "sqlite",
38
- "fts5"
39
- ],
40
- "author": "",
41
- "license": "MIT",
42
- "dependencies": {
43
- "@modelcontextprotocol/sdk": "^1.0.0",
44
- "better-sqlite3": "^11.0.0",
45
- "commander": "^12.0.0",
46
- "uuid": "^10.0.0"
47
- },
48
- "devDependencies": {
49
- "@swc/cli": "^0.5.2",
50
- "@swc/core": "^1.10.0",
51
- "@swc/jest": "^0.2.37",
52
- "@types/better-sqlite3": "^7.6.11",
53
- "@types/jest": "^29.5.12",
54
- "@types/node": "^20.14.0",
55
- "@types/uuid": "^10.0.0",
56
- "chokidar": "^3.6.0",
57
- "jest": "^29.7.0",
58
- "typescript": "^5.4.5"
59
- },
60
- "engines": {
61
- "node": ">=18.0.0"
62
- },
63
- "files": [
64
- "dist",
65
- "README.md"
66
- ]
67
- }
12
+ "./api": {
13
+ "types": "./dist/api.d.ts",
14
+ "default": "./dist/api.js"
15
+ }
16
+ },
17
+ "bin": {
18
+ "ai-devkit-memory": "./dist/index.js"
19
+ },
20
+ "scripts": {
21
+ "build": "swc src -d dist --strip-leading-paths && tsc --emitDeclarationOnly && cp -r src/database/migrations dist/database/",
22
+ "dev": "swc src -d dist --strip-leading-paths --watch",
23
+ "start": "node dist/index.js",
24
+ "inspect": "npm run build && npx @modelcontextprotocol/inspector node dist/index.js",
25
+ "typecheck": "tsc --noEmit",
26
+ "test": "jest",
27
+ "test:coverage": "jest --coverage",
28
+ "lint": "eslint src/**/*.ts",
29
+ "clean": "rm -rf dist",
30
+ "benchmark": "npx ts-node --swc scripts/benchmark.ts --items=5000 --searches=300"
31
+ },
32
+ "keywords": [
33
+ "mcp",
34
+ "memory",
35
+ "ai",
36
+ "agent",
37
+ "knowledge",
38
+ "sqlite",
39
+ "fts5"
40
+ ],
41
+ "author": "",
42
+ "license": "MIT",
43
+ "dependencies": {
44
+ "@modelcontextprotocol/sdk": "^1.0.0",
45
+ "better-sqlite3": "^11.0.0",
46
+ "uuid": "^10.0.0"
47
+ },
48
+ "devDependencies": {
49
+ "@swc/cli": "^0.5.2",
50
+ "@swc/core": "^1.10.0",
51
+ "@swc/jest": "^0.2.37",
52
+ "@types/better-sqlite3": "^7.6.11",
53
+ "@types/jest": "^29.5.12",
54
+ "@types/node": "^20.14.0",
55
+ "@types/uuid": "^10.0.0",
56
+ "chokidar": "^3.6.0",
57
+ "jest": "^29.7.0",
58
+ "ts-node": "^10.9.2",
59
+ "typescript": "^5.4.5"
60
+ },
61
+ "engines": {
62
+ "node": ">=18.0.0"
63
+ },
64
+ "files": [
65
+ "dist",
66
+ "README.md"
67
+ ]
68
+ }