capman 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.
Files changed (78) hide show
  1. package/bin/capman.js +152 -6
  2. package/dist/cjs/cache.d.ts +42 -0
  3. package/dist/cjs/cache.d.ts.map +1 -0
  4. package/dist/cjs/cache.js +181 -0
  5. package/dist/cjs/cache.js.map +1 -0
  6. package/dist/cjs/engine.d.ts +82 -0
  7. package/dist/cjs/engine.d.ts.map +1 -0
  8. package/dist/cjs/engine.js +154 -0
  9. package/dist/cjs/engine.js.map +1 -0
  10. package/dist/cjs/generator.d.ts.map +1 -0
  11. package/dist/{generator.js → cjs/generator.js} +2 -1
  12. package/dist/cjs/generator.js.map +1 -0
  13. package/dist/{index.d.ts → cjs/index.d.ts} +18 -1
  14. package/dist/cjs/index.d.ts.map +1 -0
  15. package/dist/cjs/index.js +77 -0
  16. package/dist/cjs/index.js.map +1 -0
  17. package/dist/cjs/learning.d.ts +56 -0
  18. package/dist/cjs/learning.d.ts.map +1 -0
  19. package/dist/cjs/learning.js +184 -0
  20. package/dist/cjs/learning.js.map +1 -0
  21. package/dist/cjs/logger.d.ts.map +1 -0
  22. package/dist/cjs/logger.js.map +1 -0
  23. package/dist/cjs/matcher.d.ts.map +1 -0
  24. package/dist/{matcher.js → cjs/matcher.js} +27 -5
  25. package/dist/cjs/matcher.js.map +1 -0
  26. package/dist/cjs/resolver.d.ts.map +1 -0
  27. package/dist/{resolver.js → cjs/resolver.js} +36 -4
  28. package/dist/cjs/resolver.js.map +1 -0
  29. package/dist/{schema.d.ts → cjs/schema.d.ts} +10 -10
  30. package/dist/{schema.d.ts.map → cjs/schema.d.ts.map} +1 -1
  31. package/dist/cjs/schema.js.map +1 -0
  32. package/dist/{types.d.ts → cjs/types.d.ts} +12 -5
  33. package/dist/cjs/types.d.ts.map +1 -0
  34. package/dist/cjs/types.js.map +1 -0
  35. package/dist/cjs/version.d.ts +2 -0
  36. package/dist/cjs/version.d.ts.map +1 -0
  37. package/dist/cjs/version.js +6 -0
  38. package/dist/cjs/version.js.map +1 -0
  39. package/dist/esm/cache.js +141 -0
  40. package/dist/esm/engine.js +149 -0
  41. package/dist/esm/generator.js +183 -0
  42. package/dist/esm/generator.js.map +1 -0
  43. package/dist/esm/index.js +56 -0
  44. package/dist/esm/index.js.map +1 -0
  45. package/dist/esm/learning.js +145 -0
  46. package/dist/esm/logger.js +47 -0
  47. package/dist/esm/logger.js.map +1 -0
  48. package/dist/esm/matcher.js +211 -0
  49. package/dist/esm/matcher.js.map +1 -0
  50. package/dist/esm/resolver.js +192 -0
  51. package/dist/esm/resolver.js.map +1 -0
  52. package/dist/esm/schema.js +88 -0
  53. package/dist/esm/schema.js.map +1 -0
  54. package/dist/esm/types.js +2 -0
  55. package/dist/esm/types.js.map +1 -0
  56. package/dist/esm/version.js +2 -0
  57. package/package.json +27 -11
  58. package/dist/generator.d.ts.map +0 -1
  59. package/dist/generator.js.map +0 -1
  60. package/dist/index.d.ts.map +0 -1
  61. package/dist/index.js +0 -42
  62. package/dist/index.js.map +0 -1
  63. package/dist/logger.d.ts.map +0 -1
  64. package/dist/logger.js.map +0 -1
  65. package/dist/matcher.d.ts.map +0 -1
  66. package/dist/matcher.js.map +0 -1
  67. package/dist/resolver.d.ts.map +0 -1
  68. package/dist/resolver.js.map +0 -1
  69. package/dist/schema.js.map +0 -1
  70. package/dist/types.d.ts.map +0 -1
  71. package/dist/types.js.map +0 -1
  72. /package/dist/{generator.d.ts → cjs/generator.d.ts} +0 -0
  73. /package/dist/{logger.d.ts → cjs/logger.d.ts} +0 -0
  74. /package/dist/{logger.js → cjs/logger.js} +0 -0
  75. /package/dist/{matcher.d.ts → cjs/matcher.d.ts} +0 -0
  76. /package/dist/{resolver.d.ts → cjs/resolver.d.ts} +0 -0
  77. /package/dist/{schema.js → cjs/schema.js} +0 -0
  78. /package/dist/{types.js → cjs/types.js} +0 -0
