capman 0.4.2 → 0.4.3

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 (47) hide show
  1. package/CHANGELOG.md +127 -0
  2. package/CODEBASE.md +391 -0
  3. package/README.md +1 -1
  4. package/bin/capman.js +11 -724
  5. package/bin/lib/cmd-demo.js +180 -0
  6. package/bin/lib/cmd-explain.js +72 -0
  7. package/bin/lib/cmd-generate.js +280 -0
  8. package/bin/lib/cmd-help.js +26 -0
  9. package/bin/lib/cmd-init.js +19 -0
  10. package/bin/lib/cmd-inspect.js +33 -0
  11. package/bin/lib/cmd-run.js +71 -0
  12. package/bin/lib/cmd-validate.js +32 -0
  13. package/bin/lib/shared.js +70 -0
  14. package/dist/cjs/engine.d.ts +58 -1
  15. package/dist/cjs/engine.d.ts.map +1 -1
  16. package/dist/cjs/engine.js +307 -12
  17. package/dist/cjs/engine.js.map +1 -1
  18. package/dist/cjs/generator.d.ts.map +1 -1
  19. package/dist/cjs/generator.js +4 -0
  20. package/dist/cjs/generator.js.map +1 -1
  21. package/dist/cjs/index.d.ts +1 -1
  22. package/dist/cjs/index.d.ts.map +1 -1
  23. package/dist/cjs/index.js.map +1 -1
  24. package/dist/cjs/matcher.d.ts.map +1 -1
  25. package/dist/cjs/matcher.js +19 -25
  26. package/dist/cjs/matcher.js.map +1 -1
  27. package/dist/cjs/types.d.ts +27 -0
  28. package/dist/cjs/types.d.ts.map +1 -1
  29. package/dist/cjs/version.d.ts +1 -1
  30. package/dist/cjs/version.js +1 -1
  31. package/dist/esm/cache.d.ts +49 -0
  32. package/dist/esm/engine.d.ts +138 -0
  33. package/dist/esm/engine.js +307 -12
  34. package/dist/esm/generator.d.ts +7 -0
  35. package/dist/esm/generator.js +4 -0
  36. package/dist/esm/index.d.ts +47 -0
  37. package/dist/esm/learning.d.ts +55 -0
  38. package/dist/esm/logger.d.ts +21 -0
  39. package/dist/esm/matcher.d.ts +6 -0
  40. package/dist/esm/matcher.js +19 -25
  41. package/dist/esm/parser.d.ts +10 -0
  42. package/dist/esm/resolver.d.ts +21 -0
  43. package/dist/esm/schema.d.ts +740 -0
  44. package/dist/esm/types.d.ts +136 -0
  45. package/dist/esm/version.d.ts +1 -0
  46. package/dist/esm/version.js +1 -1
  47. package/package.json +5 -3
