@pentoshi/clai 4.14.0 → 4.14.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/CONTRIBUTING.md +4 -1
- package/MCP.md +182 -0
- package/PROVIDERS.md +67 -0
- package/README.md +11 -2
- package/dist/agent/runner.js +1 -1
- package/dist/agent/runner.js.map +1 -1
- package/dist/agent/stream-recovery.js +5 -3
- package/dist/agent/stream-recovery.js.map +1 -1
- package/dist/agent/turn/mcp-agent-tools.d.ts +4 -2
- package/dist/agent/turn/mcp-agent-tools.js +15 -6
- package/dist/agent/turn/mcp-agent-tools.js.map +1 -1
- package/dist/agent/turn/tool-call-preparation.d.ts +2 -1
- package/dist/agent/turn/tool-call-preparation.js +20 -4
- package/dist/agent/turn/tool-call-preparation.js.map +1 -1
- package/dist/agent/turn/tool-execution/single-tool.js +1 -1
- package/dist/agent/turn/tool-execution/single-tool.js.map +1 -1
- package/dist/app/commands/catalog.js +1 -0
- package/dist/app/commands/catalog.js.map +1 -1
- package/dist/classic/app/action-handlers.js +2 -1
- package/dist/classic/app/action-handlers.js.map +1 -1
- package/dist/classic/app/app-wiring.js +2 -0
- package/dist/classic/app/app-wiring.js.map +1 -1
- package/dist/classic/chrome/composer-controller.d.ts +2 -1
- package/dist/classic/chrome/composer-controller.js +36 -19
- package/dist/classic/chrome/composer-controller.js.map +1 -1
- package/dist/classic/chrome/composer-frame.js +1 -1
- package/dist/classic/chrome/composer-frame.js.map +1 -1
- package/dist/classic/input/input-router.d.ts +2 -1
- package/dist/classic/input/input-router.js +9 -0
- package/dist/classic/input/input-router.js.map +1 -1
- package/dist/classic/input/key-event.d.ts +3 -0
- package/dist/classic/input/key-event.js.map +1 -1
- package/dist/classic/input/paste-burst.js +5 -0
- package/dist/classic/input/paste-burst.js.map +1 -1
- package/dist/classic/input/raw-decoder.d.ts +1 -0
- package/dist/classic/input/raw-decoder.js +15 -10
- package/dist/classic/input/raw-decoder.js.map +1 -1
- package/dist/classic/input/terminal-sequences.d.ts +0 -1
- package/dist/classic/input/terminal-sequences.js +0 -1
- package/dist/classic/input/terminal-sequences.js.map +1 -1
- package/dist/commands/providers.js +2 -0
- package/dist/commands/providers.js.map +1 -1
- package/dist/llm/adapters/mistral-messages.d.ts +1 -0
- package/dist/llm/adapters/mistral-messages.js +56 -0
- package/dist/llm/adapters/mistral-messages.js.map +1 -0
- package/dist/llm/capabilities.js +63 -1
- package/dist/llm/capabilities.js.map +1 -1
- package/dist/llm/capability/state.d.ts +1 -1
- package/dist/llm/capability/tool-dialect.js +8 -1
- package/dist/llm/capability/tool-dialect.js.map +1 -1
- package/dist/llm/capability/vision-patterns.js +6 -0
- package/dist/llm/capability/vision-patterns.js.map +1 -1
- package/dist/llm/capability/vision-registry.js +11 -1
- package/dist/llm/capability/vision-registry.js.map +1 -1
- package/dist/llm/catalog-context.d.ts +6 -0
- package/dist/llm/catalog-context.js +15 -0
- package/dist/llm/catalog-context.js.map +1 -0
- package/dist/llm/catalog-facts.d.ts +2 -0
- package/dist/llm/catalog-facts.js.map +1 -1
- package/dist/llm/cline-model-catalog.d.ts +4 -0
- package/dist/llm/cline-model-catalog.js +197 -0
- package/dist/llm/cline-model-catalog.js.map +1 -0
- package/dist/llm/cline.d.ts +1 -0
- package/dist/llm/cline.js +69 -17
- package/dist/llm/cline.js.map +1 -1
- package/dist/llm/free-model-limits.d.ts +1 -0
- package/dist/llm/free-model-limits.js +101 -0
- package/dist/llm/free-model-limits.js.map +1 -0
- package/dist/llm/free.js +136 -103
- package/dist/llm/free.js.map +1 -1
- package/dist/llm/mistral-models.d.ts +2 -0
- package/dist/llm/mistral-models.js +23 -0
- package/dist/llm/mistral-models.js.map +1 -0
- package/dist/llm/mistral.d.ts +2 -0
- package/dist/llm/mistral.js +129 -0
- package/dist/llm/mistral.js.map +1 -0
- package/dist/llm/profile/layer-merge.js +3 -3
- package/dist/llm/profile/layer-merge.js.map +1 -1
- package/dist/llm/provider-identity.js +5 -0
- package/dist/llm/provider-identity.js.map +1 -1
- package/dist/llm/provider-info-text.js +19 -0
- package/dist/llm/provider-info-text.js.map +1 -1
- package/dist/llm/provider-model-layers.js +45 -0
- package/dist/llm/provider-model-layers.js.map +1 -1
- package/dist/llm/provider-profile-layers.js +25 -0
- package/dist/llm/provider-profile-layers.js.map +1 -1
- package/dist/llm/provider-profiles.js +28 -4
- package/dist/llm/provider-profiles.js.map +1 -1
- package/dist/llm/quota-signals.d.ts +1 -0
- package/dist/llm/quota-signals.js +8 -0
- package/dist/llm/quota-signals.js.map +1 -1
- package/dist/llm/reasoning-capability.js +1 -0
- package/dist/llm/reasoning-capability.js.map +1 -1
- package/dist/llm/request-plan.js +15 -6
- package/dist/llm/request-plan.js.map +1 -1
- package/dist/llm/router.js +1 -1
- package/dist/llm/router.js.map +1 -1
- package/dist/llm/routing/attempt-complete.js +4 -3
- package/dist/llm/routing/attempt-complete.js.map +1 -1
- package/dist/llm/routing/attempt-request.d.ts +5 -1
- package/dist/llm/routing/attempt-request.js +22 -2
- package/dist/llm/routing/attempt-request.js.map +1 -1
- package/dist/llm/routing/attempt-stream.js +4 -3
- package/dist/llm/routing/attempt-stream.js.map +1 -1
- package/dist/llm/routing/failure-report.js +6 -2
- package/dist/llm/routing/failure-report.js.map +1 -1
- package/dist/llm/routing/provider-selection.js +3 -0
- package/dist/llm/routing/provider-selection.js.map +1 -1
- package/dist/llm/tool-protocol.d.ts +1 -1
- package/dist/llm/tool-protocol.js +4 -1
- package/dist/llm/tool-protocol.js.map +1 -1
- package/dist/llm/wire/chat-body.js +51 -28
- package/dist/llm/wire/chat-body.js.map +1 -1
- package/dist/llm/wire/effort-preflight.js +4 -1
- package/dist/llm/wire/effort-preflight.js.map +1 -1
- package/dist/llm/wire/mistral-content.d.ts +19 -0
- package/dist/llm/wire/mistral-content.js +106 -0
- package/dist/llm/wire/mistral-content.js.map +1 -0
- package/dist/llm/wire/mistral-model-catalog.d.ts +2 -0
- package/dist/llm/wire/mistral-model-catalog.js +73 -0
- package/dist/llm/wire/mistral-model-catalog.js.map +1 -0
- package/dist/llm/wire/openai-complete.js +10 -4
- package/dist/llm/wire/openai-complete.js.map +1 -1
- package/dist/llm/wire/openai-stream.js +38 -16
- package/dist/llm/wire/openai-stream.js.map +1 -1
- package/dist/mcp/auth/device.d.ts +7 -3
- package/dist/mcp/auth/device.js +55 -32
- package/dist/mcp/auth/device.js.map +1 -1
- package/dist/mcp/auth/http.d.ts +12 -0
- package/dist/mcp/auth/http.js +62 -0
- package/dist/mcp/auth/http.js.map +1 -0
- package/dist/mcp/auth/loopback.d.ts +9 -1
- package/dist/mcp/auth/loopback.js +80 -8
- package/dist/mcp/auth/loopback.js.map +1 -1
- package/dist/mcp/auth/metadata.d.ts +2 -3
- package/dist/mcp/auth/metadata.js +25 -25
- package/dist/mcp/auth/metadata.js.map +1 -1
- package/dist/mcp/auth/provider.d.ts +1 -0
- package/dist/mcp/auth/provider.js +215 -42
- package/dist/mcp/auth/provider.js.map +1 -1
- package/dist/mcp/auth/registration.d.ts +2 -3
- package/dist/mcp/auth/registration.js +10 -14
- package/dist/mcp/auth/registration.js.map +1 -1
- package/dist/mcp/auth/token-exchange.d.ts +5 -3
- package/dist/mcp/auth/token-exchange.js +15 -15
- package/dist/mcp/auth/token-exchange.js.map +1 -1
- package/dist/mcp/auth/token-store.d.ts +1 -1
- package/dist/mcp/auth/token-store.js +105 -54
- package/dist/mcp/auth/token-store.js.map +1 -1
- package/dist/mcp/auth/types.d.ts +11 -2
- package/dist/mcp/catalog.d.ts +11 -0
- package/dist/mcp/catalog.js +58 -0
- package/dist/mcp/catalog.js.map +1 -0
- package/dist/mcp/client.d.ts +10 -1
- package/dist/mcp/client.js +93 -29
- package/dist/mcp/client.js.map +1 -1
- package/dist/mcp/coerce.js +4 -4
- package/dist/mcp/coerce.js.map +1 -1
- package/dist/mcp/config-file.js +53 -10
- package/dist/mcp/config-file.js.map +1 -1
- package/dist/mcp/discovery.js +2 -0
- package/dist/mcp/discovery.js.map +1 -1
- package/dist/mcp/jsonrpc.js +28 -18
- package/dist/mcp/jsonrpc.js.map +1 -1
- package/dist/mcp/manager.d.ts +17 -0
- package/dist/mcp/manager.js +211 -29
- package/dist/mcp/manager.js.map +1 -1
- package/dist/mcp/results.js +25 -10
- package/dist/mcp/results.js.map +1 -1
- package/dist/mcp/runtime.d.ts +6 -6
- package/dist/mcp/runtime.js +168 -60
- package/dist/mcp/runtime.js.map +1 -1
- package/dist/mcp/schema-compact.js +3 -29
- package/dist/mcp/schema-compact.js.map +1 -1
- package/dist/mcp/storage-lock.d.ts +1 -0
- package/dist/mcp/storage-lock.js +80 -0
- package/dist/mcp/storage-lock.js.map +1 -0
- package/dist/mcp/transport-http.d.ts +13 -2
- package/dist/mcp/transport-http.js +245 -77
- package/dist/mcp/transport-http.js.map +1 -1
- package/dist/mcp/transport-stdio.d.ts +5 -2
- package/dist/mcp/transport-stdio.js +96 -52
- package/dist/mcp/transport-stdio.js.map +1 -1
- package/dist/mcp/transport.d.ts +9 -1
- package/dist/mcp/transport.js +38 -0
- package/dist/mcp/transport.js.map +1 -1
- package/dist/mcp/types.d.ts +8 -2
- package/dist/mcp/types.js +1 -5
- package/dist/mcp/types.js.map +1 -1
- package/dist/mcp/validation.js +81 -12
- package/dist/mcp/validation.js.map +1 -1
- package/dist/noninteractive/stream-renderer.d.ts +1 -0
- package/dist/noninteractive/stream-renderer.js +13 -0
- package/dist/noninteractive/stream-renderer.js.map +1 -1
- package/dist/store/config/endpoints.js +1 -0
- package/dist/store/config/endpoints.js.map +1 -1
- package/dist/store/config.js +2 -0
- package/dist/store/config.js.map +1 -1
- package/dist/store/rtk-usage.d.ts +1 -0
- package/dist/store/rtk-usage.js +8 -3
- package/dist/store/rtk-usage.js.map +1 -1
- package/dist/tools/definitions/aggregate.js +4 -1
- package/dist/tools/definitions/aggregate.js.map +1 -1
- package/dist/tools/rtk/binary.d.ts +2 -2
- package/dist/tools/rtk/binary.js +12 -4
- package/dist/tools/rtk/binary.js.map +1 -1
- package/dist/tools/rtk/rewrite.js +13 -3
- package/dist/tools/rtk/rewrite.js.map +1 -1
- package/dist/tui-v2/components/composer/composer-input-box.d.ts +6 -1
- package/dist/tui-v2/components/composer/composer-input-box.js +27 -18
- package/dist/tui-v2/components/composer/composer-input-box.js.map +1 -1
- package/dist/tui-v2/components/composer/paste-chip.d.ts +3 -2
- package/dist/tui-v2/components/composer/paste-chip.js +17 -48
- package/dist/tui-v2/components/composer/paste-chip.js.map +1 -1
- package/dist/tui-v2/composer/composer-cursor.d.ts +3 -0
- package/dist/tui-v2/composer/composer-cursor.js +21 -0
- package/dist/tui-v2/composer/composer-cursor.js.map +1 -0
- package/dist/tui-v2/composer/composer-editor.js +91 -100
- package/dist/tui-v2/composer/composer-editor.js.map +1 -1
- package/dist/tui-v2/composer/composer-highlight.d.ts +6 -1
- package/dist/tui-v2/composer/composer-highlight.js +9 -2
- package/dist/tui-v2/composer/composer-highlight.js.map +1 -1
- package/dist/tui-v2/composer/composer-wheel.js +2 -1
- package/dist/tui-v2/composer/composer-wheel.js.map +1 -1
- package/dist/tui-v2/composer/expand-paste.d.ts +4 -0
- package/dist/tui-v2/composer/expand-paste.js +34 -0
- package/dist/tui-v2/composer/expand-paste.js.map +1 -0
- package/dist/tui-v2/composer/paste-hit-test.d.ts +28 -0
- package/dist/tui-v2/composer/paste-hit-test.js +25 -0
- package/dist/tui-v2/composer/paste-hit-test.js.map +1 -0
- package/dist/tui-v2/composer/use-draft-actions.js +3 -1
- package/dist/tui-v2/composer/use-draft-actions.js.map +1 -1
- package/dist/tui-v2/input/paste-burst-guard.js +3 -0
- package/dist/tui-v2/input/paste-burst-guard.js.map +1 -1
- package/dist/types.d.ts +4 -3
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -1
- package/dist/ui/mentions.js +12 -1
- package/dist/ui/mentions.js.map +1 -1
- package/dist/ui-core/actions/action-id.d.ts +1 -1
- package/dist/ui-core/actions/action-id.js +1 -0
- package/dist/ui-core/actions/action-id.js.map +1 -1
- package/dist/ui-core/actions/format-shortcuts.js +3 -2
- package/dist/ui-core/actions/format-shortcuts.js.map +1 -1
- package/dist/ui-core/actions/keymap.js +2 -0
- package/dist/ui-core/actions/keymap.js.map +1 -1
- package/dist/ui-core/bootstrap/composition-root.js +29 -11
- package/dist/ui-core/bootstrap/composition-root.js.map +1 -1
- package/dist/ui-core/commands/mcp-commands.js +3 -3
- package/dist/ui-core/commands/mcp-commands.js.map +1 -1
- package/dist/ui-core/commands/pickers/search-reasoning.js +21 -6
- package/dist/ui-core/commands/pickers/search-reasoning.js.map +1 -1
- package/dist/ui-core/commands/rtk-commands.js +3 -3
- package/dist/ui-core/commands/rtk-commands.js.map +1 -1
- package/dist/ui-core/composer/completion.d.ts +1 -0
- package/dist/ui-core/composer/completion.js +31 -3
- package/dist/ui-core/composer/completion.js.map +1 -1
- package/dist/ui-core/composer/composer-height.d.ts +1 -1
- package/dist/ui-core/composer/composer-height.js +26 -3
- package/dist/ui-core/composer/composer-height.js.map +1 -1
- package/dist/ui-core/composer/paste-placeholder.d.ts +10 -0
- package/dist/ui-core/composer/paste-placeholder.js +60 -12
- package/dist/ui-core/composer/paste-placeholder.js.map +1 -1
- package/dist/ui-core/input/paste-burst.d.ts +2 -1
- package/dist/ui-core/input/paste-burst.js +20 -0
- package/dist/ui-core/input/paste-burst.js.map +1 -1
- package/dist/version.generated.d.ts +2 -2
- package/dist/version.generated.js +2 -2
- package/package.json +2 -1
package/dist/mcp/jsonrpc.js
CHANGED
|
@@ -16,9 +16,7 @@ export function createRequest(id, method, params) {
|
|
|
16
16
|
: { jsonrpc: "2.0", id, method, params };
|
|
17
17
|
}
|
|
18
18
|
export function createNotification(method, params) {
|
|
19
|
-
return params === undefined
|
|
20
|
-
? { jsonrpc: "2.0", method }
|
|
21
|
-
: { jsonrpc: "2.0", method, params };
|
|
19
|
+
return params === undefined ? { jsonrpc: "2.0", method } : { jsonrpc: "2.0", method, params };
|
|
22
20
|
}
|
|
23
21
|
export function encodeMessage(message) {
|
|
24
22
|
return JSON.stringify(message);
|
|
@@ -32,9 +30,17 @@ export function isJsonRpcResponse(value) {
|
|
|
32
30
|
const record = value;
|
|
33
31
|
if (record.jsonrpc !== "2.0")
|
|
34
32
|
return false;
|
|
35
|
-
|
|
33
|
+
const validId = typeof record.id === "string" || (typeof record.id === "number" && Number.isFinite(record.id));
|
|
34
|
+
if ("result" in record)
|
|
35
|
+
return validId && !("error" in record);
|
|
36
|
+
if (!validId && record.id !== null)
|
|
37
|
+
return false;
|
|
38
|
+
if (typeof record.error !== "object" || record.error === null)
|
|
36
39
|
return false;
|
|
37
|
-
|
|
40
|
+
const error = record.error;
|
|
41
|
+
return (typeof error.code === "number" &&
|
|
42
|
+
Number.isFinite(error.code) &&
|
|
43
|
+
typeof error.message === "string");
|
|
38
44
|
}
|
|
39
45
|
export function isJsonRpcSuccess(value) {
|
|
40
46
|
return "result" in value;
|
|
@@ -46,15 +52,15 @@ export function isJsonRpcRequest(value) {
|
|
|
46
52
|
if (typeof value !== "object" || value === null)
|
|
47
53
|
return false;
|
|
48
54
|
const record = value;
|
|
49
|
-
return record.jsonrpc === "2.0" &&
|
|
55
|
+
return (record.jsonrpc === "2.0" &&
|
|
56
|
+
typeof record.method === "string" &&
|
|
57
|
+
(typeof record.id === "string" || (typeof record.id === "number" && Number.isFinite(record.id))));
|
|
50
58
|
}
|
|
51
59
|
export function isJsonRpcNotification(value) {
|
|
52
60
|
if (typeof value !== "object" || value === null)
|
|
53
61
|
return false;
|
|
54
62
|
const record = value;
|
|
55
|
-
return
|
|
56
|
-
typeof record.method === "string" &&
|
|
57
|
-
!("id" in record));
|
|
63
|
+
return record.jsonrpc === "2.0" && typeof record.method === "string" && !("id" in record);
|
|
58
64
|
}
|
|
59
65
|
export function parseMessage(line) {
|
|
60
66
|
const trimmed = line.trim();
|
|
@@ -67,9 +73,7 @@ export function parseMessage(line) {
|
|
|
67
73
|
catch {
|
|
68
74
|
return undefined;
|
|
69
75
|
}
|
|
70
|
-
if (isJsonRpcResponse(parsed) ||
|
|
71
|
-
isJsonRpcRequest(parsed) ||
|
|
72
|
-
isJsonRpcNotification(parsed)) {
|
|
76
|
+
if (isJsonRpcResponse(parsed) || isJsonRpcRequest(parsed) || isJsonRpcNotification(parsed)) {
|
|
73
77
|
return parsed;
|
|
74
78
|
}
|
|
75
79
|
return undefined;
|
|
@@ -87,18 +91,21 @@ export class LineDecoder {
|
|
|
87
91
|
this.maxBytes = maxBytes > 0 ? maxBytes : MCP_MAX_FRAME_BYTES;
|
|
88
92
|
}
|
|
89
93
|
push(chunk) {
|
|
90
|
-
this.buffer +=
|
|
91
|
-
typeof chunk === "string" ? chunk : this.decoder.decode(chunk, { stream: true });
|
|
94
|
+
this.buffer += typeof chunk === "string" ? chunk : this.decoder.decode(chunk, { stream: true });
|
|
92
95
|
const lines = [];
|
|
93
96
|
let index = this.buffer.indexOf("\n");
|
|
94
97
|
while (index !== -1) {
|
|
95
98
|
const line = this.buffer.slice(0, index).replace(/\r$/, "");
|
|
99
|
+
if (Buffer.byteLength(line, "utf8") > this.maxBytes) {
|
|
100
|
+
this.buffer = "";
|
|
101
|
+
throw new McpTransportError("too-large", `MCP message exceeded the ${this.maxBytes}-byte line framing limit.`);
|
|
102
|
+
}
|
|
96
103
|
this.buffer = this.buffer.slice(index + 1);
|
|
97
104
|
if (line.length > 0)
|
|
98
105
|
lines.push(line);
|
|
99
106
|
index = this.buffer.indexOf("\n");
|
|
100
107
|
}
|
|
101
|
-
if (this.buffer
|
|
108
|
+
if (Buffer.byteLength(this.buffer, "utf8") > this.maxBytes) {
|
|
102
109
|
this.buffer = "";
|
|
103
110
|
throw new McpTransportError("too-large", `MCP message exceeded the ${this.maxBytes}-byte line framing limit before a newline arrived.`);
|
|
104
111
|
}
|
|
@@ -118,19 +125,22 @@ export class SseDecoder {
|
|
|
118
125
|
this.maxBytes = maxBytes > 0 ? maxBytes : MCP_MAX_FRAME_BYTES;
|
|
119
126
|
}
|
|
120
127
|
push(chunk) {
|
|
121
|
-
this.buffer +=
|
|
122
|
-
typeof chunk === "string" ? chunk : this.decoder.decode(chunk, { stream: true });
|
|
128
|
+
this.buffer += typeof chunk === "string" ? chunk : this.decoder.decode(chunk, { stream: true });
|
|
123
129
|
const events = [];
|
|
124
130
|
let boundary = this.nextBoundary();
|
|
125
131
|
while (boundary) {
|
|
126
132
|
const block = this.buffer.slice(0, boundary.index);
|
|
133
|
+
if (Buffer.byteLength(block, "utf8") > this.maxBytes) {
|
|
134
|
+
this.buffer = "";
|
|
135
|
+
throw new McpTransportError("too-large", `MCP SSE event exceeded the ${this.maxBytes}-byte framing limit.`);
|
|
136
|
+
}
|
|
127
137
|
this.buffer = this.buffer.slice(boundary.index + boundary.length);
|
|
128
138
|
const parsed = this.parseBlock(block);
|
|
129
139
|
if (parsed)
|
|
130
140
|
events.push(parsed);
|
|
131
141
|
boundary = this.nextBoundary();
|
|
132
142
|
}
|
|
133
|
-
if (this.buffer
|
|
143
|
+
if (Buffer.byteLength(this.buffer, "utf8") > this.maxBytes) {
|
|
134
144
|
this.buffer = "";
|
|
135
145
|
throw new McpTransportError("too-large", `MCP SSE event exceeded the ${this.maxBytes}-byte framing limit before a boundary arrived.`);
|
|
136
146
|
}
|
package/dist/mcp/jsonrpc.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jsonrpc.js","sourceRoot":"","sources":["../../src/mcp/jsonrpc.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAEpD,MAAM,OAAO,YAAa,SAAQ,KAAK;IAC5B,IAAI,CAAS;IACb,IAAI,CAAU;IACvB,YAAY,OAA4B;QACtC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAC3B,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAC3B,CAAC;CACF;AAED,MAAM,UAAU,aAAa,
|
|
1
|
+
{"version":3,"file":"jsonrpc.js","sourceRoot":"","sources":["../../src/mcp/jsonrpc.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp/manager.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ export interface McpManagerOptions {
|
|
|
16
16
|
readonly oauthInteractive?: boolean | undefined;
|
|
17
17
|
readonly onDeviceAuthorization?: AuthProviderDeps["onDeviceAuthorization"];
|
|
18
18
|
readonly onAuthorizationUrl?: AuthProviderDeps["onAuthorizationUrl"];
|
|
19
|
+
readonly readCallbackUrl?: AuthProviderDeps["readCallbackUrl"];
|
|
19
20
|
readonly authProviderFactory?: ((definition: McpServerDefinition) => McpAuthProvider | undefined) | undefined;
|
|
20
21
|
}
|
|
21
22
|
export declare class McpManager {
|
|
@@ -24,8 +25,17 @@ export declare class McpManager {
|
|
|
24
25
|
private readonly authProviders;
|
|
25
26
|
private readonly authSignatures;
|
|
26
27
|
private readonly stopped;
|
|
28
|
+
private readonly listeners;
|
|
29
|
+
private readonly recoveries;
|
|
30
|
+
private readonly catalogRefreshes;
|
|
31
|
+
private readonly dirtyCatalogs;
|
|
32
|
+
private operations;
|
|
33
|
+
private readonly lifetime;
|
|
34
|
+
private closed;
|
|
27
35
|
private discovery;
|
|
28
36
|
constructor(options?: McpManagerOptions);
|
|
37
|
+
subscribe(listener: (snapshot: McpSnapshot) => void): () => void;
|
|
38
|
+
private enqueue;
|
|
29
39
|
private get connectTimeoutMs();
|
|
30
40
|
private get requestTimeoutMs();
|
|
31
41
|
private createTransport;
|
|
@@ -41,21 +51,28 @@ export declare class McpManager {
|
|
|
41
51
|
refresh(options?: {
|
|
42
52
|
force?: boolean;
|
|
43
53
|
}): Promise<McpSnapshot>;
|
|
54
|
+
private refreshConnections;
|
|
44
55
|
forceRefresh(): Promise<McpSnapshot>;
|
|
45
56
|
private setIdleConnection;
|
|
46
57
|
isStopped(serverName: string): boolean;
|
|
47
58
|
stop(serverName: string): Promise<McpSnapshot>;
|
|
59
|
+
private stopConnection;
|
|
48
60
|
reconnect(name: string): Promise<McpSnapshot>;
|
|
61
|
+
private reconnectConnection;
|
|
49
62
|
private connect;
|
|
50
63
|
private fallbackTransportFor;
|
|
51
64
|
private attemptConnect;
|
|
65
|
+
private catalogTools;
|
|
52
66
|
private reconcileToolNames;
|
|
67
|
+
private scheduleCatalogRefresh;
|
|
53
68
|
private disposeConnection;
|
|
54
69
|
closeAll(): Promise<void>;
|
|
70
|
+
private disposeAll;
|
|
55
71
|
snapshot(): McpSnapshot;
|
|
56
72
|
private toStatus;
|
|
57
73
|
getTool(name: string): McpToolMetadata | undefined;
|
|
58
74
|
listTools(): McpToolMetadata[];
|
|
75
|
+
private recoverConnection;
|
|
59
76
|
callTool(name: string, args: Record<string, unknown>, options?: McpRequestOptions): Promise<McpNormalizedResult>;
|
|
60
77
|
login(serverName: string): Promise<{
|
|
61
78
|
ok: boolean;
|
package/dist/mcp/manager.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { discoverMcpServers } from "./discovery.js";
|
|
2
|
+
import { pathToFileURL } from "node:url";
|
|
3
|
+
import { safeCwd } from "../os/cwd.js";
|
|
2
4
|
import { McpClient } from "./client.js";
|
|
3
5
|
import { redactSecrets } from "./format.js";
|
|
4
6
|
import { toToolMetadata } from "./results.js";
|
|
5
|
-
import { allocateWireNames, canonicalToolName, toolIdentity
|
|
6
|
-
import { McpTransportError } from "./transport.js";
|
|
7
|
+
import { allocateWireNames, canonicalToolName, toolIdentity } from "./names.js";
|
|
8
|
+
import { awaitMcpOperation, McpTransportError, withTimeout, } from "./transport.js";
|
|
7
9
|
import { StdioTransport } from "./transport-stdio.js";
|
|
8
10
|
import { LegacySseTransport, StreamableHttpTransport, } from "./transport-http.js";
|
|
9
11
|
import { createAuthProvider, } from "./auth/provider.js";
|
|
@@ -30,6 +32,13 @@ export class McpManager {
|
|
|
30
32
|
authProviders = new Map();
|
|
31
33
|
authSignatures = new Map();
|
|
32
34
|
stopped = new Set();
|
|
35
|
+
listeners = new Set();
|
|
36
|
+
recoveries = new Map();
|
|
37
|
+
catalogRefreshes = new Set();
|
|
38
|
+
dirtyCatalogs = new Set();
|
|
39
|
+
operations = Promise.resolve();
|
|
40
|
+
lifetime = new AbortController();
|
|
41
|
+
closed = false;
|
|
33
42
|
discovery = {
|
|
34
43
|
servers: [],
|
|
35
44
|
shadowed: [],
|
|
@@ -40,6 +49,15 @@ export class McpManager {
|
|
|
40
49
|
constructor(options = {}) {
|
|
41
50
|
this.options = options;
|
|
42
51
|
}
|
|
52
|
+
subscribe(listener) {
|
|
53
|
+
this.listeners.add(listener);
|
|
54
|
+
return () => this.listeners.delete(listener);
|
|
55
|
+
}
|
|
56
|
+
enqueue(operation) {
|
|
57
|
+
const result = this.operations.then(operation);
|
|
58
|
+
this.operations = result.then(() => undefined, () => undefined);
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
43
61
|
get connectTimeoutMs() {
|
|
44
62
|
return this.options.connectTimeoutMs ?? DEFAULT_CONNECT_TIMEOUT_MS;
|
|
45
63
|
}
|
|
@@ -51,13 +69,15 @@ export class McpManager {
|
|
|
51
69
|
if (config.transport === "stdio") {
|
|
52
70
|
if (this.options.transportFactory)
|
|
53
71
|
return this.options.transportFactory(definition);
|
|
54
|
-
return new StdioTransport(config, {
|
|
72
|
+
return new StdioTransport(config, {
|
|
73
|
+
requestTimeoutMs: config.timeoutMs ?? this.requestTimeoutMs,
|
|
74
|
+
});
|
|
55
75
|
}
|
|
56
76
|
const authProvider = this.buildAuthProvider(definition, config);
|
|
57
77
|
if (this.options.transportFactory)
|
|
58
78
|
return this.options.transportFactory(definition);
|
|
59
79
|
const httpOptions = {
|
|
60
|
-
requestTimeoutMs: this.requestTimeoutMs,
|
|
80
|
+
requestTimeoutMs: config.timeoutMs ?? this.requestTimeoutMs,
|
|
61
81
|
...(authProvider ? { authProvider } : {}),
|
|
62
82
|
};
|
|
63
83
|
if (config.transport === "sse")
|
|
@@ -91,6 +111,7 @@ export class McpManager {
|
|
|
91
111
|
...(this.options.onAuthorizationUrl
|
|
92
112
|
? { onAuthorizationUrl: this.options.onAuthorizationUrl }
|
|
93
113
|
: {}),
|
|
114
|
+
...(this.options.readCallbackUrl ? { readCallbackUrl: this.options.readCallbackUrl } : {}),
|
|
94
115
|
};
|
|
95
116
|
const provider = createAuthProvider(config.auth ?? { kind: "oauth" }, deps);
|
|
96
117
|
this.rememberAuthProvider(definition, provider);
|
|
@@ -133,6 +154,11 @@ export class McpManager {
|
|
|
133
154
|
return this.options.discovery?.workspaceFolder;
|
|
134
155
|
}
|
|
135
156
|
async refresh(options = {}) {
|
|
157
|
+
return this.enqueue(() => this.refreshConnections(options));
|
|
158
|
+
}
|
|
159
|
+
async refreshConnections(options) {
|
|
160
|
+
if (this.closed)
|
|
161
|
+
return this.snapshot();
|
|
136
162
|
this.discovery = discoverMcpServers(this.options.discovery ?? {});
|
|
137
163
|
const next = new Map();
|
|
138
164
|
for (const definition of this.discovery.servers)
|
|
@@ -200,6 +226,9 @@ export class McpManager {
|
|
|
200
226
|
return this.stopped.has(this.resolveServerName(serverName) ?? serverName);
|
|
201
227
|
}
|
|
202
228
|
async stop(serverName) {
|
|
229
|
+
return this.enqueue(() => this.stopConnection(serverName));
|
|
230
|
+
}
|
|
231
|
+
async stopConnection(serverName) {
|
|
203
232
|
const definition = this.findDefinition(serverName);
|
|
204
233
|
if (!definition)
|
|
205
234
|
return this.snapshot();
|
|
@@ -211,6 +240,11 @@ export class McpManager {
|
|
|
211
240
|
return this.snapshot();
|
|
212
241
|
}
|
|
213
242
|
async reconnect(name) {
|
|
243
|
+
return this.enqueue(() => this.reconnectConnection(name));
|
|
244
|
+
}
|
|
245
|
+
async reconnectConnection(name) {
|
|
246
|
+
if (this.closed)
|
|
247
|
+
return this.snapshot();
|
|
214
248
|
const definition = this.findDefinition(name);
|
|
215
249
|
if (!definition)
|
|
216
250
|
return this.snapshot();
|
|
@@ -271,7 +305,7 @@ export class McpManager {
|
|
|
271
305
|
};
|
|
272
306
|
const authProvider = this.buildAuthProvider(definition, config);
|
|
273
307
|
const httpOptions = {
|
|
274
|
-
requestTimeoutMs: this.requestTimeoutMs,
|
|
308
|
+
requestTimeoutMs: config.timeoutMs ?? this.requestTimeoutMs,
|
|
275
309
|
...(authProvider ? { authProvider } : {}),
|
|
276
310
|
};
|
|
277
311
|
return alternate.transport === "sse"
|
|
@@ -280,24 +314,31 @@ export class McpManager {
|
|
|
280
314
|
}
|
|
281
315
|
async attemptConnect(definition, state, transport) {
|
|
282
316
|
let client;
|
|
317
|
+
const timeoutMs = definition.config.connectTimeoutMs ?? this.connectTimeoutMs;
|
|
318
|
+
const { signal, dispose } = withTimeout(this.lifetime.signal, timeoutMs);
|
|
283
319
|
try {
|
|
284
|
-
client = new McpClient(transport,
|
|
285
|
-
|
|
320
|
+
client = new McpClient(transport, {
|
|
321
|
+
roots: () => [
|
|
322
|
+
{
|
|
323
|
+
uri: pathToFileURL(this.options.discovery?.workspaceFolder ?? safeCwd()).href,
|
|
324
|
+
},
|
|
325
|
+
],
|
|
326
|
+
...this.options.clientOptions,
|
|
327
|
+
});
|
|
328
|
+
client.onToolsChanged(() => this.scheduleCatalogRefresh(state));
|
|
329
|
+
const init = await awaitMcpOperation(client.initialize({
|
|
330
|
+
timeoutMs,
|
|
331
|
+
signal,
|
|
332
|
+
}), signal);
|
|
286
333
|
state.client = client;
|
|
287
334
|
state.serverInfo = init.serverInfo;
|
|
288
335
|
state.protocolVersion = init.protocolVersion;
|
|
289
336
|
try {
|
|
290
|
-
const descriptors = await client.listTools({
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
.sort((a, b) => a.name.localeCompare(b.name));
|
|
296
|
-
const allocated = allocateWireNames(selected.map((descriptor) => ({
|
|
297
|
-
serverName: definition.name,
|
|
298
|
-
toolName: descriptor.name,
|
|
299
|
-
})));
|
|
300
|
-
state.tools = selected.map((descriptor) => toToolMetadata(definition.name, descriptor, allocated.get(toolIdentity(definition.name, descriptor.name))));
|
|
337
|
+
const descriptors = await client.listTools({
|
|
338
|
+
timeoutMs,
|
|
339
|
+
signal,
|
|
340
|
+
});
|
|
341
|
+
state.tools = this.catalogTools(definition, descriptors);
|
|
301
342
|
state.status = "ready";
|
|
302
343
|
state.detail = undefined;
|
|
303
344
|
}
|
|
@@ -316,8 +357,26 @@ export class McpManager {
|
|
|
316
357
|
state.client = undefined;
|
|
317
358
|
return error;
|
|
318
359
|
}
|
|
360
|
+
finally {
|
|
361
|
+
dispose();
|
|
362
|
+
}
|
|
319
363
|
return undefined;
|
|
320
364
|
}
|
|
365
|
+
catalogTools(definition, descriptors) {
|
|
366
|
+
const unique = new Map();
|
|
367
|
+
for (const tool of descriptors) {
|
|
368
|
+
if (definition.toolSelection !== "all" && !definition.toolSelection.includes(tool.name))
|
|
369
|
+
continue;
|
|
370
|
+
if (!unique.has(tool.name))
|
|
371
|
+
unique.set(tool.name, tool);
|
|
372
|
+
}
|
|
373
|
+
const selected = [...unique.values()].sort((left, right) => left.name.localeCompare(right.name));
|
|
374
|
+
const allocated = allocateWireNames(selected.map((tool) => ({
|
|
375
|
+
serverName: definition.name,
|
|
376
|
+
toolName: tool.name,
|
|
377
|
+
})));
|
|
378
|
+
return selected.map((tool) => toToolMetadata(definition.name, tool, allocated.get(toolIdentity(definition.name, tool.name))));
|
|
379
|
+
}
|
|
321
380
|
reconcileToolNames() {
|
|
322
381
|
const all = [...this.connections.values()].flatMap((state) => state.status === "ready"
|
|
323
382
|
? state.tools.map((tool) => ({
|
|
@@ -327,14 +386,52 @@ export class McpManager {
|
|
|
327
386
|
: []);
|
|
328
387
|
const allocated = allocateWireNames(all);
|
|
329
388
|
for (const state of this.connections.values()) {
|
|
330
|
-
state.tools = state.tools.map((tool) =>
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
tool
|
|
335
|
-
|
|
389
|
+
state.tools = state.tools.map((tool) => {
|
|
390
|
+
const canonicalName = canonicalToolName(tool.serverName, tool.toolName);
|
|
391
|
+
const wireName = allocated.get(toolIdentity(tool.serverName, tool.toolName)) ?? tool.wireName;
|
|
392
|
+
return canonicalName === tool.canonicalName && wireName === tool.wireName
|
|
393
|
+
? tool
|
|
394
|
+
: { ...tool, canonicalName, wireName };
|
|
395
|
+
});
|
|
336
396
|
}
|
|
337
397
|
}
|
|
398
|
+
scheduleCatalogRefresh(state) {
|
|
399
|
+
if (this.closed)
|
|
400
|
+
return;
|
|
401
|
+
if (this.catalogRefreshes.has(state)) {
|
|
402
|
+
this.dirtyCatalogs.add(state);
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
this.catalogRefreshes.add(state);
|
|
406
|
+
void this.enqueue(async () => {
|
|
407
|
+
if (this.closed || this.connections.get(state.definition.name) !== state || !state.client)
|
|
408
|
+
return;
|
|
409
|
+
this.dirtyCatalogs.delete(state);
|
|
410
|
+
try {
|
|
411
|
+
const descriptors = await state.client.listTools({
|
|
412
|
+
timeoutMs: state.definition.config.connectTimeoutMs ?? this.connectTimeoutMs,
|
|
413
|
+
signal: this.lifetime.signal,
|
|
414
|
+
});
|
|
415
|
+
state.tools = this.catalogTools(state.definition, descriptors);
|
|
416
|
+
state.status = "ready";
|
|
417
|
+
state.detail = undefined;
|
|
418
|
+
}
|
|
419
|
+
catch (error) {
|
|
420
|
+
state.detail = `Tool catalog refresh failed: ${describeError(error, this.mergedSecrets(state.definition))}`;
|
|
421
|
+
}
|
|
422
|
+
const snapshot = this.snapshot();
|
|
423
|
+
for (const listener of this.listeners)
|
|
424
|
+
listener(snapshot);
|
|
425
|
+
})
|
|
426
|
+
.catch(() => undefined)
|
|
427
|
+
.finally(() => {
|
|
428
|
+
this.catalogRefreshes.delete(state);
|
|
429
|
+
if (this.dirtyCatalogs.delete(state) &&
|
|
430
|
+
!this.closed &&
|
|
431
|
+
this.connections.get(state.definition.name) === state)
|
|
432
|
+
this.scheduleCatalogRefresh(state);
|
|
433
|
+
});
|
|
434
|
+
}
|
|
338
435
|
async disposeConnection(state) {
|
|
339
436
|
const client = state.client;
|
|
340
437
|
state.client = undefined;
|
|
@@ -342,6 +439,12 @@ export class McpManager {
|
|
|
342
439
|
await client.close().catch(() => undefined);
|
|
343
440
|
}
|
|
344
441
|
async closeAll() {
|
|
442
|
+
this.closed = true;
|
|
443
|
+
this.lifetime.abort(new McpTransportError("closed", "MCP manager closed."));
|
|
444
|
+
await this.enqueue(() => this.disposeAll());
|
|
445
|
+
this.listeners.clear();
|
|
446
|
+
}
|
|
447
|
+
async disposeAll() {
|
|
345
448
|
const states = [...this.connections.values()];
|
|
346
449
|
this.connections.clear();
|
|
347
450
|
this.stopped.clear();
|
|
@@ -407,6 +510,26 @@ export class McpManager {
|
|
|
407
510
|
listTools() {
|
|
408
511
|
return this.snapshot().tools.slice();
|
|
409
512
|
}
|
|
513
|
+
recoverConnection(serverName, client) {
|
|
514
|
+
const pending = this.recoveries.get(serverName);
|
|
515
|
+
if (pending)
|
|
516
|
+
return pending;
|
|
517
|
+
if (this.connections.get(serverName)?.client !== client)
|
|
518
|
+
return Promise.resolve(this.snapshot());
|
|
519
|
+
const recovery = this.reconnect(serverName).then((snapshot) => {
|
|
520
|
+
for (const listener of this.listeners)
|
|
521
|
+
listener(snapshot);
|
|
522
|
+
return snapshot;
|
|
523
|
+
});
|
|
524
|
+
this.recoveries.set(serverName, recovery);
|
|
525
|
+
void recovery
|
|
526
|
+
.finally(() => {
|
|
527
|
+
if (this.recoveries.get(serverName) === recovery)
|
|
528
|
+
this.recoveries.delete(serverName);
|
|
529
|
+
})
|
|
530
|
+
.catch(() => undefined);
|
|
531
|
+
return recovery;
|
|
532
|
+
}
|
|
410
533
|
async callTool(name, args, options = {}) {
|
|
411
534
|
const tool = this.getTool(name);
|
|
412
535
|
if (!tool) {
|
|
@@ -416,10 +539,63 @@ export class McpManager {
|
|
|
416
539
|
if (!state || !state.client || state.status !== "ready") {
|
|
417
540
|
throw new McpTransportError("closed", `MCP server "${tool.serverName}" is not ready.`);
|
|
418
541
|
}
|
|
419
|
-
|
|
420
|
-
timeoutMs: this.requestTimeoutMs,
|
|
542
|
+
const requestOptions = {
|
|
421
543
|
...options,
|
|
422
|
-
|
|
544
|
+
timeoutMs: options.timeoutMs ?? state.definition.config.timeoutMs ?? this.requestTimeoutMs,
|
|
545
|
+
signal: options.signal
|
|
546
|
+
? AbortSignal.any([options.signal, this.lifetime.signal])
|
|
547
|
+
: this.lifetime.signal,
|
|
548
|
+
};
|
|
549
|
+
const deadline = Date.now() + requestOptions.timeoutMs;
|
|
550
|
+
const client = state.client;
|
|
551
|
+
try {
|
|
552
|
+
return await client.callTool(tool.toolName, args, requestOptions);
|
|
553
|
+
}
|
|
554
|
+
catch (error) {
|
|
555
|
+
if (this.closed ||
|
|
556
|
+
this.stopped.has(tool.serverName) ||
|
|
557
|
+
options.signal?.aborted ||
|
|
558
|
+
!(error instanceof McpTransportError))
|
|
559
|
+
throw error;
|
|
560
|
+
const expiredSession = error.status === 404 && client.getSessionId() !== undefined;
|
|
561
|
+
const transient = ["closed", "network"].includes(error.kind) &&
|
|
562
|
+
(error.status === undefined || error.status >= 500);
|
|
563
|
+
if (!expiredSession && !transient)
|
|
564
|
+
throw error;
|
|
565
|
+
const remainingMs = deadline - Date.now();
|
|
566
|
+
const recovery = this.recoverConnection(tool.serverName, client);
|
|
567
|
+
if (remainingMs <= 0)
|
|
568
|
+
throw error;
|
|
569
|
+
const { signal, dispose } = withTimeout(requestOptions.signal, remainingMs);
|
|
570
|
+
try {
|
|
571
|
+
await awaitMcpOperation(recovery, signal);
|
|
572
|
+
}
|
|
573
|
+
finally {
|
|
574
|
+
dispose();
|
|
575
|
+
}
|
|
576
|
+
if (!expiredSession && !tool.readOnly && !tool.idempotent)
|
|
577
|
+
throw error;
|
|
578
|
+
const current = this.connections.get(tool.serverName);
|
|
579
|
+
const replacement = this.getTool(tool.canonicalName);
|
|
580
|
+
if (!current?.client ||
|
|
581
|
+
current.status !== "ready" ||
|
|
582
|
+
!replacement ||
|
|
583
|
+
replacement.readOnly !== tool.readOnly ||
|
|
584
|
+
replacement.idempotent !== tool.idempotent ||
|
|
585
|
+
replacement.destructive !== tool.destructive ||
|
|
586
|
+
replacement.openWorld !== tool.openWorld ||
|
|
587
|
+
JSON.stringify(replacement.inputSchema) !== JSON.stringify(tool.inputSchema))
|
|
588
|
+
throw error;
|
|
589
|
+
if (options.signal?.aborted)
|
|
590
|
+
throw new McpTransportError("cancelled", "MCP tool call cancelled during reconnect.");
|
|
591
|
+
const remaining = deadline - Date.now();
|
|
592
|
+
if (remaining <= 0)
|
|
593
|
+
throw new McpTransportError("timeout", "MCP tool deadline expired during reconnect.");
|
|
594
|
+
return current.client.callTool(tool.toolName, args, {
|
|
595
|
+
...requestOptions,
|
|
596
|
+
timeoutMs: remaining,
|
|
597
|
+
});
|
|
598
|
+
}
|
|
423
599
|
}
|
|
424
600
|
async login(serverName) {
|
|
425
601
|
const definition = this.findDefinition(serverName);
|
|
@@ -436,7 +612,10 @@ export class McpManager {
|
|
|
436
612
|
}
|
|
437
613
|
const provider = this.authProviders.get(resolved) ?? this.buildAuthProvider(definition, config);
|
|
438
614
|
try {
|
|
439
|
-
const ok = await provider.onUnauthorized(undefined
|
|
615
|
+
const ok = await provider.onUnauthorized(undefined, {
|
|
616
|
+
interactive: true,
|
|
617
|
+
signal: this.lifetime.signal,
|
|
618
|
+
});
|
|
440
619
|
return ok
|
|
441
620
|
? { ok: true, detail: `Authenticated MCP server ${resolved}.` }
|
|
442
621
|
: {
|
|
@@ -445,7 +624,10 @@ export class McpManager {
|
|
|
445
624
|
};
|
|
446
625
|
}
|
|
447
626
|
catch (error) {
|
|
448
|
-
return {
|
|
627
|
+
return {
|
|
628
|
+
ok: false,
|
|
629
|
+
detail: describeError(error, this.mergedSecrets(definition)),
|
|
630
|
+
};
|
|
449
631
|
}
|
|
450
632
|
}
|
|
451
633
|
}
|