capman 0.4.0 → 0.4.2

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 (43) hide show
  1. package/README.md +222 -106
  2. package/bin/capman.js +420 -91
  3. package/dist/cjs/cache.d.ts +16 -8
  4. package/dist/cjs/cache.d.ts.map +1 -1
  5. package/dist/cjs/cache.js +45 -31
  6. package/dist/cjs/cache.js.map +1 -1
  7. package/dist/cjs/engine.d.ts +2 -2
  8. package/dist/cjs/engine.d.ts.map +1 -1
  9. package/dist/cjs/engine.js +5 -3
  10. package/dist/cjs/engine.js.map +1 -1
  11. package/dist/cjs/generator.js +1 -1
  12. package/dist/cjs/generator.js.map +1 -1
  13. package/dist/cjs/index.d.ts +13 -10
  14. package/dist/cjs/index.d.ts.map +1 -1
  15. package/dist/cjs/index.js +23 -37
  16. package/dist/cjs/index.js.map +1 -1
  17. package/dist/cjs/learning.d.ts.map +1 -1
  18. package/dist/cjs/learning.js +10 -0
  19. package/dist/cjs/learning.js.map +1 -1
  20. package/dist/cjs/matcher.d.ts.map +1 -1
  21. package/dist/cjs/matcher.js +18 -9
  22. package/dist/cjs/matcher.js.map +1 -1
  23. package/dist/cjs/parser.d.ts +11 -0
  24. package/dist/cjs/parser.d.ts.map +1 -0
  25. package/dist/cjs/parser.js +304 -0
  26. package/dist/cjs/parser.js.map +1 -0
  27. package/dist/cjs/resolver.d.ts.map +1 -1
  28. package/dist/cjs/resolver.js +31 -25
  29. package/dist/cjs/resolver.js.map +1 -1
  30. package/dist/cjs/types.d.ts +2 -2
  31. package/dist/cjs/types.d.ts.map +1 -1
  32. package/dist/cjs/version.d.ts +1 -1
  33. package/dist/cjs/version.js +1 -1
  34. package/dist/esm/cache.js +44 -32
  35. package/dist/esm/engine.js +5 -3
  36. package/dist/esm/generator.js +1 -1
  37. package/dist/esm/index.js +20 -37
  38. package/dist/esm/learning.js +10 -0
  39. package/dist/esm/matcher.js +18 -9
  40. package/dist/esm/parser.js +267 -0
  41. package/dist/esm/resolver.js +31 -25
  42. package/dist/esm/version.js +1 -1
  43. package/package.json +1 -1
package/README.md CHANGED
@@ -1,178 +1,273 @@
1
- # Capman — Capability Manifest Engine
1
+ # capman
2
2
 
3
- Let AI agents interact with your app **without navigating the UI**.
3
+ **Capability Manifest Engine** — let AI agents interact with your app reliably and explainably.
4
4
 
5
- Instead of an AI blindly clicking through screens to find information,
6
- capman lets your app declare what it can do — and the AI uses that map
7
- to get answers directly.
5
+ Instead of an AI blindly clicking through screens, capman gives it a structured map of what your app can do — and shows you exactly why it made every decision.
6
+
7
+ ```bash
8
+ npm install capman
9
+ ```
8
10
 
9
11
  ---
10
12
 
11
13
  ## The Problem
12
14
 
13
- When an AI agent needs to answer "are there available seats for Friday?",
14
- today it navigates your entire app like a tourist with no map:
15
+ When an AI agent answers *"are there seats available Friday?"*, today it navigates your app like a tourist with no map:
15
16
 
16
17
  ```
17
- AI clicks → Home → Explore → Events → Category → Detail → Availability
18
+ AI clicks → Home → Explore → Events → Category → Availability
18
19
  ```
19
20
 
20
- That's slow, wasteful, and exposes parts of your app the AI shouldn't see.
21
+ Slow. Wasteful. Touches screens it shouldn't.
21
22
 
22
23
  ## The Solution
23
24
 
24
- Your app publishes a **capability manifest** — a machine-readable list of
25
- everything it can do, what API to call, and what data scope is allowed.
26
-
27
- The AI reads the manifest and goes directly to the answer.
25
+ Your app publishes a **capability manifest** — a machine-readable list of everything it can do, what API to call, and what data is allowed. The AI reads the manifest and goes directly to the answer.
28
26
 
29
27
  ```
30
- User query → match capability → resolve via API or nav → done
28
+ User query → match capability → resolve via API or nav → structured result
31
29
  ```
32
30
 
33
31
  ---
34
32
 
35
- ## Install
33
+ ## Quick Start
34
+
35
+ **1. Generate your manifest — three ways:**
36
36
 
