@frontmcp/adapters 1.1.2 → 1.2.1
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/esm/index.mjs +396 -385
- package/esm/openapi/index.mjs +396 -385
- package/esm/package.json +18 -6
- package/esm/skills/index.mjs +2117 -0
- package/index.js +407 -389
- package/openapi/index.d.ts +11 -1
- package/openapi/index.d.ts.map +1 -1
- package/openapi/index.js +407 -389
- package/openapi/openapi.adapter.d.ts +2 -2
- package/openapi/openapi.adapter.d.ts.map +1 -1
- package/openapi/openapi.tool.d.ts.map +1 -1
- package/openapi/openapi.types.d.ts +3 -3
- package/openapi/openapi.types.d.ts.map +1 -1
- package/openapi/openapi.utils.d.ts.map +1 -1
- package/package.json +18 -6
- package/skills/audit/audit-chain.d.ts +81 -0
- package/skills/audit/audit-chain.d.ts.map +1 -0
- package/skills/audit/audit-config.d.ts +87 -0
- package/skills/audit/audit-config.d.ts.map +1 -0
- package/skills/audit/audit-record.types.d.ts +114 -0
- package/skills/audit/audit-record.types.d.ts.map +1 -0
- package/skills/audit/audit-signer.d.ts +72 -0
- package/skills/audit/audit-signer.d.ts.map +1 -0
- package/skills/audit/audit-store.d.ts +84 -0
- package/skills/audit/audit-store.d.ts.map +1 -0
- package/skills/audit/audit-writer.d.ts +175 -0
- package/skills/audit/audit-writer.d.ts.map +1 -0
- package/skills/audit/index.d.ts +7 -0
- package/skills/audit/index.d.ts.map +1 -0
- package/skills/bundle/bundle-diff.d.ts +30 -0
- package/skills/bundle/bundle-diff.d.ts.map +1 -0
- package/skills/bundle/bundle.schema.d.ts +101 -0
- package/skills/bundle/bundle.schema.d.ts.map +1 -0
- package/skills/bundle/bundle.store.d.ts +143 -0
- package/skills/bundle/bundle.store.d.ts.map +1 -0
- package/skills/bundle/bundle.types.d.ts +143 -0
- package/skills/bundle/bundle.types.d.ts.map +1 -0
- package/skills/bundle/overlay-parser.d.ts +42 -0
- package/skills/bundle/overlay-parser.d.ts.map +1 -0
- package/skills/dependency/skill-dag.d.ts +39 -0
- package/skills/dependency/skill-dag.d.ts.map +1 -0
- package/skills/index.d.ts +17 -0
- package/skills/index.d.ts.map +1 -0
- package/skills/index.js +2192 -0
- package/skills/security/bundle-signature.d.ts +44 -0
- package/skills/security/bundle-signature.d.ts.map +1 -0
- package/skills/security/jwt-verifier.d.ts +38 -0
- package/skills/security/jwt-verifier.d.ts.map +1 -0
- package/skills/security/webhook-replay-guard.d.ts +52 -0
- package/skills/security/webhook-replay-guard.d.ts.map +1 -0
- package/skills/source-options.d.ts +55 -0
- package/skills/source-options.d.ts.map +1 -0
- package/skills/sources/filesystem-skills.source.d.ts +127 -0
- package/skills/sources/filesystem-skills.source.d.ts.map +1 -0
- package/skills/sources/index.d.ts +10 -0
- package/skills/sources/index.d.ts.map +1 -0
- package/skills/sources/npm.source.d.ts +30 -0
- package/skills/sources/npm.source.d.ts.map +1 -0
- package/skills/sources/saas-pull.source.d.ts +47 -0
- package/skills/sources/saas-pull.source.d.ts.map +1 -0
- package/skills/sources/skill-bundle-source.interface.d.ts +36 -0
- package/skills/sources/skill-bundle-source.interface.d.ts.map +1 -0
- package/skills/sources/static.source.d.ts +30 -0
- package/skills/sources/static.source.d.ts.map +1 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { BundleIntegrity, ResolvedBundle } from '../bundle/bundle.types';
|
|
2
|
+
import type { SignatureKey } from '../source-options';
|
|
3
|
+
export type SignatureVerifyResult = {
|
|
4
|
+
ok: true;
|
|
5
|
+
keyId: string;
|
|
6
|
+
alg: BundleIntegrity['alg'];
|
|
7
|
+
} | {
|
|
8
|
+
ok: false;
|
|
9
|
+
reason: string;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Minimal telemetry surface for signature verification failures. Structurally
|
|
13
|
+
* compatible with `@frontmcp/observability`'s `TelemetryAccessor` so callers
|
|
14
|
+
* can pass that directly, while keeping this module dependency-free.
|
|
15
|
+
*/
|
|
16
|
+
export interface SignatureVerifyCounter {
|
|
17
|
+
inc(by?: number, attributes?: Record<string, string>): void;
|
|
18
|
+
}
|
|
19
|
+
export interface SignatureVerifyTelemetry {
|
|
20
|
+
createCounter(name: string, description?: string): SignatureVerifyCounter;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Stable JSON canonicalization for signing: sorted object keys, no whitespace.
|
|
24
|
+
* Matches RFC 8785 (JCS) for our subset (no floats with weird precision).
|
|
25
|
+
*/
|
|
26
|
+
export declare function canonicalize(value: unknown): string;
|
|
27
|
+
/** sha256 hex digest of the canonical bytes of an object (minus integrity). */
|
|
28
|
+
export declare function bundleDigest(bundle: ResolvedBundle): string;
|
|
29
|
+
/**
|
|
30
|
+
* Verify an integrity envelope against a set of trusted keys.
|
|
31
|
+
*
|
|
32
|
+
* Verification flow:
|
|
33
|
+
* 1. Re-compute the canonical digest of the bundle (excluding `integrity`).
|
|
34
|
+
* 2. Reject if the computed digest does not match the envelope's `digest`.
|
|
35
|
+
* 3. Look up the trusted key by `keyId`. Reject if unknown.
|
|
36
|
+
* 4. Reject if the key's `alg` does not match the envelope's `alg`.
|
|
37
|
+
* 5. Verify the signature over the canonical bytes (NOT the digest hex)
|
|
38
|
+
* using the public key.
|
|
39
|
+
*
|
|
40
|
+
* Returns a structured ok/reason envelope. Callers MUST refuse to apply the
|
|
41
|
+
* bundle on `ok: false`.
|
|
42
|
+
*/
|
|
43
|
+
export declare function verifyBundleSignature(bundle: ResolvedBundle, trustedKeys: SignatureKey[], telemetry?: SignatureVerifyTelemetry): SignatureVerifyResult;
|
|
44
|
+
//# sourceMappingURL=bundle-signature.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundle-signature.d.ts","sourceRoot":"","sources":["../../../src/skills/security/bundle-signature.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,MAAM,MAAM,qBAAqB,GAC7B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,eAAe,CAAC,KAAK,CAAC,CAAA;CAAE,GACxD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAElC;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC,GAAG,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;CAC7D;AACD,MAAM,WAAW,wBAAwB;IACvC,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,sBAAsB,CAAC;CAC3E;AAmBD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAUnD;AAED,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAI3D;AAeD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,cAAc,EACtB,WAAW,EAAE,YAAY,EAAE,EAC3B,SAAS,CAAC,EAAE,wBAAwB,GACnC,qBAAqB,CAoEvB"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { JwksService } from '@frontmcp/auth';
|
|
2
|
+
import type { FrontMcpLogger } from '@frontmcp/sdk';
|
|
3
|
+
export interface BundlePushJwtVerifierOptions {
|
|
4
|
+
/** SaaS issuer URL (matched against `iss`). */
|
|
5
|
+
expectedIssuer: string;
|
|
6
|
+
/** Audience the token must encode (RFC 8707 `aud` claim). */
|
|
7
|
+
expectedAudience: string;
|
|
8
|
+
/**
|
|
9
|
+
* RFC 8707 resource indicator the token must encode (matches the FrontMCP
|
|
10
|
+
* server's canonical URL). MCP spec 2026-03-15 mandates this on every JWT.
|
|
11
|
+
*/
|
|
12
|
+
expectedResource: string;
|
|
13
|
+
/** JWKS endpoint URL of the SaaS issuer. */
|
|
14
|
+
jwksUri: string;
|
|
15
|
+
/** Required role claim values; the token must contain at least one. */
|
|
16
|
+
requiredRoles?: string[];
|
|
17
|
+
/** Required scope claim values; the token must contain at least one. */
|
|
18
|
+
requiredScopes?: string[];
|
|
19
|
+
}
|
|
20
|
+
export interface PushJwtVerifyResult {
|
|
21
|
+
ok: boolean;
|
|
22
|
+
reason?: string;
|
|
23
|
+
payload?: Record<string, unknown>;
|
|
24
|
+
}
|
|
25
|
+
export declare class BundlePushJwtVerifier {
|
|
26
|
+
private readonly options;
|
|
27
|
+
private readonly logger;
|
|
28
|
+
private readonly providerRef;
|
|
29
|
+
private readonly jwks;
|
|
30
|
+
constructor(options: BundlePushJwtVerifierOptions, logger: FrontMcpLogger, jwks?: JwksService);
|
|
31
|
+
/**
|
|
32
|
+
* Verify a SaaS-issued bearer token. Returns ok=true only if signature,
|
|
33
|
+
* issuer, audience, RFC 8707 resource indicator, and role claims all check.
|
|
34
|
+
*/
|
|
35
|
+
verify(token: string): Promise<PushJwtVerifyResult>;
|
|
36
|
+
private matchesAny;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=jwt-verifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwt-verifier.d.ts","sourceRoot":"","sources":["../../../src/skills/security/jwt-verifier.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,WAAW,EAA6C,MAAM,gBAAgB,CAAC;AACxF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,MAAM,WAAW,4BAA4B;IAC3C,+CAA+C;IAC/C,cAAc,EAAE,MAAM,CAAC;IACvB,6DAA6D;IAC7D,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,gBAAgB,EAAE,MAAM,CAAC;IACzB,4CAA4C;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,wEAAwE;IACxE,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAID,qBAAa,qBAAqB;IAK9B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IALzB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoB;IAChD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAc;gBAGhB,OAAO,EAAE,4BAA4B,EACrC,MAAM,EAAE,cAAc,EACvC,IAAI,CAAC,EAAE,WAAW;IAUpB;;;OAGG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAsDzD,OAAO,CAAC,UAAU;CAQnB"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export interface ReplayCheckResult {
|
|
2
|
+
ok: boolean;
|
|
3
|
+
reason?: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Minimal telemetry surface for replay rejects. Structurally compatible
|
|
7
|
+
* with `@frontmcp/observability`'s `TelemetryAccessor` so callers can pass
|
|
8
|
+
* that directly while keeping this module dependency-free.
|
|
9
|
+
*/
|
|
10
|
+
export interface ReplayGuardCounter {
|
|
11
|
+
inc(by?: number, attributes?: Record<string, string>): void;
|
|
12
|
+
}
|
|
13
|
+
export interface ReplayGuardTelemetry {
|
|
14
|
+
createCounter(name: string, description?: string): ReplayGuardCounter;
|
|
15
|
+
}
|
|
16
|
+
export interface WebhookReplayGuardOptions {
|
|
17
|
+
/** Allowed clock skew window in ms (default 300_000 = 5min). */
|
|
18
|
+
windowMs?: number;
|
|
19
|
+
/** Max nonces tracked simultaneously (default 5_000). */
|
|
20
|
+
capacity?: number;
|
|
21
|
+
/**
|
|
22
|
+
* Optional telemetry hook. When provided, every `check()` rejection is
|
|
23
|
+
* recorded against `frontmcp_skills_replay_rejects_total` with a low-cardinality
|
|
24
|
+
* `{ reason }` attribute. When omitted, the guard emits no telemetry.
|
|
25
|
+
*/
|
|
26
|
+
telemetry?: ReplayGuardTelemetry;
|
|
27
|
+
}
|
|
28
|
+
export declare class WebhookReplayGuard {
|
|
29
|
+
private readonly windowMs;
|
|
30
|
+
private readonly capacity;
|
|
31
|
+
private readonly seen;
|
|
32
|
+
private now;
|
|
33
|
+
private readonly rejectsCounter;
|
|
34
|
+
private readonly checksCounter;
|
|
35
|
+
constructor(options?: WebhookReplayGuardOptions);
|
|
36
|
+
/** For tests: override the time source. */
|
|
37
|
+
setNowProvider(fn: () => number): void;
|
|
38
|
+
/**
|
|
39
|
+
* Check that a (timestamp, nonce) pair is fresh and unseen. Returns ok=false
|
|
40
|
+
* if the timestamp is outside the freshness window or the nonce has already
|
|
41
|
+
* been observed within that window.
|
|
42
|
+
*/
|
|
43
|
+
check(args: {
|
|
44
|
+
timestampMs: number;
|
|
45
|
+
nonce: string;
|
|
46
|
+
}): ReplayCheckResult;
|
|
47
|
+
/** Test/maintenance helper: drop expired entries proactively. */
|
|
48
|
+
prune(): number;
|
|
49
|
+
/** Inspect: number of nonces currently tracked. */
|
|
50
|
+
get size(): number;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=webhook-replay-guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook-replay-guard.d.ts","sourceRoot":"","sources":["../../../src/skills/security/webhook-replay-guard.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,GAAG,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;CAC7D;AACD,MAAM,WAAW,oBAAoB;IACnC,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,kBAAkB,CAAC;CACvE;AAED,MAAM,WAAW,yBAAyB;IACxC,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,SAAS,CAAC,EAAE,oBAAoB,CAAC;CAClC;AAgBD,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA6B;IAClD,OAAO,CAAC,GAAG,CAA0B;IACrC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiC;IAChE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAiC;gBAEnD,OAAO,GAAE,yBAA8B;IAyBnD,2CAA2C;IAC3C,cAAc,CAAC,EAAE,EAAE,MAAM,MAAM,GAAG,IAAI;IAItC;;;;OAIG;IACH,KAAK,CAAC,IAAI,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,iBAAiB;IA0DtE,iEAAiE;IACjE,KAAK,IAAI,MAAM;IAYf,mDAAmD;IACnD,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { z } from '@frontmcp/lazy-zod';
|
|
2
|
+
export declare const staticSourceSchema: import("@frontmcp/lazy-zod").ZodObject<{
|
|
3
|
+
type: import("@frontmcp/lazy-zod").ZodLiteral<"static">;
|
|
4
|
+
path: import("@frontmcp/lazy-zod").ZodString;
|
|
5
|
+
watch: import("@frontmcp/lazy-zod").ZodDefault<import("@frontmcp/lazy-zod").ZodBoolean>;
|
|
6
|
+
}, import("zod/v4/core").$strip>;
|
|
7
|
+
export declare const npmSourceSchema: import("@frontmcp/lazy-zod").ZodObject<{
|
|
8
|
+
type: import("@frontmcp/lazy-zod").ZodLiteral<"npm">;
|
|
9
|
+
packageName: import("@frontmcp/lazy-zod").ZodString;
|
|
10
|
+
exportName: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodString>;
|
|
11
|
+
verifyProvenance: import("@frontmcp/lazy-zod").ZodDefault<import("@frontmcp/lazy-zod").ZodBoolean>;
|
|
12
|
+
}, import("zod/v4/core").$strip>;
|
|
13
|
+
export declare const saasSourceSchema: import("@frontmcp/lazy-zod").ZodObject<{
|
|
14
|
+
type: import("@frontmcp/lazy-zod").ZodLiteral<"saas">;
|
|
15
|
+
endpoint: import("@frontmcp/lazy-zod").ZodString;
|
|
16
|
+
authToken: import("@frontmcp/lazy-zod").ZodString;
|
|
17
|
+
expectedAudience: import("@frontmcp/lazy-zod").ZodString;
|
|
18
|
+
pollIntervalMs: import("@frontmcp/lazy-zod").ZodDefault<import("@frontmcp/lazy-zod").ZodNumber>;
|
|
19
|
+
enableWebhook: import("@frontmcp/lazy-zod").ZodDefault<import("@frontmcp/lazy-zod").ZodBoolean>;
|
|
20
|
+
jwksUrl: import("@frontmcp/lazy-zod").ZodString;
|
|
21
|
+
expectedIssuer: import("@frontmcp/lazy-zod").ZodString;
|
|
22
|
+
}, import("zod/v4/core").$strip>;
|
|
23
|
+
export declare const bundleSourceSchema: import("@frontmcp/lazy-zod").ZodDiscriminatedUnion<[import("@frontmcp/lazy-zod").ZodObject<{
|
|
24
|
+
type: import("@frontmcp/lazy-zod").ZodLiteral<"static">;
|
|
25
|
+
path: import("@frontmcp/lazy-zod").ZodString;
|
|
26
|
+
watch: import("@frontmcp/lazy-zod").ZodDefault<import("@frontmcp/lazy-zod").ZodBoolean>;
|
|
27
|
+
}, import("zod/v4/core").$strip>, import("@frontmcp/lazy-zod").ZodObject<{
|
|
28
|
+
type: import("@frontmcp/lazy-zod").ZodLiteral<"npm">;
|
|
29
|
+
packageName: import("@frontmcp/lazy-zod").ZodString;
|
|
30
|
+
exportName: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodString>;
|
|
31
|
+
verifyProvenance: import("@frontmcp/lazy-zod").ZodDefault<import("@frontmcp/lazy-zod").ZodBoolean>;
|
|
32
|
+
}, import("zod/v4/core").$strip>, import("@frontmcp/lazy-zod").ZodObject<{
|
|
33
|
+
type: import("@frontmcp/lazy-zod").ZodLiteral<"saas">;
|
|
34
|
+
endpoint: import("@frontmcp/lazy-zod").ZodString;
|
|
35
|
+
authToken: import("@frontmcp/lazy-zod").ZodString;
|
|
36
|
+
expectedAudience: import("@frontmcp/lazy-zod").ZodString;
|
|
37
|
+
pollIntervalMs: import("@frontmcp/lazy-zod").ZodDefault<import("@frontmcp/lazy-zod").ZodNumber>;
|
|
38
|
+
enableWebhook: import("@frontmcp/lazy-zod").ZodDefault<import("@frontmcp/lazy-zod").ZodBoolean>;
|
|
39
|
+
jwksUrl: import("@frontmcp/lazy-zod").ZodString;
|
|
40
|
+
expectedIssuer: import("@frontmcp/lazy-zod").ZodString;
|
|
41
|
+
}, import("zod/v4/core").$strip>], "type">;
|
|
42
|
+
export type StaticSourceOptions = z.infer<typeof staticSourceSchema>;
|
|
43
|
+
export type NpmSourceOptions = z.infer<typeof npmSourceSchema>;
|
|
44
|
+
export type SaasSourceOptions = z.infer<typeof saasSourceSchema>;
|
|
45
|
+
export type BundleSourceOptions = z.infer<typeof bundleSourceSchema>;
|
|
46
|
+
export declare const signatureKeySchema: import("@frontmcp/lazy-zod").ZodObject<{
|
|
47
|
+
keyId: import("@frontmcp/lazy-zod").ZodString;
|
|
48
|
+
alg: import("@frontmcp/lazy-zod").ZodEnum<{
|
|
49
|
+
RS256: "RS256";
|
|
50
|
+
EdDSA: "EdDSA";
|
|
51
|
+
}>;
|
|
52
|
+
publicKeyPem: import("@frontmcp/lazy-zod").ZodString;
|
|
53
|
+
}, import("zod/v4/core").$strip>;
|
|
54
|
+
export type SignatureKey = z.infer<typeof signatureKeySchema>;
|
|
55
|
+
//# sourceMappingURL=source-options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-options.d.ts","sourceRoot":"","sources":["../../src/skills/source-options.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,CAAC,EAAE,MAAM,oBAAoB,CAAC;AAkBvC,eAAO,MAAM,kBAAkB;;;;gCAM7B,CAAC;AAEH,eAAO,MAAM,eAAe;;;;;gCAW1B,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;gCAsB3B,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;0CAAwF,CAAC;AAExH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AACrE,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAC/D,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AACjE,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAIrE,eAAO,MAAM,kBAAkB;;;;;;;gCAO7B,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight logger surface — kept narrow so this module can sit in a
|
|
3
|
+
* standalone adapter without dragging the SDK's full FrontMcpLogger type in.
|
|
4
|
+
*/
|
|
5
|
+
export interface FilesystemSkillsLogger {
|
|
6
|
+
info(message: string, meta?: Record<string, unknown>): void;
|
|
7
|
+
warn(message: string, meta?: Record<string, unknown>): void;
|
|
8
|
+
error(message: string, meta?: Record<string, unknown>): void;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Minimum subset of `SkillContent` produced by this source. Hosts can map it
|
|
12
|
+
* onto the SDK's full `SkillContent` (with resources, parameters, etc.) when
|
|
13
|
+
* they wire `onChange` into `registerSkillContent`. The fields here are the
|
|
14
|
+
* ones we read from SKILL.md directly.
|
|
15
|
+
*/
|
|
16
|
+
export interface FilesystemSkillContent {
|
|
17
|
+
id: string;
|
|
18
|
+
name: string;
|
|
19
|
+
description: string;
|
|
20
|
+
instructions: string;
|
|
21
|
+
tools: Array<{
|
|
22
|
+
name: string;
|
|
23
|
+
purpose?: string;
|
|
24
|
+
required?: boolean;
|
|
25
|
+
}>;
|
|
26
|
+
/** Bundled resource subdirs the host may also load (scripts/, references/, examples/, assets/). */
|
|
27
|
+
resources?: {
|
|
28
|
+
scripts?: string;
|
|
29
|
+
references?: string;
|
|
30
|
+
examples?: string;
|
|
31
|
+
assets?: string;
|
|
32
|
+
};
|
|
33
|
+
/** Optional license / compatibility notes parsed from frontmatter. */
|
|
34
|
+
license?: string;
|
|
35
|
+
compatibility?: string;
|
|
36
|
+
}
|
|
37
|
+
export type FilesystemSkillsEvent = {
|
|
38
|
+
op: 'upsert';
|
|
39
|
+
skill: FilesystemSkillContent;
|
|
40
|
+
absPath: string;
|
|
41
|
+
} | {
|
|
42
|
+
op: 'delete';
|
|
43
|
+
skillId: string;
|
|
44
|
+
absPath: string;
|
|
45
|
+
};
|
|
46
|
+
export type FilesystemSkillsListener = (event: FilesystemSkillsEvent) => void;
|
|
47
|
+
export interface FilesystemSkillsSourceOptions {
|
|
48
|
+
/** Directory holding skill subdirectories. Default: `./skills`. */
|
|
49
|
+
skillsDir?: string;
|
|
50
|
+
/**
|
|
51
|
+
* Watch for changes after the initial scan. Default: true. When false the
|
|
52
|
+
* source emits each skill once on `start()` and never re-fires.
|
|
53
|
+
*/
|
|
54
|
+
watch?: boolean;
|
|
55
|
+
/** Debounce window in ms before re-reading a changed subdir. Default: 200. */
|
|
56
|
+
debounceMs?: number;
|
|
57
|
+
/**
|
|
58
|
+
* Polling interval (ms) used as a fallback when `fs.watch` is unreliable
|
|
59
|
+
* (Linux watch limits, network FS, exotic mount points). When set, the
|
|
60
|
+
* source falls back to polling the dir mtime; otherwise it surfaces the
|
|
61
|
+
* `fs.watch` failure as a warning and stops watching.
|
|
62
|
+
* Default: 2000.
|
|
63
|
+
*/
|
|
64
|
+
pollIntervalMs?: number;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Filesystem-backed skills source with hot reload.
|
|
68
|
+
*
|
|
69
|
+
* Lifecycle:
|
|
70
|
+
* - `start()` performs the initial scan, emitting one `upsert` per skill.
|
|
71
|
+
* Errors loading a single subdirectory are logged and that subdirectory
|
|
72
|
+
* is skipped — one bad skill never blocks the rest of the dir.
|
|
73
|
+
* - When `watch: true`, fs.watch runs against `skillsDir` (recursive). On
|
|
74
|
+
* change events we debounce, then re-load the affected subdir and emit
|
|
75
|
+
* `upsert`. A subdir that disappeared emits `delete`.
|
|
76
|
+
* - When `fs.watch` throws (Linux watch-count limit, certain network
|
|
77
|
+
* filesystems), we fall back to a polling loop that compares the
|
|
78
|
+
* directory listing on each tick.
|
|
79
|
+
* - `stop()` halts watchers, clears timers, and drops listeners.
|
|
80
|
+
*/
|
|
81
|
+
export declare class FilesystemSkillsSource {
|
|
82
|
+
private readonly logger;
|
|
83
|
+
readonly id: string;
|
|
84
|
+
private readonly options;
|
|
85
|
+
private readonly listeners;
|
|
86
|
+
private readonly known;
|
|
87
|
+
private watcher;
|
|
88
|
+
private pollTimer;
|
|
89
|
+
private debounceTimers;
|
|
90
|
+
private stopped;
|
|
91
|
+
private rootResolved;
|
|
92
|
+
constructor(options: FilesystemSkillsSourceOptions, logger: FilesystemSkillsLogger);
|
|
93
|
+
onChange(listener: FilesystemSkillsListener): () => void;
|
|
94
|
+
start(): Promise<void>;
|
|
95
|
+
stop(): Promise<void>;
|
|
96
|
+
private initialScan;
|
|
97
|
+
private listSkillSubdirs;
|
|
98
|
+
/** Reload a single skill subdir and emit upsert (or delete if vanished). */
|
|
99
|
+
private refreshSkill;
|
|
100
|
+
private emit;
|
|
101
|
+
private beginWatch;
|
|
102
|
+
private beginPolling;
|
|
103
|
+
/** Compare current dir listing to known set; emit upserts/deletes. */
|
|
104
|
+
private pollOnce;
|
|
105
|
+
/** Coarse rescan when filename is unknown (some Linux/macOS fs.watch events). */
|
|
106
|
+
private scheduleRescan;
|
|
107
|
+
private scheduleRefresh;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Read a single skill directory's SKILL.md and produce a `FilesystemSkillContent`.
|
|
111
|
+
* Exported for unit tests and for hosts that want to call directly.
|
|
112
|
+
*/
|
|
113
|
+
export declare function loadFilesystemSkill(absDir: string): Promise<FilesystemSkillContent>;
|
|
114
|
+
interface ParsedFrontmatter {
|
|
115
|
+
frontmatter: Record<string, unknown>;
|
|
116
|
+
body: string;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Minimal YAML-ish frontmatter parser — supports the subset that SKILL.md
|
|
120
|
+
* actually uses (key/value pairs, optional quoted strings, simple lists).
|
|
121
|
+
* For full YAML the host should use `loadSkillDirectory` from the SDK; this
|
|
122
|
+
* adapter intentionally avoids pulling js-yaml as a runtime dep just for
|
|
123
|
+
* parsing skill metadata.
|
|
124
|
+
*/
|
|
125
|
+
export declare function parseSkillFrontmatter(raw: string): ParsedFrontmatter;
|
|
126
|
+
export {};
|
|
127
|
+
//# sourceMappingURL=filesystem-skills.source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filesystem-skills.source.d.ts","sourceRoot":"","sources":["../../../src/skills/sources/filesystem-skills.source.ts"],"names":[],"mappings":"AAoBA;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC5D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC5D,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC9D;AAED;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACrE,mGAAmG;IACnG,SAAS,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1F,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,qBAAqB,GAC7B;IAAE,EAAE,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,sBAAsB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAChE;IAAE,EAAE,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvD,MAAM,MAAM,wBAAwB,GAAG,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC;AAE9E,MAAM,WAAW,6BAA6B;IAC5C,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,8EAA8E;IAC9E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AASD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,sBAAsB;IAa/B,OAAO,CAAC,QAAQ,CAAC,MAAM;IAZzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0C;IAClE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuC;IACjE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6C;IACnE,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,SAAS,CAA6B;IAC9C,OAAO,CAAC,cAAc,CAAqC;IAC3D,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,YAAY,CAAM;gBAGxB,OAAO,EAAE,6BAA6B,EACrB,MAAM,EAAE,sBAAsB;IAMjD,QAAQ,CAAC,QAAQ,EAAE,wBAAwB,GAAG,MAAM,IAAI;IAOlD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAoBb,WAAW;YAOX,gBAAgB;IAsC9B,4EAA4E;YAC9D,YAAY;IAoC1B,OAAO,CAAC,IAAI;IAUZ,OAAO,CAAC,UAAU;IA8BlB,OAAO,CAAC,YAAY;IAgBpB,sEAAsE;YACxD,QAAQ;IAYtB,iFAAiF;IACjF,OAAO,CAAC,cAAc;IActB,OAAO,CAAC,eAAe;CAYxB;AAID;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC,CA0CzF;AAED,UAAU,iBAAiB;IACzB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,CAuCpE"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { FrontMcpLogger } from '@frontmcp/sdk';
|
|
2
|
+
import type { BundleSourceOptions } from '../source-options';
|
|
3
|
+
import { NpmSource } from './npm.source';
|
|
4
|
+
import { SaasPullSource } from './saas-pull.source';
|
|
5
|
+
import type { SkillBundleSource } from './skill-bundle-source.interface';
|
|
6
|
+
import { StaticSource } from './static.source';
|
|
7
|
+
export { StaticSource, NpmSource, SaasPullSource };
|
|
8
|
+
export type { SkillBundleSource, BundleSourceListener } from './skill-bundle-source.interface';
|
|
9
|
+
export declare function createBundleSource(source: BundleSourceOptions, cacheDir: string | undefined, logger: FrontMcpLogger): SkillBundleSource;
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/skills/sources/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,CAAC;AACnD,YAAY,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAE/F,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,mBAAmB,EAC3B,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,MAAM,EAAE,cAAc,GACrB,iBAAiB,CASnB"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { FrontMcpLogger } from '@frontmcp/sdk';
|
|
2
|
+
import type { NpmSourceOptions } from '../source-options';
|
|
3
|
+
import type { BundleSourceListener, SkillBundleSource } from './skill-bundle-source.interface';
|
|
4
|
+
/**
|
|
5
|
+
* Loads a bundle from an npm package's default (or named) export.
|
|
6
|
+
*
|
|
7
|
+
* Refresh model: npm sources do NOT auto-refresh — the package is pinned via
|
|
8
|
+
* `package.json` and only updates after a server redeploy. This is the
|
|
9
|
+
* intentional, lower-blast-radius distribution mode.
|
|
10
|
+
*
|
|
11
|
+
* Provenance verification (GitHub artifact attestations / Sigstore) is in the
|
|
12
|
+
* v1.2 SHOULD-HAVE list but not yet implemented in OSS — when
|
|
13
|
+
* `verifyProvenance: true` (the default), this source emits a startup warning
|
|
14
|
+
* if no attestation is present so customers know what they're trading off.
|
|
15
|
+
*/
|
|
16
|
+
export declare class NpmSource implements SkillBundleSource {
|
|
17
|
+
private readonly options;
|
|
18
|
+
private readonly logger;
|
|
19
|
+
readonly id: string;
|
|
20
|
+
private listeners;
|
|
21
|
+
private cached?;
|
|
22
|
+
constructor(options: NpmSourceOptions, logger: FrontMcpLogger);
|
|
23
|
+
start(): Promise<void>;
|
|
24
|
+
onChange(listener: BundleSourceListener): () => void;
|
|
25
|
+
stop(): Promise<void>;
|
|
26
|
+
private loadBundleFromPackage;
|
|
27
|
+
protected dynamicImport(specifier: string): Promise<unknown>;
|
|
28
|
+
private notify;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=npm.source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"npm.source.d.ts","sourceRoot":"","sources":["../../../src/skills/sources/npm.source.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAIpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,KAAK,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAE/F;;;;;;;;;;;GAWG;AACH,qBAAa,SAAU,YAAW,iBAAiB;IAO/C,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAPzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,MAAM,CAAC,CAAiB;gBAGb,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAE,cAAc;IAKnC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAM5B,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,GAAG,MAAM,IAAI;IAe9C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAIb,qBAAqB;IAqBnC,SAAS,CAAC,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI5D,OAAO,CAAC,MAAM;CASf"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { FrontMcpLogger } from '@frontmcp/sdk';
|
|
2
|
+
import type { SaasSourceOptions } from '../source-options';
|
|
3
|
+
import type { BundleSourceListener, SkillBundleSource } from './skill-bundle-source.interface';
|
|
4
|
+
/**
|
|
5
|
+
* Pulls bundles from a configured SaaS endpoint via authenticated HTTPS.
|
|
6
|
+
*
|
|
7
|
+
* Boot semantics:
|
|
8
|
+
* - Always attempts a fresh pull on `start()`.
|
|
9
|
+
* - If the pull fails AND a cached bundle exists on disk, falls back to it
|
|
10
|
+
* and emits a warning. This prevents a SaaS outage at boot from killing
|
|
11
|
+
* the customer's MCP server.
|
|
12
|
+
* - If both pull and cache fail, `start()` throws.
|
|
13
|
+
*
|
|
14
|
+
* Refresh: poll on `pollIntervalMs`. Single-flight per source — overlapping
|
|
15
|
+
* polls are skipped, never queued. Webhook support is gated behind
|
|
16
|
+
* `enableWebhook` and deferred to v1.2.x (route mounting requires plugin HTTP
|
|
17
|
+
* infrastructure not yet in scope).
|
|
18
|
+
*
|
|
19
|
+
* NOTE: This source ONLY parses + caches bundles. Signature verification is
|
|
20
|
+
* applied by the bundle-sync service before the bundle becomes active.
|
|
21
|
+
*/
|
|
22
|
+
export declare class SaasPullSource implements SkillBundleSource {
|
|
23
|
+
private readonly options;
|
|
24
|
+
private readonly cacheDir;
|
|
25
|
+
private readonly logger;
|
|
26
|
+
readonly id: string;
|
|
27
|
+
private listeners;
|
|
28
|
+
private pollHandle;
|
|
29
|
+
private inFlight;
|
|
30
|
+
private stopped;
|
|
31
|
+
constructor(options: SaasSourceOptions, cacheDir: string | undefined, logger: FrontMcpLogger);
|
|
32
|
+
start(): Promise<void>;
|
|
33
|
+
onChange(listener: BundleSourceListener): () => void;
|
|
34
|
+
stop(): Promise<void>;
|
|
35
|
+
private schedulePoll;
|
|
36
|
+
private pollOnce;
|
|
37
|
+
protected httpGet(url: string, headers: Record<string, string>): Promise<{
|
|
38
|
+
status: number;
|
|
39
|
+
body: string;
|
|
40
|
+
}>;
|
|
41
|
+
private fetchOnce;
|
|
42
|
+
private cachePath;
|
|
43
|
+
private persistCache;
|
|
44
|
+
private loadCache;
|
|
45
|
+
private notify;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=saas-pull.source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"saas-pull.source.d.ts","sourceRoot":"","sources":["../../../src/skills/sources/saas-pull.source.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAIpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,KAAK,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAK/F;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,cAAe,YAAW,iBAAiB;IASpD,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAVzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,UAAU,CAA6B;IAC/C,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAS;gBAGL,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,MAAM,EAAE,cAAc;IAKnC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAqB5B,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,GAAG,MAAM,IAAI;IAO9C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAS3B,OAAO,CAAC,YAAY;YAQN,QAAQ;cAqBN,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;YAgBlG,SAAS;IAiBvB,OAAO,CAAC,SAAS;YAKH,YAAY;YAUZ,SAAS;IAUvB,OAAO,CAAC,MAAM;CASf"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ResolvedBundle } from '../bundle/bundle.types';
|
|
2
|
+
/**
|
|
3
|
+
* Pluggable source of skill bundles. Static, npm-installed, and SaaS-pull
|
|
4
|
+
* implementations all conform to this interface.
|
|
5
|
+
*
|
|
6
|
+
* Lifecycle:
|
|
7
|
+
* - `start()` is called once when the plugin is ready. The source performs
|
|
8
|
+
* its initial fetch and begins any background polling/watching.
|
|
9
|
+
* - `onChange()` registers a listener invoked every time a new bundle is
|
|
10
|
+
* available (initial fetch + every refresh).
|
|
11
|
+
* - `stop()` halts all background work and releases resources.
|
|
12
|
+
*
|
|
13
|
+
* Sources are responsible for parsing/validating their input into a
|
|
14
|
+
* ResolvedBundle (typically by calling `parseOverlay` from bundle/overlay-parser).
|
|
15
|
+
* They MUST NOT verify signatures themselves — the bundle-sync service applies
|
|
16
|
+
* the signature gate before swapping the bundle into the registry.
|
|
17
|
+
*/
|
|
18
|
+
export interface SkillBundleSource {
|
|
19
|
+
/** Stable id of this source (e.g. 'static:/path/to/bundle.yaml'). */
|
|
20
|
+
readonly id: string;
|
|
21
|
+
/**
|
|
22
|
+
* Begin operation. Must perform an initial fetch and notify listeners
|
|
23
|
+
* before resolving. Must throw if the initial fetch fails AND no fallback
|
|
24
|
+
* (e.g. cached bundle on disk for SaaS sources) is available.
|
|
25
|
+
*/
|
|
26
|
+
start(): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Subscribe to bundle updates. Returns an unsubscribe function. The first
|
|
29
|
+
* notification fires on or shortly after `start()` resolves.
|
|
30
|
+
*/
|
|
31
|
+
onChange(listener: BundleSourceListener): () => void;
|
|
32
|
+
/** Halt background work; idempotent. */
|
|
33
|
+
stop(): Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
export type BundleSourceListener = (bundle: ResolvedBundle) => void;
|
|
36
|
+
//# sourceMappingURL=skill-bundle-source.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-bundle-source.interface.d.ts","sourceRoot":"","sources":["../../../src/skills/sources/skill-bundle-source.interface.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7D;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,iBAAiB;IAChC,qEAAqE;IACrE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB;;;;OAIG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,GAAG,MAAM,IAAI,CAAC;IAErD,wCAAwC;IACxC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED,MAAM,MAAM,oBAAoB,GAAG,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { FrontMcpLogger } from '@frontmcp/sdk';
|
|
2
|
+
import type { StaticSourceOptions } from '../source-options';
|
|
3
|
+
import type { BundleSourceListener, SkillBundleSource } from './skill-bundle-source.interface';
|
|
4
|
+
/**
|
|
5
|
+
* Loads a bundle from a local file (YAML or JSON). Optionally watches the
|
|
6
|
+
* file for changes via `fs.watch` and re-fetches on edit.
|
|
7
|
+
*
|
|
8
|
+
* Bundle file extensions:
|
|
9
|
+
* - `.yaml` / `.yml` — parsed as YAML
|
|
10
|
+
* - `.json` — parsed as JSON
|
|
11
|
+
* - anything else — content sniffed (starts with `{` or `[` => JSON; else YAML)
|
|
12
|
+
*/
|
|
13
|
+
export declare class StaticSource implements SkillBundleSource {
|
|
14
|
+
private readonly options;
|
|
15
|
+
private readonly logger;
|
|
16
|
+
readonly id: string;
|
|
17
|
+
private listeners;
|
|
18
|
+
private watcher;
|
|
19
|
+
private debounceTimer;
|
|
20
|
+
private stopped;
|
|
21
|
+
constructor(options: StaticSourceOptions, logger: FrontMcpLogger);
|
|
22
|
+
start(): Promise<void>;
|
|
23
|
+
onChange(listener: BundleSourceListener): () => void;
|
|
24
|
+
stop(): Promise<void>;
|
|
25
|
+
private fetchOnce;
|
|
26
|
+
private notify;
|
|
27
|
+
private beginWatch;
|
|
28
|
+
private scheduleRefresh;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=static.source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static.source.d.ts","sourceRoot":"","sources":["../../../src/skills/sources/static.source.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAKpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,KAAK,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAE/F;;;;;;;;GAQG;AACH,qBAAa,YAAa,YAAW,iBAAiB;IASlD,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IATzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,OAAO,CAAS;gBAGL,OAAO,EAAE,mBAAmB,EAC5B,MAAM,EAAE,cAAc;IAKnC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ5B,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,GAAG,MAAM,IAAI;IAO9C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAab,SAAS;IAoBvB,OAAO,CAAC,MAAM;IAUd,OAAO,CAAC,UAAU;IAiBlB,OAAO,CAAC,eAAe;CAaxB"}
|