capman 0.5.4 → 0.5.5

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 (49) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/CODEBASE.md +111 -66
  3. package/README.md +45 -4
  4. package/bin/lib/cmd-generate.js +44 -28
  5. package/dist/cjs/cache.d.ts.map +1 -1
  6. package/dist/cjs/cache.js +22 -5
  7. package/dist/cjs/cache.js.map +1 -1
  8. package/dist/cjs/engine.d.ts.map +1 -1
  9. package/dist/cjs/engine.js +39 -14
  10. package/dist/cjs/engine.js.map +1 -1
  11. package/dist/cjs/generator.d.ts.map +1 -1
  12. package/dist/cjs/generator.js +7 -1
  13. package/dist/cjs/generator.js.map +1 -1
  14. package/dist/cjs/learning.d.ts.map +1 -1
  15. package/dist/cjs/learning.js +39 -12
  16. package/dist/cjs/learning.js.map +1 -1
  17. package/dist/cjs/matcher.d.ts +14 -9
  18. package/dist/cjs/matcher.d.ts.map +1 -1
  19. package/dist/cjs/matcher.js +71 -22
  20. package/dist/cjs/matcher.js.map +1 -1
  21. package/dist/cjs/parser.d.ts.map +1 -1
  22. package/dist/cjs/parser.js +15 -8
  23. package/dist/cjs/parser.js.map +1 -1
  24. package/dist/cjs/resolver.d.ts +1 -0
  25. package/dist/cjs/resolver.d.ts.map +1 -1
  26. package/dist/cjs/resolver.js +16 -5
  27. package/dist/cjs/resolver.js.map +1 -1
  28. package/dist/cjs/schema.d.ts +18 -18
  29. package/dist/cjs/schema.js +1 -1
  30. package/dist/cjs/schema.js.map +1 -1
  31. package/dist/cjs/types.d.ts +1 -1
  32. package/dist/cjs/types.d.ts.map +1 -1
  33. package/dist/cjs/version.d.ts +1 -1
  34. package/dist/cjs/version.js +1 -1
  35. package/dist/esm/cache.js +22 -5
  36. package/dist/esm/engine.js +41 -16
  37. package/dist/esm/generator.js +7 -1
  38. package/dist/esm/learning.js +39 -12
  39. package/dist/esm/matcher.d.ts +14 -9
  40. package/dist/esm/matcher.js +71 -22
  41. package/dist/esm/parser.js +15 -8
  42. package/dist/esm/resolver.d.ts +1 -0
  43. package/dist/esm/resolver.js +16 -6
  44. package/dist/esm/schema.d.ts +18 -18
  45. package/dist/esm/schema.js +1 -1
  46. package/dist/esm/types.d.ts +1 -1
  47. package/dist/esm/version.d.ts +1 -1
  48. package/dist/esm/version.js +1 -1
  49. package/package.json +1 -1