package/bin/capman.js CHANGED
@@ -32,23 +32,31 @@ const log = {
32
32
  }
33
33
 
34
34
  function header() {
35
+ const pkg = require(path.join(__dirname, '..', 'package.json'))
35
36
  console.log()
36
- console.log(`${c.bold}${c.teal} capman${c.reset} ${c.gray}v0.1.0 — Capability Manifest Engine${c.reset}`)
37
+ console.log(`${c.bold}${c.teal} capman${c.reset} ${c.gray}v${pkg.version} — Capability Manifest Engine${c.reset}`)
37
38
  console.log(`${c.gray} ─────────────────────────────────────────${c.reset}`)
38
39
  console.log()
39
40
  }
40
41
 
41
42
  function requireSrc() {
42
- const distPath = path.join(__dirname, '..', 'dist', 'index.js')
43
+ const distPath = path.join(__dirname, '..', 'dist', 'cjs', 'index.js')
43
44
  if (fs.existsSync(distPath)) return require(distPath)
44
45
 
46
+ // dist not built — try to build automatically
47
+ log.info('dist/cjs not found — running build...')
45
48
  try {
46
- require('ts-node/register')
47
- return require(path.join(__dirname, '..', 'src', 'index.ts'))
49
+ require('child_process').execSync('npm run build', {
50
+ cwd: path.join(__dirname, '..'),
51
+ stdio: 'inherit'
52
+ })
53
+ if (fs.existsSync(distPath)) return require(distPath)
48
54
  } catch {
49
- log.error('Cannot find dist/. Run: npx tsc')
50
- process.exit(1)
55
+ // build failed
51
56
  }
57
+
58
+ log.error('Cannot find dist/cjs/. Run: pnpm run build')
59
+ process.exit(1)
52
60
  }
53
61
 
