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.
- package/README.md +222 -106
- package/bin/capman.js +420 -91
- package/dist/cjs/cache.d.ts +16 -8
- package/dist/cjs/cache.d.ts.map +1 -1
- package/dist/cjs/cache.js +45 -31
- package/dist/cjs/cache.js.map +1 -1
- package/dist/cjs/engine.d.ts +2 -2
- package/dist/cjs/engine.d.ts.map +1 -1
- package/dist/cjs/engine.js +5 -3
- package/dist/cjs/engine.js.map +1 -1
- package/dist/cjs/generator.js +1 -1
- package/dist/cjs/generator.js.map +1 -1
- package/dist/cjs/index.d.ts +13 -10
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +23 -37
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/learning.d.ts.map +1 -1
- package/dist/cjs/learning.js +10 -0
- package/dist/cjs/learning.js.map +1 -1
- package/dist/cjs/matcher.d.ts.map +1 -1
- package/dist/cjs/matcher.js +18 -9
- package/dist/cjs/matcher.js.map +1 -1
- package/dist/cjs/parser.d.ts +11 -0
- package/dist/cjs/parser.d.ts.map +1 -0
- package/dist/cjs/parser.js +304 -0
- package/dist/cjs/parser.js.map +1 -0
- package/dist/cjs/resolver.d.ts.map +1 -1
- package/dist/cjs/resolver.js +31 -25
- package/dist/cjs/resolver.js.map +1 -1
- package/dist/cjs/types.d.ts +2 -2
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/cache.js +44 -32
- package/dist/esm/engine.js +5 -3
- package/dist/esm/generator.js +1 -1
- package/dist/esm/index.js +20 -37
- package/dist/esm/learning.js +10 -0
- package/dist/esm/matcher.js +18 -9
- package/dist/esm/parser.js +267 -0
- package/dist/esm/resolver.js +31 -25
- package/dist/esm/version.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,178 +1,273 @@
|
|
|
1
|
-
#
|
|
1
|
+
# capman
|
|
2
2
|
|
|
3
|
-
|
|
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
|
|
6
|
-
|
|
7
|
-
|
|
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
|
|
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 →
|
|
18
|
+
AI clicks → Home → Explore → Events → Category → Availability
|
|
18
19
|
```
|
|
19
20
|
|
|
20
|
-
|
|
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 →
|
|
28
|
+
User query → match capability → resolve via API or nav → structured result
|
|
31
29
|
```
|
|
32
30
|
|
|
33
31
|
---
|
|
34
32
|
|
|
35
|
-
##
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
**1. Generate your manifest — three ways:**
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
|
-
|
|
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
|
-
|
|
51
|
+
```typescript
|
|
52
|
+
import { CapmanEngine, readManifest } from 'capman'
|
|
53
|
+
|
|
54
|
+
const manifest = readManifest()
|
|
44
55
|
|
|
45
|
-
|
|
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
|
|
72
|
+
npx capman demo
|
|
49
73
|
```
|
|
50
74
|
|
|
51
|
-
|
|
52
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
97
|
+
```
|
|
98
|
+
✓ Parsed 19 capabilities from spec
|
|
99
|
+
✓ Config written to capman.config.js
|
|
100
|
+
✓ Manifest written to manifest.json
|
|
101
|
+
```
|
|
63
102
|
|
|
64
|
-
|
|
65
|
-
import { match, resolve, readManifest } from 'capman'
|
|
103
|
+
### AI-assisted generation
|
|
66
104
|
|
|
67
|
-
|
|
105
|
+
No OpenAPI spec? Describe your app in plain English and capman uses an LLM to generate a full manifest.
|
|
68
106
|
|
|
69
|
-
|
|
70
|
-
|
|
107
|
+
```bash
|
|
108
|
+
npx capman generate --ai
|
|
109
|
+
```
|
|
71
110
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
-
|
|
78
|
-
|
|
126
|
+
```bash
|
|
127
|
+
npx capman init
|
|
79
128
|
```
|
|
80
129
|
|
|
81
130
|
---
|
|
82
131
|
|
|
83
|
-
##
|
|
132
|
+
## Execution Trace
|
|
84
133
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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
|
-
##
|
|
172
|
+
## Matching Modes
|
|
95
173
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
118
|
-
Executes a matched capability via API call, navigation, or both.
|
|
207
|
+
---
|
|
119
208
|
|
|
120
|
-
|
|
121
|
-
Convenience function — match + resolve in one call.
|
|
209
|
+
## Caching + Learning
|
|
122
210
|
|
|
123
211
|
```typescript
|
|
124
|
-
|
|
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
|
-
##
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
```
|
|
134
|
-
{
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
'
|
|
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
|
-
|
|
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
|
-
##
|
|
247
|
+
## Resolver Hardening
|
|
167
248
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
249
|
+
```typescript
|
|
250
|
+
const result = await engine.ask('show my orders', {
|
|
251
|
+
retries: 2,
|
|
252
|
+
timeoutMs: 3000,
|
|
253
|
+
})
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
---
|
|
173
257
|
|
|
174
|
-
|
|
175
|
-
|
|
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
|
-
-
|
|
194
|
-
-
|
|
195
|
-
-
|
|
196
|
-
-
|
|
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
|
-
-
|
|
202
|
-
-
|
|
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]
|