@@ -21,10 +21,8 @@ export const STOPWORDS = new Set([
21
21
  function filterStopwords(words) {
22
22
  return words.filter(w => !STOPWORDS.has(w.toLowerCase()) && w.length > 1);
23
23
  }
24
- function scoreCapability(query, cap) {
25
- const q = query.toLowerCase();
24
+ function scoreCapability(qWordSet, cap) {
26
25
  let score = 0;
27
- const qWords = filterStopwords(q.split(/\W+/).filter(Boolean));
28
26
  // Check examples — take the best single example match, not the sum.
29
27
  // Accumulating across examples rewards bloated example lists over precise ones:
30
28
  // 10 examples at 50% overlap = 300 points (clamped to 60) beats 1 perfect example at 60.
@@ -34,21 +32,23 @@ function scoreCapability(query, cap) {
34
32
  const exWords = filterStopwords(example.toLowerCase().split(/\s+/));
35
33
  if (exWords.length === 0)
36
34
  continue;
37
- const overlap = exWords.filter(w => qWords.includes(w)).length;
35
+ const overlap = exWords.filter(w => qWordSet.has(w)).length;
38
36
  const contribution = (overlap / exWords.length) * 60;
39
37
  bestExampleScore = Math.max(bestExampleScore, contribution);
40
38
  }
41
39
  score += bestExampleScore;
42
- // Check description words
40
+ // Check description words — normalize against min(length, 10) to avoid
41
+ // penalizing rich documentation (many words = lower ratio) while also
42
+ // preventing single-word descriptions from maxing out on any match.
43
43
  const descWords = filterStopwords(cap.description.toLowerCase().split(/\W+/).filter(Boolean));
44
44
  if (descWords.length > 0) {
45
- const descOverlap = descWords.filter(w => qWords.includes(w)).length;
46
- score += (descOverlap / descWords.length) * 30;
45
+ const descOverlap = descWords.filter(w => qWordSet.has(w)).length;
46
+ score += Math.min((descOverlap / Math.min(descWords.length, 10)) * 30, 30);
47
47
  }
48
48
  // Check name words
49
49
  const nameWords = filterStopwords(cap.name.toLowerCase().split(/\W+/).filter(Boolean));
50
50
  if (nameWords.length > 0) {
51
- const nameOverlap = nameWords.filter(w => qWords.includes(w)).length;
51
+ const nameOverlap = nameWords.filter(w => qWordSet.has(w)).length;
52
52
  score += (nameOverlap / nameWords.length) * 10;
53
53
  }
54
54
  return Math.min(Math.round(score), 100);
@@ -63,14 +63,33 @@ export function resolverToIntent(cap) {
63
63
  return 'hybrid';
64
64
  return 'out_of_scope';
65
65
  }
66
+ /**
67
+ * Strips characters that could break LLM prompt structure from
68
+ * capability field values before injection into the system prompt.
69
+ * Removes control characters, newlines, and delimiter-like sequences.
70
+ */
71
+ function sanitizeForPrompt(value, maxLen) {
72
+ return value
73
+ .replace(/[\r\n\t]/g, ' ') // newlines → space
74
+ .replace(/---+/g, '—') // horizontal rules → em dash
75
+ .replace(/^\s*[{}\[\]]/gm, ' ') // leading braces/brackets → space
76
+ .replace(/\s+/g, ' ') // collapse whitespace
77
+ .trim()
78
+ .slice(0, maxLen);
79
+ }
66
80
  /**
67
81
  * Extracts parameter values from a user query using keyword heuristics.
82
+ *
68
83
  * Known limits:
69
84
  * - Extracts single tokens only — "jane smith" would extract "jane"
70
85
  * - Keyword matching is positional — "articles from authors I follow"
71
86
  * may extract "authors" instead of nothing, since "from" is a keyword
72
- * - For complex or ambiguous queries, use matchWithLLM() which handles
73
- * param extraction more accurately via the LLM prompt
87
+ * - Required param fallback grabs the last meaningful word — "list all
88
+ * recent orders" may extract "orders" even with the denylist extended.
89
+ * For precise extraction of complex queries, use matchWithLLM() which
90
+ * handles param extraction via structured LLM prompt.
91
+ * - To support richer extraction patterns, add a `pattern` field to
92
+ * CapabilityParam in a future version.
74
93
  */
75
94
  export function extractParams(query, cap) {
76
95
  const result = {};
@@ -205,9 +224,11 @@ export function match(query, manifest, options = {}) {
205
224
  }
206
225
  }
207
226
  // ── Score all capabilities ────────────────────────────────────────────────
227
+ // Build qWordSet once — O(1) lookups instead of O(n) Array.includes per word
228
+ const qWordSet = new Set(filterStopwords(query.toLowerCase().split(/\W+/).filter(Boolean)));
208
229
  const allScores = [];
209
230
  for (const cap of manifest.capabilities) {
210
- const keywordScore = scoreCapability(query, cap);
231
+ const keywordScore = scoreCapability(qWordSet, cap);
211
232
  const fuzzyScore = fuzzyScoreMap.get(cap.id) ?? 0;
212
233
  const via = fuzzyScore > keywordScore ? 'fuzzy' : 'keyword';
213
234
  const score = Math.min(100, Math.round(Math.max(keywordScore, fuzzyScore)));
@@ -255,25 +276,28 @@ export function match(query, manifest, options = {}) {
255
276
  /**
256
277
  * Matches a query to a capability using an LLM.
257
278
  *
258
- * ⚠️ SECURITY NOTE: Capability `description` and `examples` fields from the
259
- * manifest are injected verbatim into the LLM prompt (system portion).
260
- * In a solo deployment with a developer-controlled manifest this is safe.
261
- * If your manifest is generated from third-party OpenAPI specs, user-controlled
262
- * sources, or any external input, sanitize `description` and `examples` fields
263
- * before passing the manifest to this function adversarial content in those
264
- * fields can influence LLM routing decisions.
279
+ * ⚠️ SECURITY NOTE: Capability fields are sanitized before injection into
280
+ * the LLM prompt (newlines stripped, delimiters neutralized, length capped).
281
+ * However, the current interface passes a single prompt string it cannot
282
+ * provide true system/user message separation that some LLM APIs support.
283
+ * For maximum injection resistance in high-security deployments, use an LLM
284
+ * wrapper that maps the prompt to a proper system message, keeping user query
285
+ * data in the user turn only.
265
286
  */
266
287
  export async function matchWithLLM(query, manifest, options) {
267
288
  // Truncate description and examples — prevents context window overflow and
268
289
  // reduces prompt injection surface from third-party OpenAPI spec content.
269
290
  const MAX_DESC_LEN = 200;
270
291
  const MAX_EXAMPLE_LEN = 100;
271
- const manifestSummary = manifest.capabilities.map(c => `- ${c.id} (${c.resolver.type}): ${c.description.slice(0, MAX_DESC_LEN)}${c.description.length > MAX_DESC_LEN ? '…' : ''}${c.examples?.length
272
- ? `\n examples: ${c.examples.slice(0, 2).map(e => e.slice(0, MAX_EXAMPLE_LEN)).join(', ')}`
292
+ const manifestSummary = manifest.capabilities.map(c => `- ${c.id} (${c.resolver.type}): ${sanitizeForPrompt(c.description, MAX_DESC_LEN)}${c.examples?.length
293
+ ? `\n examples: ${c.examples.slice(0, 2).map(e => sanitizeForPrompt(e, MAX_EXAMPLE_LEN)).join(', ')}`
273
294
  : ''}`).join('\n');
295
+ // Sanitize app name — strip newlines and control characters that could
296
+ // break the prompt structure or inject additional instructions.
297
+ const safeApp = sanitizeForPrompt(manifest.app, 100);
274
298
  const prompt = `You are an intent matcher for an AI agent system.
275
299
 
276
- App: ${manifest.app}
300
+ App: ${safeApp}
277
301
 
278
302
  Available capabilities:
279
303
  ${manifestSummary}
@@ -331,7 +355,32 @@ ${JSON.stringify({ user_query: query })}
331
355
  capability,
332
356
  confidence: llmConfidence,
333
357
  intent: effectivelyOOS ? 'out_of_scope' : parsed.intent,
334
- extractedParams: (parsed.extracted_params ?? {}),
358
+ extractedParams: (() => {
359
+ // Validate extracted params against declared capability params.
360
+ // Rejects nested objects ("[object Object]" in URLs), unknown keys,
361
+ // and non-scalar values. For OOS results (capability === null),
362
+ // drops all params — correct since there's no capability to match against.
363
+ const rawParams = (parsed.extracted_params ?? {});
364
+ const validParams = {};
365
+ for (const param of capability?.params ?? []) {
366
+ const val = rawParams[param.name];
367
+ if (val === null || val === undefined) {
368
+ validParams[param.name] = null;
369
+ }
370
+ else if (typeof val === 'string') {
371
+ validParams[param.name] = val;
372
+ }
373
+ else if (typeof val === 'number' || typeof val === 'boolean') {
374
+ validParams[param.name] = String(val);
375
+ }
376
+ else {
377
+ // Reject complex types (objects, arrays) — would produce "[object Object]" in URLs
378
+ logger.warn(`LLM returned non-scalar value for param "${param.name}" — dropping`);
379
+ validParams[param.name] = null;
380
+ }
381
+ }
382
+ return validParams;
383
+ })(),
335
384
  reasoning: parsed.reasoning ?? 'No reasoning provided',
336
385
  candidates: allCandidates,
337
386
  };
@@ -166,7 +166,7 @@ function extractParams(op) {
166
166
  continue;
167
167
  const source = p.in === 'path' ? 'user_query' :
168
168
  p.in === 'query' ? 'user_query' :
169
- 'context';
169
+ 'user_query'; // body/formData (Swagger 2.x) — treat as user_query
170
170
  params.push({
171
171
  name: toSnakeCase(p.name),
172
172
  description: p.description ?? toHumanName(p.name),
@@ -201,13 +201,17 @@ function inferPrivacy(op, hasGlobalAuth, securitySchemes) {
201
201
  // Explicitly no security on this operation
202
202
  if (op.security !== undefined && op.security.length === 0)
203
203
  return 'public';
204
- // Check operation tags for admin hints
205
- const tags = (op.tags ?? []).map(t => t.toLowerCase());
206
- if (tags.some(t => t.includes('admin') || t.includes('internal')))
204
+ // Check operation tags for admin hints — word-boundary match only.
205
+ // Avoids false positives like 'manageWishlist', 'fileManager', 'managedService'
206
+ // being classified as admin when they are user-facing operations.
207
+ const ADMIN_PATTERN = /\b(admin|administrator|backoffice|back-office|internal|superuser)\b/i;
208
+ const tags = op.tags ?? [];
209
+ if (tags.some(t => ADMIN_PATTERN.test(t)))
207
210
  return 'admin';
208
- // Check operation ID / summary for admin hints
211
+ // Check operation ID / summary same word-boundary pattern.
212
+ // 'manage' alone is NOT an admin signal — too many user-facing ops use it.
209
213
  const hint = `${op.operationId ?? ''} ${op.summary ?? ''}`.toLowerCase();
210
- if (hint.includes('admin') || hint.includes('manage') || hint.includes('internal')) {
214
+ if (ADMIN_PATTERN.test(hint)) {
211
215
  return 'admin';
212
216
  }
213
217
  // If global auth exists or operation has security, it's user_owned
@@ -248,12 +252,15 @@ function extractBaseUrl(spec) {
248
252
  if (spec.servers?.length) {
249
253
  return spec.servers[0].url.replace(/\/$/, '');
250
254
  }
251
- // Swagger 2.x
255
+ // Swagger 2.x — respect declared schemes, prefer https over http
252
256
  if (spec.host) {
253
- const scheme = 'https';
257
+ const schemes = spec.schemes ?? ['https'];
258
+ const scheme = schemes.includes('https') ? 'https' : schemes[0] ?? 'https';
254
259
  const base = spec.basePath ?? '';
255
260
  return `${scheme}://${spec.host}${base}`.replace(/\/$/, '');
256
261
  }
262
+ logger.warn(`No server URL found in spec — using placeholder "https://api.your-app.com". ` +
263
+ `Set baseUrl manually in the generated config before use.`);
257
264
  return 'https://api.your-app.com';
258
265
  }
259
266
  function sanitizeAppName(title) {
@@ -25,4 +25,5 @@ export interface ResolveOptions {
25
25
  */
26
26
  retryAllMethods?: boolean;
27
27
  }
28
+ export declare function checkPrivacy(capability: import('./types').Capability, auth?: AuthContext): string | null;
28
29
  export declare function resolve(matchResult: MatchResult, params?: Record<string, unknown>, options?: ResolveOptions): Promise<ResolveResult>;
@@ -4,7 +4,7 @@ const SAFE_METHODS = new Set(['GET', 'HEAD', 'OPTIONS']);
4
4
  function redactParams(params) {
5
5
  return Object.fromEntries(Object.entries(params).map(([k, v]) => [k, v != null ? '[REDACTED]' : 'null']));
6
6
  }
7
- function checkPrivacy(capability, auth) {
7
+ export function checkPrivacy(capability, auth) {
8
8
  const level = capability.privacy.level;
9
9
  if (level === 'public')
10
10
  return null;
@@ -109,6 +109,12 @@ export async function resolve(matchResult, params = {}, options = {}) {
109
109
  *
110
110
  * For capabilities where ordering or rollback matters, define separate capabilities
111
111
  * with single endpoints and orchestrate them at the application layer.
112
+ *
113
+ * Note: the current ResolveResult does not expose which endpoints succeeded and
114
+ * which failed in a partial failure scenario. If your use case requires this
115
+ * granularity, use separate single-endpoint capabilities and inspect each result.
116
+ * Full partial success reporting (partialSuccess, completedCalls, failedCalls)
117
+ * is planned for a future version.
112
118
  */
113
119
  async function resolveApi(resolver, params, options, sessionParamNames = new Set()) {
114
120
  const startTime = Date.now();
@@ -126,7 +132,7 @@ async function resolveApi(resolver, params, options, sessionParamNames = new Set
126
132
  }
127
133
  return {
128
134
  method: endpoint.method,
129
- url: buildUrl(options.baseUrl ?? '', endpoint.path, endpointParams),
135
+ url: buildUrl(options.baseUrl ?? '', endpoint.path, endpointParams, sessionParamNames),
130
136
  params: Object.fromEntries(Object.entries(endpointParams).filter(([, v]) => v !== null && v !== undefined)),
131
137
  };
132
138
  });
@@ -210,9 +216,12 @@ async function resolveApi(resolver, params, options, sessionParamNames = new Set
210
216
  }
211
217
  }
212
218
  function validateNavParam(key, value) {
213
- if (!/^[a-zA-Z0-9_\-]+$/.test(value)) {
219
+ // Allowlist aligned with validateApiPathParam — permits dots, colons, @ for
220
+ // deep links (myapp://path), domain-qualified values (auth.tokens), and
221
+ // versioned routes (v1:resource). Rejects path separators and shell metacharacters.
222
+ if (!/^[a-zA-Z0-9_\-.:@]+$/.test(value)) {
214
223
  throw new Error(`Nav param "${key}" contains invalid characters: "${value}". ` +
215
- `Only alphanumeric, hyphens, and underscores are allowed.`);
224
+ `Only alphanumeric, hyphens, underscores, dots, colons, and @ are allowed.`);
216
225
  }
217
226
  }
218
227
  function resolveNav(resolver, params) {
@@ -237,7 +246,7 @@ function validateApiPathParam(key, value) {
237
246
  }
238
247
  // Both buildUrl (API) and resolveNav (nav) validate path param values against
239
248
  // an allowlist before substitution — prevents path traversal via unencoded slashes.
240
- function buildUrl(baseUrl, urlPath, params) {
249
+ function buildUrl(baseUrl, urlPath, params, blockedQsParams) {
241
250
  let resolved = urlPath;
242
251
  const unused = {};
243
252
  for (const [key, value] of Object.entries(params)) {
@@ -254,7 +263,8 @@ function buildUrl(baseUrl, urlPath, params) {
254
263
  }
255
264
  const base = `${baseUrl.replace(/\/$/, '')}${resolved}`;
256
265
  const qs = Object.entries(unused)
257
- .filter(([, v]) => v !== null && v !== undefined)
266
+ .filter(([k, v]) => v !== null && v !== undefined
267
+ && (!blockedQsParams || !blockedQsParams.has(k)))
258
268
  .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`)
259
269
  .join('&');
260
270
  return qs ? `${base}?${qs}` : base;
@@ -11,19 +11,19 @@ export declare const CapmanConfigSchema: z.ZodEffects<z.ZodObject<{
11
11
  name: z.ZodString;
12
12
  description: z.ZodString;
13
13
  required: z.ZodBoolean;
14
- source: z.ZodEnum<["user_query", "session", "context", "static"]>;
14
+ source: z.ZodEnum<["user_query", "session"]>;
15
15
  default: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
16
16
  }, "strip", z.ZodTypeAny, {
17
17
  name: string;
18
18
  required: boolean;
19
19
  description: string;
20
- source: "user_query" | "session" | "context" | "static";
20
+ source: "user_query" | "session";
21
21
  default?: string | number | boolean | undefined;
22
22
  }, {
23
23
  name: string;
24
24
  required: boolean;
25
25
  description: string;
26
- source: "user_query" | "session" | "context" | "static";
26
+ source: "user_query" | "session";
27
27
  default?: string | number | boolean | undefined;
28
28
  }>, "many">;
29
29
  returns: z.ZodArray<z.ZodString, "many">;
@@ -151,7 +151,7 @@ export declare const CapmanConfigSchema: z.ZodEffects<z.ZodObject<{
151
151
  name: string;
152
152
  required: boolean;
153
153
  description: string;
154
- source: "user_query" | "session" | "context" | "static";
154
+ source: "user_query" | "session";
155
155
  default?: string | number | boolean | undefined;
156
156
  }[];
157
157
  description: string;
@@ -193,7 +193,7 @@ export declare const CapmanConfigSchema: z.ZodEffects<z.ZodObject<{
193
193
  name: string;
194
194
  required: boolean;
195
195
  description: string;
196
- source: "user_query" | "session" | "context" | "static";
196
+ source: "user_query" | "session";
197
197
  default?: string | number | boolean | undefined;
198
198
  }[];
199
199
  description: string;
@@ -235,7 +235,7 @@ export declare const CapmanConfigSchema: z.ZodEffects<z.ZodObject<{
235
235
  name: string;
236
236
  required: boolean;
237
237
  description: string;
238
- source: "user_query" | "session" | "context" | "static";
238
+ source: "user_query" | "session";
239
239
  default?: string | number | boolean | undefined;
240
240
  }[];
241
241
  description: string;
@@ -277,7 +277,7 @@ export declare const CapmanConfigSchema: z.ZodEffects<z.ZodObject<{
277
277
  name: string;
278
278
  required: boolean;
279
279
  description: string;
280
- source: "user_query" | "session" | "context" | "static";
280
+ source: "user_query" | "session";
281
281
  default?: string | number | boolean | undefined;
282
282
  }[];
283
283
  description: string;
@@ -322,7 +322,7 @@ export declare const CapmanConfigSchema: z.ZodEffects<z.ZodObject<{
322
322
  name: string;
323
323
  required: boolean;
324
324
  description: string;
325
- source: "user_query" | "session" | "context" | "static";
325
+ source: "user_query" | "session";
326
326
  default?: string | number | boolean | undefined;
327
327
  }[];
328
328
  description: string;
@@ -368,7 +368,7 @@ export declare const CapmanConfigSchema: z.ZodEffects<z.ZodObject<{
368
368
  name: string;
369
369
  required: boolean;
370
370
  description: string;
371
- source: "user_query" | "session" | "context" | "static";
371
+ source: "user_query" | "session";
372
372
  default?: string | number | boolean | undefined;
373
373
  }[];
374
374
  description: string;
@@ -414,7 +414,7 @@ export declare const CapmanConfigSchema: z.ZodEffects<z.ZodObject<{
414
414
  name: string;
415
415
  required: boolean;
416
416
  description: string;
417
- source: "user_query" | "session" | "context" | "static";
417
+ source: "user_query" | "session";
418
418
  default?: string | number | boolean | undefined;
419
419
  }[];
420
420
  description: string;
@@ -460,7 +460,7 @@ export declare const CapmanConfigSchema: z.ZodEffects<z.ZodObject<{
460
460
  name: string;
461
461
  required: boolean;
462
462
  description: string;
463
- source: "user_query" | "session" | "context" | "static";
463
+ source: "user_query" | "session";
464
464
  default?: string | number | boolean | undefined;
465
465
  }[];
466
466
  description: string;
@@ -511,19 +511,19 @@ export declare const ManifestSchema: z.ZodObject<{
511
511
  name: z.ZodString;
512
512
  description: z.ZodString;
513
513
  required: z.ZodBoolean;
514
- source: z.ZodEnum<["user_query", "session", "context", "static"]>;
514
+ source: z.ZodEnum<["user_query", "session"]>;
515
515
  default: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
516
516
  }, "strip", z.ZodTypeAny, {
517
517
  name: string;
518
518
  required: boolean;
519
519
  description: string;
520
- source: "user_query" | "session" | "context" | "static";
520
+ source: "user_query" | "session";
521
521
  default?: string | number | boolean | undefined;
522
522
  }, {
523
523
  name: string;
524
524
  required: boolean;
525
525
  description: string;
526
- source: "user_query" | "session" | "context" | "static";
526
+ source: "user_query" | "session";
527
527
  default?: string | number | boolean | undefined;
528
528
  }>, "many">;
529
529
  returns: z.ZodArray<z.ZodString, "many">;
@@ -651,7 +651,7 @@ export declare const ManifestSchema: z.ZodObject<{
651
651
  name: string;
652
652
  required: boolean;
653
653
  description: string;
654
- source: "user_query" | "session" | "context" | "static";
654
+ source: "user_query" | "session";
655
655
  default?: string | number | boolean | undefined;
656
656
  }[];
657
657
  description: string;
@@ -693,7 +693,7 @@ export declare const ManifestSchema: z.ZodObject<{
693
693
  name: string;
694
694
  required: boolean;
695
695
  description: string;
696
- source: "user_query" | "session" | "context" | "static";
696
+ source: "user_query" | "session";
697
697
  default?: string | number | boolean | undefined;
698
698
  }[];
699
699
  description: string;
@@ -739,7 +739,7 @@ export declare const ManifestSchema: z.ZodObject<{
739
739
  name: string;
740
740
  required: boolean;
741
741
  description: string;
742
- source: "user_query" | "session" | "context" | "static";
742
+ source: "user_query" | "session";
743
743
  default?: string | number | boolean | undefined;
744
744
  }[];
745
745
  description: string;
@@ -786,7 +786,7 @@ export declare const ManifestSchema: z.ZodObject<{
786
786
  name: string;
787
787
  required: boolean;
788
788
  description: string;
789
- source: "user_query" | "session" | "context" | "static";
789
+ source: "user_query" | "session";
790
790
  default?: string | number | boolean | undefined;
791
791
  }[];
792
792
  description: string;
@@ -4,7 +4,7 @@ const CapabilityParamSchema = z.object({
4
4
  name: z.string().min(1, 'param name is required'),
5
5
  description: z.string().min(1, 'param description is required'),
6
6
  required: z.boolean(),
7
- source: z.enum(['user_query', 'session', 'context', 'static']),
7
+ source: z.enum(['user_query', 'session']),
8
8
  default: z.union([z.string(), z.number(), z.boolean()]).optional(),
9
9
  });
10
10
  // ─── Resolver Schemas ─────────────────────────────────────────────────────────
@@ -4,7 +4,7 @@ export interface CapabilityParam {
4
4
  name: string;
5
5
  description: string;
6
6
  required: boolean;
7
- source: 'user_query' | 'session' | 'context' | 'static';
7
+ source: 'user_query' | 'session';
8
8
  default?: string | number | boolean;
9
9
  }
10
10
  export interface ApiResolver {
@@ -1 +1 @@
1
- export declare const VERSION = "0.5.3";
1
+ export declare const VERSION = "0.5.5";
@@ -1,2 +1,2 @@
1
1
  // Auto-generated by scripts/version.js — do not edit manually
2
- export const VERSION = '0.5.3';
2
+ export const VERSION = '0.5.5';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "capman",
3
- "version": "0.5.4",
3
+ "version": "0.5.5",
4
4
  "description": "Capability Manifest Engine — let AI agents interact with your app without navigating the UI",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "module": "./dist/esm/index.js",