37
37
  ```bash
38
- npm install capman
38
+ # From an OpenAPI/Swagger spec (fastest, no API key needed)
39
+ npx capman generate --from openapi.json
40
+ npx capman generate --from https://api.your-app.com/openapi.json
41
+
42
+ # AI-assisted — describe your app in plain English
43
+ npx capman generate --ai
44
+
45
+ # Manual — edit capman.config.js yourself
46
+ npx capman init
39
47
  ```
40
48
 
41
- ---
49
+ **2. Use the engine in your AI agent**
42
50
 
43
- ## Quick Start
51
+ ```typescript
52
+ import { CapmanEngine, readManifest } from 'capman'
53
+
54
+ const manifest = readManifest()
44
55
 
45
- **1. Create a config file**
56
+ const engine = new CapmanEngine({
57
+ manifest,
58
+ baseUrl: 'https://api.your-app.com',
59
+ })
60
+
61
+ const result = await engine.ask('Check availability for blue jacket')
62
+
63
+ console.log(result.match.capability?.id) // 'check_product_availability'
64
+ console.log(result.resolution.apiCalls) // [{ method: 'GET', url: '...' }]
65
+ console.log(result.resolvedVia) // 'keyword' | 'llm' | 'cache'
66
+ console.log(result.trace.reasoning) // ['Matched "check_product_availability" with 100% confidence', ...]
67
+ ```
68
+
69
+ **3. See it live**
46
70
 
47
71
  ```bash
48
- npx capman init
72
+ npx capman demo
49
73
  ```
50
74
 
51
- This creates a `capman.config.js` in your project. Edit it to define
52
- your app's capabilities.
75
+ ---
76
+
77
+ ## Manifest Generation
78
+
79
+ capman gives you three ways to create your manifest — pick based on what you have:
80
+
81
+ ### From OpenAPI / Swagger spec
53
82
 
54
- **2. Generate the manifest**
83
+ If your backend has an OpenAPI spec (most do), capman reads it and generates a complete manifest automatically. No LLM needed, no API key, works offline.
55
84
 
56
85
  ```bash
57
- npx capman generate
86
+ npx capman generate --from openapi.json
87
+ npx capman generate --from https://api.your-app.com/openapi.json
58
88
  ```
59
89
 
60
- This reads your config and outputs a `manifest.json`.
90
+ What it does automatically:
91
+ - Converts every endpoint into a capability with correct ID, name, and description
92
+ - Extracts path params, query params, and request body fields
93
+ - Infers privacy scope from security schemes — bearer token → `user_owned`, admin tags → `admin`, no auth → `public`
94
+ - Generates natural language examples from the operation summary
95
+ - Writes a ready `capman.config.js` for you to review and adjust
61
96
 
62
- **3. Use the SDK in your AI agent**
97
+ ```
98
+ ✓ Parsed 19 capabilities from spec
99
+ ✓ Config written to capman.config.js
100
+ ✓ Manifest written to manifest.json
101
+ ```
63
102
 
64
- ```typescript
65
- import { match, resolve, readManifest } from 'capman'
103
+ ### AI-assisted generation
66
104
 
67
- const manifest = readManifest()
105
+ No OpenAPI spec? Describe your app in plain English and capman uses an LLM to generate a full manifest.
68
106
 
69
- // Match a user query to a capability
70
- const matchResult = match("show me my account details", manifest)
107
+ ```bash
108
+ npx capman generate --ai
109
+ ```
71
110
 
72
- // Resolve it
73
- const result = await resolve(matchResult, {}, {
74
- baseUrl: 'https://api.your-app.com'
75
- })
111
+ ```
112
+ Describe your app and its main capabilities:
113
+ > A SaaS CRM. Users can create contacts, log calls, view pipeline
114
+ stages. Admins can manage teams and billing.
115
+
116
+ Using anthropic to generate manifest...
117
+ ✓ 6 capabilities generated
118
+ ```
119
+
120
+ Requires one of: `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, or `OPENROUTER_API_KEY` in your environment.
121
+
122
+ ### Manual
123
+
124
+ For full control, start from a starter config and define capabilities yourself:
76
125
 
77
- console.log(result.apiCalls) // [{ method: 'GET', url: '...' }]
78
- console.log(result.navTarget) // '/dashboard/profile'
126
+ ```bash
127
+ npx capman init
79
128
  ```
80
129
 
81
130
  ---
82
131
 
83
- ## CLI Commands
132
+ ## Execution Trace
84
133
 
