capman 0.4.2 → 0.4.4
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/CHANGELOG.md +153 -0
- package/CODEBASE.md +393 -0
- package/README.md +1 -1
- package/bin/capman.js +11 -724
- package/bin/lib/cmd-demo.js +180 -0
- package/bin/lib/cmd-explain.js +72 -0
- package/bin/lib/cmd-generate.js +280 -0
- package/bin/lib/cmd-help.js +26 -0
- package/bin/lib/cmd-init.js +19 -0
- package/bin/lib/cmd-inspect.js +33 -0
- package/bin/lib/cmd-run.js +71 -0
- package/bin/lib/cmd-validate.js +32 -0
- package/bin/lib/shared.js +77 -0
- package/dist/cjs/cache.d.ts.map +1 -1
- package/dist/cjs/cache.js +8 -2
- package/dist/cjs/cache.js.map +1 -1
- package/dist/cjs/engine.d.ts +58 -1
- package/dist/cjs/engine.d.ts.map +1 -1
- package/dist/cjs/engine.js +312 -12
- package/dist/cjs/engine.js.map +1 -1
- package/dist/cjs/generator.d.ts.map +1 -1
- package/dist/cjs/generator.js +4 -0
- package/dist/cjs/generator.js.map +1 -1
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/learning.d.ts.map +1 -1
- package/dist/cjs/learning.js +7 -2
- package/dist/cjs/learning.js.map +1 -1
- package/dist/cjs/matcher.d.ts.map +1 -1
- package/dist/cjs/matcher.js +23 -27
- package/dist/cjs/matcher.js.map +1 -1
- package/dist/cjs/parser.js +2 -1
- package/dist/cjs/parser.js.map +1 -1
- package/dist/cjs/resolver.js +6 -2
- package/dist/cjs/resolver.js.map +1 -1
- package/dist/cjs/types.d.ts +27 -0
- 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.d.ts +49 -0
- package/dist/esm/cache.js +8 -2
- package/dist/esm/engine.d.ts +138 -0
- package/dist/esm/engine.js +312 -12
- package/dist/esm/generator.d.ts +7 -0
- package/dist/esm/generator.js +4 -0
- package/dist/esm/index.d.ts +47 -0
- package/dist/esm/learning.d.ts +55 -0
- package/dist/esm/learning.js +7 -2
- package/dist/esm/logger.d.ts +21 -0
- package/dist/esm/matcher.d.ts +6 -0
- package/dist/esm/matcher.js +23 -27
- package/dist/esm/parser.d.ts +10 -0
- package/dist/esm/parser.js +2 -1
- package/dist/esm/resolver.d.ts +21 -0
- package/dist/esm/resolver.js +6 -2
- package/dist/esm/schema.d.ts +740 -0
- package/dist/esm/types.d.ts +136 -0
- package/dist/esm/version.d.ts +1 -0
- package/dist/esm/version.js +1 -1
- package/package.json +5 -3
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type LogLevel = 'silent' | 'error' | 'warn' | 'info' | 'debug';
|
|
2
|
+
export declare class Logger {
|
|
3
|
+
private level;
|
|
4
|
+
constructor(level?: LogLevel);
|
|
5
|
+
setLevel(level: LogLevel): void;
|
|
6
|
+
error(msg: string, ...args: unknown[]): void;
|
|
7
|
+
warn(msg: string, ...args: unknown[]): void;
|
|
8
|
+
info(msg: string, ...args: unknown[]): void;
|
|
9
|
+
debug(msg: string, ...args: unknown[]): void;
|
|
10
|
+
}
|
|
11
|
+
export declare const logger: Logger;
|
|
12
|
+
/**
|
|
13
|
+
* Set the global log level for capman.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* import { setLogLevel } from 'capman'
|
|
17
|
+
* setLogLevel('debug') // see everything
|
|
18
|
+
* setLogLevel('info') // see key steps
|
|
19
|
+
* setLogLevel('silent') // no output (default)
|
|
20
|
+
*/
|
|
21
|
+
export declare function setLogLevel(level: LogLevel): void;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Manifest, MatchResult } from './types';
|
|
2
|
+
export declare function match(query: string, manifest: Manifest): MatchResult;
|
|
3
|
+
export interface LLMMatcherOptions {
|
|
4
|
+
llm: (prompt: string) => Promise<string>;
|
|
5
|
+
}
|
|
6
|
+
export declare function matchWithLLM(query: string, manifest: Manifest, options: LLMMatcherOptions): Promise<MatchResult>;
|
package/dist/esm/matcher.js
CHANGED
|
@@ -76,9 +76,6 @@ function extractParams(query, cap) {
|
|
|
76
76
|
// e.g. "profile for johndoe" → johndoe
|
|
77
77
|
// "articles by jane" → jane
|
|
78
78
|
// "tag javascript" → javascript
|
|
79
|
-
// Use param name and description as hints for what to look for
|
|
80
|
-
const paramHints = [param.name, ...param.description.toLowerCase().split(/\s+/)]
|
|
81
|
-
.filter(w => w.length > 2);
|
|
82
79
|
// Try keyword-based extraction first
|
|
83
80
|
const keywords = [
|
|
84
81
|
`for `, `by `, `about `, `named `, `called `,
|
|
@@ -203,29 +200,28 @@ export async function matchWithLLM(query, manifest, options) {
|
|
|
203
200
|
"reasoning": "<one sentence>",
|
|
204
201
|
"extracted_params": { "<param_name>": "<value or null>" }
|
|
205
202
|
}`;
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
intent: isOOS ? 'out_of_scope' : parsed.intent,
|
|
218
|
-
extractedParams: parsed.extracted_params ?? {},
|
|
219
|
-
reasoning: parsed.reasoning,
|
|
220
|
-
candidates: capability ? [{
|
|
221
|
-
capabilityId: capability.id,
|
|
222
|
-
score: parsed.confidence,
|
|
223
|
-
matched: true,
|
|
224
|
-
}] : [],
|
|
225
|
-
};
|
|
226
|
-
}
|
|
227
|
-
catch (err) {
|
|
228
|
-
logger.warn(`LLM match failed, falling back to keyword matcher: ${err}`);
|
|
229
|
-
return match(query, manifest);
|
|
203
|
+
const raw = await options.llm(prompt);
|
|
204
|
+
const clean = raw.replace(/```json|```/g, '').trim();
|
|
205
|
+
const parsed = JSON.parse(clean);
|
|
206
|
+
const isOOS = parsed.matched_capability === 'OUT_OF_SCOPE';
|
|
207
|
+
const capability = isOOS
|
|
208
|
+
? null
|
|
209
|
+
: manifest.capabilities.find(c => c.id === parsed.matched_capability) ?? null;
|
|
210
|
+
// If LLM returned an unknown capability ID, treat as out of scope
|
|
211
|
+
const effectivelyOOS = isOOS || capability === null;
|
|
212
|
+
if (!effectivelyOOS && capability === null) {
|
|
213
|
+
logger.warn(`LLM returned unknown capability ID: "${parsed.matched_capability}" — treating as out_of_scope`);
|
|
230
214
|
}
|
|
215
|
+
return {
|
|
216
|
+
capability,
|
|
217
|
+
confidence: effectivelyOOS ? 0 : parsed.confidence,
|
|
218
|
+
intent: effectivelyOOS ? 'out_of_scope' : parsed.intent,
|
|
219
|
+
extractedParams: parsed.extracted_params ?? {},
|
|
220
|
+
reasoning: parsed.reasoning ?? 'No reasoning provided',
|
|
221
|
+
candidates: capability ? [{
|
|
222
|
+
capabilityId: capability.id,
|
|
223
|
+
score: parsed.confidence,
|
|
224
|
+
matched: true,
|
|
225
|
+
}] : [],
|
|
226
|
+
};
|
|
231
227
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CapmanConfig } from './types';
|
|
2
|
+
export interface ParseResult {
|
|
3
|
+
config: CapmanConfig;
|
|
4
|
+
stats: {
|
|
5
|
+
total: number;
|
|
6
|
+
skipped: number;
|
|
7
|
+
warnings: string[];
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export declare function parseOpenAPI(specPathOrUrl: string): Promise<ParseResult>;
|
package/dist/esm/parser.js
CHANGED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { MatchResult, ResolveResult } from './types';
|
|
2
|
+
export interface AuthContext {
|
|
3
|
+
/** Whether the current request is authenticated */
|
|
4
|
+
isAuthenticated: boolean;
|
|
5
|
+
/** Current user's role */
|
|
6
|
+
role?: 'user' | 'admin';
|
|
7
|
+
/** Current user's ID — injected into session params */
|
|
8
|
+
userId?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface ResolveOptions {
|
|
11
|
+
baseUrl?: string;
|
|
12
|
+
fetch?: typeof globalThis.fetch;
|
|
13
|
+
dryRun?: boolean;
|
|
14
|
+
headers?: Record<string, string>;
|
|
15
|
+
auth?: AuthContext;
|
|
16
|
+
/** Number of retries on failure (default: 0) */
|
|
17
|
+
retries?: number;
|
|
18
|
+
/** Timeout in milliseconds (default: 5000) */
|
|
19
|
+
timeoutMs?: number;
|
|
20
|
+
}
|
|
21
|
+
export declare function resolve(matchResult: MatchResult, params?: Record<string, unknown>, options?: ResolveOptions): Promise<ResolveResult>;
|
package/dist/esm/resolver.js
CHANGED
|
@@ -43,7 +43,7 @@ export async function resolve(matchResult, params = {}, options = {}) {
|
|
|
43
43
|
// ── Session param injection ───────────────────────────────────────────────
|
|
44
44
|
// Inject auth.userId into any params marked as source: 'session'
|
|
45
45
|
const enrichedParams = { ...params };
|
|
46
|
-
if (options.auth?.userId) {
|
|
46
|
+
if (options.auth?.userId !== undefined) {
|
|
47
47
|
for (const param of capability.params) {
|
|
48
48
|
if (param.source === 'session') {
|
|
49
49
|
enrichedParams[param.name] = options.auth.userId;
|
|
@@ -172,7 +172,9 @@ async function resolveApi(resolver, params, options) {
|
|
|
172
172
|
function resolveNav(resolver, params) {
|
|
173
173
|
let destination = resolver.destination;
|
|
174
174
|
for (const [key, value] of Object.entries(params)) {
|
|
175
|
-
|
|
175
|
+
if (value === null || value === undefined)
|
|
176
|
+
continue;
|
|
177
|
+
destination = destination.replace(`{${key}}`, encodeURIComponent(String(value)));
|
|
176
178
|
}
|
|
177
179
|
return { success: true, resolverType: 'nav', navTarget: destination };
|
|
178
180
|
}
|
|
@@ -180,6 +182,8 @@ function buildUrl(baseUrl, urlPath, params) {
|
|
|
180
182
|
let resolved = urlPath;
|
|
181
183
|
const unused = {};
|
|
182
184
|
for (const [key, value] of Object.entries(params)) {
|
|
185
|
+
if (value === null || value === undefined)
|
|
186
|
+
continue; // never write null into URLs
|
|
183
187
|
if (resolved.includes(`{${key}}`)) {
|
|
184
188
|
resolved = resolved.replace(`{${key}}`, encodeURIComponent(String(value)));
|
|
185
189
|
}
|