package/CHANGELOG.md ADDED
@@ -0,0 +1,127 @@
1
+ # Changelog
2
+
3
+ All notable changes to capman are documented here.
4
+
5
+ ---
6
+
7
+ ## [Unreleased] — v0.4.3
8
+ ### Added
9
+ - `CapmanEngine.explain(query)` — explains what would match without executing
10
+ - Returns all candidates with per-candidate human-readable explanations
11
+ - Shows `wouldExecute.action` — what API call or nav would happen
12
+ - Shows `wouldExecute.blocked` — if privacy would prevent execution
13
+ - Fully respects rate limiting and circuit breaker (mirrors `ask()` logic)
14
+ - `ExplainResult` and `ExplainCandidate` types exported from public API
15
+ - `capman explain "query"` CLI command — shows full explanation in terminal
16
+ - LLM rate limiting and circuit breaker in `CapmanEngine`
17
+ - `maxLLMCallsPerMinute` — hard rate limit (default: 60)
18
+ - `llmCooldownMs` — minimum ms between consecutive LLM calls (default: 0)
19
+ - `llmCircuitBreakerThreshold` — failures before circuit opens (default: 3)
20
+ - `llmCircuitBreakerResetMs` — ms before circuit resets (default: 60000)
21
+ - `balanced` and `accurate` modes both respect all limits
22
+ - `explain()` shares the same rate limit state as `ask()`
23
+
24
+ ### Fixed
25
+ - `explain()` now mirrors `ask()` matching logic exactly — balanced mode escalates to LLM when confidence < threshold
26
+ - `matchWithLLM` internal try-catch removed — errors propagate to engine for proper circuit breaker tracking
27
+ - Removed `?? []` on required `candidates` field in trace building
28
+ - Removed `?.` on `candidates` in CLI `--debug` block
29
+ - Fixed mixed indentation in `ask()` switch statement
30
+
31
+ ---
32
+
33
+ ## [0.4.2] — 2026-02-01
34
+ ### Added
35
+ - `parseOpenAPI(specPathOrUrl)` — parses OpenAPI 3.x and Swagger 2.x specs into capman configs
36
+ - Reads local files or fetches from URL
37
+ - Extracts path params, query params, and request body fields
38
+ - Infers privacy scope from security schemes — bearer → `user_owned`, admin tags → `admin`
39
+ - Generates natural language examples from operation summaries
40
+ - Supports JSON specs; YAML requires `js-yaml` installed
41
+ - `capman generate --from <path|url>` — generate manifest from OpenAPI/Swagger spec
42
+ - `capman generate --ai` — AI-assisted manifest generation from plain English description
43
+ - Detects `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, or `OPENROUTER_API_KEY` automatically
44
+ - Validates generated config with Zod before writing
45
+ - `ParseResult` type exported from public API
46
+ - 9 new parser tests covering all extraction and inference paths
47
+
48
+ ### Fixed
49
+ - `bin/capman.js` `generate` command wrapped in async IIFE for proper async support
50
+ - OpenAPI duplicate capability IDs resolved automatically with method suffix
51
+
52
+ ---
53
+
54
+ ## [0.4.1] — 2026-03-28
55
+ ### Fixed
56
+ - Prompt injection sanitization in `matchWithLLM` — query now passed as JSON field
57
+ - `ask()` now delegates to `CapmanEngine` internally — eliminates logic duplication
58
+ - `FileLearningStore` and `MemoryLearningStore` now cap at 10,000 entries with oldest-first pruning
59
+ - Post-match cache key now uses `capabilityId + params` instead of raw query — higher hit rate
60
+ - Removed duplicate `AskOptions` interface declaration in `index.ts`
61
+ - Removed dead imports (`_match`, `_matchWithLLM`, `_resolve`) from `index.ts`
62
+ ---
63
+
64
+ ## [0.4.0] — 2026-03-xx
65
+ ### Added
66
+ - `CapmanEngine` class — unified entry point with caching, learning, and tracing
67
+ - `ExecutionTrace` — structured trace returned with every `engine.ask()` result
68
+ - `MatchCandidate[]` — all scored candidates returned, not just the winner
69
+ - `capman run "query" --debug` CLI command — shows all candidate scores
70
+ - `capman demo` CLI command — live demo with zero config
71
+ - Configurable retries and timeout on API resolver
72
+ - `MemoryCache`, `FileCache`, `ComboCache` — pluggable cache backends
73
+ - `FileLearningStore`, `MemoryLearningStore` — usage analytics and keyword index
74
+ - `MatchMode` — `cheap | balanced | accurate` matching modes
75
+
76
+ ### Fixed
77
+ - Optional params no longer get garbage fallback values
78
+ - `candidates` field made required (was optional `?`)
79
+ - Empty query and LLM paths now correctly set `candidates: []`
80
+ - `generate()` now deep-copies capabilities — prevents config mutation
81
+ - `MemoryCache` now has 512-entry cap with oldest-first eviction
82
+ - `fetchWithRetry` converted from recursive to iterative — no stack overflow risk
83
+
84
+ ---
85
+
86
+ ## [0.3.0] — 2026-03-xx
87
+ ### Added
88
+ - `CapmanEngine` initial design with cache and learning stores
89
+ - `FileLearningStore` — persists query history and keyword index
90
+ - `ComboCache` — memory-first with file fallback
91
+ - `scripts/version.js` — prebuild script keeps `src/version.ts` in sync
92
+ - Dual ESM/CJS build verification in CI
93
+
94
+ ### Fixed
95
+ - Default stores changed to memory-only — no silent filesystem writes
96
+ - `FileCache` and `FileLearningStore` converted to async `fs.promises`
97
+ - Shared `computeStats()` helper — eliminates code duplication
98
+
99
+ ---
100
+
101
+ ## [0.2.0] — 2026-03-xx
102
+ ### Added
103
+ - Dual CJS + ESM build (`dist/cjs/` and `dist/esm/`)
104
+ - `MatchMode` — `cheap | balanced | accurate`
105
+ - `AuthContext` — privacy enforcement per capability
106
+ - `ApiCallResult` with `status` and `data` fields
107
+ - Configurable `retries` and `timeoutMs` on resolver
108
+ - `setLogLevel()` exported from public API
109
+
110
+ ### Fixed
111
+ - POST/PUT/DELETE requests no longer silently dropped
112
+ - `extractParams` now extracts real values from queries
113
+ - Stopword filtering in scorer
114
+ - Zod runtime validation on config and manifest load
115
+ - `files` field in `package.json` — clean npm publish
116
+
117
+ ---
118
+
119
+ ## [0.1.0] — 2026-03-xx
120
+ ### Added
121
+ - Initial release
122
+ - CLI: `init`, `generate`, `validate`, `inspect`
123
+ - SDK: `match()`, `matchWithLLM()`, `resolve()`, `ask()`
124
+ - Two-tier matching: keyword-first, LLM fallback
125
+ - Privacy scopes: `public`, `user_owned`, `admin`
126
+ - Zod schema validation
127
+ - GitHub Actions CI
package/CODEBASE.md ADDED
@@ -0,0 +1,391 @@
1
+ # Codebase Map
2
+
3
+ A guide to every file in capman — what it does, what it exports, and how it connects to everything else.
4
+
5
+ ---
6
+
7
+ ## Overview
8
+
9
+ ```
10
+ capman/
11
+ ├── src/ ← TypeScript source — compiled to dist/
12
+ ├── dist/
13
+ │ ├── cjs/ ← CommonJS build (Node require)
14
+ │ └── esm/ ← ES Module build (bundlers, import)
15
+ ├── bin/ ← CLI entry point and command modules
16
+ │ └── lib/ ← one file per CLI command
17
+ ├── tests/ ← Vitest test suites
18
+ ├── scripts/ ← build-time utilities
19
+ └── test/ ← live integration tests (not in CI)
20
+ ```
21
+
22
+ ---
23
+
24
+ ## src/
25
+
26
+ ### `src/types.ts`
27
+ All TypeScript types and interfaces. No logic — pure declarations.
28
+
29
+ Key exports:
30
+ - `Capability`, `CapabilityParam`, `Manifest`, `CapmanConfig` — core data shapes
31
+ - `MatchResult` — what `match()` returns, including `candidates: MatchCandidate[]`
32
+ - `MatchCandidate` — `{ capabilityId, score, matched }` — all scored candidates
33
+ - `ResolveResult`, `ApiCallResult` — what `resolve()` returns, with `status` and `data`
34
+ - `ExecutionTrace`, `TraceStep` — full step-by-step trace returned by `engine.ask()`
35
+ - `ExplainResult`, `ExplainCandidate` — what `engine.explain()` returns
36
+ - `ValidationResult` — `{ valid, errors, warnings }`
37
+ - `Resolver`, `ApiResolver`, `NavResolver`, `HybridResolver` — discriminated union
38
+ - `PrivacyScope`, `ResolverType`, `HttpMethod` — enums/literals
39
+
40
+ ---
41
+
42
+ ### `src/schema.ts`
43
+ Zod runtime validation schemas. Mirrors `types.ts` but adds validation rules.
44
+
45
+ Key exports:
46
+ - `validateConfig(config)` — validates a `CapmanConfig` at load time
47
+ - `validateManifest(manifest)` — validates a `Manifest` at read time
48
+
49
+ Notable rules:
50
+ - `id` must match `/^[a-z][a-z0-9_]*$/` — snake_case only
51
+ - `description` minimum 10 characters
52
+ - Capability IDs must be unique within a manifest
53
+
54
+ ---
55
+
56
+ ### `src/generator.ts`
57
+ Manifest lifecycle — create, read, write, validate.
58
+
59
+ Key exports:
60
+ - `generate(config)` → `Manifest` — converts config to manifest, deep-copies capabilities
61
+ - `loadConfig(path?)` → `CapmanConfig` — loads `capman.config.js` via `require()`
62
+ - `writeManifest(manifest, path?)` — writes `manifest.json`
63
+ - `readManifest(path?)` → `Manifest` — reads and Zod-validates `manifest.json`
64
+ - `validate(manifest)` → `ValidationResult` — runs Zod + warns on missing examples
65
+ - `generateStarterConfig()` → `string` — returns starter `capman.config.js` content
66
+ - `VERSION` — current version string, auto-generated by `scripts/version.js`
67
+
68
+ ---
69
+
70
+ ### `src/matcher.ts`
71
+ Intent matching — keyword scoring and LLM-based matching.
72
+
73
+ Key exports:
74
+ - `match(query, manifest)` → `MatchResult`
75
+ - Scores every capability against the query
76
+ - Returns winner + all candidates with scores
77
+ - Extracts params from the query using keyword heuristics
78
+ - Returns `out_of_scope` if best score < 50%
79
+ - `matchWithLLM(query, manifest, { llm })` → `MatchResult`
80
+ - Sends structured prompt to LLM with query as JSON field (prompt injection safe)
81
+ - Returns matched capability, confidence, intent, extracted params
82
+ - Errors propagate to caller — no internal try/catch
83
+
84
+ Scoring algorithm (weights):
85
+ - Examples match: up to 60 points
86
+ - Description match: up to 30 points
87
+ - Name match: up to 10 points
88
+
89
+ Param extraction:
90
+ - `isIdParam` — single token (e.g. `order_id=1234`)
91
+ - `isNavParam` — single token after nav keywords (`to`, `open`, `show`)
92
+ - Everything else — multi-word joined with `-` (e.g. `product=blue-jacket`)
93
+ - Optional params stay `null` if no keyword match found
94
+
95
+ ---
96
+
97
+ ### `src/resolver.ts`
98
+ Capability execution — API calls, navigation, hybrid.
99
+
100
+ Key exports:
101
+ - `resolve(matchResult, params, options)` → `ResolveResult`
102
+ - Enforces privacy before executing
103
+ - Injects `auth.userId` into session params automatically
104
+ - Supports `dryRun: true` — returns call plan without executing
105
+ - Retries with `AbortController` timeout on failure
106
+ - Returns `status` and parsed `data` from API response
107
+
108
+ `ResolveOptions`:
109
+ - `baseUrl` — prepended to all API paths
110
+ - `auth` — `{ isAuthenticated, role, userId }`
111
+ - `dryRun` — skip actual fetch
112
+ - `retries` — retry count on failure (default: 0)
113
+ - `timeoutMs` — abort timeout (default: 5000)
114
+ - `headers` — custom request headers
115
+ - `fetch` — injectable fetch function (used in tests)
116
+
117
+ Privacy enforcement:
118
+ - `public` — always allowed
119
+ - `user_owned` — requires `auth.isAuthenticated === true`
120
+ - `admin` — requires `auth.role === 'admin'`
121
+
122
+ ---
123
+
124
+ ### `src/cache.ts`
125
+ Pluggable cache backends.
126
+
127
+ Key exports:
128
+ - `CacheStore` interface — `get(key)`, `set(key, result)`, `clear()`, `size()`
129
+ - `MemoryCache` — in-memory Map, 512-entry cap with oldest-first eviction
130
+ - `FileCache` — async `fs.promises` read/write, lazy-loaded on first access
131
+ - `ComboCache` — memory-first with file fallback, promotes file hits to memory
132
+ - `normalizeQuery(query)` — lowercase + trim + collapse whitespace → cache key
133
+ - `buildCacheKey(query, capabilityId, params)` — smarter key using capability + params (exported for future post-match cache layer — not currently used by engine)
134
+
135
+ Notes:
136
+ - `FileCache` and `ComboCache` are single-instance only — concurrent writers will corrupt
137
+ - For multi-instance deployments, use a Redis adapter (planned v0.5)
138
+
139
+ ---
140
+
141
+ ### `src/learning.ts`
142
+ Usage analytics and keyword index.
143
+
144
+ Key exports:
145
+ - `LearningStore` interface — `record(entry)`, `getStats()`, `getTopCapabilities(limit)`
146
+ - `FileLearningStore` — persists to `.capman/learning.json`, caps at 10,000 entries
147
+ - `MemoryLearningStore` — in-memory only, used in tests
148
+
149
+ `LearningEntry`:
150
+ - `query`, `capabilityId`, `confidence`, `intent`, `extractedParams`
151
+ - `resolvedVia: 'keyword' | 'llm' | 'cache'`
152
+ - `timestamp`
153
+
154
+ `KeywordStats` (from `getStats()`):
155
+ - `index` — `{ word → { capabilityId → hitCount } }` — foundation for adaptive matching
156
+ - `totalQueries`, `llmQueries`, `cacheHits`, `outOfScope`
157
+
158
+ ---
159
+
160
+ ### `src/engine.ts`
161
+ The recommended API — orchestrates matching, caching, learning, and tracing.
162
+
163
+ Key exports:
164
+ - `CapmanEngine` class
165
+ - `EngineOptions` — all constructor options
166
+ - `EngineResult` — `{ match, resolution, resolvedVia, durationMs, trace }`
167
+
168
+ `CapmanEngine` methods:
169
+ - `ask(query, overrides?)` → `EngineResult` — full pipeline: cache → match → resolve → learn
170
+ - `explain(query)` → `ExplainResult` — match only, no execution, with candidate explanations
171
+ - `getStats()` → `KeywordStats | null`
172
+ - `getTopCapabilities(limit?)` → `Array<{ id, hits }>`
173
+ - `clearCache()`
174
+
175
+ Matching pipeline in `ask()`:
176
+ 1. Cache check — return immediately on hit
177
+ 2. Match — `cheap` / `balanced` / `accurate` mode
178
+ 3. Privacy check — recorded in trace
179
+ 4. Cache set — stores under normalized query key
180
+ 5. Resolve — actual API call or nav
181
+ 6. Reasoning build — human-readable array
182
+ 7. Learning record
183
+
184
+ LLM rate limiting (all modes respect these):
185
+ - `maxLLMCallsPerMinute` — sliding window (default: 60)
186
+ - `llmCooldownMs` — minimum gap between calls (default: 0)
187
+ - `llmCircuitBreakerThreshold` — failures before circuit opens (default: 3)
188
+ - `llmCircuitBreakerResetMs` — circuit reset time (default: 60,000ms)
189
+
190
+ ---
191
+
192
+ ### `src/parser.ts`
193
+ OpenAPI/Swagger → capman config converter.
194
+
195
+ Key exports:
196
+ - `parseOpenAPI(specPathOrUrl)` → `ParseResult`
197
+ - Accepts local file path or HTTP URL
198
+ - Parses JSON natively; YAML requires `js-yaml` installed
199
+ - Converts every path+method into a `Capability`
200
+ - Infers privacy from security schemes and tags
201
+ - Extracts path/query/body params
202
+ - Generates examples from operation summaries
203
+
204
+ `ParseResult`:
205
+ - `config` — ready-to-use `CapmanConfig`
206
+ - `stats` — `{ total, skipped, warnings }`
207
+
208
+ Supported: OpenAPI 3.x, Swagger 2.x (JSON or YAML)
209
+
210
+ ---
211
+
212
+ ### `src/logger.ts`
213
+ Minimal logger. Silent by default.
214
+
215
+ Key exports:
216
+ - `logger` — singleton with `debug()`, `info()`, `warn()`, `error()`
217
+ - `setLogLevel(level)` — `'silent' | 'error' | 'warn' | 'info' | 'debug'`
218
+ - `LogLevel` type
219
+
220
+ ---
221
+
222
+ ### `src/index.ts`
223
+ Public API surface. Re-exports everything the library exposes.
224
+
225
+ Notable:
226
+ - `ask(query, manifest, options?)` — convenience function, delegates to `CapmanEngine` internally
227
+ - Marked `@deprecated` — use `CapmanEngine` directly for full features
228
+ - `MatchMode` type — `'cheap' | 'balanced' | 'accurate'`
229
+ - All types, classes, and functions from all modules above
230
+
231
+ ---
232
+
233
+ ## bin/
234
+
235
+ ### `bin/capman.js`
236
+ Entry point only. Reads `command` from `process.argv` and routes to the correct module.
237
+ ~20 lines. No logic here.
238
+
239
+ ### `bin/lib/shared.js`
240
+ Shared utilities used by all command modules.
241
+
242
+ Exports:
243
+ - `args`, `command`, `flags` — parsed from `process.argv`
244
+ - `getFlag(name)` — returns value of `--name value` flag
245
+ - `c` — ANSI color codes (`reset`, `bold`, `teal`, `yellow`, `red`, `green`, `gray`)
246
+ - `log` — `{ info, success, warn, error, blank }`
247
+ - `header()` — prints capman version header
248
+ - `requireSrc()` — loads `dist/cjs/index.js`, auto-builds if missing
249
+
250
+ ### `bin/lib/cmd-init.js`
251
+ Creates `capman.config.js` starter file in current directory.
252
+
253
+ ### `bin/lib/cmd-generate.js`
254
+ Three generation paths:
255
+ - `--from <path|url>` → OpenAPI parser → `capman.config.js` + `manifest.json`
256
+ - `--ai` → LLM-assisted generation from plain English description
257
+ - _(no flags)_ → load `capman.config.js` manually → `manifest.json`
258
+
259
+ Contains `buildAIPrompt(description)` and `callLLM(provider, apiKey, prompt)`.
260
+ Supports `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `OPENROUTER_API_KEY`.
261
+
262
+ ### `bin/lib/cmd-validate.js`
263
+ Reads `manifest.json`, runs Zod validation, prints errors and warnings.
264
+ Exits with code 1 if invalid.
265
+
266
+ ### `bin/lib/cmd-inspect.js`
267
+ Prints all capabilities in `manifest.json` — name, ID, resolver type, privacy, description, first example.
268
+
269
+ ### `bin/lib/cmd-demo.js`
270
+ Live demo using a hardcoded e-commerce manifest.
271
+ Shows the full **QUERY → MATCH → EXECUTION → RESULT → EXPLANATION** blueprint for 4 sample queries.
272
+ No config or API key required.
273
+
274
+ ### `bin/lib/cmd-run.js`
275
+ Runs a single query against the current `manifest.json`.
276
+ `--debug` flag shows all candidate scores.
277
+
278
+ ### `bin/lib/cmd-explain.js`
279
+ Runs `engine.explain(query)` and prints the full explanation:
280
+ - What matched and why
281
+ - All candidates with per-candidate explanations
282
+ - What would execute (without executing)
283
+ - Whether privacy would block it
284
+
285
+ ---
286
+
287
+ ## tests/
288
+
289
+ ### `tests/matcher.test.ts`
290
+ 14 tests covering:
291
+ - Keyword scoring accuracy
292
+ - Out-of-scope detection
293
+ - Param extraction (single token, multi-word, ID params, nav params)
294
+ - `ask()` matching modes (cheap, balanced, accurate, default)
295
+
296
+ ### `tests/resolver.test.ts`
297
+ 18 tests covering:
298
+ - API resolver — dry run, path substitution, query string params
299
+ - Nav resolver — destination building
300
+ - Hybrid resolver — both API and nav
301
+ - No match — graceful failure
302
+ - Privacy enforcement — public, user_owned, admin, session injection
303
+ - Fetch error handling — network error, non-ok status, ok + data
304
+ - Retry behaviour — succeeds after N failures, exhausts retries
305
+
306
+ ### `tests/engine.test.ts`
307
+ 26 tests covering:
308
+ - Basic `ask()` — match and resolve
309
+ - Caching — cache hit, cache cleared, ComboCache promotion
310
+ - Learning — records queries, top capabilities, resolvedVia tracking
311
+ - Matching modes — cheap never calls LLM, accurate calls LLM
312
+ - Execution trace — candidates, reasoning, steps, cache hit trace
313
+ - `explain()` — matched, out of scope, candidates with explanations, wouldExecute, blocked, no side effects
314
+ - LLM rate limiting — rate limit, cooldown, circuit breaker, fallback on failure
315
+
316
+ ### `tests/parser.test.ts`
317
+ 9 tests covering:
318
+ - Capability extraction from spec
319
+ - Correct IDs from `operationId`
320
+ - Privacy inference from tags and security
321
+ - Path and query param extraction
322
+ - Request body field extraction
323
+ - Base URL extraction
324
+ - Skipping operations with insufficient info
325
+ - Error on missing file
326
+
327
+ ---
328
+
329
+ ## scripts/
330
+
331
+ ### `scripts/version.js`
332
+ Prebuild script. Reads `version` from `package.json` and writes:
333
+ ```typescript
334
+ // Auto-generated by scripts/version.js — do not edit manually
335
+ export const VERSION = '0.4.2'
336
+ ```
337
+ to `src/version.ts`. Runs automatically before every `pnpm run build`.
338
+
339
+ `src/version.ts` is gitignored.
340
+
341
+ ---
342
+
343
+ ## test/ (integration, not in CI)
344
+
345
+ ### `test/conduit.config.js`
346
+ capman config for the RealWorld Conduit app (`conduit.productionready.io`).
347
+ 8 capabilities covering all resolver types.
348
+
349
+ ### `test/test-conduit.ts`
350
+ Tests keyword matcher against live Conduit API.
351
+
352
+ ### `test/test-llm-live.ts`
353
+ Tests `matchWithLLM` and `CapmanEngine` accurate mode against live API using OpenRouter free models.
354
+
355
+ ---
356
+
357
+ ## Config files
358
+
359
+ | File | Purpose |
360
+ |---|---|
361
+ | `tsconfig.json` | CJS build → `dist/cjs/` |
362
+ | `tsconfig.esm.json` | ESM build → `dist/esm/` |
363
+ | `package.json` | Version, exports map, scripts, dependencies |
364
+ | `.github/workflows/ci.yml` | Build + test + verify dist on every push |
365
+ | `.gitignore` | Ignores `dist/`, `node_modules/`, `src/version.ts`, `.capman/` |
366
+ | `CHANGELOG.md` | All notable changes per version |
367
+ | `CODEBASE.md` | This file |
368
+
369
+ ---
370
+
371
+ ## Data flow
372
+
373
+ ```
374
+ Developer writes capman.config.js
375
+
376
+ capman generate
377
+
378
+ generator.ts → manifest.json
379
+
380
+ CapmanEngine.ask("user query")
381
+
382
+ cache.ts → cache hit? return immediately
383
+
384
+ matcher.ts → score all capabilities → pick winner
385
+
386
+ resolver.ts → enforce privacy → call API or navigate
387
+
388
+ learning.ts → record query + result
389
+
390
+ EngineResult → { match, resolution, trace, resolvedVia }
391
+ ```
package/README.md CHANGED
@@ -321,4 +321,4 @@ const result = await engine.ask('show my orders', {
321
321
 
322
322
  ## License
323
323
 
324
- MIT — [github.com/Hobbydefiningdoctory/capman]
324
+ MIT — [(github.com/Hobbydefiningdoctory/capman)](https://github.com/Hobbydefiningdoctory/capman.git)