85
- | Command | What it does |
86
- |---|---|
87
- | `capman init` | Create a starter `capman.config.js` |
88
- | `capman generate` | Generate `manifest.json` from config |
89
- | `capman validate` | Validate your manifest for errors |
90
- | `capman inspect` | Print all capabilities in the manifest |
134
+ Every `engine.ask()` call returns a full execution trace — so you always know why the AI did what it did.
135
+
136
+ ```typescript
137
+ const result = await engine.ask('Check availability for blue jacket')
138
+
139
+ console.log(result.trace)
140
+ // {
141
+ // query: 'Check availability for blue jacket',
142
+ // candidates: [
143
+ // { capabilityId: 'check_product_availability', score: 100, matched: true },
144
+ // { capabilityId: 'get_order_status', score: 12, matched: false },
145
+ // { capabilityId: 'navigate_to_screen', score: 0, matched: false },
146
+ // ],
147
+ // reasoning: [
148
+ // 'Matched "check_product_availability" with 100% confidence',
149
+ // 'Rejected: get_order_status (12%)',
150
+ // 'Resolved via: keyword',
151
+ // 'Extracted params: product=blue-jacket',
152
+ // ],
153
+ // steps: [
154
+ // { type: 'cache_check', status: 'miss', durationMs: 0 },
155
+ // { type: 'keyword_match', status: 'pass', durationMs: 1, detail: 'confidence: 100%' },
156
+ // { type: 'privacy_check', status: 'pass', durationMs: 0, detail: 'level: public' },
157
+ // { type: 'resolve', status: 'pass', durationMs: 2, detail: 'via api' },
158
+ // ],
159
+ // resolvedVia: 'keyword',
160
+ // totalMs: 4,
161
+ // }
162
+ ```
163
+
164
+ Debug any query from the CLI:
165
+
166
+ ```bash
167
+ npx capman run "check availability for blue jacket" --debug
168
+ ```
91
169
 
92
170
  ---
93
171
 
94
- ## SDK Reference
172
+ ## Matching Modes
95
173
 
96
- ### `match(query, manifest)`
97
- Matches a user query to the best capability using keyword scoring.
98
- Returns a `MatchResult` with the capability, confidence score, and intent.
174
+ Control the cost/accuracy tradeoff with three matching modes:
175
+
176
+ ```typescript
177
+ // cheap — keyword only, no LLM, free
178
+ const engine = new CapmanEngine({ manifest, mode: 'cheap' })
179
+
180
+ // balanced — keyword first, LLM fallback if confidence < 50% (default)
181
+ const engine = new CapmanEngine({ manifest, mode: 'balanced', llm: myLLM })
182
+
183
+ // accurate — LLM first, keyword fallback
184
+ const engine = new CapmanEngine({ manifest, mode: 'accurate', llm: myLLM })
185
+ ```
99
186
 
100
- ### `matchWithLLM(query, manifest, { llm })`
101
- Same as `match()` but uses an LLM for higher accuracy on ambiguous queries.
102
- Pass in any LLM function — works with Anthropic, OpenAI, or any local model.
187
+ Pass any LLM function — works with Anthropic, OpenAI, or any model:
103
188
 
104
189
  ```typescript
105
- const result = await matchWithLLM("find me something", manifest, {
190
+ import Anthropic from '@anthropic-ai/sdk'
191
+ const anthropic = new Anthropic()
192
+
193
+ const engine = new CapmanEngine({
194
+ manifest,
195
+ mode: 'balanced',
106
196
  llm: async (prompt) => {
107
197
  const res = await anthropic.messages.create({
108
198
  model: 'claude-sonnet-4-20250514',
109
199
  max_tokens: 500,
110
- messages: [{ role: 'user', content: prompt }]
200
+ messages: [{ role: 'user', content: prompt }],
111
201
  })
112
202
  return res.content[0].text
113
- }
203
+ },
114
204
  })
115
205
  ```
116
206
 
117
- ### `resolve(matchResult, params, options)`
118
- Executes a matched capability via API call, navigation, or both.
207
+ ---
119
208
 
120
- ### `ask(query, manifest, options)`
121
- Convenience function — match + resolve in one call.
209
+ ## Caching + Learning
122
210
 
123
211
  ```typescript
124
- const { match, resolution } = await ask("go to settings", manifest)
212
+ import { CapmanEngine, FileCache, FileLearningStore } from 'capman'
213
+
214
+ const engine = new CapmanEngine({
215
+ manifest,
216
+ cache: new FileCache('.capman/cache.json'),
217
+ learning: new FileLearningStore('.capman/learning.json'),
218
+ })
219
+
220
+ const stats = await engine.getStats()
221
+ // { totalQueries: 142, llmQueries: 18, cacheHits: 67, outOfScope: 3 }
222
+
223
+ const top = await engine.getTopCapabilities(3)
224
+ // [{ id: 'check_product_availability', hits: 58 }, ...]
125
225
  ```
126
226
 
127
227
  ---
128
228
 