54
62
  function cmdHelp() {
@@ -60,6 +68,7 @@ function cmdHelp() {
60
68
  console.log(` ${c.teal}generate${c.reset} Generate manifest.json from config`)
61
69
  console.log(` ${c.teal}validate${c.reset} Validate an existing manifest.json`)
62
70
  console.log(` ${c.teal}inspect${c.reset} Print all capabilities in manifest`)
71
+ console.log(` ${c.teal}demo${c.reset} Run a live demo with sample queries`)
63
72
  console.log()
64
73
  console.log(`${c.bold} Options:${c.reset}`)
65
74
  console.log(` ${c.gray}--config Path to config file (default: capman.config.js)${c.reset}`)
@@ -176,11 +185,148 @@ function cmdInspect() {
176
185
  }
177
186
  }
178
187
 
188
+ function cmdDemo() {
189
+ header()
190
+ const { generate, match, resolve } = requireSrc()
191
+
192
+ console.log(`${c.bold} Live demo — see capman in action${c.reset}`)
193
+ console.log(`${c.gray} ─────────────────────────────────────────${c.reset}\n`)
194
+
195
+ // Demo manifest — generic e-commerce app
196
+ const config = {
197
+ app: 'demo-store',
198
+ baseUrl: 'https://api.demo-store.com',
199
+ capabilities: [
200
+ {
201
+ id: 'check_product_availability',
202
+ name: 'Check product availability',
203
+ description: 'Check stock and pricing for a product by name or ID.',
204
+ examples: [
205
+ 'Is the blue jacket in stock?',
206
+ 'Check stock for blue jacket',
207
+ 'Do you have size M available?',
208
+ 'Product availability for jacket',
209
+ 'Is jacket available?',
210
+ ],
211
+ params: [
212
+ { name: 'product', description: 'Product name or ID', required: true, source: 'user_query' }
213
+ ],
214
+ returns: ['stock', 'price', 'variants'],
215
+ resolver: { type: 'api', endpoints: [{ method: 'GET', path: '/products/{product}/availability' }] },
216
+ privacy: { level: 'public' },
217
+ },
218
+ {
219
+ id: 'get_order_status',
220
+ name: 'Get order status',
221
+ description: 'Retrieve the current status and tracking info for an order.',
222
+ examples: [
223
+ 'Where is my order?',
224
+ 'Track order 1234',
225
+ 'What is the status of my recent purchase?',
226
+ ],
227
+ params: [
228
+ { name: 'order_id', description: 'Order ID', required: true, source: 'user_query' }
229
+ ],
230
+ returns: ['status', 'tracking', 'estimated_delivery'],
231
+ resolver: { type: 'api', endpoints: [{ method: 'GET', path: '/orders/{order_id}' }] },
232
+ privacy: { level: 'user_owned' },
233
+ },
234
+ {
235
+ id: 'navigate_to_screen',
236
+ name: 'Navigate to screen',
237
+ description: 'Route the user to a specific page in the store.',
238
+ examples: [
239
+ 'Take me to cart',
240
+ 'Open cart',
241
+ 'Go to checkout',
242
+ 'Navigate to account',
243
+ 'Show homepage',
244
+ ],
245
+ params: [
246
+ { name: 'destination', description: 'Target screen', required: true, source: 'user_query' }
247
+ ],
248
+ returns: ['deep_link'],
249
+ resolver: { type: 'nav', destination: '/{destination}' },
250
+ privacy: { level: 'public' },
251
+ },
252
+ ],
253
+ }
254
+
255
+ const manifest = generate(config)
256
+
257
+ const queries = [
258
+ 'Check availability for blue jacket',
259
+ 'Track order 1234',
260
+ 'Go to cart',
261
+ 'Is the website down?',
262
+ ]
263
+
264
+ console.log(`${c.gray} App: ${c.reset}${c.bold}${config.app}${c.reset}`)
265
+ console.log(`${c.gray} Capabilities: ${c.reset}${manifest.capabilities.length}`)
266
+ console.log(`${c.gray} Mode: keyword matcher (no LLM required)\n${c.reset}`)
267
+
268
+ let passed = 0
269
+ let outOfScope = 0
270
+
271
+ for (const query of queries) {
272
+ const start = Date.now()
273
+ const result = match(query, manifest)
274
+ const duration = Date.now() - start
275
+
276
+ if (result.capability) {
277
+ passed++
278
+ const resolverColor = result.capability.resolver.type === 'api' ? c.teal :
279
+ result.capability.resolver.type === 'nav' ? c.teal : c.yellow
280
+
281
+ console.log(` ${c.green}✓${c.reset} ${c.bold}"${query}"${c.reset}`)
282
+ console.log(` ${c.gray}→ matched:${c.reset} ${resolverColor}${result.capability.id}${c.reset}`)
283
+ console.log(` ${c.gray}→ intent:${c.reset} ${result.intent}`)
284
+ console.log(` ${c.gray}→ confidence:${c.reset} ${result.confidence}%`)
285
+
286
+ if (Object.keys(result.extractedParams).length > 0) {
287
+ const params = Object.entries(result.extractedParams)
288
+ .map(([k, v]) => `${k}=${v}`)
289
+ .join(', ')
290
+ console.log(` ${c.gray}→ params:${c.reset} ${params}`)
291
+ }
292
+
293
+ // Show what API call would be made
294
+ if (result.capability.resolver.type === 'api') {
295
+ const endpoint = result.capability.resolver.endpoints[0]
296
+ let path = endpoint.path
297
+ for (const [k, v] of Object.entries(result.extractedParams)) {
298
+ if (v) path = path.replace(`{${k}}`, v)
299
+ }
300
+ console.log(` ${c.gray}→ api call:${c.reset} ${endpoint.method} ${config.baseUrl}${path}`)
301
+ } else if (result.capability.resolver.type === 'nav') {
302
+ let dest = result.capability.resolver.destination
303
+ for (const [k, v] of Object.entries(result.extractedParams)) {
304
+ if (v) dest = dest.replace(`{${k}}`, v)
305
+ }
306
+ console.log(` ${c.gray}→ nav target:${c.reset} ${dest}`)
307
+ }
308
+
309
+ console.log(` ${c.gray}→ time:${c.reset} ${duration}ms\n`)
310
+ } else {
311
+ outOfScope++
312
+ console.log(` ${c.yellow}○${c.reset} ${c.bold}"${query}"${c.reset}`)
313
+ console.log(` ${c.gray}→ out of scope — no capability handles this\n${c.reset}`)
314
+ }
315
+ }
316
+
317
+ console.log(`${c.gray} ─────────────────────────────────────────${c.reset}`)
318
+ console.log(` ${c.green}${passed} matched${c.reset} ${c.gray}·${c.reset} ${c.yellow}${outOfScope} out of scope${c.reset} ${c.gray}·${c.reset} ${manifest.capabilities.length} capabilities\n`)
319
+ console.log(` ${c.gray}Try it on your own app:${c.reset}`)
320
+ console.log(` ${c.teal}npx capman init${c.reset} ${c.gray}→ create your manifest${c.reset}`)
321
+ console.log(` ${c.teal}npx capman generate${c.reset} ${c.gray}→ generate manifest.json${c.reset}\n`)
322
+ }
323
+
179
324
  switch (command) {
180
325
  case 'init': cmdInit(); break
181
326
  case 'generate': cmdGenerate(); break
182
327
  case 'validate': cmdValidate(); break
183
328
  case 'inspect': cmdInspect(); break
329
+ case 'demo': cmdDemo(); break
184
330
  case undefined:
185
331
  case '--help':
186
332
  case '-h': cmdHelp(); break
@@ -0,0 +1,42 @@
1
+ import type { MatchResult } from './types';
2
+ export interface CacheEntry {
3
+ query: string;
4
+ result: MatchResult;
5
+ cachedAt: string;
6
+ hits: number;
7
+ }
8
+ export interface CacheStore {
9
+ get(query: string): Promise<CacheEntry | null>;
10
+ set(query: string, result: MatchResult): Promise<void>;
11
+ clear(): Promise<void>;
12
+ size(): Promise<number>;
13
+ }
14
+ export declare class MemoryCache implements CacheStore {
15
+ private store;
16
+ get(query: string): Promise<CacheEntry | null>;
17
+ set(query: string, result: MatchResult): Promise<void>;
18
+ clear(): Promise<void>;
19
+ size(): Promise<number>;
20
+ }
21
+ export declare class FileCache implements CacheStore {
22
+ private filePath;
23
+ private store;
24
+ private loaded;
25
+ constructor(filePath?: string);
26
+ private load;
27
+ private save;
28
+ get(query: string): Promise<CacheEntry | null>;
29
+ set(query: string, result: MatchResult): Promise<void>;
30
+ clear(): Promise<void>;
31
+ size(): Promise<number>;
32
+ }
33
+ export declare class ComboCache implements CacheStore {
34
+ private memory;
35
+ private file;
36
+ constructor(filePath?: string);
37
+ get(query: string): Promise<CacheEntry | null>;
38
+ set(query: string, result: MatchResult): Promise<void>;
39
+ clear(): Promise<void>;
40
+ size(): Promise<number>;
41
+ }
42
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/cache.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAK1C,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,WAAW,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;CACb;AAID,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAA;IAC9C,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACtD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACtB,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;CACxB;AAUD,qBAAa,WAAY,YAAW,UAAU;IAC5C,OAAO,CAAC,KAAK,CAAgC;IAEvC,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAW9C,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAWtD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;CAG9B;AAID,qBAAa,SAAU,YAAW,UAAU;IAC1C,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,KAAK,CAAqC;IAClD,OAAO,CAAC,MAAM,CAAQ;gBAEV,QAAQ,SAAuB;IAI3C,OAAO,CAAC,IAAI;IAcZ,OAAO,CAAC,IAAI;IAWN,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAY9C,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAatD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAKtB,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;CAI9B;AAID,qBAAa,UAAW,YAAW,UAAU;IAC3C,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,IAAI,CAAW;gBAEX,QAAQ,SAAuB;IAKrC,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAgB9C,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAOtD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAOtB,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;CAG9B"}
@@ -0,0 +1,181 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.ComboCache = exports.FileCache = exports.MemoryCache = void 0;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const logger_1 = require("./logger");
40
+ // ─── Normalize query for cache key ────────────────────────────────────────────
41
+ function normalizeQuery(query) {
42
+ return query.toLowerCase().trim().replace(/\s+/g, ' ');
43
+ }
44
+ // ─── Memory Cache ─────────────────────────────────────────────────────────────
45
+ class MemoryCache {
46
+ constructor() {
47
+ this.store = new Map();
48
+ }
49
+ async get(query) {
50
+ const key = normalizeQuery(query);
51
+ const entry = this.store.get(key);
52
+ if (entry) {
53
+ entry.hits++;
54
+ logger_1.logger.debug(`Cache hit (memory): "${query}"`);
55
+ return entry;
56
+ }
57
+ return null;
58
+ }
59
+ async set(query, result) {
60
+ const key = normalizeQuery(query);
61
+ this.store.set(key, {
62
+ query,
63
+ result,
64
+ cachedAt: new Date().toISOString(),
65
+ hits: 0,
66
+ });
67
+ logger_1.logger.debug(`Cache set (memory): "${query}"`);
68
+ }
69
+ async clear() {
70
+ this.store.clear();
71
+ }
72
+ async size() {
73
+ return this.store.size;
74
+ }
75
+ }
76
+ exports.MemoryCache = MemoryCache;
77
+ // ─── File Cache ───────────────────────────────────────────────────────────────
78
+ class FileCache {
79
+ constructor(filePath = '.capman/cache.json') {
80
+ this.store = new Map();
81
+ this.loaded = false;
82
+ this.filePath = path.resolve(process.cwd(), filePath);
83
+ }
84
+ load() {
85
+ if (this.loaded)
86
+ return;
87
+ try {
88
+ if (fs.existsSync(this.filePath)) {
89
+ const raw = JSON.parse(fs.readFileSync(this.filePath, 'utf-8'));
90
+ this.store = new Map(Object.entries(raw));
91
+ logger_1.logger.debug(`File cache loaded: ${this.store.size} entries`);
92
+ }
93
+ }
94
+ catch {
95
+ logger_1.logger.warn(`Failed to load file cache at ${this.filePath}`);
96
+ }
97
+ this.loaded = true;
98
+ }
99
+ save() {
100
+ try {
101
+ const dir = path.dirname(this.filePath);
102
+ if (!fs.existsSync(dir))
103
+ fs.mkdirSync(dir, { recursive: true });
104
+ const obj = Object.fromEntries(this.store);
105
+ fs.writeFileSync(this.filePath, JSON.stringify(obj, null, 2));
106
+ }
107
+ catch {
108
+ logger_1.logger.warn(`Failed to save file cache to ${this.filePath}`);
109
+ }
110
+ }
111
+ async get(query) {
112
+ this.load();
113
+ const key = normalizeQuery(query);
114
+ const entry = this.store.get(key);
115
+ if (entry) {
116
+ entry.hits++;
117
+ logger_1.logger.debug(`Cache hit (file): "${query}"`);
118
+ return entry;
119
+ }
120
+ return null;
121
+ }
122
+ async set(query, result) {
123
+ this.load();
124
+ const key = normalizeQuery(query);
125
+ this.store.set(key, {
126
+ query,
127
+ result,
128
+ cachedAt: new Date().toISOString(),
129
+ hits: 0,
130
+ });
131
+ this.save();
132
+ logger_1.logger.debug(`Cache set (file): "${query}"`);
133
+ }
134
+ async clear() {
135
+ this.store.clear();
136
+ this.save();
137
+ }
138
+ async size() {
139
+ this.load();
140
+ return this.store.size;
141
+ }
142
+ }
143
+ exports.FileCache = FileCache;
144
+ // ─── Combo Cache (memory first, file fallback) ────────────────────────────────
145
+ class ComboCache {
146
+ constructor(filePath = '.capman/cache.json') {
147
+ this.memory = new MemoryCache();
148
+ this.file = new FileCache(filePath);
149
+ }
150
+ async get(query) {
151
+ // Memory first — fastest
152
+ const memHit = await this.memory.get(query);
153
+ if (memHit)
154
+ return memHit;
155
+ // File fallback — persists across restarts
156
+ const fileHit = await this.file.get(query);
157
+ if (fileHit) {
158
+ // Promote to memory for next time
159
+ await this.memory.set(query, fileHit.result);
160
+ return fileHit;
161
+ }
162
+ return null;
163
+ }
164
+ async set(query, result) {
165
+ await Promise.all([
166
+ this.memory.set(query, result),
167
+ this.file.set(query, result),
168
+ ]);
169
+ }
170
+ async clear() {
171
+ await Promise.all([
172
+ this.memory.clear(),
173
+ this.file.clear(),
174
+ ]);
175
+ }
176
+ async size() {
177
+ return this.file.size();
178
+ }
179
+ }
180
+ exports.ComboCache = ComboCache;
181
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ import type { Manifest, MatchResult, ResolveResult } from './types';
2
+ import type { LLMMatcherOptions } from './matcher';
3
+ import type { ResolveOptions, AuthContext } from './resolver';
4
+ import type { CacheStore } from './cache';
5
+ import type { LearningStore } from './learning';
6
+ import type { MatchMode } from './index';
7
+ export interface EngineOptions {
8
+ /** The capability manifest to use */
9
+ manifest: Manifest;
10
+ /**
11
+ * Matching mode
12
+ * - 'cheap' — keyword only, no LLM
13
+ * - 'balanced' — keyword first, LLM fallback (default)
14
+ * - 'accurate' — LLM first, keyword fallback
15
+ */
16
+ mode?: MatchMode;
17
+ /** LLM function for accurate/balanced matching */
18
+ llm?: LLMMatcherOptions['llm'];
19
+ /** Cache store — defaults to ComboCache (memory + file) */
20
+ cache?: CacheStore | false;
21
+ /** Learning store — defaults to FileLearningStore */
22
+ learning?: LearningStore | false;
23
+ /** Base URL for API resolvers */
24
+ baseUrl?: string;
25
+ /** Auth context for privacy-scoped capabilities */
26
+ auth?: AuthContext;
27
+ /** Custom headers for API calls */
28
+ headers?: Record<string, string>;
29
+ /** Confidence threshold for keyword matcher (default: 50) */
30
+ threshold?: number;
31
+ }
32
+ export interface EngineResult {
33
+ match: MatchResult;
34
+ resolution: ResolveResult;
35
+ /** How the match was resolved */
36
+ resolvedVia: 'cache' | 'keyword' | 'llm';
37
+ /** Total time in milliseconds */
38
+ durationMs: number;
39
+ }
40
+ export declare class CapmanEngine {
41
+ private manifest;
42
+ private mode;
43
+ private llm?;
44
+ private cache;
45
+ private learning;
46
+ private baseUrl?;
47
+ private auth?;
48
+ private headers?;
49
+ private threshold;
50
+ constructor(options: EngineOptions);
51
+ /**
52
+ * Ask the engine a natural language query.
53
+ * Automatically handles caching, matching, resolution, and learning.
54
+ *
55
+ * @example
56
+ * const engine = new CapmanEngine({ manifest, llm: myLLM })
57
+ * const result = await engine.ask("Check availability for blue jacket")
58
+ * console.log(result.match.capability?.id) // check_product_availability
59
+ * console.log(result.resolution.apiCalls) // [{ url: '...', method: 'GET' }]
60
+ * console.log(result.resolvedVia) // 'keyword' | 'llm' | 'cache'
61
+ */
62
+ ask(query: string, overrides?: Partial<ResolveOptions>): Promise<EngineResult>;
63
+ /**
64
+ * Get stats from the learning store.
65
+ * Shows which capabilities are most used, LLM vs keyword ratio, cache hit rate.
66
+ */
67
+ getStats(): Promise<import("./learning").KeywordStats | null>;
68
+ /**
69
+ * Get the most frequently matched capabilities.
70
+ */
71
+ getTopCapabilities(limit?: number): Promise<{
72
+ id: string;
73
+ hits: number;
74
+ }[]>;
75
+ /**
76
+ * Clear the cache.
77
+ */
78
+ clearCache(): Promise<void>;
79
+ private resolveOptions;
80
+ private recordLearning;
81
+ }
82
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AACnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACzC,OAAO,KAAK,EAAE,aAAa,EAAiB,MAAM,YAAY,CAAA;AAM9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAIxC,MAAM,WAAW,aAAa;IAC5B,qCAAqC;IACrC,QAAQ,EAAE,QAAQ,CAAA;IAClB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,kDAAkD;IAClD,GAAG,CAAC,EAAE,iBAAiB,CAAC,KAAK,CAAC,CAAA;IAC9B,2DAA2D;IAC3D,KAAK,CAAC,EAAE,UAAU,GAAG,KAAK,CAAA;IAC1B,qDAAqD;IACrD,QAAQ,CAAC,EAAE,aAAa,GAAG,KAAK,CAAA;IAChC,iCAAiC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,mDAAmD;IACnD,IAAI,CAAC,EAAE,WAAW,CAAA;IAClB,mCAAmC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,6DAA6D;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAID,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,WAAW,CAAA;IAClB,UAAU,EAAE,aAAa,CAAA;IACzB,iCAAiC;IACjC,WAAW,EAAE,OAAO,GAAG,SAAS,GAAG,KAAK,CAAA;IACxC,iCAAiC;IACjC,UAAU,EAAE,MAAM,CAAA;CACnB;AAID,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,IAAI,CAAgB;IAC5B,OAAO,CAAC,GAAG,CAAC,CAA+B;IAC3C,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,OAAO,CAAC,CAAS;IACzB,OAAO,CAAC,IAAI,CAAC,CAAiB;IAC9B,OAAO,CAAC,OAAO,CAAC,CAAyB;IACzC,OAAO,CAAC,SAAS,CAAQ;gBAEb,OAAO,EAAE,aAAa;IAsBlC;;;;;;;;;;OAUG;IACG,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,GAAE,OAAO,CAAC,cAAc,CAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAkFxF;;;OAGG;IACG,QAAQ;IAKd;;OAEG;IACG,kBAAkB,CAAC,KAAK,SAAI;;;;IAKlC;;OAEG;IACG,UAAU;IAMhB,OAAO,CAAC,cAAc;YASR,cAAc;CAgB7B"}
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CapmanEngine = void 0;
4
+ const matcher_1 = require("./matcher");
5
+ const resolver_1 = require("./resolver");
6
+ const cache_1 = require("./cache");
7
+ const learning_1 = require("./learning");
8
+ const logger_1 = require("./logger");
9
+ // ─── CapmanEngine ─────────────────────────────────────────────────────────────
10
+ class CapmanEngine {
11
+ constructor(options) {
12
+ this.manifest = options.manifest;
13
+ this.mode = options.mode ?? 'balanced';
14
+ this.llm = options.llm;
15
+ this.baseUrl = options.baseUrl;
16
+ this.auth = options.auth;
17
+ this.headers = options.headers;
18
+ this.threshold = options.threshold ?? 50;
19
+ // Cache — default ComboCache, or disabled with false
20
+ this.cache = options.cache === false
21
+ ? null
22
+ : (options.cache ?? new cache_1.ComboCache());
23
+ // Learning — default FileLearningStore, or disabled with false
24
+ this.learning = options.learning === false
25
+ ? null
26
+ : (options.learning ?? new learning_1.FileLearningStore());
27
+ logger_1.logger.info(`CapmanEngine initialized — mode: ${this.mode}, cache: ${this.cache ? 'enabled' : 'disabled'}, learning: ${this.learning ? 'enabled' : 'disabled'}`);
28
+ }
29
+ /**
30
+ * Ask the engine a natural language query.
31
+ * Automatically handles caching, matching, resolution, and learning.
32
+ *
33
+ * @example
34
+ * const engine = new CapmanEngine({ manifest, llm: myLLM })
35
+ * const result = await engine.ask("Check availability for blue jacket")
36
+ * console.log(result.match.capability?.id) // check_product_availability
37
+ * console.log(result.resolution.apiCalls) // [{ url: '...', method: 'GET' }]
38
+ * console.log(result.resolvedVia) // 'keyword' | 'llm' | 'cache'
39
+ */
40
+ async ask(query, overrides = {}) {
41
+ const start = Date.now();
42
+ // ── Step 1: Check cache ──────────────────────────────────────────────────
43
+ if (this.cache) {
44
+ const cached = await this.cache.get(query);
45
+ if (cached) {
46
+ logger_1.logger.info(`Cache hit for: "${query}"`);
47
+ const resolution = await (0, resolver_1.resolve)(cached.result, cached.result.extractedParams, this.resolveOptions(overrides));
48
+ const result = {
49
+ match: cached.result,
50
+ resolution,
51
+ resolvedVia: 'cache',
52
+ durationMs: Date.now() - start,
53
+ };
54
+ await this.recordLearning(query, cached.result, 'cache');
55
+ return result;
56
+ }
57
+ }
58
+ // ── Step 2: Match ────────────────────────────────────────────────────────
59
+ let matchResult;
60
+ let resolvedVia = 'keyword';
61
+ switch (this.mode) {
62
+ case 'cheap': {
63
+ matchResult = (0, matcher_1.match)(query, this.manifest);
64
+ break;
65
+ }
66
+ case 'accurate': {
67
+ if (this.llm) {
68
+ matchResult = await (0, matcher_1.matchWithLLM)(query, this.manifest, { llm: this.llm });
69
+ resolvedVia = 'llm';
70
+ }
71
+ else {
72
+ logger_1.logger.warn('accurate mode requires llm — falling back to keyword');
73
+ matchResult = (0, matcher_1.match)(query, this.manifest);
74
+ }
75
+ break;
76
+ }
77
+ case 'balanced':
78
+ default: {
79
+ const keywordResult = (0, matcher_1.match)(query, this.manifest);
80
+ if (keywordResult.confidence >= this.threshold || !this.llm) {
81
+ matchResult = keywordResult;
82
+ }
83
+ else {
84
+ logger_1.logger.info(`Low confidence (${keywordResult.confidence}%) — escalating to LLM`);
85
+ matchResult = await (0, matcher_1.matchWithLLM)(query, this.manifest, { llm: this.llm });
86
+ resolvedVia = 'llm';
87
+ }
88
+ break;
89
+ }
90
+ }
91
+ // ── Step 3: Cache the match result ───────────────────────────────────────
92
+ if (this.cache && matchResult.capability) {
93
+ await this.cache.set(query, matchResult);
94
+ }
95
+ // ── Step 4: Resolve ──────────────────────────────────────────────────────
96
+ const resolution = await (0, resolver_1.resolve)(matchResult, matchResult.extractedParams, this.resolveOptions(overrides));
97
+ // ── Step 5: Record learning ──────────────────────────────────────────────
98
+ await this.recordLearning(query, matchResult, resolvedVia);
99
+ return {
100
+ match: matchResult,
101
+ resolution,
102
+ resolvedVia,
103
+ durationMs: Date.now() - start,
104
+ };
105
+ }
106
+ /**
107
+ * Get stats from the learning store.
108
+ * Shows which capabilities are most used, LLM vs keyword ratio, cache hit rate.
109
+ */
110
+ async getStats() {
111
+ if (!this.learning)
112
+ return null;
113
+ return this.learning.getStats();
114
+ }
115
+ /**
116
+ * Get the most frequently matched capabilities.
117
+ */
118
+ async getTopCapabilities(limit = 5) {
119
+ if (!this.learning)
120
+ return [];
121
+ return this.learning.getTopCapabilities(limit);
122
+ }
123
+ /**
124
+ * Clear the cache.
125
+ */
126
+ async clearCache() {
127
+ if (this.cache)
128
+ await this.cache.clear();
129
+ }
130
+ // ── Private helpers ────────────────────────────────────────────────────────
131
+ resolveOptions(overrides = {}) {
132
+ return {
133
+ baseUrl: this.baseUrl,
134
+ auth: this.auth,
135
+ headers: this.headers,
136
+ ...overrides,
137
+ };
138
+ }
139
+ async recordLearning(query, matchResult, resolvedVia) {
140
+ if (!this.learning)
141
+ return;
142
+ await this.learning.record({
143
+ query,
144
+ capabilityId: matchResult.capability?.id ?? null,
145
+ confidence: matchResult.confidence,
146
+ intent: matchResult.intent,
147
+ extractedParams: matchResult.extractedParams,
148
+ resolvedVia,
149
+ timestamp: new Date().toISOString(),
150
+ });
151
+ }
152
+ }
153
+ exports.CapmanEngine = CapmanEngine;
154
+ //# sourceMappingURL=engine.js.map