@redocly/realm 0.135.0 → 0.136.0-next.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/CHANGELOG.md +35 -0
- package/dist/cli/build/analytics/collect-analytics.js +1 -1
- package/dist/cli/build/analytics/collectors/get-skills-usage.d.ts +3 -0
- package/dist/cli/build/analytics/collectors/get-skills-usage.js +1 -0
- package/dist/client/templates/openapi-docs/helpers.js +1 -1
- package/dist/constants/common.d.ts +8 -0
- package/dist/constants/common.js +1 -1
- package/dist/server/api-routes/execute-api-route.js +1 -1
- package/dist/server/api-routes/helpers/enhance-context.d.ts +3 -1
- package/dist/server/api-routes/helpers/enhance-context.js +1 -1
- package/dist/server/api-routes/helpers/is-mock-server.d.ts +2 -0
- package/dist/server/api-routes/helpers/is-mock-server.js +1 -0
- package/dist/server/api-routes/mock-server/kv-state-store.d.ts +3 -0
- package/dist/server/api-routes/mock-server/kv-state-store.js +1 -0
- package/dist/server/api-routes/mock-server/mock-js-executor.d.ts +3 -0
- package/dist/server/api-routes/mock-server/mock-js-executor.js +13 -0
- package/dist/server/config/env-config.d.ts +4 -0
- package/dist/server/config/env-schema.d.ts +10 -0
- package/dist/server/config/env-schemas/catalog.d.ts +3 -0
- package/dist/server/config/env-schemas/catalog.js +1 -1
- package/dist/server/config/env-schemas/feature-flags.d.ts +4 -0
- package/dist/server/config/env-schemas/feature-flags.js +1 -1
- package/dist/server/constants/plugins/search.d.ts +1 -2
- package/dist/server/constants/plugins/search.js +1 -1
- package/dist/server/esbuild/plugins/on-rebuild.js +1 -1
- package/dist/server/fs/fs.js +1 -1
- package/dist/server/plugins/catalog-entities/database/catalog-entities-diff-publisher.d.ts +27 -0
- package/dist/server/plugins/catalog-entities/database/catalog-entities-diff-publisher.js +12 -0
- package/dist/server/plugins/catalog-entities/database/catalog-entities-publisher.js +1 -12
- package/dist/server/plugins/catalog-entities/database/catalog-entities-revisions-pruner.d.ts +20 -0
- package/dist/server/plugins/catalog-entities/database/catalog-entities-revisions-pruner.js +42 -0
- package/dist/server/plugins/catalog-entities/database/consts.d.ts +5 -0
- package/dist/server/plugins/catalog-entities/database/consts.js +1 -1
- package/dist/server/plugins/catalog-entities/database/repositories/entities/entities-write-repository.js +1 -1
- package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/arazzo-entities-extractor.js +1 -1
- package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/asyncapi-entities-extractor.js +1 -1
- package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/graphql-entities-extractor.js +2 -2
- package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/openapi-entities-extractor.js +1 -1
- package/dist/server/plugins/catalog-entities/plugin.js +1 -1
- package/dist/server/plugins/config-parser/loaders/redocly-config-loader.js +1 -1
- package/dist/server/plugins/lifecycle.js +2 -2
- package/dist/server/plugins/mcp/{docs-mcp/codemode → codemode}/build-tool-type-declarations.d.ts +1 -1
- package/dist/server/plugins/mcp/codemode/capabilities/fetch/index.d.ts +4 -0
- package/dist/server/plugins/mcp/codemode/capabilities/fetch/index.js +4 -0
- package/dist/server/plugins/mcp/codemode/capabilities/index.d.ts +3 -0
- package/dist/server/plugins/mcp/codemode/capabilities/index.js +1 -0
- package/dist/server/plugins/mcp/codemode/capabilities/registry.d.ts +4 -0
- package/dist/server/plugins/mcp/codemode/capabilities/registry.js +1 -0
- package/dist/server/plugins/mcp/codemode/capabilities/types.d.ts +13 -0
- package/dist/server/plugins/mcp/codemode/capabilities/utils.d.ts +13 -0
- package/dist/server/plugins/mcp/codemode/capabilities/utils.js +7 -0
- package/dist/server/plugins/mcp/codemode/constants.d.ts +8 -0
- package/dist/server/plugins/mcp/codemode/constants.js +1 -0
- package/dist/server/plugins/mcp/codemode/invoke-tool.d.ts +4 -0
- package/dist/server/plugins/mcp/codemode/invoke-tool.js +1 -0
- package/dist/server/plugins/mcp/codemode/prompts.d.ts +6 -0
- package/dist/server/plugins/mcp/codemode/prompts.js +4 -0
- package/dist/server/plugins/mcp/codemode/sandbox/create-sandbox-setup.d.ts +10 -0
- package/dist/server/plugins/mcp/codemode/sandbox/create-sandbox-setup.js +11 -0
- package/dist/server/plugins/mcp/codemode/sandbox/polyfills.d.ts +2 -0
- package/dist/server/plugins/mcp/codemode/sandbox/polyfills.js +99 -0
- package/dist/server/plugins/mcp/codemode/tools/describe-tools.d.ts +7 -0
- package/dist/server/plugins/mcp/codemode/tools/describe-tools.js +1 -0
- package/dist/server/plugins/mcp/codemode/tools/execute-schema.d.ts +5 -0
- package/dist/server/plugins/mcp/codemode/tools/execute-schema.js +1 -0
- package/dist/server/plugins/mcp/codemode/tools/execute.js +1 -0
- package/dist/server/plugins/mcp/codemode/types.d.ts +16 -0
- package/dist/server/plugins/mcp/codemode/types.js +0 -0
- package/dist/server/plugins/mcp/constants.d.ts +2 -0
- package/dist/server/plugins/mcp/constants.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tool-schemas.d.ts +0 -4
- package/dist/server/plugins/mcp/docs-mcp/tool-schemas.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/openapi/list-apis.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/utils.js +1 -1
- package/dist/server/plugins/mcp/gateway-mcp/eligibility.d.ts +30 -0
- package/dist/server/plugins/mcp/gateway-mcp/eligibility.js +1 -0
- package/dist/server/plugins/mcp/gateway-mcp/fetch/allowed-hosts.d.ts +13 -0
- package/dist/server/plugins/mcp/gateway-mcp/fetch/allowed-hosts.js +1 -0
- package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-bridge.d.ts +12 -0
- package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-bridge.js +1 -0
- package/dist/server/plugins/mcp/gateway-mcp/fetch/ssrf-guard.d.ts +9 -0
- package/dist/server/plugins/mcp/gateway-mcp/fetch/ssrf-guard.js +1 -0
- package/dist/server/plugins/mcp/gateway-mcp/fetch-capability.d.ts +6 -0
- package/dist/server/plugins/mcp/gateway-mcp/fetch-capability.js +1 -0
- package/dist/server/plugins/mcp/handlers/docs-mcp-handler.js +1 -1
- package/dist/server/plugins/mcp/handlers/errors.d.ts +3 -21
- package/dist/server/plugins/mcp/handlers/errors.js +1 -1
- package/dist/server/plugins/mcp/handlers/handle-mcp-request.js +1 -1
- package/dist/server/plugins/mcp/index.js +1 -1
- package/dist/server/plugins/mcp/servers/docs-server.d.ts +5 -10
- package/dist/server/plugins/mcp/servers/docs-server.js +1 -3
- package/dist/server/plugins/mcp/servers/mcp-server.d.ts +18 -0
- package/dist/server/plugins/mcp/servers/mcp-server.js +1 -0
- package/dist/server/plugins/mcp/types.d.ts +23 -8
- package/dist/server/plugins/mcp/utils/mode.d.ts +7 -0
- package/dist/server/plugins/mcp/utils/mode.js +1 -0
- package/dist/server/plugins/mcp/utils/xmcp-utils.d.ts +12 -60
- package/dist/server/plugins/mcp/utils/xmcp-utils.js +1 -1
- package/dist/server/plugins/mcp/utils.d.ts +8 -0
- package/dist/server/plugins/mcp/utils.js +1 -1
- package/dist/server/plugins/mcp/workers/execute-mcp-tool.js +1 -1
- package/dist/server/plugins/mcp/workers/mcp-tool-telemetry.d.ts +15 -3
- package/dist/server/plugins/mcp/workers/mcp-tool-telemetry.js +1 -1
- package/dist/server/plugins/openapi-docs/index.js +1 -1
- package/dist/server/plugins/search/engines/search-engine.d.ts +2 -1
- package/dist/server/plugins/search/index.js +1 -1
- package/dist/server/plugins/skills/discover-skills.d.ts +17 -0
- package/dist/server/plugins/skills/discover-skills.js +1 -0
- package/dist/server/plugins/skills/index.d.ts +3 -0
- package/dist/server/plugins/skills/index.js +1 -0
- package/dist/server/plugins/skills/utils/parse-skill.d.ts +18 -0
- package/dist/server/plugins/skills/utils/parse-skill.js +1 -0
- package/dist/server/plugins/sso/index.js +1 -1
- package/dist/server/sandbox/constants/host-functions.d.ts +3 -0
- package/dist/server/sandbox/constants/host-functions.js +1 -0
- package/dist/server/sandbox/constants/sandbox.d.ts +6 -0
- package/dist/server/sandbox/constants/sandbox.js +1 -0
- package/dist/server/sandbox/sandbox.d.ts +8 -0
- package/dist/server/sandbox/sandbox.js +3 -0
- package/dist/server/sandbox/types.d.ts +24 -0
- package/dist/server/sandbox/types.js +0 -0
- package/dist/server/sandbox/utils/eval-guest-code.d.ts +15 -0
- package/dist/server/sandbox/utils/eval-guest-code.js +1 -0
- package/dist/server/sandbox/utils/execution-budget.d.ts +11 -0
- package/dist/server/sandbox/utils/execution-budget.js +1 -0
- package/dist/server/sandbox/utils/setup-host-functions.d.ts +18 -0
- package/dist/server/sandbox/utils/setup-host-functions.js +5 -0
- package/dist/server/store.d.ts +4 -0
- package/dist/server/store.js +1 -1
- package/dist/server/types/plugins/common.d.ts +3 -0
- package/dist/server/types/plugins/search.d.ts +0 -1
- package/dist/server/types/plugins/skills.d.ts +16 -0
- package/dist/server/types/plugins/skills.js +0 -0
- package/dist/server/utils/cookie.d.ts +3 -0
- package/dist/server/utils/cookie.js +1 -1
- package/dist/server/utils/fetch-with-client.d.ts +10 -0
- package/dist/server/utils/fetch-with-client.js +1 -0
- package/dist/server/utils/skills/can-access-skill.d.ts +9 -0
- package/dist/server/utils/skills/can-access-skill.js +1 -0
- package/dist/server/utils/skills/get-accessible-skills.d.ts +5 -0
- package/dist/server/utils/skills/get-accessible-skills.js +1 -0
- package/dist/server/utils/skills/get-skill-url.d.ts +2 -0
- package/dist/server/utils/skills/get-skill-url.js +1 -0
- package/dist/server/web-server/auth.js +4 -4
- package/dist/server/web-server/middleware/apiKeyMiddleware.js +1 -1
- package/dist/server/web-server/middleware/catalogAuthMiddleware.js +1 -1
- package/dist/server/web-server/middleware/corsMiddleware.d.ts +1 -0
- package/dist/server/web-server/middleware/corsMiddleware.js +1 -1
- package/dist/server/web-server/middleware/ensureSearchData.js +1 -1
- package/dist/server/web-server/routes/ask-ai.js +1 -1
- package/dist/server/web-server/routes/auth.js +1 -1
- package/dist/server/web-server/routes/catalog/helpers/create-entity-schema.d.ts +305 -256
- package/dist/server/web-server/routes/catalog/helpers/create-entity-update-schema.d.ts +46 -39
- package/dist/server/web-server/routes/catalog/helpers/upsert-pages-stats.js +1 -1
- package/dist/server/web-server/routes/feedback.js +1 -1
- package/dist/server/web-server/routes/health.js +1 -1
- package/dist/server/web-server/routes/index.js +1 -1
- package/dist/server/web-server/routes/mcp-routes/a2a.d.ts +10 -0
- package/dist/server/web-server/routes/mcp-routes/a2a.js +1 -0
- package/dist/server/web-server/routes/mcp-routes/agent-card.d.ts +4 -0
- package/dist/server/web-server/routes/mcp-routes/agent-card.js +1 -0
- package/dist/server/web-server/routes/mcp-routes/constants.d.ts +14 -0
- package/dist/server/web-server/routes/mcp-routes/constants.js +1 -0
- package/dist/server/web-server/routes/mcp-routes/mcp-routes.d.ts +1 -1
- package/dist/server/web-server/routes/mcp-routes/mcp-routes.js +1 -1
- package/dist/server/web-server/routes/mcp-routes/mcp-server-card.d.ts +4 -0
- package/dist/server/web-server/routes/mcp-routes/mcp-server-card.js +1 -0
- package/dist/server/web-server/routes/mcp-routes/types.d.ts +34 -0
- package/dist/server/web-server/routes/mcp-routes/types.js +0 -0
- package/dist/server/web-server/routes/mcp-routes/utils/build-agent-card.d.ts +10 -0
- package/dist/server/web-server/routes/mcp-routes/utils/build-agent-card.js +1 -0
- package/dist/server/web-server/routes/page-data.js +1 -1
- package/dist/server/web-server/routes/semantic-search.js +1 -1
- package/dist/server/web-server/routes/skills/build-skills-index.d.ts +4 -0
- package/dist/server/web-server/routes/skills/build-skills-index.js +1 -0
- package/dist/server/web-server/routes/skills/constants.d.ts +4 -0
- package/dist/server/web-server/routes/skills/constants.js +1 -0
- package/dist/server/web-server/routes/skills/skill-markdown.d.ts +4 -0
- package/dist/server/web-server/routes/skills/skill-markdown.js +1 -0
- package/dist/server/web-server/routes/skills/skills-index.d.ts +4 -0
- package/dist/server/web-server/routes/skills/skills-index.js +1 -0
- package/dist/server/web-server/routes/skills/skills-routes.d.ts +4 -0
- package/dist/server/web-server/routes/skills/skills-routes.js +1 -0
- package/dist/server/web-server/routes/skills/types.d.ts +12 -0
- package/dist/server/web-server/routes/skills/types.js +0 -0
- package/dist/server/web-server/utils/resolve-public-base-url.d.ts +4 -0
- package/dist/server/web-server/utils/resolve-public-base-url.js +1 -0
- package/dist/server/web-server/utils.js +1 -1
- package/dist/server/workers/api-routes-worker-pool.js +1 -1
- package/dist/server/workers/mcp-tool-worker-pool.js +1 -1
- package/dist/server/workers/scorecards-worker-pool.js +1 -1
- package/dist/server/workers/worker-pool.d.ts +1 -0
- package/dist/server/workers/worker-pool.js +1 -1
- package/package.json +10 -10
- package/dist/server/plugins/mcp/docs-mcp/codemode/prompts.d.ts +0 -5
- package/dist/server/plugins/mcp/docs-mcp/codemode/prompts.js +0 -4
- package/dist/server/plugins/mcp/docs-mcp/codemode/sandbox.d.ts +0 -3
- package/dist/server/plugins/mcp/docs-mcp/codemode/sandbox.js +0 -7
- package/dist/server/plugins/mcp/docs-mcp/codemode/types.d.ts +0 -9
- package/dist/server/plugins/mcp/docs-mcp/tools/execute.js +0 -1
- package/dist/server/plugins/mcp/mode.d.ts +0 -9
- package/dist/server/plugins/mcp/mode.js +0 -1
- /package/dist/server/plugins/mcp/{docs-mcp/codemode → codemode}/build-tool-type-declarations.js +0 -0
- /package/dist/server/plugins/mcp/{docs-mcp/codemode → codemode/capabilities}/types.js +0 -0
- /package/dist/server/plugins/mcp/{docs-mcp → codemode}/tools/execute.d.ts +0 -0
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import type { OpenAPIPath } from '@redocly/openapi-docs/src/types';
|
|
1
|
+
import type { OpenAPIOperation, OpenAPIPath } from '@redocly/openapi-docs/src/types';
|
|
2
2
|
import type { ApiFunctionsContext, ApiFunctionsContextMethods, PageStaticData } from '@redocly/config';
|
|
3
3
|
import type { CallToolResult, RequestId, RequestInfo, RequestMeta } from '@redocly/mcp-typescript-sdk/types.js';
|
|
4
4
|
import type { AuthInfo } from '@redocly/mcp-typescript-sdk/server/types.js';
|
|
5
5
|
import type { OpenAPIServer } from '@redocly/openapi-docs/lib/types/open-api.js';
|
|
6
6
|
import type { McpErrorCodes, McpServerType } from './constants';
|
|
7
7
|
import type { McpToolSchema } from '../../types';
|
|
8
|
+
import type { Skill } from '../../types/plugins/skills.js';
|
|
8
9
|
type ObjectValues<T> = T[keyof T];
|
|
9
10
|
export type McpServerType = ObjectValues<typeof McpServerType>;
|
|
10
11
|
export type McpErrorCodeTypes = ObjectValues<typeof McpErrorCodes>;
|
|
@@ -14,6 +15,7 @@ export type ApiDescriptionInfo = {
|
|
|
14
15
|
description?: string;
|
|
15
16
|
version?: string;
|
|
16
17
|
servers?: OpenAPIServer[];
|
|
18
|
+
fetchEligible?: boolean;
|
|
17
19
|
};
|
|
18
20
|
export type GraphqlDescriptionInfo = {
|
|
19
21
|
name: string;
|
|
@@ -30,8 +32,17 @@ export type McpDocsStaticData = PageStaticData & {
|
|
|
30
32
|
config: McpDocsStaticDataPropsConfig;
|
|
31
33
|
serverOutDir?: string;
|
|
32
34
|
tools?: McpToolSchema[];
|
|
35
|
+
skills?: Skill[];
|
|
36
|
+
skillsBaseUrl?: string;
|
|
33
37
|
};
|
|
34
38
|
};
|
|
39
|
+
export type SkillMcpResource = {
|
|
40
|
+
slug: string;
|
|
41
|
+
name: string;
|
|
42
|
+
description: string;
|
|
43
|
+
content: string;
|
|
44
|
+
uri: string;
|
|
45
|
+
};
|
|
35
46
|
export type McpPath = {
|
|
36
47
|
'x-mcp'?: XMcpConfig;
|
|
37
48
|
} & OpenAPIPath;
|
|
@@ -39,10 +50,13 @@ export type XMcpConfig = {
|
|
|
39
50
|
docs?: {
|
|
40
51
|
hide?: boolean;
|
|
41
52
|
};
|
|
53
|
+
gateway?: {
|
|
54
|
+
hide?: boolean;
|
|
55
|
+
};
|
|
42
56
|
};
|
|
43
|
-
export type
|
|
57
|
+
export type XMcpSection = keyof XMcpConfig;
|
|
58
|
+
export type McpEndpoint = OpenAPIOperation & {
|
|
44
59
|
'x-mcp'?: XMcpConfig;
|
|
45
|
-
[key: string]: any;
|
|
46
60
|
};
|
|
47
61
|
export type McpMode = 'tools' | 'code';
|
|
48
62
|
export type McpPluginConfig = {
|
|
@@ -52,10 +66,10 @@ export type McpPluginConfig = {
|
|
|
52
66
|
readonly name: string;
|
|
53
67
|
readonly ignore: readonly string[];
|
|
54
68
|
};
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
69
|
+
readonly gateway?: {
|
|
70
|
+
readonly hide: boolean;
|
|
71
|
+
readonly allowedHosts?: readonly string[];
|
|
72
|
+
};
|
|
59
73
|
};
|
|
60
74
|
export type McpUserInfo = {
|
|
61
75
|
email?: string;
|
|
@@ -66,7 +80,7 @@ export type McpUserInfo = {
|
|
|
66
80
|
scope?: string;
|
|
67
81
|
iat?: number;
|
|
68
82
|
exp?: number;
|
|
69
|
-
[key: string]:
|
|
83
|
+
[key: string]: unknown;
|
|
70
84
|
};
|
|
71
85
|
export type SemanticSearchResult = {
|
|
72
86
|
title: string;
|
|
@@ -87,6 +101,7 @@ export type McpToolContext = Omit<ApiFunctionsContext, 'telemetry' | 'getKv' | k
|
|
|
87
101
|
products?: string[];
|
|
88
102
|
accessToken?: string;
|
|
89
103
|
metadata?: Record<string, unknown>;
|
|
104
|
+
upstreamAuthorization?: string;
|
|
90
105
|
};
|
|
91
106
|
export type McpToolHandler<TArgs extends Record<string, unknown> = Record<string, unknown>> = (args: TArgs, context: McpToolContext, extra: McpToolExtra) => Promise<McpToolWorkerResponse>;
|
|
92
107
|
export type McpToolIsAvailable = (context: McpToolContext) => boolean | Promise<boolean>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { McpMode } from '../types.js';
|
|
2
|
+
/** Codemode - `execute` sandbox and `describeTools`. */
|
|
3
|
+
export declare function isMcpCodeModeEnabled(): boolean;
|
|
4
|
+
/** The gateway capability — a guarded `fetch` in the `execute` sandbox. Requires codemode to be on. */
|
|
5
|
+
export declare function isMcpGatewayEnabled(): boolean;
|
|
6
|
+
export declare function getMcpMode(): McpMode;
|
|
7
|
+
//# sourceMappingURL=mode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{envConfig as e}from"../../../config/env-config.js";function o(){return e.REDOCLY_EXP_MCP_CODE_MODE_ENABLED??!1}function n(){return(e.REDOCLY_EXP_MCP_GATEWAY_SERVER_ENABLED??!1)&&o()}function t(){return o()?"code":"tools"}export{t as getMcpMode,o as isMcpCodeModeEnabled,n as isMcpGatewayEnabled};
|
|
@@ -1,62 +1,14 @@
|
|
|
1
1
|
import type { OpenAPIDefinition } from '@redocly/openapi-docs';
|
|
2
|
-
import type { XMcpConfig,
|
|
3
|
-
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
* getXMcpConfig({}); // undefined
|
|
15
|
-
*/
|
|
16
|
-
export declare function getXMcpConfig(endpoint: McpEndpoint): XMcpConfig | undefined;
|
|
17
|
-
/**
|
|
18
|
-
* Checks if an endpoint should be hidden for a specific server type.
|
|
19
|
-
*
|
|
20
|
-
* This function determines whether an MCP endpoint should be hidden based on the
|
|
21
|
-
* x-mcp configuration and the target server type (gateway or catalog).
|
|
22
|
-
*
|
|
23
|
-
* @param endpoint - The MCP endpoint to check.
|
|
24
|
-
* @param serverType - The server type to check visibility for ('gateway' or 'catalog').
|
|
25
|
-
* @returns `true` if the endpoint should be hidden, `false` otherwise.
|
|
26
|
-
*
|
|
27
|
-
* @example
|
|
28
|
-
* isEndpointHidden({ 'x-mcp': { docs: { hide: false } } }, 'docs'); // false
|
|
29
|
-
*/
|
|
30
|
-
export declare function isEndpointHidden(endpoint: McpEndpoint, serverType: McpServerType): boolean;
|
|
31
|
-
/**
|
|
32
|
-
* Checks endpoint visibility and removes x-mcp configuration from output.
|
|
33
|
-
*
|
|
34
|
-
* This function first checks if an endpoint should be hidden for the given server type.
|
|
35
|
-
* If the endpoint is accessible, it removes the x-mcp configuration to clean up the output.
|
|
36
|
-
* This is typically used to prepare endpoints for public API documentation.
|
|
37
|
-
*
|
|
38
|
-
* @param endpoint - The MCP endpoint to process.
|
|
39
|
-
* @param serverType - The server type to check visibility for.
|
|
40
|
-
* @returns `true` if the endpoint is accessible and processed, `false` if hidden.
|
|
41
|
-
*
|
|
42
|
-
* @example
|
|
43
|
-
* checkEndpointAndDeleteXMcp(endpoint, 'docs');
|
|
44
|
-
* // Returns true and removes x-mcp from endpoint if accessible
|
|
45
|
-
*/
|
|
46
|
-
export declare function checkEndpointAndDeleteXMcp(endpoint: McpEndpoint, serverType: McpServerType): boolean;
|
|
47
|
-
/**
|
|
48
|
-
* Checks if an OpenAPI definition should be hidden based on x-mcp configuration.
|
|
49
|
-
*
|
|
50
|
-
* This function examines the info section of an OpenAPI definition for x-mcp configuration
|
|
51
|
-
* and determines if the definition should be hidden for the specified server type.
|
|
52
|
-
* If no server type is provided, it checks if the definition is hidden for any server type.
|
|
53
|
-
*
|
|
54
|
-
* @param info - The OpenAPI info object to check.
|
|
55
|
-
* @param serverType - Optional server type to check ('docs' or 'gateway').
|
|
56
|
-
* @returns `true` if the definition should be hidden, `false` otherwise.
|
|
57
|
-
*
|
|
58
|
-
* @example
|
|
59
|
-
* isDefinitionHidden({ 'x-mcp': { docs: { hide: false } } }); // false
|
|
60
|
-
*/
|
|
61
|
-
export declare function isDefinitionHidden(info: OpenAPIDefinition['info'], serverType?: McpServerType): boolean;
|
|
2
|
+
import type { XMcpConfig, XMcpSection } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Returns false when the endpoint is hidden for `section`; otherwise strips x-mcp from the
|
|
5
|
+
* output and returns true.
|
|
6
|
+
*/
|
|
7
|
+
export declare function checkEndpointAndDeleteXMcp(endpoint: {
|
|
8
|
+
'x-mcp'?: XMcpConfig;
|
|
9
|
+
}, section: XMcpSection): boolean;
|
|
10
|
+
/** Whether the definition's info-level x-mcp hides it for `section` (defaults to `docs`). */
|
|
11
|
+
export declare function isDefinitionHidden(info?: OpenAPIDefinition['info'], section?: XMcpSection): boolean;
|
|
12
|
+
/** Whether the API explicitly opts into the gateway via `x-mcp.gateway`. */
|
|
13
|
+
export declare function hasGatewayConfig(info: OpenAPIDefinition['info'] | undefined): boolean;
|
|
62
14
|
//# sourceMappingURL=xmcp-utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function
|
|
1
|
+
function c(e,t){return e?.["x-mcp"]?.[t]?.hide?!1:(e&&delete e["x-mcp"],!0)}function i(e,t){if(!e)return!1;const n=e["x-mcp"];return!n||typeof n!="object"?!1:t?n[t]?.hide===!0:n.docs?.hide===!0}function o(e){if(!e)return!1;const t=e["x-mcp"];return!!(t&&typeof t=="object"&&t.gateway)}export{c as checkEndpointAndDeleteXMcp,o as hasGatewayConfig,i as isDefinitionHidden};
|
|
@@ -60,4 +60,12 @@ export declare function filterIgnoredApiDescriptions<T extends {
|
|
|
60
60
|
export declare function isMcpInRedirects(redirects?: {
|
|
61
61
|
[key: string]: RedirectConfig;
|
|
62
62
|
}): boolean;
|
|
63
|
+
/** Whether an API definition is part of the Docs MCP catalog (not a localized copy, has public paths, not ignored via mcp.docs.ignore). */
|
|
64
|
+
export declare function isApiIncludedInDocsMcp(relativePath: string, definition: {
|
|
65
|
+
paths?: Record<string, unknown>;
|
|
66
|
+
} | undefined, mcpConfig: {
|
|
67
|
+
docs?: {
|
|
68
|
+
ignore?: readonly string[];
|
|
69
|
+
};
|
|
70
|
+
} | undefined): boolean;
|
|
63
71
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import f,{join as a}from"node:path";import u from"picomatch";import{PUBLIC_API_DEFINITIONS_FOLDER as h,L10N_DIR_NAME as o,I18N_DIR_NAME as s}from"../../constants/common.js";import{RESERVED_ROUTES as l}from"../../plugins/get-reserved-routes.js";import{canDownloadApiDefinition as m}from"../../utils/rbac.js";function p(r){if(typeof r!="object"||r===null)return r;if(Array.isArray(r))return r.map(p);const i={};for(const t in r)if(Object.hasOwn(r,t)){if(t.toString().startsWith("x-parsed-"))continue;i[t]=p(r[t])}return i}function x(r){return r.reduce((i,t)=>(t.relativePath.startsWith(o)||t.relativePath.startsWith(s)||t.definition?.paths&&Object.keys(t.definition.paths).length>0&&i.push({...t,definition:p(t.definition)}),i),[])}function R(r,i,t,e){const n={};for(const[D,c]of Object.entries(r))m(a(h,c.relativePath),t,e,i)&&(n[D]=c);return n}function g(r,i,t,e){return r.filter(n=>m(a(h,n.relativePath),t,e,i))}function E(r){return r.filter(({relativePath:i})=>!i.startsWith(o)&&!i.startsWith(s)).map(({relativePath:i,settings:t})=>({name:t.info?.title||f.basename(i,f.extname(i)),description:t.info?.description,relativePath:i}))}function _(r,i){return r.filter(({relativePath:t})=>!u(i||[])(t))}function W(r={}){for(const[i,t]of Object.entries(r))if(i===l.mcp||(typeof t=="string"?t:t.to)===l.mcp)return!0;return!1}function b(r,i,t){return r.startsWith(o)||r.startsWith(s)||!i?.paths||Object.keys(i.paths).length===0?!1:!u(t?.docs?.ignore||[])(r)}export{E as buildGraphqlDescriptions,R as filterApiDescriptionsByRbac,g as filterGraphqlDescriptionsByRbac,_ as filterIgnoredApiDescriptions,x as getCleanedUpApiDescriptions,b as isApiIncludedInDocsMcp,W as isMcpInRedirects};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{telemetry as
|
|
1
|
+
import{telemetry as d}from"../../../telemetry/index.js";import{mcpToolHandlers as w}from"../../../../client/mcp-tool-handlers-entry.js";import{getMcpMode as h}from"../utils/mode.js";import{McpServerType as i}from"../constants.js";import{reportMcpToolCalled as x,reportMcpToolError as u}from"./mcp-tool-telemetry.js";async function A(r){d.initialize();const{toolName:o,args:l,context:f,extra:t}=r,a=h(),n=performance.now();try{const e=w[o];if(!e)throw new Error(`Unknown MCP tool: ${o}`);const{default:M}=await e(),c=M[o];if(!c)throw new Error(`MCP tool module does not export a handler for "${o}". Expected \`export default { '${o}': handler }\`.`);const s=await(typeof c=="function"?c:c.execute)(l,f,t);if(!g(s))throw new Error(`MCP tool "${o}" returned an invalid result.`);const m=Math.round(performance.now()-n);if(s.isError)u({tool:o,message:s.content.map(({text:p})=>p).join(" "),mode:a,serverType:i.Docs,durationMs:m});else{const p=s.content.map(({text:y})=>y).join("").length;x({tool:o,mode:a,serverType:i.Docs,durationMs:m,outputLength:p})}return s}catch(e){throw u({tool:o,message:e instanceof Error?e.message:String(e),mode:a,serverType:i.Docs,durationMs:Math.round(performance.now()-n),stack:e instanceof Error&&e.stack||""}),e}}function g(r){return!r||typeof r!="object"?!1:Array.isArray(r.content)}async function j(r){d.initialize();const{toolName:o,context:l}=r,f=performance.now();try{const t=w[o];if(!t)return!1;const{default:a}=await t(),n=a[o];return n?typeof n=="object"&&typeof n.isAvailable=="function"?await n.isAvailable(l):!0:!1}catch(t){throw u({tool:o,message:"Failed to check if MCP tool is available: "+(t instanceof Error?t.message:String(t)),mode:h(),serverType:i.Docs,durationMs:Math.round(performance.now()-f),stack:t instanceof Error&&t.stack||""}),t}}export{A as executeMcpTool,j as isMcpToolAvailable};
|
|
@@ -1,4 +1,16 @@
|
|
|
1
|
-
import type { McpMode } from '../types.js';
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import type { McpMode, McpServerType } from '../types.js';
|
|
2
|
+
type McpToolEvent = {
|
|
3
|
+
tool: string;
|
|
4
|
+
mode: McpMode;
|
|
5
|
+
serverType: McpServerType;
|
|
6
|
+
durationMs: number;
|
|
7
|
+
};
|
|
8
|
+
export declare function reportMcpToolCalled({ tool, mode, serverType, durationMs, outputLength }: McpToolEvent & {
|
|
9
|
+
outputLength: number;
|
|
10
|
+
}): void;
|
|
11
|
+
export declare function reportMcpToolError({ tool, mode, serverType, durationMs, message, stack }: McpToolEvent & {
|
|
12
|
+
message: string;
|
|
13
|
+
stack?: string;
|
|
14
|
+
}): void;
|
|
15
|
+
export {};
|
|
4
16
|
//# sourceMappingURL=mcp-tool-telemetry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{telemetry as
|
|
1
|
+
import{telemetry as c}from"../../../telemetry/index.js";function l(r){return{id:r,object:"mcpServer",uri:`urn:redocly:realm:mcp:server:${r}`,server_type:r}}function s({tool:r,mode:e,serverType:o,durationMs:t,outputLength:n}){c.sendMcpToolCalledMessage([{...l(o),tool:r,mode:e,output_length:n,duration_ms:t}])}function i({tool:r,mode:e,serverType:o,durationMs:t,message:n,stack:p=""}){c.sendMcpErrorMessage([{...l(o),tool:r,message:n,stack:p,mode:e,duration_ms:t}])}export{s as reportMcpToolCalled,i as reportMcpToolError};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{simplifyAstStructure as Z}from"@redocly/openapi-docs";import{REDOCLY_ROUTE_RBAC as
|
|
1
|
+
import{simplifyAstStructure as Z}from"@redocly/openapi-docs";import{REDOCLY_ROUTE_RBAC as y,REDOCLY_TEAMS_RBAC as D}from"@redocly/config";import{OPENAPI_DOCS_TEMPLATE_ID as j,PUBLIC_RBAC_SCOPE_ITEM as U}from"../../../constants/common.js";import{DEPRECATED_PUBLIC_API_DEFINITIONS_FOLDER as ee,PUBLIC_API_DEFINITIONS_FOLDER as te}from"../../constants/common.js";import{OPENAPI_SHARED_DATA_PREFIX as L}from"../../constants/plugins/openapi-docs.js";import{envConfig as V}from"../../config/env-config.js";import{isRbacScopeItems as oe}from"../../utils/rbac/is-rbac-scope-items.js";import{getRouteSlugsForPath as ae}from"../utils.js";import{searchResolver as re}from"./search/search-resolver.js";import{convertOpenAPIDocs2Sidebar as ie,shouldAddRoute as se}from"./utils.js";import{getTemplatePath as q}from"./get-template-path.js";import{storeDefinitionBundles as ne}from"./store-definition-bundles.js";import{definitionLoader as pe,definitionsLoader as ce}from"./load-definition.js";import{getAiDocumentsStore as de}from"./search/get-ai-search-documents.js";import{fromCurrentDir as le}from"../../utils/paths.js";import{telemetryTraceStep as fe}from"../../../cli/telemetry/helpers/trace-step.js";import{getApiConfigByPath as ue}from"../get-api-config.js";import{shouldAdvertiseGatewayXMcp as me,buildGatewayXMcp as ge}from"../mcp/gateway-mcp/eligibility.js";const x="openapi-spec-download";async function Be(){let k=[],C={},N=new Set,d={};return{id:"openapi",requiredEntitlements:["openapi"],loaders:{"load-oas-docs":ce,"load-oas":pe},processContent:async(e,n)=>{await fe("build.plugin.openapi_docs",async l=>{e.createRequestHandler(x,le(import.meta.url,"./spec-download.api.js")),e.addApiRoute({slug:te+"/*",requestHandlerId:x,httpMethod:"all",[D]:U,getStaticData:async()=>({props:{}})}),e.addApiRoute({slug:ee+"/*",requestHandlerId:x,httpMethod:"all",[D]:U,getStaticData:async()=>({props:{}})});const E=e.createTemplate(j,q("../../../client/templates/openapi-docs/template.js")),f=e.registerServerPropsGetter(j,q("./get-server-props.js")),u=await n.getConfig();l?.setAttribute("config",JSON.stringify(u.openapi||{})),C={},d={};const p=await e.loadOpenApiDefinitions(n);k=p.map(({markdocChunks:a,relativePath:o,customOutputRelativeFile:r,isVirtual:i,realRelativePath:m})=>({chunks:a,relativePath:o,realRelativePath:m,isVirtual:r!=null||i})),ne(p,e.outdir);for(const a of p||[]){const{definition:o,config:r,relativePath:i,customOutputRelativeFile:m,contentItems:_,flatItems:g,parser:h,options:I,rawOptions:v,hash:R}=a,S=m||i,s=[],G={},{definition:X}=h||{},{info:c}=X||{},O=c?.["x-metadata"],w=!!r.openapi?.excludeFromSearch||!!r.theme?.openapi?.excludeFromSearch||!!u.openapi?.excludeFromSearch||!!u.theme?.openapi?.excludeFromSearch,H={title:c?.title,description:c?.description,summary:c?.summary,...r.metadata,...O},P={untagged:[],tagged:new Map};for(const t of g){const{id:F,href:A,operationDefinition:T}=t;if(T){const{tags:b}=T;if(b)for(const B of b)P.tagged.has(B)||P.tagged.set(B,[]),P.tagged.get(B)?.push(t);else P.untagged.push(t);V.isDevelopMode&&(G[`#${T.pointer}`]=t.href)}if(!se({item:t}))continue;const M=t,Q=M.type==="section"&&!!M.infoDefinition,W=A.split("#")[0]+"/",z=t?.operationDefinition?.[D],K=oe(r.access?.rbac)?r.access.rbac:void 0;s.push({excludeFromSearch:w,slugSuffix:W,fsPath:S,metadata:{subType:"openapi-operation"},httpVerb:t?.httpVerb||"",path:i,templateId:E,[D]:z||K,getAiDocumentsStore:de({parser:h,options:I,info:c,tagOperations:P,openapiContentItem:M,metadata:H,relativePath:i,getSearchFacets:e.getSearchFacets,includeInLLMsTxt:Q,excludeFromSearch:w}),getStaticData:async b=>({props:{dynamicMarkdocComponents:["openapi"],baseSlug:b.baseSlug,seo:t["x-metadata"]?.seo||{title:t.name,description:t.description},itemId:F,disableAutoScroll:!0}})})}if(s[0]={...s[0],metadata:{type:"openapi",...H},hasClientRoutes:!0,getSidebar:(t,F)=>{const A=[];return ie({contentItems:_,sidebarItems:A,routeSlug:t.slug,navItem:F}),A},getNavText:()=>c?.title,getSearchDocuments:re(h,I,g,e.getSearchFacets,e.setSearchFacets,w)},O?.apiId&&!a.isVirtual){const t=ue(a.config.apis,a.realRelativePath);d[O.apiId]={[D]:t.rbac,[y]:{fsPath:S}}}const Y=s[0];s[0]=s[s.length-1],s[s.length-1]=Y;for(const t of s)e.addRoute({...t,serverPropsGetterIds:[f]});const J=V.isDevelopMode?i:void 0,$=`${L}${i}`;C[$]={fsPath:S,definition:o,options:v,sourcePath:J,routesMapping:G,hash:R};for(const t of s)e.addRoute({...t,sharedData:[{id:$,key:"openAPIDocsStore"}],serverPropsGetterIds:[f]})}})},afterRoutesCreated:async(e,n)=>{const l=new Set;for(const{chunks:a,relativePath:o,isVirtual:r,realRelativePath:i}of k){const m=ae(e.getAllRoutes(),o),_=(await n.cache.load(i,"load-oas")).compoundHash;await n.cache.load(o,{loader:async function(){for(const{node:h,markdown:I,key:v,relativePath:R}of a){const{ast:S}=await e.parseMarkdoc({input:{content:I,relativePath:R,isVirtual:r},context:n,deps:{sharedDataIds:[`${L}${R}`],routeSlugs:m}});h[`x-parsed-md-${v}`]={result:Z(S)}}},name:"openapi-markdoc-inline-parser"},[_]);for(const{pointer:g}of a)l.add(g)}const E=N.difference(l);for(const a of E)n.cache.delete(a);N=l;const f=e.getConfig(),u=f.access?.rbac??{},p=n.withPathPrefix("/mcp");for(const[a,o]of Object.entries(C)){const r=e.getRouteByFsPath(o.fsPath)?.baseSlug,i=r&&me(o.definition,a.slice(L.length),u,f.mcp)?{...o.definition,"x-mcp":{...ge(p),...o.definition["x-mcp"],servers:[{url:p}]}}:o.definition;await e.createSharedData(a,{...o,definition:i,baseSlug:r},o.hash)}Object.entries(d).forEach(([a,o])=>{const r=o[y]?.fsPath;if(!r)return;const i=e.getRouteByFsPath(r)?.baseSlug;d[a]={...o,[y]:{...o[y],slug:i},slug:i}}),e.setGlobalData({apiProducts:d})}}}export{Be as openAPIDocsPlugin};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { SearchFacet } from '@redocly/theme/core/types';
|
|
2
|
-
import type { SearchEngineType
|
|
2
|
+
import type { SearchEngineType } from '@redocly/config';
|
|
3
|
+
import type { AfterRoutesCreatedActions, AddDocumentsParams, SearchDocument, AuthDetails } from '../../../types';
|
|
3
4
|
import type { FacetCountsRequestParams, GlobalData, SearchRequestParams, SearchResponse } from '../../../../types/index.js';
|
|
4
5
|
export declare class SearchEngine {
|
|
5
6
|
#private;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{REDOCLY_TEAMS_RBAC as
|
|
1
|
+
import{DEFAULT_SEARCH_ENGINE as s,REDOCLY_TEAMS_RBAC as E}from"@redocly/config";import{envConfig as c}from"../../config/env-config.js";import{logger as p}from"../../tools/notifiers/logger.js";import{reporter as u}from"../../tools/notifiers/reporter.js";import{prepareSearchDocuments as S}from"./documents/search-documents.js";import{SearchEngine as b}from"./engines/search-engine.js";import{prepareSemanticDocuments as D}from"./ai-indexer/prepare-semantic-documents.js";import{isAiSearchEnabled as y,shouldGenerateEmbeddings as A}from"./utils.js";import{telemetryTraceStep as C}from"../../../cli/telemetry/helpers/trace-step.js";import{EntitlementsProvider as R}from"../../entitlements/entitlements-provider.js";async function k(){let e=!0;return{async afterRoutesCreated(t,n){(c.SEARCH_DEV_REINIT||e)&&await _(t,n),e=!1},id:"search"}}async function _(e,t){await C("build.plugin.search",async n=>{const r=e.getConfig();if(n?.setAttribute("config",JSON.stringify(r.search||{})),r.search?.hide){p.info("Search is disabled in the config, skipping");return}const o=r.search?.engine||s,m=c.isDevelopMode?c.SEARCH_DEV_DEBUG?o:s:o,{l10n:l}=e.getGlobalData(),d=y(r),i=r.access?.rbac?.features?.aiSearch,f=A(r);let a;try{a=new b(m,l)}catch(g){await u.panic(g);return}await a.initIndexSchema(e.getSearchFacets()),e.setSearchEngine(a),e.setGlobalData({searchFeatures:{advanced:{enabled:m!==s&&!r.search?.filters?.hide},ai:{enabled:d,[E]:i&&Object.keys(i).length?i:void 0}}}),await S(t.fs,e,a);const h=R.instance().canAccessFeature("seo")===!0&&r.seo?.llmstxt?.hide!==!0;await D(e,t,{embeddingsEnabled:f,llmstxtEnabled:h})})}export{k as searchPlugin};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Skill } from '../../types/plugins/skills.js';
|
|
2
|
+
type DiscoverSkillsInput = {
|
|
3
|
+
cwd: string;
|
|
4
|
+
excludeFiles?: string[];
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Produce the full, unfiltered skill set: one skill per `@skills/<folder>/SKILL.md`
|
|
8
|
+
* plus an optional root `SKILL.md`. Slugs must be unique: the root skill wins over a
|
|
9
|
+
* colliding `@skills` entry.
|
|
10
|
+
*
|
|
11
|
+
* Skill filenames in folders are matched case-insensitively against directory listings,
|
|
12
|
+
* so behavior is identical on case-sensitive and case-insensitive filesystems — the
|
|
13
|
+
* lowercase served path is a routing concern, not an authoring rule.
|
|
14
|
+
*/
|
|
15
|
+
export declare function discoverSkills(input: DiscoverSkillsInput): Promise<Skill[]>;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=discover-skills.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import k from"picomatch";import{readdir as w,readFile as F}from"fs/promises";import p from"node:path";import{USER_SKILLS_ALIAS as h,USER_SKILL_FILENAME as u}from"../../../constants/common.js";import{logger as S}from"../../tools/notifiers/logger.js";import{slug as y}from"../../../utils/slugger.js";import{envConfig as L}from"../../config/env-config.js";import{parseSkill as j}from"./utils/parse-skill.js";const E="project-docs";async function M(t){const{cwd:s,excludeFiles:e=[]}=t,o=L.PROJECT_SLUG||E,l=e.map(r=>k(r)),c=new Map,d=await g(p.join(s,u)),i=d!==void 0?[{slug:o,fsPath:u,content:d}]:[],a=await _({cwd:s,baseSegments:[h]});for(const r of[...a,...i]){if(l.some(m=>m(r.fsPath)))continue;const n=j(r);if("error"in n){S.warn(n.error);continue}const f=c.get(n.slug);f!==void 0&&S.warn(`Skill "${n.slug}" from "${f.fsPath}" is replaced by "${n.fsPath}".`),c.set(n.slug,n)}return Array.from(c.values())}async function _(t){const{cwd:s,baseSegments:e}=t,o=p.join(s,...e),l=[],c=new Map,d=await P(o);for(const i of d){const a=y(i,{replaceDots:!0}),r=c.get(a);if(r!==void 0){S.warn(`Skipping skill folder "${[...e,i].join("/")}": its slug "${a}" collides with the folder "${r}" after slugification.`);continue}const n=await I(p.join(o,i)),f=$(n,[...e,i].join("/"));if(f===void 0)continue;const m=await g(p.join(o,i,f));m!==void 0&&(c.set(a,i),l.push({slug:a,fsPath:[...e,i,f].join("/"),content:m}))}return l}function $(t,s){const e=t.filter(l=>l.toLowerCase()===u.toLowerCase()),o=e.includes(u)?u:e[0];return e.length>1&&S.warn(`Multiple skill files in "${s}" differ only by case; using "${o}".`),o}async function g(t){try{return await F(t,"utf-8")}catch{return}}async function P(t){try{return(await w(t,{withFileTypes:!0})).filter(e=>e.isDirectory()).map(e=>e.name).sort()}catch{return[]}}async function I(t){try{return(await w(t,{withFileTypes:!0})).filter(e=>e.isFile()).map(e=>e.name).sort()}catch{return[]}}export{M as discoverSkills};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{discoverSkills as r}from"./discover-skills.js";async function o(){return{id:"skills",async afterRoutesCreated(s,l){const e=s.getConfig();if(e.skills?.hide===!0)return;const i=await r({cwd:l.fs.cwd,excludeFiles:e.skills?.excludeFiles??[]});s.addSkills(i),l.logger.verbose(`Discovered ${i.length} skill(s)`)}}}export{o as skillsPlugin};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Skill } from '../../../types/plugins/skills.js';
|
|
2
|
+
type ParseSkillInput = {
|
|
3
|
+
slug: string;
|
|
4
|
+
fsPath: string;
|
|
5
|
+
content: string;
|
|
6
|
+
};
|
|
7
|
+
type ParseSkillError = {
|
|
8
|
+
error: string;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* @param input - the skill slug, its project-relative path, and the raw file content
|
|
12
|
+
* @returns the parsed `Skill` with a `sha256:<hex>` digest over the raw content,
|
|
13
|
+
* or a `{ error }` object when the frontmatter is invalid or the required
|
|
14
|
+
* `name`/`description` fields are missing
|
|
15
|
+
*/
|
|
16
|
+
export declare function parseSkill(input: ParseSkillInput): Skill | ParseSkillError;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=parse-skill.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{extractFrontmatter as p}from"../../markdown/extract-frontmatter.js";import{shaHex as d}from"../../../utils/crypto/sha-hex.js";function u(s){const{slug:a,fsPath:t,content:e}=s,{frontmatter:r,frontmatterError:i}=p(e);if(i)return{error:`Invalid frontmatter in ${t}: ${i}`};const n=typeof r.name=="string"?r.name.trim():"",o=typeof r.description=="string"?r.description.trim():"";if(!n)return{error:`Skill ${t} is missing required frontmatter "name"`};if(!o)return{error:`Skill ${t} is missing required frontmatter "description"`};const c=r.rbac&&typeof r.rbac=="object"&&!Array.isArray(r.rbac)?r.rbac:void 0,f=Array.isArray(r.tags)?r.tags.filter(m=>typeof m=="string"):[];return{slug:a,name:n,description:o,content:e,digest:`sha256:${d(e)}`,fsPath:t,rbac:c,tags:f}}export{u as parseSkill};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{DEFAULT_SSO_IDP_TITLE as A}from"../../../constants/common.js";import{envConfig as d}from"../../config/env-config.js";import{telemetryTraceStep as I}from"../../../cli/telemetry/helpers/trace-step.js";import{logger as C}from"../../tools/notifiers/logger.js";const O="https://auth.cloud.redocly.com/oidc/.well-known/openid-configuration",_="https://auth.cloud.redocly.com/api/sso/oidc/introspect";async function S(T){return{id:"sso",async processContent(i){await I("build.plugin.sso",async f=>{const o=i.getConfig(),s=o.access;if(f?.setAttribute("config",`{"ssoDirect": ${JSON.stringify(o.ssoDirect||{})}}, {"sso": ${JSON.stringify(s?.sso||{})}}, {"idps": ${JSON.stringify(s?.idps||{})}}`),o.ssoDirect&&typeof o.ssoDirect=="object"&&Object.keys(o.ssoDirect).length!==0)return;const y=!!s?.sso&&(Array.isArray(s.sso)?s.sso.length>0:!0),r=!!s?.idps&&(Array.isArray(s.idps)?s.idps.length>0:!0);if(s?.sso&&Array.isArray(s.sso)&&!s.sso.length&&!r)return;const g=!!(s?.rbac&&typeof s.rbac=="object"&&Object.keys(s.rbac).length!==0),u=s?.requiresLogin;if(!g&&!u)return;y&&r&&C.error("access.sso and access.idps both set \u2014 should have been rejected by config validation",{sso:s.sso,idps:s.idps});let c=O,a=d.REDOCLY_OAUTH_USE_INTROSPECT?_:"";const e=s?.residency;if(e){const l=e.endsWith("/")?e.slice(0,-1):e;c=`${l.replace("app.","auth.")}/oidc/.well-known/openid-configuration`,a=d.REDOCLY_OAUTH_USE_INTROSPECT?`${l}/api/sso/oidc/introspect`:""}let n="AUTO";s?.sso&&(Array.isArray(s.sso)?n=s.sso.join(","):n=s.sso);let t="";s?.idps&&(Array.isArray(s.idps)?t=s.idps.join(","):t=s.idps);const p={login_hint:"{{ process.env.ORGANIZATION_ID }}",login_type:n
|
|
1
|
+
import{DEFAULT_SSO_IDP_TITLE as A}from"../../../constants/common.js";import{envConfig as d}from"../../config/env-config.js";import{telemetryTraceStep as I}from"../../../cli/telemetry/helpers/trace-step.js";import{logger as C}from"../../tools/notifiers/logger.js";const O="https://auth.cloud.redocly.com/oidc/.well-known/openid-configuration",_="https://auth.cloud.redocly.com/api/sso/oidc/introspect";async function S(T){return{id:"sso",async processContent(i){await I("build.plugin.sso",async f=>{const o=i.getConfig(),s=o.access;if(f?.setAttribute("config",`{"ssoDirect": ${JSON.stringify(o.ssoDirect||{})}}, {"sso": ${JSON.stringify(s?.sso||{})}}, {"idps": ${JSON.stringify(s?.idps||{})}}`),o.ssoDirect&&typeof o.ssoDirect=="object"&&Object.keys(o.ssoDirect).length!==0)return;const y=!!s?.sso&&(Array.isArray(s.sso)?s.sso.length>0:!0),r=!!s?.idps&&(Array.isArray(s.idps)?s.idps.length>0:!0);if(s?.sso&&Array.isArray(s.sso)&&!s.sso.length&&!r)return;const g=!!(s?.rbac&&typeof s.rbac=="object"&&Object.keys(s.rbac).length!==0),u=s?.requiresLogin;if(!g&&!u)return;y&&r&&C.error("access.sso and access.idps both set \u2014 should have been rejected by config validation",{sso:s.sso,idps:s.idps});let c=O,a=d.REDOCLY_OAUTH_USE_INTROSPECT?_:"";const e=s?.residency;if(e){const l=e.endsWith("/")?e.slice(0,-1):e;c=`${l.replace("app.","auth.")}/oidc/.well-known/openid-configuration`,a=d.REDOCLY_OAUTH_USE_INTROSPECT?`${l}/api/sso/oidc/introspect`:""}let n="AUTO";s?.sso&&(Array.isArray(s.sso)?n=s.sso.join(","):n=s.sso);let t="";s?.idps&&(Array.isArray(s.idps)?t=s.idps.join(","):t=s.idps);const p={login_hint:"{{ process.env.ORGANIZATION_ID }}",login_type:n};t&&(p.login_idps=t);const m={oidc:{title:A,type:"OIDC",configurationUrl:c,clientId:"{{ process.env.OAUTH_CLIENT_ID }}",clientSecret:"{{ process.env.OAUTH_CLIENT_SECRET }}",teamsClaimName:"https://redocly.com/sso/teams",scopes:["openid"],authorizationRequestCustomParams:p,audience:"{{ process.env.ORGANIZATION_ID }}",introspectEndpoint:a}};i.setGlobalConfig({ssoDirect:m})})},async afterRoutesCreated(i){}}}export{S as ssoPlugin};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const o=1048576,t="hostFunctions";export{t as DEFAULT_GLOBAL_NAME,o as MAX_HOST_OUTPUT_BYTES};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const DEFAULT_TIMEOUT_MS = 10000;
|
|
2
|
+
export declare const MEMORY_LIMIT_BYTES: number;
|
|
3
|
+
export declare const DEFAULT_MAX_LIFETIME_MS: number;
|
|
4
|
+
export declare const MAX_STACK_SIZE_BYTES: number;
|
|
5
|
+
export declare const MAX_RESULT_BYTES: number;
|
|
6
|
+
//# sourceMappingURL=sandbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const _=1e4,E=67108864,T=6e5,o=262144,t=1048576;export{T as DEFAULT_MAX_LIFETIME_MS,_ as DEFAULT_TIMEOUT_MS,t as MAX_RESULT_BYTES,o as MAX_STACK_SIZE_BYTES,E as MEMORY_LIMIT_BYTES};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { RunInSandboxOptions, SandboxResult } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Evaluates `code` in a fresh, isolated QuickJS VM bounded by memory, stack, and time. The VM
|
|
4
|
+
* starts pristine — no host access of any kind. Consumers shape the guest realm through
|
|
5
|
+
* `setupContext` (see e.g. `setupHostFunctions`); the time bounds live in `createExecutionBudget`.
|
|
6
|
+
*/
|
|
7
|
+
export declare function runInSandbox(code: string, options?: RunInSandboxOptions): Promise<SandboxResult>;
|
|
8
|
+
//# sourceMappingURL=sandbox.d.ts.map
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import f from"@jitl/quickjs-singlefile-mjs-release-sync";import{newQuickJSWASMModuleFromVariant as p}from"quickjs-emscripten-core";import{createExecutionBudget as E}from"./utils/execution-budget.js";import{DEFAULT_MAX_LIFETIME_MS as _,DEFAULT_TIMEOUT_MS as T,MAX_RESULT_BYTES as g,MAX_STACK_SIZE_BYTES as x,MEMORY_LIMIT_BYTES as y}from"./constants/sandbox.js";let c;function A(){return c??=p(f)}async function v(t,l={}){const{timeoutMs:m=T,maxLifetimeMs:d=_,setupContext:M}=l,e=(await A()).newContext();let n,s,r;try{e.runtime.setMemoryLimit(y),e.runtime.setMaxStackSize(x),n=E(e,m,d),s=M?.(e,n)??void 0,r=e.unwrapResult(e.evalCode(`(async () => {
|
|
2
|
+
${t}
|
|
3
|
+
})()`));const o=e.resolvePromise(r);e.runtime.executePendingJobs();const S=await Promise.race([o,n.aborted]),i=e.unwrapResult(S),u=e.dump(i);i.dispose();const a=JSON.stringify(u??null).length;return a>g?{error:`Result is too large (${a} bytes); return less data`}:{result:u}}catch(o){return{error:I(o)}}finally{n?.dispose(),r?.dispose();try{s?.()}catch{}try{e.dispose()}catch{c=void 0}}}function I(t){return t instanceof Error?t.message:String(t)}export{v as runInSandbox};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { QuickJSContext } from 'quickjs-emscripten-core';
|
|
2
|
+
export type SandboxResult = {
|
|
3
|
+
result?: unknown;
|
|
4
|
+
error?: string;
|
|
5
|
+
};
|
|
6
|
+
export type ExecutionBudget = {
|
|
7
|
+
/**
|
|
8
|
+
* Run `work()` as a host call: its latency is exempt from the compute budget (`timeoutMs`).
|
|
9
|
+
* While the call is in flight the idle timer is paused, and the guest gets a fresh CPU
|
|
10
|
+
* deadline when it settles — so time spent off in the host isn't charged as guest compute.
|
|
11
|
+
*/
|
|
12
|
+
hostCall<T>(work: () => Promise<T>): Promise<T>;
|
|
13
|
+
/** Rejects when a wall-clock deadline fires */
|
|
14
|
+
aborted: Promise<never>;
|
|
15
|
+
dispose(): void;
|
|
16
|
+
};
|
|
17
|
+
export type SetupSandboxContext = (context: QuickJSContext, budget: ExecutionBudget) => void | (() => void);
|
|
18
|
+
export type RunInSandboxOptions = {
|
|
19
|
+
timeoutMs?: number;
|
|
20
|
+
maxLifetimeMs?: number;
|
|
21
|
+
setupContext?: SetupSandboxContext;
|
|
22
|
+
};
|
|
23
|
+
export type SandboxHostFunction = (input: unknown) => Promise<unknown> | unknown;
|
|
24
|
+
//# sourceMappingURL=types.d.ts.map
|
|
File without changes
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { QuickJSContext } from 'quickjs-emscripten-core';
|
|
2
|
+
/**
|
|
3
|
+
* Evaluates guest source inside a QuickJS context for its side effects
|
|
4
|
+
*
|
|
5
|
+
* @param context - The QuickJS context to evaluate in
|
|
6
|
+
* @param source - Guest JavaScript source evaluated for side effects
|
|
7
|
+
* @throws When the source throws or fails to parse (unwrapped from the VM)
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* evalGuestCode(context, 'globalThis.ctx = Object.freeze({ n: 41 });');
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export declare function evalGuestCode(context: QuickJSContext, source: string): void;
|
|
15
|
+
//# sourceMappingURL=eval-guest-code.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function s(e,o){e.unwrapResult(e.evalCode(o)).dispose()}export{s as evalGuestCode};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ExecutionBudget } from '../types.js';
|
|
2
|
+
import type { QuickJSContext } from 'quickjs-emscripten-core';
|
|
3
|
+
/**
|
|
4
|
+
* Time-bounds a single sandbox run. Two deadlines — a refreshable per-stretch compute budget
|
|
5
|
+
* (`timeoutMs`) and a fixed whole-run ceiling (`maxLifetimeMs`) — are each enforced two ways,
|
|
6
|
+
* because the guest is only ever in one of two states and each enforcer reaches only one:
|
|
7
|
+
* - while the guest RUNS bytecode → the interrupt handler
|
|
8
|
+
* - while the guest is PARKED on an `await` → a wall-clock `setTimeout`
|
|
9
|
+
*/
|
|
10
|
+
export declare function createExecutionBudget(context: QuickJSContext, timeoutMs: number, maxLifetimeMs: number): ExecutionBudget;
|
|
11
|
+
//# sourceMappingURL=execution-budget.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function f(a,t,i){const s=Date.now()+i;let c=Date.now()+t,l=()=>{};const d=new Promise((e,o)=>{l=r=>o(new Error(r))});let n;const u=()=>{clearTimeout(n),n=setTimeout(()=>l(`Execution timed out after ${t}ms`),t)};a.runtime.setInterruptHandler(()=>{const e=Date.now();return e>c||e>s}),u();const T=setTimeout(()=>l(`Exceeded the maximum lifetime of ${i}ms`),i);let m=0;return{hostCall:e=>{m++,clearTimeout(n);const o=()=>{a.alive&&(c=Date.now()+t,--m===0&&u())},r=e();return r.then(o,o),r},aborted:d,dispose(){clearTimeout(n),clearTimeout(T)}}}export{f as createExecutionBudget};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ExecutionBudget, SandboxHostFunction } from '../types.js';
|
|
2
|
+
import type { QuickJSContext } from 'quickjs-emscripten-core';
|
|
3
|
+
/**
|
|
4
|
+
* Optional adapter for `runInSandbox`'s `setupContext`: exposes named host functions to the
|
|
5
|
+
* guest as one frozen global — `hostFunctions` by default, or the `globalName` the consumer
|
|
6
|
+
* chooses. Values cross the boundary as JSON strings — the guest only ever receives copies.
|
|
7
|
+
* Returns the cleanup callback.
|
|
8
|
+
*/
|
|
9
|
+
export declare function setupHostFunctions(context: QuickJSContext, hostFunctions: Record<string, SandboxHostFunction>, options?: {
|
|
10
|
+
globalName?: string;
|
|
11
|
+
budget?: ExecutionBudget;
|
|
12
|
+
maxCalls?: number;
|
|
13
|
+
messages?: {
|
|
14
|
+
outputTooLarge?: (bytes: number) => string;
|
|
15
|
+
callLimitExceeded?: (max: number) => string;
|
|
16
|
+
};
|
|
17
|
+
}): () => void;
|
|
18
|
+
//# sourceMappingURL=setup-host-functions.d.ts.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import{DEFAULT_GLOBAL_NAME as v,MAX_HOST_OUTPUT_BYTES as _}from"../constants/host-functions.js";import{evalGuestCode as E}from"./eval-guest-code.js";function w(e,o,s){const l=s?.globalName??v,u=s?.maxCalls,f=s?.messages?.outputTooLarge??(n=>`Host function output is too large (${n} bytes); request narrower data instead`),m=s?.messages?.callLimitExceeded??(n=>`Exceeded the limit of ${n} host calls`),d=s?.budget?.hostCall??(n=>n()),c=new Set;let S=0;return e.newFunction("__invoke",(n,a)=>{const h=e.getString(n),p=JSON.parse(e.getString(a)),r=e.newPromise();return c.add(r),u!==void 0&&++S>u?e.newError(m(u)).consume(r.reject):d(()=>Promise.resolve().then(()=>o[h](p))).then(t=>{if(!e.alive)return;let i;try{i=JSON.stringify(t??null)}catch(g){const b=g instanceof Error?g.message:String(g);e.newError(`Host function output is not serializable: ${b}`).consume(r.reject);return}i.length>_?e.newError(f(i.length)).consume(r.reject):e.newString(i).consume(r.resolve)},t=>{if(!e.alive)return;const i=t instanceof Error?t.message:String(t);e.newError(i).consume(r.reject)}),r.settled.then(()=>{e.alive&&e.runtime.executePendingJobs()}),r.handle}).consume(n=>e.setProp(e.global,"__invoke",n)),E(e,O(Object.keys(o),l)),function(){for(const a of c)a.alive&&a.dispose()}}function O(e,o){const s=e.map(l=>`${JSON.stringify(l)}: (input) => invoke(${JSON.stringify(l)}, JSON.stringify(input ?? {})).then(JSON.parse)`).join(", ");return`(() => {
|
|
2
|
+
const invoke = globalThis.__invoke;
|
|
3
|
+
delete globalThis.__invoke;
|
|
4
|
+
globalThis[${JSON.stringify(o)}] = Object.freeze({ ${s} });
|
|
5
|
+
})();`}export{w as setupHostFunctions};
|
package/dist/server/store.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { Node } from '@markdoc/markdoc';
|
|
|
2
2
|
import type { JSX } from 'react';
|
|
3
3
|
import type { CommonError, GlobalData } from '../types/index.js';
|
|
4
4
|
import type { MiddlewareDetails, PageRouteInit, PageRouteDetails, RouteDetails, LifecycleContext, ApiRoute, ParseMarkdocOpts, WildcardRedirectsTree, RedirectOptions, McpToolRegistration, McpToolSchema, MarkdocOptions } from './types';
|
|
5
|
+
import type { Skill } from './types/plugins/skills.js';
|
|
5
6
|
import type { RedoclyConfig, RedirectConfig, CompilationError, PageStaticData } from '@redocly/config';
|
|
6
7
|
import type { SearchFacet } from '@redocly/theme/core/types';
|
|
7
8
|
import type { BundledDefinition as OpenApiBundledDefinition } from './plugins/openapi-docs/load-definition.js';
|
|
@@ -55,6 +56,7 @@ export declare class Store {
|
|
|
55
56
|
browserPlugins: Set<string>;
|
|
56
57
|
apiRoutesRequestHandlers: Map<string, string>;
|
|
57
58
|
mcpToolHandlers: Map<string, McpToolRegistration>;
|
|
59
|
+
skills: Map<string, Skill>;
|
|
58
60
|
serverPropsGetters: Map<string, string>;
|
|
59
61
|
pagePropsGetters: Map<string, string>;
|
|
60
62
|
listeners: Map<string, Set<(...args: any[]) => void>>;
|
|
@@ -127,6 +129,8 @@ export declare class Store {
|
|
|
127
129
|
addApiRoute: (route: ApiRoute) => void;
|
|
128
130
|
addMcpTools: (importPath: string, tools: McpToolSchema[]) => void;
|
|
129
131
|
getMcpTools: () => McpToolRegistration[];
|
|
132
|
+
addSkills: (skills: Skill[]) => void;
|
|
133
|
+
getSkills: () => Skill[];
|
|
130
134
|
addMiddleware: (middleware: MiddlewareDetails) => void;
|
|
131
135
|
setResourceResponseHeaders: (resourcePath: string, headers: NonNullable<RedoclyConfig['responseHeaders']>[string]) => void;
|
|
132
136
|
getRouteByFsPath: (relativePath: string) => PageRouteDetails | undefined;
|