129
- ## Capability Config
130
-
131
- Each capability in your `capman.config.js` looks like this:
132
-
133
- ```javascript
134
- {
135
- id: 'get_resource',
136
- name: 'Get a resource',
137
- description: 'Fetch a resource by ID or name.', // used for matching
138
- examples: [ // improves accuracy
139
- 'Show me resource details',
140
- 'Find resource by ID',
141
- ],
142
- params: [
143
- {
144
- name: 'resource_id',
145
- description: 'The resource ID',
146
- required: true,
147
- source: 'user_query', // or 'session', 'context', 'static'
148
- }
149
- ],
150
- returns: ['resource', 'metadata'],
151
- resolver: {
152
- type: 'api', // 'api', 'nav', or 'hybrid'
153
- endpoints: [
154
- { method: 'GET', path: '/resources/{resource_id}' }
155
- ],
229
+ ## Privacy + Auth
230
+
231
+ Privacy scope is enforced **per capability**, before resolution happens:
232
+
233
+ ```typescript
234
+ const engine = new CapmanEngine({
235
+ manifest,
236
+ baseUrl: 'https://api.your-app.com',
237
+ auth: {
238
+ isAuthenticated: true,
239
+ role: 'user',
240
+ userId: 'user-123', // auto-injected into session params
156
241
  },
157
- privacy: {
158
- level: 'public', // 'public', 'user_owned', or 'admin'
159
- note: 'No auth required'
160
- }
161
- }
242
+ })
162
243
  ```
163
244
 
164
245
  ---
165
246
 
166
- ## Privacy Scopes
247
+ ## Resolver Hardening
167
248
 
168
- | Level | Meaning |
169
- |---|---|
170
- | `public` | No auth required |
171
- | `user_owned` | Requires auth, scoped to current user only |
172
- | `admin` | Restricted to admin roles |
249
+ ```typescript
250
+ const result = await engine.ask('show my orders', {
251
+ retries: 2,
252
+ timeoutMs: 3000,
253
+ })
254
+ ```
255
+
256
+ ---
173
257
 
174
- Privacy scope is declared **per capability** — the AI is scoped to only
175
- what each capability allows, before resolution happens.
258
+ ## CLI Commands
259
+
260
+ | Command | What it does |
261
+ |---|---|
262
+ | `capman init` | Create a starter `capman.config.js` |
263
+ | `capman generate` | Generate manifest from `capman.config.js` |
264
+ | `capman generate --from <path\|url>` | Generate from OpenAPI/Swagger spec |
265
+ | `capman generate --ai` | Generate manifest using AI |
266
+ | `capman validate` | Validate your manifest for errors |
267
+ | `capman inspect` | Print all capabilities in the manifest |
268
+ | `capman run "query"` | Run a query against your manifest |
269
+ | `capman run "query" --debug` | Run with full candidate scoring |
270
+ | `capman demo` | Live demo with a sample app |
176
271
 
177
272
  ---
178
273
 
@@ -186,23 +281,44 @@ what each capability allows, before resolution happens.
186
281
 
187
282
  ---
188
283
 
284
+ ## Privacy Scopes
285
+
286
+ | Level | Meaning |
287
+ |---|---|
288
+ | `public` | No auth required |
289
+ | `user_owned` | Requires auth, scoped to current user only |
290
+ | `admin` | Restricted to admin roles |
291
+
292
+ ---
293
+
294
+ ## Param Sources
295
+
296
+ | Source | Meaning |
297
+ |---|---|
298
+ | `user_query` | Extracted from the user's query |
299
+ | `session` | Injected from `auth.userId` automatically |
300
+ | `context` | Provided by the caller |
301
+ | `static` | Fixed value, never changes |
302
+
303
+ ---
304
+
189
305
  ## Honest Limits
190
306
 
191
307
  **Works well:**
192
308
  - Structured data retrieval via APIs
193
- - Navigating to known app screens
194
- - Multi-endpoint aggregation
195
- - Privacy scoping per capability
196
- - Auto-updating on deploy
309
+ - Auto-generating manifests from OpenAPI specs
310
+ - Privacy enforcement per capability
311
+ - Full execution tracing and debugging
312
+ - Caching repeated queries
197
313
 
198
314
  **Current limits:**
199
315
  - Real-time infra status (is the server down?)
200
316
  - UI-only state with no API backing
201
- - Cross-app orchestration
202
- - Very ambiguous queries without LLM matcher
317
+ - Very ambiguous queries — use `mode: 'accurate'` with an LLM
318
+ - Multi-instance deployments need Redis adapter (planned for v0.5)
203
319
 
204
320
  ---
205
321
 
206
322
  ## License
207
323
 
208
- MIT
324
+ MIT — [github.com/Hobbydefiningdoctory/capman]